diff --git a/.clang-format b/.clang-format index 2a9205219a..ef3ce64192 100644 --- a/.clang-format +++ b/.clang-format @@ -7,28 +7,34 @@ AlignConsecutiveDeclarations: false AlignEscapedNewlines: Right AlignOperands: false AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: None AlwaysBreakAfterReturnType: None AlwaysBreakTemplateDeclarations: true +BinPackParameters: false BreakBeforeBraces: Custom BraceWrapping: AfterClass: true + AfterControlStatement: true AfterEnum: true AfterFunction: true AfterNamespace: true + BeforeLambdaBody: true AfterStruct: true - SplitEmptyFunction: true - AfterControlStatement: true BeforeElse: true + SplitEmptyFunction: true BreakBeforeTernaryOperators: true BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma ColumnLimit: 140 ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true +Cpp11BracedListStyle: false FixNamespaceComments: true IncludeBlocks: Preserve +IndentCaseBlocks: true IndentCaseLabels: false IndentPPDirectives: None IndentWidth: 4 @@ -38,27 +44,17 @@ NamespaceIndentation: All PenaltyReturnTypeOnItsOwnLine: 1000 PointerAlignment: Left SortIncludes: true +SpaceAfterLogicalNot: false SpaceAfterTemplateKeyword: false SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyParentheses: false SpacesInAngles: false SpacesInCStyleCastParentheses: false SpacesInParentheses: false +Standard: c++17 UseTab: Never - -# Not available in clang-format version 6.0.0 -# BasedOnStyle: Microsoft -# Standard: c++17 -# AllowAllArgumentsOnNextLine: true -# AllowShortLambdasOnASingleLine: None -# BreakInheritanceList: BeforeComma -# SpaceAfterLogicalNot: false -# SpaceBeforeCpp11BracedList: false -# SpaceBeforeCtorInitializerColon: true -# SpaceBeforeInheritanceColon: true -# SpaceBeforeRangeBasedForLoopColon: true - -# Not available in clang-format version 10.0.0 -# BeforeLambdaBody: true (BraceWrapping) -# IndentCaseBlocks: true diff --git a/.gitattributes b/.gitattributes index 1755def66a..2037909dbd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -115,5 +115,12 @@ *.wav filter=lfs diff=lfs merge=lfs -text *.webm filter=lfs diff=lfs merge=lfs -text *.wem filter=lfs diff=lfs merge=lfs -text -*.wxs filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text +*.tbscene filter=lfs diff=lfs merge=lfs -text +*.spp filter=lfs diff=lfs merge=lfs -text +Gems/Atom/Tools/MaterialEditor/Assets/MaterialEditor/ViewportModels/Hermanubis.fbx filter=lfs diff=lfs merge=lfs -text +Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/Lucy_High.fbx filter=lfs diff=lfs merge=lfs -text +Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/Lucy_low.fbx filter=lfs diff=lfs merge=lfs -text +Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/marmoset_bake.tbscene filter=lfs diff=lfs merge=lfs -text +Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/Brass/brass_bake.spp filter=lfs diff=lfs merge=lfs -text +Gems/AtomLyIntegration/CommonFeatures/Assets/Objects/Lucy/.wip/stone/stone_bake.spp filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index c3af907e97..664680c5bf 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ __pycache__ AssetProcessorTemp/** [Bb]uild/** [Cc]ache/ +/install/ Editor/EditorEventLog.xml Editor/EditorLayout.xml **/*egg-info/** @@ -19,3 +20,4 @@ _savebackup/ TestResults/** *.swatches /imgui.ini +/scripts/project_manager/logs/ diff --git a/Assets/Editor/Icons/Components/NonUniformScale.svg b/Assets/Editor/Icons/Components/NonUniformScale.svg new file mode 100644 index 0000000000..f377232d62 --- /dev/null +++ b/Assets/Editor/Icons/Components/NonUniformScale.svg @@ -0,0 +1,27 @@ + + + Icons / Toolbar / Non Uniform Scaling + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/Editor/Prefabs/Default_Level.prefab b/Assets/Editor/Prefabs/Default_Level.prefab new file mode 100644 index 0000000000..fb82c5ab03 --- /dev/null +++ b/Assets/Editor/Prefabs/Default_Level.prefab @@ -0,0 +1,666 @@ +{ + "Source": "Default_Level.prefab", + "ContainerEntity": { + "Id": "Entity_[1146574390643]", + "Name": "Level", + "Components": { + "Component_[10641544592923449938]": { + "$type": "EditorInspectorComponent", + "Id": 10641544592923449938 + }, + "Component_[12039882709170782873]": { + "$type": "EditorOnlyEntityComponent", + "Id": 12039882709170782873 + }, + "Component_[12265484671603697631]": { + "$type": "EditorPendingCompositionComponent", + "Id": 12265484671603697631 + }, + "Component_[14126657869720434043]": { + "$type": "EditorEntitySortComponent", + "Id": 14126657869720434043 + }, + "Component_[15230859088967841193]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 15230859088967841193, + "Parent Entity": "", + "Cached World Transform Parent": "" + }, + "Component_[16239496886950819870]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 16239496886950819870 + }, + "Component_[5688118765544765547]": { + "$type": "EditorEntityIconComponent", + "Id": 5688118765544765547 + }, + "Component_[6545738857812235305]": { + "$type": "SelectionComponent", + "Id": 6545738857812235305 + }, + "Component_[7247035804068349658]": { + "$type": "EditorPrefabComponent", + "Id": 7247035804068349658 + }, + "Component_[9307224322037797205]": { + "$type": "EditorLockComponent", + "Id": 9307224322037797205 + }, + "Component_[9562516168917670048]": { + "$type": "EditorVisibilityComponent", + "Id": 9562516168917670048 + } + }, + "IsDependencyReady": true + }, + "Entities": { + "Entity_[1155164325235]": { + "Id": "Entity_[1155164325235]", + "Name": "Sun", + "Components": { + "Component_[10440557478882592717]": { + "$type": "SelectionComponent", + "Id": 10440557478882592717 + }, + "Component_[13620450453324765907]": { + "$type": "EditorLockComponent", + "Id": 13620450453324765907 + }, + "Component_[2134313378593666258]": { + "$type": "EditorInspectorComponent", + "Id": 2134313378593666258 + }, + "Component_[234010807770404186]": { + "$type": "EditorVisibilityComponent", + "Id": 234010807770404186 + }, + "Component_[2970359110423865725]": { + "$type": "EditorEntityIconComponent", + "Id": 2970359110423865725 + }, + "Component_[3722854130373041803]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3722854130373041803 + }, + "Component_[5992533738676323195]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5992533738676323195 + }, + "Component_[7378860763541895402]": { + "$type": "AZ::Render::EditorDirectionalLightComponent", + "Id": 7378860763541895402, + "Controller": { + "Configuration": { + "Intensity": 1.0, + "CameraEntityId": "", + "ShadowFilterMethod": 1, + "ShadowmapSize": "Size1024", + "Pcf Method": 1 + } + } + }, + "Component_[7892834440890947578]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 7892834440890947578, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Translate": [ + 0.0, + 0.0, + 13.487043380737305 + ], + "Rotate": [ + -76.13099670410156, + -0.847000002861023, + -15.8100004196167 + ] + }, + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 9.442070960998536 + ], + "Rotation": [ + -0.6098860502243042, + -0.09055805951356888, + -0.10376212745904924, + 0.7804304361343384 + ] + }, + "Cached World Transform Parent": "Entity_[1176639161715]" + }, + "Component_[8599729549570828259]": { + "$type": "EditorEntitySortComponent", + "Id": 8599729549570828259 + }, + "Component_[952797371922080273]": { + "$type": "EditorPendingCompositionComponent", + "Id": 952797371922080273 + } + }, + "IsDependencyReady": true + }, + "Entity_[1159459292531]": { + "Id": "Entity_[1159459292531]", + "Name": "Ground", + "Components": { + "Component_[11701138785793981042]": { + "$type": "SelectionComponent", + "Id": 11701138785793981042 + }, + "Component_[12260880513256986252]": { + "$type": "EditorEntityIconComponent", + "Id": 12260880513256986252 + }, + "Component_[13711420870643673468]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 13711420870643673468 + }, + "Component_[138002849734991713]": { + "$type": "EditorOnlyEntityComponent", + "Id": 138002849734991713 + }, + "Component_[16578565737331764849]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 16578565737331764849, + "Parent Entity": "Entity_[1176639161715]", + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 0.0 + ] + }, + "Cached World Transform Parent": "Entity_[1176639161715]" + }, + "Component_[16919232076966545697]": { + "$type": "EditorInspectorComponent", + "Id": 16919232076966545697 + }, + "Component_[5182430712893438093]": { + "$type": "EditorMaterialComponent", + "Id": 5182430712893438093, + "materialSlots": [ + { + "id": { + "materialAssetId": { + "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}", + "subId": 803645540 + } + } + } + ], + "materialSlotsByLod": [ + [ + { + "id": { + "lodIndex": 0, + "materialAssetId": { + "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}", + "subId": 803645540 + } + } + } + ] + ] + }, + "Component_[5675108321710651991]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 5675108321710651991, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}", + "subId": 277333723 + }, + "assetHint": "objects/groudplane/groundplane_521x521m.azmodel" + } + } + } + }, + "Component_[5681893399601237518]": { + "$type": "EditorEntitySortComponent", + "Id": 5681893399601237518 + }, + "Component_[592692962543397545]": { + "$type": "EditorPendingCompositionComponent", + "Id": 592692962543397545 + }, + "Component_[7090012899106946164]": { + "$type": "EditorLockComponent", + "Id": 7090012899106946164 + }, + "Component_[9410832619875640998]": { + "$type": "EditorVisibilityComponent", + "Id": 9410832619875640998 + } + }, + "IsDependencyReady": true + }, + "Entity_[1163754259827]": { + "Id": "Entity_[1163754259827]", + "Name": "Camera", + "Components": { + "Component_[11895140916889160460]": { + "$type": "EditorEntityIconComponent", + "Id": 11895140916889160460 + }, + "Component_[16880285896855930892]": { + "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent", + "Id": 16880285896855930892, + "Controller": { + "Configuration": { + "Field of View": 55.0, + "EditorEntityId": 8929576024571800510 + } + } + }, + "Component_[17187464423780271193]": { + "$type": "EditorLockComponent", + "Id": 17187464423780271193 + }, + "Component_[17495696818315413311]": { + "$type": "EditorEntitySortComponent", + "Id": 17495696818315413311 + }, + "Component_[18086214374043522055]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 18086214374043522055, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Translate": [ + -2.300000190734864, + -3.9368600845336916, + 1.0 + ], + "Rotate": [ + -2.050307512283325, + 1.9552897214889529, + -43.62335586547852 + ] + }, + "Cached World Transform": { + "Translation": [ + -11.904647827148438, + 13.392678260803223, + -3.0449724197387697 + ], + "Rotation": [ + -0.02294669672846794, + 0.00919158011674881, + -0.37172695994377139, + 0.9280129671096802 + ] + }, + "Cached World Transform Parent": "Entity_[1176639161715]" + }, + "Component_[18387556550380114975]": { + "$type": "SelectionComponent", + "Id": 18387556550380114975 + }, + "Component_[2654521436129313160]": { + "$type": "EditorVisibilityComponent", + "Id": 2654521436129313160 + }, + "Component_[5265045084611556958]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5265045084611556958 + }, + "Component_[7169798125182238623]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7169798125182238623 + }, + "Component_[8866210352157164042]": { + "$type": "EditorInspectorComponent", + "Id": 8866210352157164042 + }, + "Component_[9129253381063760879]": { + "$type": "EditorOnlyEntityComponent", + "Id": 9129253381063760879 + } + }, + "IsDependencyReady": true + }, + "Entity_[1168049227123]": { + "Id": "Entity_[1168049227123]", + "Name": "Grid", + "Components": { + "Component_[11443347433215807130]": { + "$type": "EditorEntityIconComponent", + "Id": 11443347433215807130 + }, + "Component_[11779275529534764488]": { + "$type": "SelectionComponent", + "Id": 11779275529534764488 + }, + "Component_[14249419413039427459]": { + "$type": "EditorInspectorComponent", + "Id": 14249419413039427459 + }, + "Component_[15448581635946161318]": { + "$type": "AZ::Render::EditorGridComponent", + "Id": 15448581635946161318, + "Controller": { + "Configuration": { + "primarySpacing": 4.0, + "primaryColor": [ + 0.501960813999176, + 0.501960813999176, + 0.501960813999176 + ], + "secondarySpacing": 0.5, + "secondaryColor": [ + 0.250980406999588, + 0.250980406999588, + 0.250980406999588 + ] + } + } + }, + "Component_[1843303322527297409]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 1843303322527297409 + }, + "Component_[380249072065273654]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 380249072065273654, + "Parent Entity": "Entity_[1176639161715]", + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 0.0 + ] + }, + "Cached World Transform Parent": "Entity_[1176639161715]" + }, + "Component_[7476660583684339787]": { + "$type": "EditorPendingCompositionComponent", + "Id": 7476660583684339787 + }, + "Component_[7557626501215118375]": { + "$type": "EditorEntitySortComponent", + "Id": 7557626501215118375 + }, + "Component_[7984048488947365511]": { + "$type": "EditorVisibilityComponent", + "Id": 7984048488947365511 + }, + "Component_[8118181039276487398]": { + "$type": "EditorOnlyEntityComponent", + "Id": 8118181039276487398 + }, + "Component_[9189909764215270515]": { + "$type": "EditorLockComponent", + "Id": 9189909764215270515 + } + }, + "IsDependencyReady": true + }, + "Entity_[1172344194419]": { + "Id": "Entity_[1172344194419]", + "Name": "Shader Ball", + "Components": { + "Component_[10789351944715265527]": { + "$type": "EditorOnlyEntityComponent", + "Id": 10789351944715265527 + }, + "Component_[12037033284781049225]": { + "$type": "EditorEntitySortComponent", + "Id": 12037033284781049225 + }, + "Component_[13759153306105970079]": { + "$type": "EditorPendingCompositionComponent", + "Id": 13759153306105970079 + }, + "Component_[14135560884830586279]": { + "$type": "EditorInspectorComponent", + "Id": 14135560884830586279 + }, + "Component_[16247165675903986673]": { + "$type": "EditorVisibilityComponent", + "Id": 16247165675903986673 + }, + "Component_[18082433625958885247]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 18082433625958885247 + }, + "Component_[6472623349872972660]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6472623349872972660, + "Parent Entity": "Entity_[1176639161715]", + "Transform Data": { + "Rotate": [ + 0.0, + 0.10000000149011612, + 180.0 + ] + }, + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 0.0 + ], + "Rotation": [ + 0.0008726645028218627, + 0.0, + 0.9999996423721314, + 0.0 + ] + }, + "Cached World Transform Parent": "Entity_[1176639161715]" + }, + "Component_[6495255223970673916]": { + "$type": "AZ::Render::EditorMeshComponent", + "Id": 6495255223970673916, + "Controller": { + "Configuration": { + "ModelAsset": { + "assetId": { + "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}", + "subId": 281415304 + }, + "assetHint": "objects/shaderball/shaderball_default_1m.azmodel" + } + } + } + }, + "Component_[8056625192494070973]": { + "$type": "SelectionComponent", + "Id": 8056625192494070973 + }, + "Component_[8550141614185782969]": { + "$type": "EditorEntityIconComponent", + "Id": 8550141614185782969 + }, + "Component_[9439770997198325425]": { + "$type": "EditorLockComponent", + "Id": 9439770997198325425 + } + }, + "IsDependencyReady": true + }, + "Entity_[1176639161715]": { + "Id": "Entity_[1176639161715]", + "Name": "Atom Default Environment", + "Components": { + "Component_[10757302973393310045]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 10757302973393310045, + "Parent Entity": "Entity_[1146574390643]", + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 0.0 + ] + }, + "Cached World Transform Parent": "Entity_[1146574390643]" + }, + "Component_[14505817420424255464]": { + "$type": "EditorInspectorComponent", + "Id": 14505817420424255464, + "ComponentOrderEntryArray": [ + { + "ComponentId": 10757302973393310045 + } + ] + }, + "Component_[14988041764659020032]": { + "$type": "EditorLockComponent", + "Id": 14988041764659020032 + }, + "Component_[15808690248755038124]": { + "$type": "SelectionComponent", + "Id": 15808690248755038124 + }, + "Component_[15900837685796817138]": { + "$type": "EditorVisibilityComponent", + "Id": 15900837685796817138 + }, + "Component_[3298767348226484884]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3298767348226484884 + }, + "Component_[4076975109609220594]": { + "$type": "EditorPendingCompositionComponent", + "Id": 4076975109609220594 + }, + "Component_[5679760548946028854]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 5679760548946028854 + }, + "Component_[5855590796136709437]": { + "$type": "EditorEntitySortComponent", + "Id": 5855590796136709437, + "ChildEntityOrderEntryArray": [ + { + "EntityId": "Entity_[1155164325235]" + }, + { + "EntityId": "Entity_[1180934129011]", + "SortIndex": 1 + }, + { + "EntityId": "Entity_[1172344194419]", + "SortIndex": 2 + }, + { + "EntityId": "Entity_[1168049227123]", + "SortIndex": 3 + }, + { + "EntityId": "Entity_[1163754259827]", + "SortIndex": 4 + }, + { + "EntityId": "Entity_[1159459292531]", + "SortIndex": 5 + } + ] + }, + "Component_[9277695270015777859]": { + "$type": "EditorEntityIconComponent", + "Id": 9277695270015777859 + } + }, + "IsDependencyReady": true + }, + "Entity_[1180934129011]": { + "Id": "Entity_[1180934129011]", + "Name": "Global Sky", + "Components": { + "Component_[11231930600558681245]": { + "$type": "AZ::Render::EditorHDRiSkyboxComponent", + "Id": 11231930600558681245, + "Controller": { + "Configuration": { + "CubemapAsset": { + "assetId": { + "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}", + "subId": 1000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage" + } + } + } + }, + "Component_[11980494120202836095]": { + "$type": "SelectionComponent", + "Id": 11980494120202836095 + }, + "Component_[1428633914413949476]": { + "$type": "EditorLockComponent", + "Id": 1428633914413949476 + }, + "Component_[14936200426671614999]": { + "$type": "AZ::Render::EditorImageBasedLightComponent", + "Id": 14936200426671614999, + "Controller": { + "Configuration": { + "diffuseImageAsset": { + "assetId": { + "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}", + "subId": 3000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage" + }, + "specularImageAsset": { + "assetId": { + "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}", + "subId": 2000 + }, + "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage" + } + } + } + }, + "Component_[14994774102579326069]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 14994774102579326069 + }, + "Component_[15417479889044493340]": { + "$type": "EditorPendingCompositionComponent", + "Id": 15417479889044493340 + }, + "Component_[15826613364991382688]": { + "$type": "EditorEntitySortComponent", + "Id": 15826613364991382688 + }, + "Component_[1665003113283562343]": { + "$type": "EditorOnlyEntityComponent", + "Id": 1665003113283562343 + }, + "Component_[3704934735944502280]": { + "$type": "EditorEntityIconComponent", + "Id": 3704934735944502280 + }, + "Component_[5698542331457326479]": { + "$type": "EditorVisibilityComponent", + "Id": 5698542331457326479 + }, + "Component_[6644513399057217122]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 6644513399057217122, + "Parent Entity": "Entity_[1176639161715]", + "Cached World Transform": { + "Translation": [ + 0.0, + 0.0, + 0.0 + ] + }, + "Cached World Transform Parent": "Entity_[1176639161715]" + }, + "Component_[931091830724002070]": { + "$type": "EditorInspectorComponent", + "Id": 931091830724002070 + } + }, + "IsDependencyReady": true + } + } +} \ No newline at end of file diff --git a/Assets/Engine/Config/engine_core.thread_config b/Assets/Engine/Config/engine_core.thread_config deleted file mode 100644 index f9183d9174..0000000000 --- a/Assets/Engine/Config/engine_core.thread_config +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Assets/Engine/Config/engine_sandbox.thread_config b/Assets/Engine/Config/engine_sandbox.thread_config deleted file mode 100644 index 7c0dc00b71..0000000000 --- a/Assets/Engine/Config/engine_sandbox.thread_config +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Assets/Engine/SeedAssetList.seed b/Assets/Engine/SeedAssetList.seed index 45a02f7682..77ec509721 100644 --- a/Assets/Engine/SeedAssetList.seed +++ b/Assets/Engine/SeedAssetList.seed @@ -67,106 +67,98 @@ - + - + - + - + - + - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -264,109 +256,101 @@ - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -387,498 +371,474 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -896,14 +856,6 @@ - - - - - - - - @@ -928,29 +880,13 @@ - - - - - - - - - - - - - - - - - + - + @@ -1451,146 +1387,146 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -1699,42 +1635,42 @@ - + - + - + - + - + - + - + - + - + - + diff --git a/Assets/Engine/Shaders/DistanceClouds.ext b/Assets/Engine/Shaders/DistanceClouds.ext deleted file mode 100644 index 322acef5f3..0000000000 --- a/Assets/Engine/Shaders/DistanceClouds.ext +++ /dev/null @@ -1,51 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Particles shader extension used by the editor -// for automatic shader generation (based on "Particles" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %DIFFUSE - Mask = 0x1 - Hidden -} - -Property -{ - Name = %SIMPLE - Mask = 0x2 - Property (Simple distance clouds) - Description (Use distance clouds with no volumetric shading computations) -} - -Property -{ - Name = %ADVANCED - Mask = 0x4 - Property (Advanced distance clouds) - Description (Use distance clouds with more accurate shading computations) -} - -Property -{ - Name = %DEPTH_FADE - Mask = 0x8 - Property (Depth Fade) - Description (Fades the output based on closeness of objects behind it) -} diff --git a/Assets/Engine/Shaders/Eye.ext b/Assets/Engine/Shaders/Eye.ext deleted file mode 100644 index 28df961f79..0000000000 --- a/Assets/Engine/Shaders/Eye.ext +++ /dev/null @@ -1,74 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Eye shader extension used by the editor -// for automatic shader generation (based on "Eye" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %ENVIRONMENT_MAP - Mask = 0x2 - Property (Environment map) - Description (Use environment map as separate texture) - DependencyReset = $TEX_EnvCM -} - -Property -{ - Name = %EYE_AO_OVERLAY - Mask = 0x4 - Property (Ambient occlusion overlay) - Description (Use for ambient occlusion overlay rendering) -} - -Property -{ - Name = %EYE_SPECULAR_OVERLAY - Mask = 0x8 - Property (Specular overlay) - Description (Use for specular overlay rendering) -} - -Property -{ - Name = %VERTCOLORS - Mask = 0x400000 - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %TEMP_EYES - Mask = 0x80000000 - DependencySet = $UserEnabled - Hidden -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/Fur.ext b/Assets/Engine/Shaders/Fur.ext deleted file mode 100644 index 067c85d274..0000000000 --- a/Assets/Engine/Shaders/Fur.ext +++ /dev/null @@ -1,126 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// - -// Description: Fur shader extension used by the editor -// for automatic shader generation (based on "Fur" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x2 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %CUSTOM_MODIFICATOR - Mask = 0x4 - Property (Call CustomModificator function in vertex shader) - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %FUR_VERT_COLORS - Mask = 0x8 - Property (Fur Color Data) - Description (Vertex color channel contains fur combing and scaling info) -} - -Property -{ - Name = %FUR_WIND_BENDING - Mask = 0x10 - Property (Wind bending) - Description (Enable wind bending for fur) -} - -Property -{ - Name = %FUR_BLENDLAYER - Mask = 0x20 - Property (Fur Blendlayer) - Description (Diffuse layer blended into fur as it grows from base to tip) -} - -Property -{ - Name = %FUR_BLENDCOLOR - Mask = 0x40 - Property (Fur Blend color) - Description (Specified color blended into fur diffuse as it grows from base to tip) -} - -Property -{ - Name = %FUR_LENGTH_SCALED - Mask = 0x80 - Property (Scale fur length) - Description (Fur length scales with object scale) -} - -Property -{ - Name = %MODEL_SPACE_Z_UP - Mask = 0x100 - Property (Model Space Z Up) - Description (Check if model was generated with Z up, if unchecked, assumes Y up) -} - -Property -{ - Name = %DEPTH_FIXUP - Mask = 0x200 - Property (Depth Fixup) - Description (Write depth for depth of field and postprocessing) - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %ZPASS_CUSTOM_DIFFUSE - Mask = 0x400 - Property (Calls GetZPassDiffuse function in z pass pixel shader for custom diffuse handling) - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %FUR_MULTI_LAYER_ALPHA_BLEND - Mask = 0x800 - Property(Enable OIT) - Description(Use OIT for accurate alpha blending - performance penalty expected) -} diff --git a/Assets/Engine/Shaders/GeometryBeam.ext b/Assets/Engine/Shaders/GeometryBeam.ext deleted file mode 100644 index 25e395f42d..0000000000 --- a/Assets/Engine/Shaders/GeometryBeam.ext +++ /dev/null @@ -1,43 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// - - -Property -{ - Name = %NOISE - Mask = 0x1 - Property (Dust & Turbulence) - Description (Add a dust overlay [spec map for dust, bump map for turbulence] ) -} - - -Property -{ - Name = %RECEIVE_SHADOWS - Mask = 0x2 - Property (Receive Shadows) - Description (Enable shadow receiving) -} - - -Property -{ - Name = %UV_VIGNETTING - Mask = 0x4 - Property (UV Vignetting) - Description (Enabling this will cause contents to fade out at UV boundaries) -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/Glass.ext b/Assets/Engine/Shaders/Glass.ext deleted file mode 100644 index 1070d4e5c9..0000000000 --- a/Assets/Engine/Shaders/Glass.ext +++ /dev/null @@ -1,111 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Glass shader extension used by the editor -// for automatic shader generation (based on "Glass" shader template) -// -//////////////////////////////////////////////////////////////////////////// - - -Version (2.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %DIRT_MAP - Mask = 0x100000 - Property (Use Diffuse map) - Description (Use Diffuse map for dirt, etc. Requires Alpha channel) -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x200000 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %ENVIRONMENT_MAP - Mask = 0x10 - Property (Environment map) - Description (Use environment map as separate texture) - DependencyReset = $TEX_EnvCM -} - - -Property -{ - Name = %TINT_MAP - Mask = 0x200 - Property (Tint map - Tint/Gloss/Spec) - Description (Use RGB Spec Map to control Tinting in Red channel / Cloudiness in Green channel / Specular in Blue channel) - -} - -Property -{ - Name = %TINT_COLOR_MAP - Mask = 0x400 - Property (Use Tint Color Map) - Description (Use Tint Color Map for multi-colored glass, goes in the custom Tint Color Map slot) - DependencyReset = $TEX_Custom - DependencySet = $TEX_Custom -} - -Property -{ - Name = %BLUR_REFRACTION - Mask = 0x2000 - Property (Blur refraction - PC Only) - Description (Blur objects seen through the glass) -} - -Property -{ - Name = %DEPTH_FOG - Mask = 0x4000 - Property (Depth Fog) - Description (Enables depth fog behind glass surface) -} - -Property -{ - Name = %UNLIT - Mask = 0x8000 - Property (Disable Lights) - Description (Disables the reflection of lights) -} - -Property -{ - Name = %DEPTH_FIXUP - Mask = 0x4000000 - Property (Depth Fixup) - Description (Write depth for depth of field and postprocessing) -} - -Property -{ - Name = %SAA_FILTERING - Mask = 0x80000000 - Property (Specular Antialiasing) - Description (Perform specular Antialiasing) -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/AuxGeom.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/AuxGeom.cfx deleted file mode 100644 index ac64ed293a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/AuxGeom.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d924c59739f63724999b1bf6cd326d10024b031bdfbf02fe8e09cb0b783dfe67 -size 2891 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Clouds.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Clouds.cfx deleted file mode 100644 index cf8ee86492..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Clouds.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:045f6506425364221f9dbf0b359e38877f276300770ef7a5ab694f1055eb0d02 -size 1569 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfi deleted file mode 100644 index 644826685e..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f25999b453c3e91c8237d28ccc1ef3baefaa2a7ec8f9aad65adb95042e25e435 -size 56582 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfx deleted file mode 100644 index d347b5c967..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Common.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:396a70d86a4678b16fa110b3eceacbd5b515aa85090d16bdb6a8562d7c94e4a8 -size 17205 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonDebugPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonDebugPass.cfi deleted file mode 100644 index 95abf99bbf..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonDebugPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b05841cd01ec853455ad792e80302cf5ffbbd104c5ecf46699f5ecd4b0624c09 -size 983 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPass.cfi deleted file mode 100644 index 54f160e01b..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:725006c2f2844e49b691506cbc3d015466cdfbad19209a63964acc264b78c782 -size 4096 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPassTess.cfi deleted file mode 100644 index 4d74269d97..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonMotionBlurPassTess.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5886e0be4d4047a9b41431c141738cb0a13a3b3a4033cc262f173b5e9e195707 -size 4734 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonSVO.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonSVO.cfi deleted file mode 100644 index 023437ec3c..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonSVO.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57682432ba4de87ddc5ba542b6630ad512f75dbaca2a0c1402fb2a59ed35804c -size 111615 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPass.cfi deleted file mode 100644 index 7907e3913d..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:01bbe928766a8c75bc3d990747f91e5becfbed6a59d58b71d2a2922f6d14bc1f -size 6970 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPassTess.cfi deleted file mode 100644 index ccb63377d1..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonShadowGenPassTess.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c4c004afe3782ae58fa4ac90dd7f16e026d0c38e4bf66ed475beaa1ce3fcf98 -size 3363 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonTessellation.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonTessellation.cfi deleted file mode 100644 index 33aa6974cf..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonTessellation.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86f594a6f8fb6e1328b95e6b03a04109ea3e9e8b8642d30c674281ea916dbf41 -size 19522 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPass.cfi deleted file mode 100644 index 71876eddd2..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:04850ac23185147fd8e97303efad70cbb876c6589c71cb413b0429d267705cd3 -size 8020 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPassTess.cfi deleted file mode 100644 index 96cbad4a40..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonViewsPassTess.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6c660b79e7532b5a9513341d3f37215a742d3ee99532ba0003e2c13381d55bc6 -size 4238 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPass.cfi deleted file mode 100644 index 8a9f7ef4f1..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8fe036b79e16737499920500c87997567d8ee32534748df4ea617c4118237cb5 -size 32052 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPassTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPassTess.cfi deleted file mode 100644 index adc03e7945..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPassTess.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a30f1c7b94eb1bcb0261e518062da6eb69987698d65e6dd786bfe29be32d749e -size 4995 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPrePass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPrePass.cfi deleted file mode 100644 index 43481f75fe..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/CommonZPrePass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c4ac5b9fa8a288f8fdfc4110599b25742b19ddd3a251d638e5e1da9284310d6 -size 2814 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DXTCompress.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DXTCompress.cfx deleted file mode 100644 index 26545c6531..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DXTCompress.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a2b214f2873a3a99bcaccc120d6a397c708a4b3309c9b953860f8f9cf93461c8 -size 8591 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Debug.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Debug.cfx deleted file mode 100644 index 71ab497cc5..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Debug.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f26436234a598c2aa906653e711eb0e8ae14f99b65fc25eea0d238d9f56d914a -size 4345 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DebugLight.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DebugLight.cfx deleted file mode 100644 index cc9a79a324..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DebugLight.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bb0a8212530051bd6e4ac5646f6ab2f0a59f43a349ce8e03e544f6cf6d87ba4b -size 1929 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredCaustics.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredCaustics.cfx deleted file mode 100644 index f477baa00c..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredCaustics.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24e1f7c4242c708a638a1069908f258fa26aa77152330a2c8da72260dd192209 -size 14703 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredRain.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredRain.cfx deleted file mode 100644 index 2e771c73bf..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredRain.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77910f05ea15757e24201187a68a9a0db924f7951dadd4b7c7330f0845bd5944 -size 14043 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShading.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShading.cfx deleted file mode 100644 index 9252e1b06e..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShading.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ab94af4462722c1a111f4199714fabd0addf095aba82840f92e6ef8b056d78c -size 94446 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShadows.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShadows.cfi deleted file mode 100644 index 63c8b33c21..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredShadows.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0641726ad6140704434896912f0e57e29e6f5e28ac2653bc97bbe7e2d444fbc2 -size 2828 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredSnow.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DeferredSnow.cfx deleted file mode 100644 index 0789202955..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DeferredSnow.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ea4c40161f4f628fbf9cd1a3b7df445615dfa8ca15761a4fec15d0c2276b369 -size 22312 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DepthOfField.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DepthOfField.cfx deleted file mode 100644 index 9a431fb20a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DepthOfField.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b67ece889d68d8ed6f891ca5cfb1f951a777616ea928b0e6f91bd541b35c62ff -size 13136 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/DistanceClouds.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/DistanceClouds.cfx deleted file mode 100644 index 7448f0304a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/DistanceClouds.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a06a4a972542f51bea726578b26ef0fc711c4b6f4a77a31a383690717c5ccba2 -size 10622 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Eye.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Eye.cfx deleted file mode 100644 index a3cb1227ea..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Eye.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fed5c2b72b2b4769954f2fad9573c6e35581c556e3a96685d449eea5576cf433 -size 19244 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FXConstantDefs.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FXConstantDefs.cfi deleted file mode 100644 index 7b0d7202e7..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FXConstantDefs.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1b6aa7281d2174f24b510a7ac820b4ab308a215d6b3eae4a039bc01e34b131ec -size 9922 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FXSamplerDefs.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FXSamplerDefs.cfi deleted file mode 100644 index 7f5b097148..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FXSamplerDefs.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:750ac5a4ef25f1379121c7346dad0230d389c7c889ffdccbe6281a511b021cea -size 4044 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FXStreamDefs.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FXStreamDefs.cfi deleted file mode 100644 index 4d05f905c1..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FXStreamDefs.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:073303aa45adc5ca237f33f29fb4de52f8b3c935912298cdec611128c510399c -size 9279 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FallBack.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/FallBack.cfx deleted file mode 100644 index 321440401b..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FallBack.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:052a458b7bdef6d7e1fa1a26d4cb66f6e24f91b9e42451a8e48045d3779aef1c -size 2383 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FixedPipelineEmu.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/FixedPipelineEmu.cfx deleted file mode 100644 index 8b92aa7399..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FixedPipelineEmu.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ab757a0df8246a0e9d20839a89219a6c616d6df054d72b21b79e459b8503ade8 -size 10188 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FogVolume.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/FogVolume.cfx deleted file mode 100644 index 929d89ab5b..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FogVolume.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a37c2ab18b0ad1da90005c0ff9fea89d7c78ade9fd51b28b665cf42b814ecd8d -size 23690 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Fur.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Fur.cfx deleted file mode 100644 index 7d7405cc5e..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Fur.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f429a8537df95455e32da7fd480e79ef46751d6bc880c34b746c21515aa012a -size 31609 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FurFinPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FurFinPass.cfi deleted file mode 100644 index 84149cb0f6..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FurFinPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e3f25ea475310f699442a160ffcc9f58c40e54b6570210dafbe41746a010b821 -size 15002 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FurObliteratePass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FurObliteratePass.cfi deleted file mode 100644 index 3ffe779a54..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FurObliteratePass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f6246f93aa73fdab460c1c82a33f2588a0ae83a162acdcdb12cec86ddac332b6 -size 5142 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/FurZPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/FurZPass.cfi deleted file mode 100644 index 5735035e49..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/FurZPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb0d83cc48ebee33b3d3db2b1a5c27636d35dfb7ce720e5391a28ff70ca0d729 -size 9023 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticle.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticle.cfi deleted file mode 100644 index 6cd187c993..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticle.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b690c770f90e33dc78604b5beca3453aba4fbb4db8014b730680c33b5cef5120 -size 2299 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBegin.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBegin.cfx deleted file mode 100644 index 3bc0dd3e01..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBegin.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:64c184691014423f2f6c518d34ff9657acc1dc8867e0e43d20b5526491d35d5b -size 462 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSort.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSort.cfx deleted file mode 100644 index 14c0b06c58..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSort.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a71929dda4a7b4516754286da5494546a0ea2075b9fde5cefef68f0a99d37381 -size 1520 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortGlobal2048.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortGlobal2048.cfx deleted file mode 100644 index b8ff2e6afc..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortGlobal2048.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a50144544a4c292d172d4bb9586a6016de4cc5b0a39958abfb00bc720e8c23e9 -size 1989 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortLocal.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortLocal.cfx deleted file mode 100644 index 6ee0b7b645..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleBitonicSortLocal.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:25d51818120964a1576f35727c0f13bc10a01727ab793f5fdf79cb9c1f7bf563 -size 2055 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleCurves.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleCurves.cfi deleted file mode 100644 index a565d62cc4..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleCurves.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4308e81d4ee4c65480a1cf110f3f602d347f2899b4cf299f334c2659904329dd -size 553 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleEmit.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleEmit.cfx deleted file mode 100644 index 8d417c29ac..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleEmit.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfe3a765c1057d5dfae514ba17d0ce99d6598693035df2037314da5f38e4c305 -size 19142 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleGatherSortDistance.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleGatherSortDistance.cfx deleted file mode 100644 index 0a223398ff..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleGatherSortDistance.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f94a71dd8cbe95080f2de1bfa8cbd9443bea18106cc7bcae2c5c7225d113f2b4 -size 644 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleHelpers.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleHelpers.cfi deleted file mode 100644 index a3b10d582b..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleHelpers.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cf39d59eefe2c6641437e9d535528edb29e1e0dad6d1b84b20662c7075928fe8 -size 6969 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleOddEvenSort.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleOddEvenSort.cfx deleted file mode 100644 index be1e36e5db..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleOddEvenSort.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5cbcdd1c83247233dce9fb5c32e9d4530b23b825b284591a921a0b7e81d230ea -size 1817 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleRenderNoGS.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleRenderNoGS.cfx deleted file mode 100644 index 2d8fc2a1d0..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleRenderNoGS.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cae99346703f5ebc9bb59edb61c17b86184ae7659af78395ec4cba11cb6da471 -size 37741 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleUpdate.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleUpdate.cfx deleted file mode 100644 index 7524f13c6f..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GPUParticleUpdate.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8a3a7bb8ad18d99c7490d15ce24b3c4867d9668b1539014a31b3ba5e80ebb00e -size 25753 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/GeometryBeam.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/GeometryBeam.cfx deleted file mode 100644 index 364f613063..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/GeometryBeam.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:45e7f387bb7cc9d7a489916b27ea6bff816510664099008ebbeaa0d10a26faa7 -size 12612 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Glass.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Glass.cfx deleted file mode 100644 index 38226fedec..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Glass.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:49aa341aa2563ced85aa4f62f74865c558238c91ba9d8d62ad21392088755820 -size 26913 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass0.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass0.cfx deleted file mode 100644 index b2df095b8a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass0.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c7f9297a483fd7d7b91a3f06f1a3eb83e77192b967691f4e2119d41b7a7afdd2 -size 2707 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass1.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass1.cfx deleted file mode 100644 index 25c959c8f6..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/HDRDolbyMetadataPass1.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:52d68438b25fbd2d88a7247295a021680a9b95a6f3ed07c3ae066cb3d44b25ed -size 2530 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcess.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcess.cfx deleted file mode 100644 index 76e692fa63..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcess.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5cf8d27075f4aa76e5814d1c4a9718d7106df50229f33e1d8d7d7a4532d1e5f3 -size 40838 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcessDolby.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcessDolby.cfi deleted file mode 100644 index b8c0c3043c..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/HDRPostProcessDolby.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2e62a2aa829af58b2ba19a9920bd87d64a27854d24de5a51842740c7ec1e9ae8 -size 33567 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Hair.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Hair.cfx deleted file mode 100644 index 4788d26a0e..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Hair.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:eb56b0070f3811f1b8780e70d4b9410a08f3aac9f8fa3e947194a4d902c9d8ef -size 33265 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Helper.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Helper.cfx deleted file mode 100644 index 5c19cc54e0..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Helper.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9764bb3ab6d2895a355466f3c53f735c3500006420bac211bc9a0b7c29a605c6 -size 2168 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Hud3D.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Hud3D.cfx deleted file mode 100644 index c460d0468c..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Hud3D.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c63de566d2a5a69781a4c1e16958d64d187e057f3447afb4ec9aa47455ef7a5c -size 9617 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkin.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkin.cfx deleted file mode 100644 index ff2a2b894a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkin.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b81300b59d42b38b7669016cc8920db9adbf07b612f12d520d9480a6de59aa73 -size 18648 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinTess.cfi deleted file mode 100644 index 8f7ce5f8c9..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinTess.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a79996ad61013920dcccd254f23e05fb4089879d477d8f3ce00ff98ee04d6ec1 -size 7783 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinValidations.cfi deleted file mode 100644 index 9743568b4d..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/HumanSkinValidations.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:548f2cc401046358ef4f4edeb37532f06437b99b2fe5bff70100e66a6ecb281a -size 986 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Illum.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Illum.cfx deleted file mode 100644 index 6de2f49547..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Illum.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c110e0891fbe46a10f2fbcf4ffb8f82c0711ffaa943fac5ca92c96f7e63d051 -size 28796 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/IllumTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/IllumTess.cfi deleted file mode 100644 index ef66d513a9..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/IllumTess.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9a52e2256a43707dfab74c680e96249d27e7eb38a2984c9d4dcff83ffe7dd15b -size 5194 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/IllumValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/IllumValidations.cfi deleted file mode 100644 index 7af7a4748c..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/IllumValidations.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4155e44e6687796095b5e2401c93a09e527c61a48830e8a35d4ab16d849d8159 -size 2031 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/LensOptics.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/LensOptics.cfx deleted file mode 100644 index ab20cc3bc7..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/LensOptics.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7acdc1aaa28aea83d9af53547f65c5686b2fc43be988068d8f4f88c87c4359a7 -size 16847 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Light.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Light.cfx deleted file mode 100644 index ebbe8183bf..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Light.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4436686d0f3e735973df2dd56523269683c66b3ae01da67fa7f41e5f9e1b1234 -size 12760 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/LightBeam.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/LightBeam.cfx deleted file mode 100644 index e19414deef..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/LightBeam.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:13c69186729534dcd2676d1740a530fb5d5a3307d7b713f5c08704220186ba6d -size 14169 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/LightVolumes.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/LightVolumes.cfi deleted file mode 100644 index 4ab290bb32..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/LightVolumes.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f79e6c1e182e86afd295758f0afefc901407e69eb3f93422d8a3089451e49c7d -size 5526 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/MeshBaker.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/MeshBaker.cfi deleted file mode 100644 index 5f019eca9a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/MeshBaker.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0ca1d710fd2b0937a04ded739ab4dc35ff48e3ff0c07d6a5d4df95f32a1947a4 -size 5032 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/MeshBakerDilate.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/MeshBakerDilate.cfx deleted file mode 100644 index 59ff9363a5..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/MeshBakerDilate.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7a7db4ca9b7d87e4c3410df26f3045a18fb96a2535b88ab8afe00dcf1d621943 -size 4173 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorTC.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorTC.cfi deleted file mode 100644 index 6d0fd6bb42..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorTC.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0eb9c63a60a3d2afb78d6e4077ac81322dbd1a0537f5551c638d57c353381e15 -size 5256 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorVT.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorVT.cfi deleted file mode 100644 index fff9af0b52..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ModificatorVT.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dd0aecf5b1620c49a9b08c35865ea8de5487098f1eed8374fa4fc85e4a87e886 -size 52858 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Monitor.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Monitor.cfx deleted file mode 100644 index 840da6f035..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Monitor.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:758aa594628cd94f10d379f08a9a0a63478cc69eb9a093404d57c46e6830150a -size 19450 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/MotionBlur.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/MotionBlur.cfx deleted file mode 100644 index b6ba57f9f3..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/MotionBlur.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8b4f6c44e52297c1dfe02040a7e63739aeed73f2c2c4930053f5a83c3c73f816 -size 8716 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/MultiLayerAlphaBlend.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/MultiLayerAlphaBlend.cfi deleted file mode 100644 index 751d38bde8..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/MultiLayerAlphaBlend.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:01f08e32bfb1f8690759da687114e66bf6652b6d17b208ed1b316315f0a66a1b -size 6435 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/NoDraw.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/NoDraw.cfx deleted file mode 100644 index a4a038ac28..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/NoDraw.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1d183abe91463d2ab90f56c055a44aa8c3cad1d731f51c9f56bd6f9df3d7eba1 -size 180 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/OcclusionTest.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/OcclusionTest.cfx deleted file mode 100644 index 7f1b7bf522..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/OcclusionTest.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ceef3fd50e977ba168e2f80803bc0a09542aa3c55721e0e6e27bbab45454607 -size 1545 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ParticleImposter.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ParticleImposter.cfx deleted file mode 100644 index 0506b14d5e..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ParticleImposter.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b67b9997024270cfdede2d057220078029db61ab5dff6d522a39c99d08420245 -size 8657 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ParticleVT.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ParticleVT.cfi deleted file mode 100644 index bbe4d0c261..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ParticleVT.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:670e9dd98f131fa0375ddcc4df8fe850eeabb43f9771d302b5c8e2fd7022d78d -size 8534 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfi deleted file mode 100644 index 6f38a8eae7..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98f62a7869360e63083eea9a784652ad0fca13a9cd741930940be75c10ca83e7 -size 40918 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfx deleted file mode 100644 index 728135d83c..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Particles.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:55bcc8a634262b6001193fabf318cdf2960904dd47e915fa17de3a60c620639d -size 4613 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesCustomPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesCustomPass.cfi deleted file mode 100644 index 7f90f9f1a5..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesCustomPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af77abd5a2d462e4b533e6e5b489bc8e39909527c64a9cd599bbf5312b3aa17a -size 6052 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMat.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMat.cfx deleted file mode 100644 index 3728b1f379..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMat.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:db6f21607b4ce4e0d0a48ffa0a7db81f29ac0546c76846dd39f1fc584f7d23e5 -size 1517 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMatMirror.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMatMirror.cfx deleted file mode 100644 index 955c99c3e9..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesNoMatMirror.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f8178b44fc27aacde3600b86bc06038aefbac6ca4fbf4fbe29f32ca6e8e0584 -size 1603 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesShadowPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesShadowPass.cfi deleted file mode 100644 index 461f4d40ac..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ParticlesShadowPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0c7c5e176c6f0a5f689bc433dd23d5bb998f8f10d4185c30cb9788022ebb38a0 -size 6464 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/PostAA.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/PostAA.cfx deleted file mode 100644 index d8ae4939e4..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/PostAA.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7a10320d3b31738cc0154de2c973fcaf912885209a7e729e3f6bd372f7633354 -size 67647 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/PostEffects.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/PostEffects.cfx deleted file mode 100644 index 95269fe06c..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/PostEffects.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ec164683d3fe45a512c0e9a2314c5b450602ee8c8a8281d99d43c1d76a761df3 -size 60596 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsGame.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsGame.cfx deleted file mode 100644 index efaa765189..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsGame.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6d66a0aed7f39e3848ee4763c408c390ec7021205cf2f0f07459b99d84f1d27 -size 80783 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsLib.cfi deleted file mode 100644 index 90ce479d4a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/PostEffectsLib.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b73c3ae905c1833cade569500b647dc504e83b34f15a4584f72a372d254d884f -size 8502 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImage.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImage.cfx deleted file mode 100644 index 08b3c94d06..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImage.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:12d61af66003a6ab90e24574925fd94bc03622386da142fcaa655df21b0fd5bd -size 2033 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImageHDR.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImageHDR.cfx deleted file mode 100644 index aaa0a26a21..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ReferenceImageHDR.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1c4913b73fec9ebdcd5b8e7c86d495b7dc9a135e7f8a77ee90b9e62a78d3cc47 -size 1819 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Scopes.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Scopes.cfx deleted file mode 100644 index 7be1e74629..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Scopes.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4565c5415b0a68ced049335d803fcfdbf899db4ea914b8fbc5ba34620e4c4045 -size 10709 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ShadowBlur.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ShadowBlur.cfx deleted file mode 100644 index ad707f2932..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ShadowBlur.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3a6eafe0f42be55811eda4ac6b164bd01e22b6cc2b77723a8693549b26939871 -size 10768 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ShadowCommon.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/ShadowCommon.cfi deleted file mode 100644 index fbaa4d7f65..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ShadowCommon.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ddac405a61300a0857cba4ea7dabcb6d5aef5253ada53d09ec4ab591ed3cfbce -size 25680 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/ShadowMaskGen.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/ShadowMaskGen.cfx deleted file mode 100644 index 36b7604c43..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/ShadowMaskGen.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2aec8020aa2454b8a0cd406198bd2c067f878cb697dad2e2059e88c7cb2e5e87 -size 32118 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Sketch.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Sketch.cfx deleted file mode 100644 index 60d4aa0f4a..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Sketch.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ba3cc8b5127ccb8a446e0ac85daf0b13c700092bcdcbdd92d5fbf45dfd430dc -size 11176 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/SketchTerrain.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/SketchTerrain.cfx deleted file mode 100644 index f8ff66d760..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/SketchTerrain.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b247b792e8e26abb50c2c01e9bc6c341216f6a84fc3fac67088294cf868428ab -size 2992 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Sky.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Sky.cfx deleted file mode 100644 index 06ec9fc6f1..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Sky.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7fec7735636fa7a4c2387e216918ec92414bc29ec6ecbd89605677214f829403 -size 4830 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/SkyHDR.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/SkyHDR.cfx deleted file mode 100644 index 48b47a9ae1..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/SkyHDR.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3195bdf90fa2a0b1539f0cac7471dc31ec7aa783d138f9c0455a32354ead3874 -size 8548 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/SoftOcclusionQuery.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/SoftOcclusionQuery.cfx deleted file mode 100644 index 425102e21d..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/SoftOcclusionQuery.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c82e35c6af179bb2405bbfe1d452ae2a8c5479934c0c9d8e8119d04db35d8cf5 -size 3546 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Stars.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Stars.cfx deleted file mode 100644 index 4fdbddb2c6..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Stars.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c5f191743c706e8531bada03abab8700c01cc9afbff0c9ea22c41d509b11ee76 -size 4075 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/StarterGame_GeometryBeamScaling.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/StarterGame_GeometryBeamScaling.cfx deleted file mode 100644 index a5a51340fc..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/StarterGame_GeometryBeamScaling.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:888486a516d3052e6b8b01cc0d36f01a68985ed482db683a25527c220290cc6c -size 13217 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Stereo.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Stereo.cfx deleted file mode 100644 index 8ef249a60f..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Stereo.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:761402eba9c7256a79fe78869b0287b95a8be8f810b48e41222049425b2eb535 -size 5422 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Sunshafts.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Sunshafts.cfx deleted file mode 100644 index 2274352ec3..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Sunshafts.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9a162b22e9ee5dc42559c8bcd4a6160c8b227bfeb6a5b367b62b8256109b99b5 -size 8884 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/TemplBeamProc.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/TemplBeamProc.cfx deleted file mode 100644 index 1a2de2a0dd..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/TemplBeamProc.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aed5eeb5e7467884319e268f985134f0d50482408cdbda6359873d211387737c -size 7182 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Terrain.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Terrain.cfx deleted file mode 100644 index 22abec6b24..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Terrain.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e4d2246d81afaad43e267addffdc01ce201dc4032bf5e05131cfb9f56ebc5ed0 -size 19043 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/TerrainValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/TerrainValidations.cfi deleted file mode 100644 index 1c8349f673..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/TerrainValidations.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3956d70a7eff854ab02d44f6c712cdb694045e87e9a0201ad8427436c693897a -size 707 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/TiledShading.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/TiledShading.cfi deleted file mode 100644 index ebc1521531..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/TiledShading.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:72448b07701ad745e35d98de2229f0675cbb74bd6d40095ec4625929da906c5f -size 50201 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Total_Illumination.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Total_Illumination.cfx deleted file mode 100644 index 9b2c8e38dc..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Total_Illumination.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c73e03d1e09efd2e8cdb9292debb5260a0690772c81a9dbb085502f822b7f91b -size 38227 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/UI.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/UI.cfx deleted file mode 100644 index e98a5a2fae..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/UI.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c2b7a3ff846dde2ba481e46180e67e81528fa2a984ba6bb1a5c83304c301551d -size 7717 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Vegetation.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Vegetation.cfx deleted file mode 100644 index 0bca5a3e53..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Vegetation.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6c330b2ecb3d850e5eeb3673500cdebb95bee46b92eb93c3274291dbf96b2c98 -size 25807 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/VegetationTess.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VegetationTess.cfi deleted file mode 100644 index 5abc5af104..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/VegetationTess.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:28aadc74c027782d5971e8145d3286f733fcbb571872447f638397df4f957765 -size 5746 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/VegetationValidations.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VegetationValidations.cfi deleted file mode 100644 index 00d2e11b8f..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/VegetationValidations.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c05fb764a9fbc9cf7ea7b225680880c32847f4d355cab27f958564d5adcfc21b -size 1167 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Video.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Video.cfx deleted file mode 100644 index 966c5d92f6..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Video.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c1c4e2eed305e2319127d12349754819350301b42d33cb109def7237c3591f1 -size 2123 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/VolumeLighting.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VolumeLighting.cfi deleted file mode 100644 index 77cb40a98f..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/VolumeLighting.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:515e3218c9b23e8ff4d67a200ca11b3c833ad3999500f7f8be4ecdc5c01d5565 -size 82057 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/VolumeObject.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/VolumeObject.cfx deleted file mode 100644 index 2ca573741e..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/VolumeObject.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a1fa34bd8cd7d8df9089739c7adf62b95c64f3d0993dcb2ee3892e05e118e83c -size 6700 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/VolumetricFog.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/VolumetricFog.cfi deleted file mode 100644 index 2556067f04..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/VolumetricFog.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3dd1721686abf6fe824df07a5e8ee1505b0fbcbaec6dc1a8ded98274d6ea4058 -size 25814 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Water.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Water.cfx deleted file mode 100644 index 175960ffc2..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Water.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d3ebab64f075124eb4cf426fee1c9ac446225ed647db3f10a28a28b1efaa5e63 -size 41727 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/WaterCausticsPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/WaterCausticsPass.cfi deleted file mode 100644 index 5aa4d40dff..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/WaterCausticsPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f73053b56ef452bf8ae72a4cc6fed59876562d9f4541172265ce6c8d5740711 -size 3340 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/WaterFogVolume.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/WaterFogVolume.cfx deleted file mode 100644 index eda54be33e..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/WaterFogVolume.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f9d26a36eb0fa05b58991aaaa6a073621309aa8a4a06a5bb4a6048b507a3fe1 -size 18306 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/WaterOceanBottom.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/WaterOceanBottom.cfx deleted file mode 100644 index 90cf67ba52..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/WaterOceanBottom.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5266c69503cb72e831e5c488332237fbfd343f96708ea3c75037780bd62fed60 -size 5280 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/WaterReflectionsPass.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/WaterReflectionsPass.cfi deleted file mode 100644 index a2ffd3d2a8..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/WaterReflectionsPass.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bb1ba5273a487655f813688f0a8500c662348639414ac53a0b0ee3d911010eab -size 10008 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/WaterVolume.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/WaterVolume.cfx deleted file mode 100644 index 7985e3dab0..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/WaterVolume.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:41c19dceb8daa6e9a9102b83c78208d6f0681066f5d6c2cf2e657a82e1ce695c -size 39737 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/Waterfall.cfx b/Assets/Engine/Shaders/HWScripts/CryFX/Waterfall.cfx deleted file mode 100644 index d09922f322..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/Waterfall.cfx +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ebece6e3b0115174da434ed1b166b7209c012a6013e219e2421ffee5ebd6dda1 -size 11237 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/fragLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/fragLib.cfi deleted file mode 100644 index ffba873be1..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/fragLib.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3a340c8cbb76900b02bc171e680cfdc628900a5c38ecd3ce6a7b9eecbafa72ef -size 23148 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/shadeLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/shadeLib.cfi deleted file mode 100644 index b2633fd0da..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/shadeLib.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b33f5a65661f977c15047dea6b01809a1ebab5dbd6c7299a0e2888c2de8a911b -size 59794 diff --git a/Assets/Engine/Shaders/HWScripts/CryFX/vertexLib.cfi b/Assets/Engine/Shaders/HWScripts/CryFX/vertexLib.cfi deleted file mode 100644 index 66def251da..0000000000 --- a/Assets/Engine/Shaders/HWScripts/CryFX/vertexLib.cfi +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8b577a8c20b7cc94e1c97909487b3a0986b47882502e120fc518880883e04435 -size 15666 diff --git a/Assets/Engine/Shaders/Hair.ext b/Assets/Engine/Shaders/Hair.ext deleted file mode 100644 index 975e29323e..0000000000 --- a/Assets/Engine/Shaders/Hair.ext +++ /dev/null @@ -1,111 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Hair shader extension used by the editor -// for automatic shader generation (based on "Hair" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %VERTCOLORS - Mask = 0x10 - Property (Vertex Colors) - Description (Use vertex colors) -} - -Property -{ - Name = %HAIR_PASS - Mask = 0x20 - Property (Hair Pass) - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %ANISO_SPECULAR - Mask = 0x40 - Property (Anisotropic specular) - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %DIRECTION_MAP - Mask = 0x200 - Property (Direction map) - Description (Use direction map as separate texture) - DependencySet = $TEX_Detail - DependencyReset = $TEX_Detail - Hidden -} - -Property -{ - Name = %VIEW_ALIGNED_STRANDS - Mask = 0x800 - Property (View aligned strands) - Description (View aligned cards that get extruded from thin quads with texture u-coords 0 and 1) -} - -Property -{ - Name = %THIN_HAIR - Mask = 0x1000 - Property (Thin hair) - Description (Thin alpha-blended hair) -} - -Property -{ - Name = %HAIR_AMBIENT - Mask = 0x2000 - Property (Ambient cubemap) - Description (Use (nearest) cubemap specified in environment map slot for ambient lighting) - DependencyReset = $TEX_EnvCM -} - -Property -{ - Name = %ENFORCE_TILED_SHADING - Mask = 0x4000 - Property (Enforce tiled shading) - Description (Force hair to be fully affected by tiled shading. This can be expensive for dense hair meshes.) -} - -Property -{ - Name = %WIND_BENDING - Mask = 0x40000000 - Property (Wind bending) - Description (Gets affected by wind entities. Use extra shader parameters to tweak look.) -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/HumanSkin.ext b/Assets/Engine/Shaders/HumanSkin.ext deleted file mode 100644 index 92429316ea..0000000000 --- a/Assets/Engine/Shaders/HumanSkin.ext +++ /dev/null @@ -1,116 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Skin shader extension used by the editor -// for automatic shader generation (based on "Skin" shader template) -// -//////////////////////////////////////////////////////////////////////////// - - - -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x2 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %WRINKLE_BLENDING - Mask = 0x200 - Property (Wrinkle blending) - Description (Use subsurface map alpha for wrinkle blending) - DependencyReset = $TEX_Custom - DependencyReset = $TEX_CustomSecondary -} - -Property -{ - Name = %TEMP_SKIN - Mask = 0x1000 - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %DECAL_MAP - Mask = 0x2000 - Property (Decal map) - Description (Use a decal map which is blended on top of the diffuse map) -} - -Property -{ - Name = %DETAIL_MAPPING - Mask = 0x20000 - Property (Detail normal-map) - Description (Tiled detail normal-map for pores and tiny details (_ddn)) -} - -Property -{ - Name = %SUBSURFACE_SCATTERING_MASK - Mask = 0x40000 - Property (Subsurface Scattering Mask) - Description (Use diffuse map alpha as subsurface scattering amount multiplier) -} - -#ifdef FEATURE_MESH_TESSELLATION -Property -{ - Name = %DISPLACEMENT_MAPPING - Mask = 0x10000000 - Property (Displacement mapping) - Description (Use displacement mapping (requires height map (_displ))) - //DependencySet = $TEX_Height - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %PHONG_TESSELLATION - Mask = 0x20000000 - Property (Phong tessellation) - Description (Use rough approximation of smooth surface subdivision) -} - -Property -{ - Name = %PN_TESSELLATION - Mask = 0x40000000 - Property (PN triangles tessellation) - Description (Use rough approximation of smooth surface subdivision) -} -#endif \ No newline at end of file diff --git a/Assets/Engine/Shaders/Illum.ext b/Assets/Engine/Shaders/Illum.ext deleted file mode 100644 index edce2900d2..0000000000 --- a/Assets/Engine/Shaders/Illum.ext +++ /dev/null @@ -1,243 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Illumination shader extension used by the editor -// for automatic shader generation (based on "Illumination" shader template) -// -//////////////////////////////////////////////////////////////////////////// - - - -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x10 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %DETAIL_MAPPING - Mask = 0x4000 - Property (Detail mapping) - Description (Enables Detail Map texture to increase surface detail. Requires Detail map before enabling.) - DependencyReset = $TEX_Detail -} - -Property -{ - Name = %DETAIL_MAPPING_UV_SET_2 - Mask = 0x8000 - Property (Use uv set 2 for detail map) - Description (Detail map will be applied to second UV set on mesh) -} - -Property -{ - Name = %OFFSET_BUMP_MAPPING - Mask = 0x20000 - Property (Offset bump mapping) - Description (Simulates surface bump detail. Used in place of POM for lower spec configs. Requires height and normal maps before enabling.) - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %FX_DISSOLVE - Mask = 0x20 - Property (Dissolve FX) - Description (Enables the use of an animated dissolve effect on the material) -} - -Property -{ - Name = %VERTCOLORS - Mask = 0x400000 - Property (Vertex Colors) - Description (Enables the use of vertex colors added to the mesh in the DCC tool) -} - -Property -{ - Name = %DECAL - Mask = 0x2000000 - Property (Decal) - Description (Enables the decal opacity map and used to prevent flickering and z-fighting) -} - -Property -{ - Name = %PARALLAX_OCCLUSION_MAPPING - Mask = 0x8000000 - Property (Parallax occlusion mapping) - Description (Simulates surface depth by parallaxing bump detail from camera view. Requires height and normal maps before enabling.) - DependencyReset = $TEX_Normals -} - -#ifdef FEATURE_MESH_TESSELLATION -Property -{ - Name = %DISPLACEMENT_MAPPING - Mask = 0x10000000 - Property (Displacement mapping) - Description (Displaces the vertices on the mesh to add depth. Requires height and normal maps before enabling.) - //DependencySet = $TEX_Height - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %PHONG_TESSELLATION - Mask = 0x20000000 - Property (Phong tessellation) - Description (Tesselates geometry for smoother faces and displacement. Can suffer from inflation.) -} - -Property -{ - Name = %PN_TESSELLATION - Mask = 0x40000000 - Property (PN triangles tessellation) - Description (Best geometry tesselation for smoother faces and displacement at the cost of perfornmance) -} -#endif - -Property -{ - Name = %BLENDLAYER - Mask = 0x100 - Property (Blendlayer) - Description (Enables a second set of texture inputs and mask to be used for a layered material) -} - -Property -{ - Name = %BLENDLAYER_UV_SET_2 - Mask = 0x200 - Property (Use uv set 2 for blendlayer maps) - Description (Second blend layer maps will be applied to second UV set on mesh) -} - -Property -{ - Name = %EMITTANCE_MAP - Mask = 0x400 - Property (Emittance Map) - Description (Use emittance map texture) - DependencySet = $TEX_Emittance - DependencyReset = $TEX_Emittance - Hidden -} - -Property -{ - Name = %EMITTANCE_MAP_UV_SET_2 - Mask = 0x800 - Property (Use uv set 2 for emittance map) - Description (Emittance map will be applied to second UV set on mesh) -} - -Property -{ - Name = %ALPHAMASK_DETAILMAP - Mask = 0x800000 - Property (DetailMap mask in Diffuse alpha) - Description (Enables the diffuse map alpha to mask the detail map) -} - -Property -{ - Name = %SILHOUETTE_PARALLAX_OCCLUSION_MAPPING - Mask = 0x10000 - Property (Silhouette POM) - Description (Simulates surface depth by parallaxing bump detail and adds silhouette displacement to the mesh edge. Requires height and normal maps before enabling.) - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %ALLOW_SILHOUETTE_POM - Mask = 0x40000 - DependencySet = $HW_SilhouettePom - DependencyReset = $HW_SilhouettePom - Hidden -} - -Property -{ - Name = %SUBSURFACE_SCATTERING - Mask = 0x80000 - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %DEPTH_FIXUP - Mask = 0x4000000 - Property (Depth Fixup) - Description (Enables to write and control depth for post-processing like depth of field) -} - -Property -{ - Name = %SAA_FILTERING - Mask = 0x80000000 - Property (Specular Antialiasing) - Description (Reduces antialiasing on bright specular meshes) -} - -Property -{ - Name = %ALLOW_SPECULAR_ANTIALIASING - Mask = 0x200000000 - DependencySet = $HW_SpecularAntialiasing - DependencyReset = $HW_SpecularAntialiasing - Hidden -} - -Property -{ - Name = %OCCLUSION_MAP - Mask = 0x40 - Property (Occlusion Map) - Description (Adds an additional texture slot for ambient occlusion) -} - -Property -{ - Name = %APPLY_FORWARD_DYNAMIC_LIGHTING - Mask = 0x400000000 - Property(Dynamic Lighting for Transparency) - Description(Adds a full forward lighting pass for transparent objects - less performant) -} diff --git a/Assets/Engine/Shaders/LensOptics.ext b/Assets/Engine/Shaders/LensOptics.ext deleted file mode 100644 index 5bd18e3895..0000000000 --- a/Assets/Engine/Shaders/LensOptics.ext +++ /dev/null @@ -1,16 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// diff --git a/Assets/Engine/Shaders/LightBeam.ext b/Assets/Engine/Shaders/LightBeam.ext deleted file mode 100644 index 835a0dbc99..0000000000 --- a/Assets/Engine/Shaders/LightBeam.ext +++ /dev/null @@ -1,44 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: LightBeam shader extension used by the editor -// for automatic shader generation (based on "LightBeam" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %NOISE - Mask = 0x1 - Property (Noise map) - Description (Use 3D noise) -} - -Property -{ - Name = %FALLOFF - Mask = 0x2 - Property (Use Falloff) - Description (Use Falloff) -} - -Property -{ - Name = %DOUBLE_SAMPLING - Mask = 0x4 - Property (Extra Sampling) - Description (Add expense to reduce aliasing) -} diff --git a/Assets/Engine/Shaders/Monitor.ext b/Assets/Engine/Shaders/Monitor.ext deleted file mode 100644 index 2a20138c1f..0000000000 --- a/Assets/Engine/Shaders/Monitor.ext +++ /dev/null @@ -1,53 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Monitor shader extension used by the editor -// for automatic shader generation -// -//////////////////////////////////////////////////////////////////////////// - - - -Version (1.00) - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x2 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %PIXELIZE - Mask = 0x4 - Property (Pixelized) - Description (Pixelize the diffuse texture.) -} - diff --git a/Assets/Engine/Shaders/ParticleImposter.ext b/Assets/Engine/Shaders/ParticleImposter.ext deleted file mode 100644 index 650541cfa3..0000000000 --- a/Assets/Engine/Shaders/ParticleImposter.ext +++ /dev/null @@ -1,37 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %SOFT_PARTICLE - Mask = 0x2 - Property (Soft Particle) - Description (Soften particle intersections with world) -} diff --git a/Assets/Engine/Shaders/Particles.ext b/Assets/Engine/Shaders/Particles.ext deleted file mode 100644 index 3f24ea84b7..0000000000 --- a/Assets/Engine/Shaders/Particles.ext +++ /dev/null @@ -1,102 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Particles shader extension used by the editor -// for automatic shader generation (based on "Particles" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %REFRACTION - Mask = 0x4 - Property (Refraction) - Description (Use normal-map texture as displacement for refraction) -} - -Property -{ - Name = %REFRACTION_TINTING - Mask = 0x800 - Property (Refraction Tinting) - Description (Use color texture to tint refraction) -} - -Property -{ - Name = %SCREEN_SPACE_DEFORMATION - Mask = 0x10 - Property (Screen space deformation) - Description (Use custom slot map for screen space particles deformation) - DependencyReset = $TEX_Custom -} - -Property -{ - Name = %DEFORMATION - Mask = 0x20 - Property (Deformation) - Description (Use custom slot map for per-particle deformation) - DependencyReset = $TEX_Custom -} - -Property -{ - Name = %COLOR_LOOKUP - Mask = 0x40 - Property (Color lookup) - Description (Use custom slot [1] map for applying color lookup) - DependencyReset = $TEX_CustomSecondary -} - -Property -{ - Name = %SPECULAR_LIGHTING - Mask = 0x100 - Property (Specular Lighting) - Description (Calculate specular lighting in addition to diffuse lighting) - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %DEPTH_FIXUP - Mask = 0x200 - Property (Depth Fixup) - Description (Write depth for depth of field and postprocessing) -} - -Property -{ - Name = %NORMAL_MAP - Mask = 0x400 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %GLOW_MAP - Mask = 0x1000 - Property (Emissive map) - Description (Use this map to mask the particle emissive intensity) - DependencySet = $TEX_Detail - DependencyReset = $TEX_Detail - Hidden -} diff --git a/Assets/Engine/Shaders/RunTime.ext b/Assets/Engine/Shaders/RunTime.ext deleted file mode 100644 index 9cc96769d5..0000000000 --- a/Assets/Engine/Shaders/RunTime.ext +++ /dev/null @@ -1,1259 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %_RT_FOG - Mask = 0x1 // 1 << 0 - Precache = GeneralPS - Precache = GeneralVS - Precache = GeneralGS - Precache = GeneralDS - Precache = GeneralHS - Precache = TerrainPS - Precache = TerrainVS - Precache = VegetationVS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationPS - Precache = SkinPS - Precache = SkinVS - Precache = HairPS - Precache = HairVS - Precache = EyePS - Precache = EyeVS - Precache = GlassPS - Precache = GlassVS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS - Precache = CustomRenderHS - Precache = CustomRenderDS - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - Precache = WaterSurfaceHS - Precache = WaterSurfaceDS - Precache = WaterFogVolume_VS - Precache = WaterFogVolume_PS - Precache = MeshBakerPS - Precache = ParticleImposterVS - Precache = ParticleImposterPS -} - -Property -{ - Name = %_RT_AMBIENT - Mask = 0x2 // 1 << 1 - Precache = GeneralPS - Precache = SkinPS - Precache = HairPS - Precache = EyePS - Precache = GlassPS - Precache = TerrainPS - Precache = VegetationPS - Precache = ParticlePS - Precache = MeshBakerPS -} - -Property -{ - Name = %_RT_OCEAN_PARTICLE - Mask = 0x4 // 1 << 2 - Precache = PostProcessGamePS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - Precache = WaterSurfaceHS - Precache = WaterSurfaceDS - Precache = WaterFogVolume_PS -} - -Property -{ - //Using the same mask as _RT_OCEAN_PARTICLE as we have run out of them. - //It should be safe to do this as this flag is not used in water rendering - Name = %_RT_DEPTHFIXUP - Mask = 0x4 // 1 << 2 - Precache = FurShellPS - Precache = GlassPS - Precache = IlluminationPS - Precache = GeneralPS -} - -Property -{ - Name = %_RT_DECAL_TEXGEN_2D - Mask = 0x8 // 1 << 3 - Precache = GeneralVS - Precache = GeneralDS - Precache = GeneralHS - Precache = ShadowGenVS - Precache = CausticsVS - Precache = GeneralPS - Precache = CustomRenderHS - Precache = CustomRenderDS - Precache = ZVS - Precache = ZPS - Precache = MeshBakerPS - Precache = TiledShadingCS -} - -Property -{ - Name = %_RT_DISSOLVE - Mask = 0x10 // 1 << 4 - Precache = ZPS - Precache = ZVS - Precache = ShadowGenVS - Precache = ShadowGenPS - Precache = GeneralPS - Precache = GeneralVS -} - -Property -{ - Name = %_RT_VOLUMETRIC_FOG - Mask = 0x20 // 1 << 5 - Precache = GeneralPS - Precache = GeneralVS - Precache = GeneralGS - Precache = GeneralDS - Precache = GeneralHS - Precache = TerrainPS - Precache = TerrainVS - Precache = VegetationVS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationPS - Precache = SkinPS - Precache = SkinVS - Precache = HairPS - Precache = HairVS - Precache = EyePS - Precache = EyeVS - Precache = GlassPS - Precache = GlassVS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS - Precache = WaterSurfacePS - Precache = WaterFogVolume_VS - Precache = WaterFogVolume_PS - Precache = MeshBakerPS - Precache = CloudVS - Precache = CloudPS - Precache = FogPostProcessPS - Precache = ParticleImposterVS - Precache = ParticleImposterPS -} - -Property -{ - Name = %_RT_NEAREST - Mask = 0x40 // 1 << 6 - Precache = ShadowGenVS - Precache = ShadowMaskGenVS - Precache = ShadowMaskGenPS - Precache = ZVS - Precache = MotionBlurVS - Precache = SkinVS - Precache = GeneralVS - Precache = VegetationVS - Precache = CausticsVS - Precache = CustomRenderVS - Precache = DebugPassVS -} - -Property -{ - Name = %_RT_GLOBAL_ILLUMINATION - Mask = 0x80 // 1 << 7 - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_ALPHATEST - Mask = 0x100 // 1 << 8 - Precache = ShadowGenVS - Precache = ShadowGenPS - Precache = ZPS - Precache = ZVS - Precache = MotionBlurPS - Precache = CustomRenderPS - Precache = VegetationVS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationPS - Precache = GeneralPS - Precache = GlassPS - Precache = GlassVS - Precache = MotionBlurVS - Precache = MeshBakerPS -} - -Property -{ - Name = %_RT_SOFT_PARTICLE - Mask = 0x200 // 1 << 9 - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_HDR_MODE - Mask = 0x400 // 1 << 10 - Precache = GeneralPS - Precache = TerrainPS - Precache = VegetationPS - Precache = SkinPS - Precache = HairPS - Precache = EyePS - Precache = GlassPS - Precache = ParticlePS - Precache = WaterSurfacePS - Precache = ParticleImposterPS -} - -Property -{ - Name = %_RT_PARTICLE_SHADOW - Mask = 0x800 // 1 << 11 - Precache = ParticlePS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS -} - -Property -{ - Name = %_RT_SAMPLE1 - Mask = 0x1000 // 1 << 12 - Precache = CustomRenderHS - Precache = CustomRenderDS - Precache = CustomRenderVS - Precache = CustomRenderPS - Precache = SkinPS - Precache = HDRPostProcessPS - Precache = PostMotionBlurVS - Precache = PostMotionBlurPS - Precache = PostSunShaftsPS - Precache = PostProcessGamePS - Precache = PostDofPS - Precache = PostEffectsVS - Precache = PostEffectsPS - Precache = PostAA_PS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - Precache = PostHUD3D_VS - Precache = PostHUD3D_PS - Precache = ParticlePS - Precache = ParticleVS - Precache = DeferredRainPS - Precache = ShadowMaskGenPS - - Precache = WaterFogVolume_VS - Precache = WaterFogVolume_PS - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - Precache = WaterSurfaceHS - Precache = WaterSurfaceDS - - Precache = BeamPS - Precache = ParticleHS - Precache = ParticleDS - - Precache = TiledShadingCS - Precache = VolumeLightInjectionCS - Precache = ResolvePS - Precache = VideoPS -} - -Property -{ - Name = %_RT_SAMPLE2 - Mask = 0x2000 // 1 << 13 - - Precache = HDRPostProcessPS - Precache = PostMotionBlurVS - Precache = PostMotionBlurPS - Precache = PostAA_PS - Precache = PostSunShaftsPS - Precache = PostProcessGamePS - Precache = DeferredDecalPassPS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - Precache = CustomRenderPS - Precache = DeferredRainPS - - Precache = ShadowMaskGenVS - Precache = ShadowMaskGenPS - Precache = ParticlePS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - - Precache = BeamPS - Precache = LensOpticsPS - Precache = WaterFogVolume_PS - Precache = TiledShadingCS - Precache = FogPostProcessPS - Precache = VideoPS -} - -Property -{ - Name = %_RT_SAMPLE3 - Mask = 0x4000 // 1 << 14 - Precache = ParticlePS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = PostAA_PS - Precache = HDRPostProcessPS - Precache = BeamPS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - Precache = DeferredRainPS - Precache = ShadowMaskGenVS - Precache = ShadowMaskGenPS - Precache = DeferredDecalPassPS - Precache = DeferredDecalEmissivePassPS - Precache = ResolvePS - - Precache = LensOpticsPS - Precache = WaterFogVolume_PS - Precache = TiledShadingCS - Precache = VideoPS -} - -Property -{ - Name = %_RT_POINT_LIGHT - Mask = 0x8000 // 1 << 15 - Precache = FogPassVolShadowsInterleavePassPS - Precache = WaterFogVolume_PS - Precache = ConeTraceDiffusePS -} - -Property -{ - Name = %_RT_ALPHABLEND - Mask = 0x10000 // 1 << 16 - Precache = GeneralHS - Precache = GeneralDS - Precache = FogPassVolShadowsInterleavePassPS - Precache = ParticlePS - Precache = ParticleVS - Precache = HairVS - Precache = EyeVS - Precache = VegetationVS - Precache = GeneralVS - Precache = GlassVS - Precache = CustomRenderHS - Precache = CustomRenderDS - Precache = ZVS - Precache = ZPS - Precache = MotionBlurPS -} - -Property -{ - Name = %_RT_ANIM_BLEND - Mask = 0x20000 // 1 << 17 - Precache = ParticlePS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticleGS -} - -Property -{ - Name = %_RT_QUALITY - Mask = 0x40000 // 1 << 18 - AutoPrecache - Precache = ShadowGenVS - Precache = ShadowGenPS - Precache = ZVS - Precache = ZPS - Precache = FogPassVolShadowsInterleavePassPS - Precache = GeneralPS - Precache = GeneralVS - Precache = SkinPS - Precache = SkinVS - Precache = HairPS - Precache = HairVS - Precache = EyePS - Precache = EyeVS - Precache = GlassPS - Precache = GlassVS - Precache = TerrainPS - Precache = TerrainVS - Precache = VegetationPS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationVS - Precache = MotionBlurVS - Precache = MotionBlurPS - Precache = CausticsVS - Precache = ParticlePS - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - - Precache = PostMotionBlurVS - Precache = PostMotionBlurPS - Precache = PostSunShaftsPS - Precache = SpriteDilatePS - Precache = ShadowMaskGenPS - - Precache = HDRPostProcessVS - Precache = HDRPostProcessPS - Precache = FogPostProcessPS - Precache = PostProcessGameVS - Precache = PostProcessGamePS - - Precache = DistanceCloudsPS - Precache = DeferredLightPassPS - Precache = VolumeLightInjectionCS -} - -Property -{ - Name = %_RT_QUALITY1 - Mask = 0x80000 // 1 << 19 - AutoPrecache - Precache = ShadowGenVS - Precache = ShadowGenPS - Precache = ZVS - Precache = ZPS - Precache = FogPassVolShadowsInterleavePassPS - Precache = GeneralPS - Precache = GeneralVS - Precache = SkinPS - Precache = SkinVS - Precache = HairPS - Precache = HairVS - Precache = EyePS - Precache = EyeVS - Precache = GlassPS - Precache = GlassVS - Precache = TerrainPS - Precache = TerrainVS - Precache = VegetationPS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationVS - Precache = MotionBlurVS - Precache = MotionBlurPS - Precache = CausticsVS - Precache = ParticlePS - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - - Precache = PostMotionBlurVS - Precache = PostMotionBlurPS - Precache = PostSunShaftsPS - Precache = SpriteDilatePS - Precache = ShadowMaskGenPS - - Precache = HDRPostProcessVS - Precache = HDRPostProcessPS - Precache = FogPostProcessPS - Precache = PostProcessGameVS - Precache = PostProcessGamePS - - Precache = DistanceCloudsPS - Precache = DeferredLightPassPS - Precache = VolumeLightInjectionCS -} - -Property -{ - Name = %_RT_INSTANCING_ATTR - Mask = 0x100000 // 1 << 20 - Precache = GeneralVS - Precache = SkinVS - Precache = HairVS - Precache = EyeVS - Precache = GlassVS - Precache = VegetationVS - Precache = ShadowGenVS - Precache = ZVS - Precache = MotionBlurVS - Precache = CausticsVS - Precache = CustomRenderVS - Precache = DebugPassVS -} - -Property -{ - Name = %_RT_ENVIRONMENT_CUBEMAP - Mask = 0x200000 // 1 << 21 - Precache = ParticlePS -} - -Property -{ - Name = %_RT_TILED_SHADING - Mask = 0x400000 // 1 << 22 - Precache = EyePS - Precache = HairPS - Precache = GlassPS - Precache = IlluminationPS -} - -Property -{ - Name = %_RT_NO_TESSELLATION - Mask = 0x800000 // 1 << 23 - Precache = GeneralVS - Precache = GeneralPS - Precache = ShadowGenVS - Precache = ShadowGenPS - Precache = ZVS - Precache = ZPS - Precache = MotionBlurVS - Precache = MotionBlurPS - Precache = CustomRenderVS - Precache = SkinVS - Precache = SkinPS - Precache = VegetationVS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationPS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS - Precache = DebugPassVS -} - -Property -{ - Name = %_RT_APPLY_TOON_SHADING - Mask = 0x1000000 // 1 << 24 - Precache = DeferredLightPassPS - Precache = TiledShadingCS -} - - -Property -{ - Name = %_RT_LIGHT_TEX_PROJ - Mask = 0x2000000 // 1 << 25 - Precache = DeferredLightPassPS - Precache = ParticleVS - Precache = ParticleDS - Precache = ConeTraceDiffusePS -} - -Property -{ - Name = %_RT_VERTEX_VELOCITY - Mask = 0x4000000 // 1 << 26 - Precache = ZVS - Precache = MotionBlurVS -} - -Property -{ - Name = %_RT_SKINNING_DUAL_QUAT - Mask = 0x8000000 // 1 << 27 - Precache = GeneralVS - Precache = SkinVS - Precache = HairVS - Precache = EyeVS - Precache = GlassVS - Precache = VegetationVS - Precache = ShadowGenVS - Precache = ZVS - Precache = MotionBlurVS - Precache = CausticsVS - Precache = CustomRenderVS - Precache = DebugPassVS -} - -Property -{ - Name = %_RT_SKINNING_DQ_LINEAR - Mask = 0x10000000 // 1 << 28 - Precache = GeneralVS - Precache = SkinVS - Precache = HairVS - Precache = EyeVS - Precache = GlassVS - Precache = VegetationVS - Precache = ShadowGenVS - Precache = ZVS - Precache = MotionBlurVS - Precache = CausticsVS - Precache = CustomRenderVS - Precache = DebugPassVS -} - -Property -{ - Name = %_RT_BLEND_WITH_TERRAIN_COLOR - Mask = 0x20000000 // 1 << 29 - Precache = ZVS - Precache = ZPS - Precache = GeneralHS - Precache = GeneralDS - Precache = VegetationVS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationPS - Precache = ConeTraceDiffusePS -} - -Property -{ - Name = %_RT_MOTION_BLUR - Mask = 0x40000000 // 1 << 30 - Precache = ParticleVS - Precache = ParticleHS - Precache = GPUParticleCS - Precache = ParticleDS - Precache = ParticlePS - Precache = ZVS - Precache = ZGS - Precache = ZPS - Precache = GeneralHS - Precache = GeneralDS -} - -Property -{ - Name = %_RT_LIGHTVOLUME0 - Mask = 0x80000000 // 1 << 31 - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - Precache = VolumeLightInjectionCS - Precache = RenderDownscaledShadowMapPS -} - -Property -{ - //Using the same mask as _RT_LIGHTVOLUME0 as we have run out of them. - //It should be safe to do this as this flag is not used in the deferred lighting pass or particles. - - Name = %_RT_SRGB0 - Mask = 0x80000000 // 1 << 31 - Precache = PostAA_PS - Precache = ResolvePS - Precache = HDRPostProcessPS -} - -Property -{ - Name = %_RT_LIGHTVOLUME1 - Mask = 0x100000000 // 1 << 32 - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS - Precache = VolumeLightInjectionCS - Precache = RenderDownscaledShadowMapPS -} - -Property -{ - //Using the same mask as _RT_LIGHTVOLUME1 as we have run out of them. - //It should be safe to do this as this flag is not used in the deferred lighting pass or particles. - - Name = %_RT_SRGB1 - Mask = 0x100000000 // 1 << 32 - Precache = PostAA_PS - Precache = ResolvePS - Precache = HDRPostProcessPS -} - -Property -{ - Name = %_RT_NOZPASS - Mask = 0x200000000 // 1 << 33 - Precache = VegetationVS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationPS -} - -Property -{ - //Using the same mask as _RT_NOZPASS as we have run out of them. - //It should be safe to do this as this flag is not used in vegetation pass. - - Name = %_RT_SRGB2 - Mask = 0x200000000 // 1 << 33 - Precache = PostAA_PS - Precache = ResolvePS - Precache = HDRPostProcessPS -} - -Property -{ - Name = %_RT_SHADOW_MIXED_MAP_G16R16 - Mask = 0x400000000 // 1 << 34 - Precache = FogPassVolShadowsInterleavePassPS - Precache = WaterFogVolume_PS - - Precache = ShadowMaskGenVS - Precache = ShadowMaskGenPS -} - -Property -{ - Name = %_RT_SHADOW_JITTERING - Mask = 0x800000000 // 1 << 35 - Precache = FogPassVolShadowsInterleavePassPS - Precache = TerrainPS - Precache = WaterFogVolume_PS - - Precache = ShadowMaskGenVS - Precache = ShadowMaskGenPS - - Precache = HairPS - Precache = EyePS -} - -Property -{ - Name = %_RT_ADDITIVE_BLENDING - Mask = 0x1000000000 // 1 << 36 - Precache = GlassPS - Precache = GeneralPS - Precache = HairPS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_SAMPLE0 - Mask = 0x2000000000 // 1 << 37 - Precache = CustomRenderVS - Precache = CustomRenderPS - Precache = SkinPS - Precache = GlassPS - - Precache = FogPostProcessPS - Precache = HDRPostProcessPS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS - Precache = PostHUD3D_VS - Precache = PostHUD3D_PS - Precache = PostMotionBlurVS - Precache = PostMotionBlurPS - Precache = PostAA_PS - Precache = PostSunShaftsPS - Precache = PostProcessGameVS - Precache = PostProcessGamePS - Precache = PostDofPS - Precache = PostEffectsVS - Precache = PostEffectsPS - Precache = DeferredDecalPassPS - Precache = DeferredDecalEmissivePassPS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - Precache = SceneRainVS - Precache = SceneRainPS - Precache = DeferredRainPS - Precache = ResolveVS - Precache = ResolvePS - - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - Precache = WaterSurfaceHS - Precache = WaterSurfaceDS - Precache = WaterFogVolume_PS - - Precache = BeamPS - Precache = LensOpticsVS - Precache = TiledShadingCS - Precache = VolumeLightInjectionCS - Precache = VideoPS -} - -// Reserved for post processes/deferred - do not use for light/common shaders -Property -{ - Name = %_RT_SAMPLE5 - Mask = 0x4000000000 // 1 << 38 - - Precache = ZVS - Precache = GeneralVS - Precache = GeneralHS - Precache = GeneralDS - - Precache = HDRPostProcessPS - Precache = PostSunShaftsPS - Precache = PostProcessGamePS - Precache = DeferredPassPS - Precache = DeferredPassVS - Precache = DeferredLightPassPS - Precache = PostMotionBlurPS - Precache = DeferredDecalPassPS - Precache = DeferredDecalEmissivePassPS - Precache = ResolvePS - Precache = FogPassVolShadowsInterleavePassPS - Precache = CustomRenderHS - Precache = CustomRenderDS - Precache = CustomRenderPS - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - Precache = WaterSurfaceHS - Precache = WaterSurfaceDS - Precache = WaterFogVolume_PS - Precache = PostAA_PS - - Precache = BeamPS - Precache = LensOpticsVS - Precache = TiledShadingCS - Precache = VolumeLightInjectionCS - Precache = ReprojectVolumetricFogCS -} - -Property -{ - Name = %_RT_HW_PCF_COMPARE - Mask = 0x8000000000 // 1 << 39 - Precache = FogPassVolShadowsInterleavePassPS - Precache = ShadowGenVS - Precache = ShadowGenPS - - Precache = DeferredLightPassPS - Precache = ShadowMaskGenVS - Precache = ShadowMaskGenPS - - Precache = WaterFogVolume_PS - Precache = ConeTraceDiffusePS -} - -Property -{ - Name = %_RT_REVERSE_DEPTH - Mask = 0x10000000000 // 1 << 40 - Precache = DistanceCloudsVS - Precache = PostProcessGamePS - Precache = TerrainVS - Precache = ZVS - Precache = ZPS - Precache = UnderwaterGodRays - Precache = WaterSurfaceVS - Precache = WaterFogVolume_VS - Precache = GeneralVS - Precache = LensOpticsVS -} - -Property -{ - Name = %_RT_DEBUG0 - Mask = 0x20000000000 // 1 << 41 - - Runtime -} - -Property -{ - Name = %_RT_DEBUG1 - Mask = 0x40000000000 // 1 << 42 - Runtime -} - -Property -{ - Name = %_RT_DEBUG2 - Mask = 0x80000000000 // 1 << 43 - Runtime -} - -Property -{ - Name = %_RT_DEBUG3 - Mask = 0x100000000000 // 1 << 44 - Runtime -} - -Property -{ - Name = %_RT_CUBEMAP0 - Mask = 0x200000000000 // 1 << 45 - Precache = ShadowGenPS - Precache = ShadowGenVS - - Precache = PostSunShaftsPS - Precache = PostProcessGamePS - - Precache = DeferredDecalPassVS - Precache = DeferredDecalPassPS - Precache = DeferredDecalEmissivePassPS - Precache = DeferredLightPassVS - Precache = DeferredLightPassPS - Precache = DeferredPassVS - Precache = DeferredPassPS - - Precache = WaterFogVolume_PS - Precache = TiledShadingCS -} - -Property -{ - Name = %_RT_SAMPLE4 - Mask = 0x400000000000 // 1 << 46 - Precache = ShadowGenVS - Precache = ShadowGenPS - Precache = PostAA_PS - - Precache = HDRPostProcessPS - Precache = PostProcessGamePS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - Precache = PostSunShaftsPS - Precache = PostMotionBlurPS - - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - Precache = WaterSurfaceHS - Precache = WaterSurfaceDS - Precache = WaterFogVolume_PS - Precache = DeferredDecalPassPS - Precache = DeferredDecalEmissivePassPS - - Precache = BeamPS - Precache = LensOpticsPS - - Precache = TiledShadingCS - - Precache = ConeTraceDiffusePS - Precache = VolumeLightInjectionCS -} - -Property -{ - Name = %_RT_SPRITE - Mask = 0x800000000000 // 1 << 47 - Precache = VegetationVS - Precache = VegetationPS - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_SHADOW_PASS - Mask = 0x1000000000000 // 1 << 48 - Precache = ParticleVS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_DEPTH_COLLISION - Mask = 0x2000000000000 // 1 << 49 - Precache = GPUParticleCS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_TURBULENCE - Mask = 0x4000000000000 // 1 << 50 - Precache = GPUParticleCS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_UV_ANIMATION - Mask = 0x8000000000000 // 1 << 51 - Precache = ParticleVS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_NORMAL_MAP - Mask = 0x10000000000000 // 1 << 52 - Precache = ParticleVS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_GLOW_MAP - Mask = 0x20000000000000 // 1 << 53 - Precache = ParticleVS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_CUBEMAP_DEPTH_COLLISION - Mask = 0x40000000000000 // 1 << 54 - Precache = GPUParticleCS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_WRITEBACK_DEATH_LOCATIONS - Mask = 0x80000000000000 // 1 << 55 - Precache = GPUParticleCS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_TARGET_ATTRACTION - Mask = 0x100000000000000 // 1<< 56 - Precache = GPUParticleCS -} - -Property -{ - // Using the same mask as _RT_GPU_PARTICLE_TARGET_ATTRACTION as we have run out of them. - //It should be safe to do this as this flag is not used in the deferred lighting pass. - - Name = %_RT_DEFERRED_RENDER_TARGET_OPTIMIZATION - Mask = 0x100000000000000 // 1<< 56 - - Precache = DeferredPassPS - Precache = DeferredPassVS - Precache = DeferredLightPassPS - Precache = TiledShadingCS - Precache = LightPassPS - Precache = LightPassGmemPS - Precache = ConeTraceDiffusePS - Precache = VolumeLightInjectionCS - Precache = CubemapPassPS - Precache = CubemapPassGmemPS - Precache = DeferredShadowGmemPS - Precache = DeferredShadingPassPS - Precache = DeferredShadingPassGmemPS - Precache = AmbientPS - Precache = ShadowMaskGenVS - Precache = ShadowMaskGenPS - Precache = DeferredDecalPassPS - Precache = DeferredDecalEmissivePassPS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_SHAPE_ANGLE - Mask = 0x200000000000000 // 1 << 57 - Precache = GPUParticleCS -} - -Property -{ - - // Using the same mask as _RT_GPU_PARTICLE_SHAPE_ANGLE as we have run out of them. - //It should be safe to do this as this flag is not used in the deferred lighting pass. - - Name = %_RT_SLIM_GBUFFER - Mask = 0x200000000000000 // 1 << 57 - AutoPrecache - Precache = ShadowGenVS - Precache = ShadowGenPS - Precache = ZVS - Precache = ZPS - Precache = FogPassVolShadowsInterleavePassPS - Precache = GeneralPS - Precache = GeneralVS - Precache = SkinPS - Precache = SkinVS - Precache = HairPS - Precache = HairVS - Precache = EyePS - Precache = EyeVS - Precache = GlassPS - Precache = GlassVS - Precache = TerrainPS - Precache = TerrainVS - Precache = VegetationPS - Precache = VegetationHS - Precache = VegetationDS - Precache = VegetationVS - Precache = MotionBlurVS - Precache = MotionBlurPS - Precache = CausticsVS - Precache = ParticlePS - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - - Precache = PostMotionBlurVS - Precache = PostMotionBlurPS - Precache = PostSunShaftsPS - Precache = SpriteDilatePS - Precache = ShadowMaskGenPS - - Precache = HDRPostProcessVS - Precache = HDRPostProcessPS - Precache = FogPostProcessPS - Precache = PostProcessGameVS - Precache = PostProcessGamePS - - Precache = DistanceCloudsPS - Precache = DeferredLightPassPS - Precache = VolumeLightInjectionCS - Precache = HDRPostProcessPS - Precache = PostProcessGamePS - Precache = DeferredLightPassPS - Precache = DeferredPassPS - Precache = PostSunShaftsPS - Precache = PostMotionBlurPS - - Precache = WaterSurfaceVS - Precache = WaterSurfacePS - Precache = WaterSurfaceHS - Precache = WaterSurfaceDS - Precache = WaterFogVolume_PS - Precache = DeferredDecalPassPS - Precache = DeferredDecalEmissivePassPS - - Precache = BeamPS - Precache = LensOpticsPS - - Precache = DeferredShadingPassPS - Precache = DeferredPassVS - Precache = DeferredLightPassPS - Precache = TiledShadingCS - Precache = LightPassPS - Precache = ConeTraceDiffusePS - Precache = VolumeLightInjectionCS - Precache = CubemapPassPS - Precache = CubemapPassGmemPS - - Precache = DeferredSnowPS - Precache = DeferredRainPS - Precache = SSRCompositionPS - Precache = SSRRaytracePS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_SHAPE_BOX - Mask = 0x400000000000000 // 1 << 58 - Precache = GPUParticleCS - Precache = ParticleVS -} - -Property -{ - // Using the same mask as _RT_GPU_PARTICLE_SHAPE_BOX as we have run out of them. - // It should be safe to do this as this (GPU Particles shouldn't have skinning) - - Name = %_RT_SKINNING_MATRIX - Mask = 0x400000000000000 // 1 << 58 - Precache = GeneralVS - Precache = SkinVS - Precache = HairVS - Precache = EyeVS - Precache = GlassVS - Precache = VegetationVS - Precache = ShadowGenVS - Precache = ZVS - Precache = MotionBlurVS - Precache = CausticsVS - Precache = CustomRenderVS - Precache = DebugPassVS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_SHAPE_POINT - Mask = 0x800000000000000 // 1 << 59 - Precache = GPUParticleCS -} - -Property -{ - //Using the same mask as _RT_GPU_PARTICLE_SHAPE_POINT as we have run out of them. - //It should be safe to do this as this flag is not used in the deferred lighting pass. - Name = %_RT_APPLY_SSDO - Mask = 0x800000000000000 // 1 << 59. - Precache = DeferredPassPS - Precache = DeferredPassVS - Precache = DeferredLightPassPS - Precache = TiledShadingCS -} - -//Using the same mask as _RT_APPLY_SSDO as we have run out of them. -//It should be safe to do this as this flag is not used in particle shaders. -Property -{ - Name = %_RT_FOG_VOLUME_HIGH_QUALITY_SHADER - Mask = 0x800000000000000 // 1 << 59 - Precache = ParticleVS - Precache = ParticleHS - Precache = ParticleDS - Precache = ParticlePS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_SHAPE_CIRCLE - Mask = 0x1000000000000000 // 1 << 60 - Precache = GPUParticleCS - Precache = ParticleVS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_SHAPE_SPHERE - Mask = 0x2000000000000000 // 1 << 61 - Precache = GPUParticleCS - Precache = ParticleVS -} - -Property -{ - Name = %_RT_GPU_PARTICLE_WIND - Mask = 0x4000000000000000 // 1 << 62 - Precache = GPUParticleCS - -} -Property -{ - Name = %_RT_MULTI_LAYER_ALPHA_BLEND - Mask = 0x8000000000000000 // 1 << 63 - Precache = FurShellPS - Precache = FurFinsPS - Precache = GlassPS - Precache = GeneralPS - Precache = HairPS - Precache = ParticlePS - Precache = MultiLayerAlphaBlendResolvePS -} - - diff --git a/Assets/Engine/Shaders/Scopes.ext b/Assets/Engine/Shaders/Scopes.ext deleted file mode 100644 index ae84db49ca..0000000000 --- a/Assets/Engine/Shaders/Scopes.ext +++ /dev/null @@ -1,42 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %REFLEX_SIGHT - Mask = 0x2 - Property (Reflex sight) - Description (New reflex sight version) -} - -Property -{ - Name = %SCOPE_ZOOMED_REFRACTION - Mask = 0x4 - Property (Scope zoomed refraction) - Description (Scope zoomed in refraction) -} - -Property -{ - Name = %HOLO_SIGHT - Mask = 0x8 - Property (Use holo sight depth) - Description (Holographic sight with depth modifier) -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/ShaderProfiles.txt b/Assets/Engine/Shaders/ShaderProfiles.txt deleted file mode 100644 index ae5178118e..0000000000 --- a/Assets/Engine/Shaders/ShaderProfiles.txt +++ /dev/null @@ -1,11 +0,0 @@ - -Version (1.00) - -Profile 'Low' -{ -} - -Profile 'High' -{ - UseNormalAlpha -} diff --git a/Assets/Engine/Shaders/ShadowMaskGen.ext b/Assets/Engine/Shaders/ShadowMaskGen.ext deleted file mode 100644 index 6c65742d63..0000000000 --- a/Assets/Engine/Shaders/ShadowMaskGen.ext +++ /dev/null @@ -1,21 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: -// -//////////////////////////////////////////////////////////////////////////// - - - -Version (1.00) diff --git a/Assets/Engine/Shaders/SketchTerrain.ext b/Assets/Engine/Shaders/SketchTerrain.ext deleted file mode 100644 index 3dfad9d1cf..0000000000 --- a/Assets/Engine/Shaders/SketchTerrain.ext +++ /dev/null @@ -1,27 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %TEMP_TERRAIN - Mask = 0x40000000 - DependencySet = $UserEnabled - Hidden -} diff --git a/Assets/Engine/Shaders/SkyHDR.ext b/Assets/Engine/Shaders/SkyHDR.ext deleted file mode 100644 index 87d1a00ca5..0000000000 --- a/Assets/Engine/Shaders/SkyHDR.ext +++ /dev/null @@ -1,39 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// -Version (1.00) - -Property -{ - Name = %NO_MOON - Mask = 0x02 - Property (No moon) - Description (Sky dome doesn't render moon) -} -Property -{ - Name = %NO_NIGHT_SKY_GRADIENT - Mask = 0x04 - Property (No night sky gradient) - Description (Sky dome doesn't render night sky gradient) -} -Property -{ - Name = %NO_DAY_SKY_GRADIENT - Mask = 0x08 - Property (No day sky gradient) - Description (Sky dome doesn't render day sky gradient) -} diff --git a/Assets/Engine/Shaders/StarterGame_GeometryBeamScaling.ext b/Assets/Engine/Shaders/StarterGame_GeometryBeamScaling.ext deleted file mode 100644 index 25e395f42d..0000000000 --- a/Assets/Engine/Shaders/StarterGame_GeometryBeamScaling.ext +++ /dev/null @@ -1,43 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// - - -Property -{ - Name = %NOISE - Mask = 0x1 - Property (Dust & Turbulence) - Description (Add a dust overlay [spec map for dust, bump map for turbulence] ) -} - - -Property -{ - Name = %RECEIVE_SHADOWS - Mask = 0x2 - Property (Receive Shadows) - Description (Enable shadow receiving) -} - - -Property -{ - Name = %UV_VIGNETTING - Mask = 0x4 - Property (UV Vignetting) - Description (Enabling this will cause contents to fade out at UV boundaries) -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/Statics.ext b/Assets/Engine/Shaders/Statics.ext deleted file mode 100644 index e7d93fbeaf..0000000000 --- a/Assets/Engine/Shaders/Statics.ext +++ /dev/null @@ -1,74 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %ST_GMEM_128BPP - Mask = 0x1 // 1 << 0 -} - -Property -{ - Name = %ST_GMEM_256BPP - Mask = 0x2 // 1 << 1 -} - -Property -{ - Name = %ST_GMEM_PLS - Mask = 0x4 // 1 << 2 -} - -Property -{ - Name = %ST_LLVM_DIRECTX_SHADER_COMPILER - Mask = 0x8 // 1 << 3 -} - -Property -{ - Name = %ST_FIXED_POINT - Mask = 0x10 // 1 << 4 -} - -Property -{ - Name = %ST_GMEM_RT_GREATER_FOUR - Mask = 0x20 // 1 << 5 -} - -Property -{ - Name = %ST_NO_DEPTH_CLIPPING - Mask = 0x40 // 1 << 6 -} - -Property -{ - Name = %ST_FEATURE_FETCH_DEPTHSTENCIL - Mask = 0x80 // 1 << 7 -} - -property -{ - Name = %ST_GMEM_VELOCITY_BUFFER - Mask = 0x100 // 1 << 8 -} - -property -{ - Name = %ST_GLES3_0 - Mask = 0x200 // 1 << 9 -} diff --git a/Assets/Engine/Shaders/TemplBeamProc.ext b/Assets/Engine/Shaders/TemplBeamProc.ext deleted file mode 100644 index 485702ace7..0000000000 --- a/Assets/Engine/Shaders/TemplBeamProc.ext +++ /dev/null @@ -1,34 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %NOISE - Mask = 0x1 - Property (Noise map) - Description (Use animated 3D noise) -} - -Property -{ - Name = %MUZZLEFLASH - Mask = 0x2 - Property (Muzzleflash) - Description (Use as muzzle flash) -} diff --git a/Assets/Engine/Shaders/Terrain.ext b/Assets/Engine/Shaders/Terrain.ext deleted file mode 100644 index 6e8b5dc6f3..0000000000 --- a/Assets/Engine/Shaders/Terrain.ext +++ /dev/null @@ -1,79 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: TerrainLayer shader extension used by the editor -// for automatic shader generation (based on "TerrainLayer" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x200 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %OFFSET_BUMP_MAPPING - Mask = 0x1000 - Property (Offset bump mapping) - Description (Use offset bump mapping (requires height map (_displ))) - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %DETAIL_MAPPING - Mask = 0x8000 - Property (Detail mapping) - Description (Use detail mapping) - DependencyReset = $TEX_Detail -} - -Property -{ - Name = %PARALLAX_OCCLUSION_MAPPING - Mask = 0x8000000 - Property (Parallax occlusion mapping) - Description (Use parallax occlusion mapping (requires height map (_displ))) - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %TEMP_TERRAIN - Mask = 0x40000000 - DependencySet = $UserEnabled - Hidden -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/Vegetation.ext b/Assets/Engine/Shaders/Vegetation.ext deleted file mode 100644 index 5f98ec49e6..0000000000 --- a/Assets/Engine/Shaders/Vegetation.ext +++ /dev/null @@ -1,137 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Vegetation extension used by the editor -// for automatic shader generation (based on "Vegetation" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -UsesCommonGlobalFlags - -Property -{ - Name = %NORMAL_MAP - Mask = 0x1 - Property (Normal map) - Description (Use normal-map texture) - DependencySet = $TEX_Normals - DependencyReset = $TEX_Normals - Hidden -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x10 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %LEAVES - Mask = 0x100 - Property (Leaves) - Description (Activate for leaves only ! Use leaf shading and leaves animation) -} - -Property -{ - Name = %GRASS - Mask = 0x2000 - Property (Grass) - Description (Activate for grass only ! Use simple grass rendering) -} - -Property -{ - Name = %SPEEDTREE_BILLBOARD - Mask = 0x40000 - Property (SpeedTree billboard) - Description (Activate for SpeedTree billboards only! Enables removal of non-camera-facing geometry from the billboard mesh) -} - -Property -{ - Name = %DETAIL_BENDING - Mask = 0x10000 - Property (Detail bending) - Description (Activate for leaves and grass only. Make sure to paint required vertex colors also) -} - -Property -{ - Name = %DETAIL_MAPPING - Mask = 0x20000 - Property (Detail mapping) - Description (Use detail mapping) - DependencyReset = $TEX_Detail -} - -Property -{ - Name = %BLENDLAYER - Mask = 0x80000 - Property (Blendlayer) - Description (Normal-mapped diffuse layer blended on top of base material) -} - -Property -{ - Name = %VERTCOLORS - Mask = 0x100000 - DependencySet = $UserEnabled - Hidden -} - -Property -{ - Name = %TEMP_VEGETATION - Mask = 0x8000000 - DependencySet = $UserEnabled - Hidden -} - -#ifdef FEATURE_MESH_TESSELLATION -Property -{ - Name = %DISPLACEMENT_MAPPING - Mask = 0x10000000 - Property (Displacement mapping) - Description (Use displacement mapping (requires height map (_displ))) - //DependencySet = $TEX_Height - DependencyReset = $TEX_Normals -} - -Property -{ - Name = %PHONG_TESSELLATION - Mask = 0x20000000 - Property (Phong tessellation) - Description (Use rough approximation of smooth surface subdivision) -} - -Property -{ - Name = %PN_TESSELLATION - Mask = 0x40000000 - Property (PN triangles tessellation) - Description (Use rough approximation of smooth surface subdivision) -} -#endif \ No newline at end of file diff --git a/Assets/Engine/Shaders/VolumeObject.ext b/Assets/Engine/Shaders/VolumeObject.ext deleted file mode 100644 index 8cab9b4270..0000000000 --- a/Assets/Engine/Shaders/VolumeObject.ext +++ /dev/null @@ -1,57 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: -// -//////////////////////////////////////////////////////////////////////////// - - - -Version (1.00) - -Property -{ - Name = %SOFT_OBJECT_INTERSECTION - Mask = 0x1 - Property (Soft Intersections) - Description (Enables soft intersections with opaque scene geometry) -} -Property -{ - Name = %BACK_LIGHTING - Mask = 0x2 - Property (Back Lighting) - Description (Adds back lighting to volume silhouette when viewing against sun) -} -Property -{ - Name = %JITTERING - Mask = 0x4 - Property (Jittering) - Description (Enables jittering on cloud steps) -} -Property -{ - Name = %SOFT_JITTERING - Mask = 0x8 - Property (Soft Jittering) - Description (Softens the effect of jittering on volume objects) -} -Property -{ - Name = %CUSTOM_SETTINGS - Mask = 0x10 - Property (Use TOD Settings) - Description (Use the custom cloud settings from the TOD for lighting) -} \ No newline at end of file diff --git a/Assets/Engine/Shaders/Water.ext b/Assets/Engine/Shaders/Water.ext deleted file mode 100644 index d44e3598e5..0000000000 --- a/Assets/Engine/Shaders/Water.ext +++ /dev/null @@ -1,62 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Water extension used by the editor -// for automatic shader generation (based on "Water" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %ENVIRONMENT_MAP - Mask = 0x4 - Property (Environment map) - Description (Use environment map instead of reflection) - DependencyReset = $TEX_EnvCM -} - -Property -{ - Name = %SUN_SHINE - Mask = 0x20 - Property (Sunshine) - Description (Activate for water sunshine) -} - -Property -{ - Name = %NO_REFRACTION_BUMP - Mask = 0x200 - Property (No refraction bump) - Description (Disables refraction bump) -} - -Property -{ - Name = %FOAM - Mask = 0x400 - Property (Foam) - Description (Enables foam) -} - -Property -{ - Name = %WATER_TESSELLATION_DX11 - Mask = 0x800 - DependencySet = $HW_WaterTessellation - DependencyReset = $HW_WaterTessellation - Hidden -} diff --git a/Assets/Engine/Shaders/WaterVolume.ext b/Assets/Engine/Shaders/WaterVolume.ext deleted file mode 100644 index dec9d1a531..0000000000 --- a/Assets/Engine/Shaders/WaterVolume.ext +++ /dev/null @@ -1,107 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Water extension used by the editor -// for automatic shader generation (based on "Water" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %SSREFL - Mask = 0x1 - Property (Realtime Reflection) - Description (Approximate realtime reflections) -} - -Property -{ - Name = %FLOW - Mask = 0x2 - Property (Water flow) - Description (Enable water to flow along geometry uvs) -} - -Property -{ - Name = %FLOW_MAP - Mask = 0x4 - Property (Water flow map) - Description (Enable water flow along a flow map) -} - -Property -{ - Name = %FLOW_MAP_STRENGTH - Mask = 0x100 - Property (Water flow map strength) - Description (Enable additional water flow strength controls - requires blue channel for strength) -} - -Property -{ - Name = %SUN_SPECULAR - Mask = 0x8 - Property (Sun specular) - Description (Activate for water sunshine) -} - -Property -{ - Name = %SPECULAR_MAP - Mask = 0x10 - Property (Specular map) - Description (Use specular map as separate texture) - DependencySet = $TEX_Specular - DependencyReset = $TEX_Specular - Hidden -} - -Property -{ - Name = %DEBUG_FLOW_MAP - Mask = 0x20 - Property (Debug flow map) - Description (Enable visualizing flow map) -} - -Property -{ - Name = %FOAM - Mask = 0x40 - Property (Foam) - Description (Enables foam) -} - -Property -{ - Name = %DECAL_MAP - Mask = 0x80 - Property (Decal map) - Description (Use tiling decal map as separate texture) - DependencySet = $TEX_Custom - DependencyReset = $TEX_Custom - Hidden -} - -Property -{ - Name = %WATER_TESSELLATION_DX11 - Mask = 0x80000000 - DependencySet = $HW_WaterTessellation - DependencyReset = $HW_WaterTessellation - Hidden -} diff --git a/Assets/Engine/Shaders/Waterfall.ext b/Assets/Engine/Shaders/Waterfall.ext deleted file mode 100644 index 8d0ff2cc73..0000000000 --- a/Assets/Engine/Shaders/Waterfall.ext +++ /dev/null @@ -1,45 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// -// 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. -// -// Original file Copyright Crytek GMBH or its affiliates, used under license. -// - -// Description: Water extension used by the editor -// for automatic shader generation (based on "Water" shader template) -// -//////////////////////////////////////////////////////////////////////////// - -Version (1.00) - -Property -{ - Name = %ENVIRONMENT_MAP - Mask = 0x1 - Property (Environment map) - Description (Use environment map as separate texture) - DependencyReset = $TEX_EnvCM -} - -Property -{ - Name = %SUN_SHADING - Mask = 0x2 - Property (Sun shading) - Description (Activate for water sunshading - for outdoors) -} - -Property -{ - Name = %FOAM - Mask = 0x4 - Property (Foam) - Description (Enables foam rendering) -} diff --git a/AutomatedTesting/AssetProcessorGamePlatformConfig.setreg b/AutomatedTesting/AssetProcessorGamePlatformConfig.setreg deleted file mode 100644 index c9876cb1f9..0000000000 --- a/AutomatedTesting/AssetProcessorGamePlatformConfig.setreg +++ /dev/null @@ -1,14 +0,0 @@ -{ - "Amazon": { - "AssetProcessor": { - "Settings": { - "RC cgf": { - "ignore": true - }, - "RC fbx": { - "ignore": true - } - } - } - } -} diff --git a/AutomatedTesting/Assets/BadAssets/three_same_named_nodes.fbx b/AutomatedTesting/Assets/BadAssets/three_same_named_nodes.fbx new file mode 100644 index 0000000000..8eadb16d86 --- /dev/null +++ b/AutomatedTesting/Assets/BadAssets/three_same_named_nodes.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45b58009dc2f9340e08cafd5e68f142d15d77e19e7cef142933f2dff3cfb9293 +size 38352 diff --git a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_diff.tif.exportsettings b/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_diff.tif.exportsettings index 5c4c862583..b65133fbb0 100644 --- a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_diff.tif.exportsettings +++ b/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_diff.tif.exportsettings @@ -1 +1 @@ -/autooptimizefile=0 /preset=AlbedoWithGenericAlpha /reduce="es3:2,ios:2,osx_gl:0,pc:0,provo:0" \ No newline at end of file +/autooptimizefile=0 /preset=AlbedoWithGenericAlpha /reduce="android:2,ios:2,mac:0,pc:0,provo:0" \ No newline at end of file diff --git a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_sss.tif.exportsettings b/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_sss.tif.exportsettings index 441a11bc68..e8da408b36 100644 --- a/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_sss.tif.exportsettings +++ b/AutomatedTesting/Assets/Objects/Foliage/Textures/grass_atlas_sss.tif.exportsettings @@ -1 +1 @@ -/autooptimizefile=0 /preset=Albedo /reduce="es3:3,ios:3,osx_gl:0,pc:0,provo:0" \ No newline at end of file +/autooptimizefile=0 /preset=Albedo /reduce="android:3,ios:3,mac:0,pc:0,provo:0" \ No newline at end of file diff --git a/AutomatedTesting/Config/aws_resource_mappings.json b/AutomatedTesting/Config/aws_resource_mappings.json new file mode 100644 index 0000000000..03a611b749 --- /dev/null +++ b/AutomatedTesting/Config/aws_resource_mappings.json @@ -0,0 +1,6 @@ +{ + "AWSResourceMappings": {}, + "AccountId": "", + "Region": "us-west-2", + "Version": "1.0.0" +} \ No newline at end of file diff --git a/AutomatedTesting/EngineFinder.cmake b/AutomatedTesting/EngineFinder.cmake index 1fdcef2b56..fbbe3d8cfe 100644 --- a/AutomatedTesting/EngineFinder.cmake +++ b/AutomatedTesting/EngineFinder.cmake @@ -20,31 +20,49 @@ if(json_error) message(FATAL_ERROR "Unable to read key 'engine' from 'project.json', error: ${json_error}") endif() -# Read the list of paths from ~.o3de/o3de_manifest.json -file(TO_CMAKE_PATH "$ENV{USERPROFILE}" home_directory) # Windows -if((NOT home_directory) OR (NOT EXISTS ${home_directory})) - file(TO_CMAKE_PATH "$ENV{HOME}" home_directory)# Unix +if(DEFINED ENV{USERPROFILE} AND EXISTS $ENV{USERPROFILE}) + set(manifest_path $ENV{USERPROFILE}/.o3de/o3de_manifest.json) # Windows +else() + set(manifest_path $ENV{HOME}/.o3de/o3de_manifest.json) # Unix endif() -if (NOT home_directory) - message(FATAL_ERROR "Cannot find user home directory, the o3de manifest cannot be found") -endif() -# Set manifest path to path in the user home directory -set(manifest_path ${home_directory}/.o3de/o3de_manifest.json) - +# Read the ~/.o3de/o3de_manifest.json file and look through the 'engines_path' object. +# 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) - string(JSON engines_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines) + + string(JSON engines_path_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines_path) if(json_error) - message(FATAL_ERROR "Unable to read key 'engines' from '${manifest_path}', error: ${json_error}") + message(FATAL_ERROR "Unable to read key 'engines_path' from '${manifest_path}', error: ${json_error}") endif() - math(EXPR engines_count "${engines_count}-1") - foreach(engine_path_index RANGE ${engines_count}) - string(JSON engine_path ERROR_VARIABLE json_error GET ${manifest_json} engines ${engine_path_index}) - if(${json_error}) - message(FATAL_ERROR "Unable to read engines[${engine_path_index}] '${manifest_path}', error: ${json_error}") + string(JSON engines_path_type ERROR_VARIABLE json_error TYPE ${manifest_json} engines_path) + if(json_error OR NOT ${engines_path_type} STREQUAL "OBJECT") + message(FATAL_ERROR "Type of 'engines_path' in '${manifest_path}' is not a JSON Object, error: ${json_error}") + endif() + + math(EXPR engines_path_count "${engines_path_count}-1") + foreach(engine_path_index RANGE ${engines_path_count}) + string(JSON engine_name ERROR_VARIABLE json_error MEMBER ${manifest_json} engines_path ${engine_path_index}) + if(json_error) + message(FATAL_ERROR "Unable to read 'engines_path/${engine_path_index}' from '${manifest_path}', error: ${json_error}") + endif() + + if(LY_ENGINE_NAME_TO_USE STREQUAL engine_name) + string(JSON engine_path ERROR_VARIABLE json_error GET ${manifest_json} engines_path ${engine_name}) + if(json_error) + message(FATAL_ERROR "Unable to read value from 'engines_path/${engine_name}', error: ${json_error}") + endif() + + if(engine_path) + list(APPEND CMAKE_MODULE_PATH "${engine_path}/cmake") + break() + endif() endif() - list(APPEND CMAKE_MODULE_PATH "${engine_path}/cmake") endforeach() +else() + # If the user is passing CMAKE_MODULE_PATH we assume thats where we will find the engine + if(NOT CMAKE_MODULE_PATH) + message(FATAL_ERROR "Engine registration is required before configuring a project. Please register an engine by running 'scripts/o3de register --this-engine'") + endif() endif() diff --git a/AutomatedTesting/Gem/Code/CMakeLists.txt b/AutomatedTesting/Gem/Code/CMakeLists.txt index 2bcc304bde..548aa51ad1 100644 --- a/AutomatedTesting/Gem/Code/CMakeLists.txt +++ b/AutomatedTesting/Gem/Code/CMakeLists.txt @@ -28,30 +28,41 @@ ly_add_target( Gem::Atom_AtomBridge.Static ) +# if enabled, AutomatedTesting is used by all kinds of applications +ly_create_alias(NAME AutomatedTesting.Builders NAMESPACE Gem TARGETS Gem::AutomatedTesting) +ly_create_alias(NAME AutomatedTesting.Tools NAMESPACE Gem TARGETS Gem::AutomatedTesting) +ly_create_alias(NAME AutomatedTesting.Clients NAMESPACE Gem TARGETS Gem::AutomatedTesting) +ly_create_alias(NAME AutomatedTesting.Servers NAMESPACE Gem TARGETS Gem::AutomatedTesting) + ################################################################################ # Gem dependencies ################################################################################ -ly_add_project_dependencies( - PROJECT_NAME - AutomatedTesting - TARGETS - AutomatedTesting.GameLauncher - DEPENDENCIES_FILES - runtime_dependencies.cmake - ${pal_dir}/runtime_dependencies.cmake -) -if(PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_project_dependencies( - PROJECT_NAME - AutomatedTesting - TARGETS - AssetBuilder - AssetProcessor - AssetProcessorBatch - Editor - DEPENDENCIES_FILES - tool_dependencies.cmake - ${pal_dir}/tool_dependencies.cmake - ) +# The GameLauncher uses "Clients" gem variants: +ly_enable_gems(PROJECT_NAME AutomatedTesting GEM_FILE enabled_gems.cmake + TARGETS AutomatedTesting.GameLauncher + VARIANTS Clients) + +# If we build a server, then apply the gems to the server +if(PAL_TRAIT_BUILD_SERVER_SUPPORTED) + # if we're making a server, then add the "Server" gem variants to it: + ly_enable_gems(PROJECT_NAME AutomatedTesting GEM_FILE enabled_gems.cmake + TARGETS AutomatedTesting.ServerLauncher + VARIANTS Servers) + + set_property(GLOBAL APPEND PROPERTY LY_LAUNCHER_SERVER_PROJECTS AutomatedTesting) +endif() + +if (PAL_TRAIT_BUILD_HOST_TOOLS) + # The Editor uses "Tools" gem variants: + ly_enable_gems( + PROJECT_NAME AutomatedTesting GEM_FILE enabled_gems.cmake + TARGETS Editor + VARIANTS Tools) + + # The pipeline tools use "Builders" gem variants: + ly_enable_gems( + PROJECT_NAME AutomatedTesting GEM_FILE enabled_gems.cmake + TARGETS AssetBuilder AssetProcessor AssetProcessorBatch + VARIANTS Builders) endif() diff --git a/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake index f9d1e60dda..ffcaf7293a 100644 --- a/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Mac/runtime_dependencies.cmake @@ -10,6 +10,4 @@ # set(GEM_DEPENDENCIES - Gem::Atom_RHI_Metal.Private - Gem::Atom_RHI_Null.Private ) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake index 2e9d450ab8..ffcaf7293a 100644 --- a/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake +++ b/AutomatedTesting/Gem/Code/Platform/Mac/tool_dependencies.cmake @@ -10,10 +10,4 @@ # set(GEM_DEPENDENCIES - Gem::Atom_RHI_Null.Private - Gem::Atom_RHI_Null.Builders - Gem::Atom_RHI_Metal.Private - Gem::Atom_RHI_Metal.Builders - Gem::Atom_RHI_Vulkan.Builders - Gem::Atom_RHI_DX12.Builders ) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake deleted file mode 100644 index 0a1541bcfc..0000000000 --- a/AutomatedTesting/Gem/Code/Platform/Windows/runtime_dependencies.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(GEM_DEPENDENCIES - Gem::Atom_RHI_Vulkan.Private - Gem::Atom_RHI_DX12.Private - Gem::Atom_RHI_Null.Private -) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake deleted file mode 100644 index ddd3bfa6a7..0000000000 --- a/AutomatedTesting/Gem/Code/Platform/Windows/tool_dependencies.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(GEM_DEPENDENCIES - Gem::QtForPython.Editor - Gem::Atom_RHI_Vulkan.Private - Gem::Atom_RHI_Vulkan.Builders - Gem::Atom_RHI_DX12.Private - Gem::Atom_RHI_DX12.Builders - Gem::Atom_RHI_Null.Private - Gem::Atom_RHI_Null.Builders - Gem::Atom_RHI_Metal.Builders -) \ No newline at end of file diff --git a/AutomatedTesting/Gem/Code/enabled_gems.cmake b/AutomatedTesting/Gem/Code/enabled_gems.cmake new file mode 100644 index 0000000000..d99d17b55e --- /dev/null +++ b/AutomatedTesting/Gem/Code/enabled_gems.cmake @@ -0,0 +1,58 @@ +# +# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +# its licensors. +# +# For complete copyright and license terms please see the LICENSE at the root of this +# distribution (the "License"). All use of this software is governed by the License, +# or, if provided, by the license below or the license accompanying this file. Do not +# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# + +set(ENABLED_GEMS + ImGui + ScriptEvents + ExpressionEvaluation + Gestures + CertificateManager + DebugDraw + SceneProcessing + GraphCanvas + InAppPurchases + AutomatedTesting + EditorPythonBindings + QtForPython + PythonAssetBuilder + Metastream + AudioSystem + Camera + EMotionFX + PhysX + CameraFramework + StartingPointMovement + StartingPointCamera + ScriptCanvas + ScriptCanvasPhysics + ScriptCanvasTesting + LyShineExamples + StartingPointInput + PhysXDebug + WhiteBox + FastNoise + SurfaceData + GradientSignal + Vegetation + GraphModel + LandscapeCanvas + NvCloth + Blast + Maestro + TextureAtlas + LmbrCentral + LyShine + HttpRequestor + Atom_AtomBridge + AWSCore + AWSClientAuth + AWSMetrics +) diff --git a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake b/AutomatedTesting/Gem/Code/runtime_dependencies.cmake deleted file mode 100644 index c8e66740e4..0000000000 --- a/AutomatedTesting/Gem/Code/runtime_dependencies.cmake +++ /dev/null @@ -1,57 +0,0 @@ -# -# 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. -# - -# Extracted from Game -set(GEM_DEPENDENCIES - Gem::Maestro - Gem::TextureAtlas - Gem::LmbrCentral - Gem::LyShine - Gem::HttpRequestor - Gem::ScriptEvents - Gem::ExpressionEvaluation - Gem::Gestures - Gem::CertificateManager - Gem::DebugDraw - Gem::AudioSystem - Gem::InAppPurchases - Gem::AutomatedTesting - Gem::Metastream - Gem::Camera - Gem::EMotionFX - Gem::PhysX - Gem::CameraFramework - Gem::StartingPointMovement - Gem::StartingPointCamera - Gem::ScriptCanvas - Gem::ImGui - Gem::LyShineExamples - Gem::StartingPointInput - Gem::ScriptCanvasPhysics - Gem::PhysXDebug - Gem::WhiteBox - Gem::FastNoise - Gem::SurfaceData - Gem::GradientSignal - Gem::Vegetation - Gem::Atom_RHI.Private - Gem::Atom_RPI.Private - Gem::Atom_Feature_Common - Gem::Atom_Bootstrap - Gem::Atom_Component_DebugCamera - Gem::AtomImGuiTools - Gem::AtomLyIntegration_CommonFeatures - Gem::EMotionFX_Atom - Gem::ImguiAtom - Gem::Atom_AtomBridge - Gem::AtomFont - Gem::Blast -) diff --git a/AutomatedTesting/Gem/Code/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/tool_dependencies.cmake deleted file mode 100644 index 8c5da63f42..0000000000 --- a/AutomatedTesting/Gem/Code/tool_dependencies.cmake +++ /dev/null @@ -1,72 +0,0 @@ -# -# 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. -# - -# Extracted from Editor.xml -set(GEM_DEPENDENCIES - Gem::Maestro.Editor - Gem::TextureAtlas - Gem::LmbrCentral.Editor - Gem::LyShine.Editor - Gem::HttpRequestor - Gem::ScriptEvents.Editor - Gem::ExpressionEvaluation - Gem::Gestures - Gem::CertificateManager - Gem::DebugDraw.Editor - Gem::SceneProcessing.Editor - Gem::GraphCanvas.Editor - Gem::InAppPurchases - Gem::AutomatedTesting - Gem::EditorPythonBindings.Editor - Gem::PythonAssetBuilder.Editor - Gem::Metastream - Gem::AudioSystem.Editor - Gem::Camera.Editor - Gem::EMotionFX.Editor - Gem::PhysX.Editor - Gem::CameraFramework - Gem::StartingPointMovement - Gem::StartingPointCamera - Gem::ScriptCanvas.Editor - Gem::ScriptEvents.Editor - Gem::ImGui.Editor - Gem::LyShineExamples - Gem::StartingPointInput.Editor - Gem::ScriptCanvasPhysics - Gem::ScriptCanvasTesting.Editor - Gem::PhysXDebug.Editor - Gem::WhiteBox.Editor - Gem::FastNoise.Editor - Gem::SurfaceData.Editor - Gem::GradientSignal.Editor - Gem::Vegetation.Editor - Gem::GraphModel.Editor - Gem::LandscapeCanvas.Editor - Gem::Atom_RHI.Private - Gem::EMotionFX.Editor - Gem::Atom_RPI.Builders - Gem::Atom_RPI.Editor - Gem::Atom_Feature_Common.Builders - Gem::Atom_Feature_Common.Editor - Gem::ImGui.Editor - Gem::Atom_Bootstrap - Gem::Atom_Asset_Shader.Builders - Gem::Atom_Component_DebugCamera - Gem::AtomImGuiTools - Gem::AtomLyIntegration_CommonFeatures.Editor - Gem::EMotionFX_Atom.Editor - Gem::ImageProcessingAtom.Editor - Gem::Atom_AtomBridge.Editor - Gem::ImguiAtom - Gem::AtomFont - Gem::AtomToolsFramework.Editor - Gem::Blast.Editor -) diff --git a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt new file mode 100644 index 0000000000..f463210cb0 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# 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. +# + +################################################################################ +# AWS Automated Tests +# Runs AWS Gems automation tests. +################################################################################ + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + # Enable after installing NodeJS and CDK on jenkins Windows AMI. + ly_add_pytest( + NAME AutomatedTesting::AWSTests + TEST_SUITE periodic + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/${PAL_PLATFORM_NAME}/ + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + AWS + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/__init__.py new file mode 100644 index 0000000000..8caef52682 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/__init__.py @@ -0,0 +1,11 @@ +""" +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. +""" + diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/__init__.py new file mode 100644 index 0000000000..cdee4b5a56 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/__init__.py @@ -0,0 +1,10 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py new file mode 100644 index 0000000000..04be31759d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py @@ -0,0 +1,237 @@ +""" +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 logging +import os +import pytest +import time +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 +from AWS.Windows.resource_mappings.resource_mappings import resource_mappings +from AWS.Windows.cdk.cdk import cdk +from .aws_metrics_utils import aws_metrics_utils + +AWS_METRICS_FEATURE_NAME = 'AWSMetrics' +GAME_LOG_NAME = 'Game.log' + +logger = logging.getLogger(__name__) + + +def setup(launcher: ly_test_tools.launchers.Launcher, + cdk: cdk, + asset_processor: asset_processor, + resource_mappings: resource_mappings, + context_variable: str = '') -> typing.Tuple[ly_test_tools.log.log_monitor.LogMonitor, str, str]: + """ + Set up the CDK application and start the log monitor. + :param launcher: Client launcher for running the test level. + :param cdk: CDK application for deploying the AWS resources. + :param asset_processor: asset_processor fixture. + :param resource_mappings: resource_mappings fixture. + :param context_variable: context_variable for enable optional CDK feature. + :return log monitor object, metrics file path and the metrics stack name. + """ + logger.info(f'Cdk stack names:\n{cdk.list()}') + stacks = cdk.deploy(context_variable=context_variable) + resource_mappings.populate_output_keys(stacks) + + asset_processor.start() + asset_processor.wait_for_idle() + + metrics_file_path = os.path.join(launcher.workspace.paths.project(), 'user', + AWS_METRICS_FEATURE_NAME, 'metrics.json') + remove_file(metrics_file_path) + + file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME) + remove_file(file_to_monitor) + + # Initialize the log monitor. + log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor) + + return log_monitor, metrics_file_path, stacks[0] + + +def monitor_metrics_submission(log_monitor: ly_test_tools.log.log_monitor.LogMonitor) -> None: + """ + Monitor the messages and notifications for submitting metrics. + :param log_monitor: Log monitor to check the log messages. + """ + expected_lines = [ + '(Script) - Submitted metrics without buffer.', + '(Script) - Submitted metrics with buffer.', + '(Script) - Metrics is sent successfully.' + ] + + unexpected_lines = [ + '(Script) - Failed to submit metrics without buffer.', + '(Script) - Failed to submit metrics with buffer.', + '(Script) - Failed to send metrics.' + ] + + result = log_monitor.monitor_log_for_lines( + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True) + + # Assert the log monitor detected expected lines and did not detect any unexpected lines. + assert result, ( + f'Log monitoring failed. Used expected_lines values: {expected_lines} & ' + f'unexpected_lines values: {unexpected_lines}') + + +def remove_file(file_path: str) -> None: + """ + Remove a local file and its directory. + :param file_path: Path to the local file. + """ + if os.path.exists(file_path): + os.remove(file_path) + + file_dir = os.path.dirname(file_path) + if os.path.exists(file_dir) and len(os.listdir(file_dir)) == 0: + os.rmdir(file_dir) + + +@pytest.mark.SUITE_periodic +@pytest.mark.usefixtures('automatic_process_killer') +@pytest.mark.parametrize('project', ['AutomatedTesting']) +@pytest.mark.parametrize('level', ['AWS/Metrics']) +@pytest.mark.parametrize('feature_name', [AWS_METRICS_FEATURE_NAME]) +@pytest.mark.parametrize('resource_mappings_filename', ['aws_resource_mappings.json']) +@pytest.mark.parametrize('profile_name', ['AWSAutomationTest']) +@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, + ): + """ + Tests that the submitted metrics are sent to CloudWatch for real-time analytics. + """ + log_monitor, metrics_file_path, stack_name = setup(launcher, cdk, asset_processor, resource_mappings) + + # Start the Kinesis Data Analytics application for real-time analytics. + analytics_application_name = f'{stack_name}-AnalyticsApplication' + aws_metrics_utils.start_kinesis_data_analytics_application(analytics_application_name) + + launcher.args = ['+LoadLevel', level] + launcher.args.extend(['-rhi=null']) + + with launcher.start(launch_ap=False): + start_time = datetime.utcnow() + monitor_metrics_submission(log_monitor) + # Verify that operational health metrics are delivered to CloudWatch. + aws_metrics_utils.verify_cloud_watch_delivery( + 'AWS/Lambda', + 'Invocations', + [{'Name': 'FunctionName', + 'Value': f'{stack_name}-AnalyticsProcessingLambda'}], + start_time) + logger.info('Operational health metrics sent to CloudWatch.') + + aws_metrics_utils.verify_cloud_watch_delivery( + AWS_METRICS_FEATURE_NAME, + 'TotalLogins', + [], + start_time) + logger.info('Real-time metrics sent to CloudWatch.') + + # 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): + """ + Tests that unauthorized users cannot send metrics events to the AWS backed backend. + """ + log_monitor, metrics_file_path, stack_name = setup(launcher, cdk, asset_processor, resource_mappings) + # Set invalid AWS credentials. + launcher.args = ['+LoadLevel', level, '+cl_awsAccessKey', 'AKIAIOSFODNN7EXAMPLE', + '+cl_awsSecretKey', 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'] + launcher.args.extend(['-rhi=null']) + + with launcher.start(launch_ap=False): + result = log_monitor.monitor_log_for_lines( + expected_lines=['(Script) - Failed to send metrics.'], + unexpected_lines=['(Script) - Metrics is sent successfully.'], + halt_on_unexpected=True) + 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, + level: str, + launcher: ly_test_tools.launchers.Launcher, + cdk: cdk, + aws_credentials: aws_credentials, + asset_processor: pytest.fixture, + resource_mappings: resource_mappings, + aws_utils: aws_utils, + aws_metrics_utils: aws_metrics_utils, + workspace: pytest.fixture): + """ + Tests that the submitted metrics are sent to the data lake for batch analytics. + """ + log_monitor, metrics_file_path, stack_name = setup(launcher, cdk, asset_processor, resource_mappings, + context_variable='batch_processing=true') + + analytics_bucket_name = aws_metrics_utils.get_analytics_bucket_name(stack_name) + + launcher.args = ['+LoadLevel', level] + launcher.args.extend(['-rhi=null']) + + with launcher.start(launch_ap=False): + start_time = datetime.utcnow() + monitor_metrics_submission(log_monitor) + # Verify that operational health metrics are delivered to CloudWatch. + aws_metrics_utils.verify_cloud_watch_delivery( + 'AWS/Lambda', + 'Invocations', + [{'Name': 'FunctionName', + 'Value': f'{stack_name}-EventsProcessingLambda'}], + start_time) + logger.info('Operational health metrics sent to CloudWatch.') + + aws_metrics_utils.verify_s3_delivery(analytics_bucket_name) + logger.info('Metrics sent to S3.') + + # Run the glue crawler to populate the AWS Glue Data Catalog with tables. + aws_metrics_utils.run_glue_crawler(f'{stack_name}-EventsCrawler') + # Run named queries on the table to verify the batch analytics. + aws_metrics_utils.run_named_queries(f'{stack_name}-AthenaWorkGroup') + logger.info('Query metrics from S3 successfully.') + + # Kinesis Data Firehose buffers incoming data before it delivers it to Amazon S3. Sleep for the + # default interval (60s) to make sure that all the metrics are sent to the bucket before cleanup. + time.sleep(60) + # Empty the S3 bucket. S3 buckets can only be deleted successfully when it doesn't contain any object. + aws_metrics_utils.empty_s3_bucket(analytics_bucket_name) + diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_utils.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_utils.py new file mode 100644 index 0000000000..686feda3d9 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_utils.py @@ -0,0 +1,252 @@ +""" +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 logging +import pathlib +import pytest +import typing + +from datetime import datetime +from botocore.exceptions import WaiterError + +from AWS.common.aws_utils import AwsUtils +from .aws_metrics_waiters import KinesisAnalyticsApplicationUpdatedWaiter, \ + CloudWatchMetricsDeliveredWaiter, DataLakeMetricsDeliveredWaiter, GlueCrawlerReadyWaiter + +logging.getLogger('boto').setLevel(logging.CRITICAL) + +# Expected directory and file extension for the S3 objects. +EXPECTED_S3_DIRECTORY = 'firehose_events/' +EXPECTED_S3_OBJECT_EXTENSION = '.parquet' + + +class AWSMetricsUtils: + """ + Provide utils functions for the AWSMetrics gem to interact with the deployed resources. + """ + + def __init__(self, aws_utils: AwsUtils): + self._aws_util = aws_utils + + def start_kinesis_data_analytics_application(self, application_name: str) -> None: + """ + Start the Kenisis Data Analytics application for real-time analytics. + :param application_name: Name of the Kenisis Data Analytics application. + """ + input_id = self.get_kinesis_analytics_application_input_id(application_name) + assert input_id, 'invalid Kinesis Data Analytics application input.' + + client = self._aws_util.client('kinesisanalytics') + try: + client.start_application( + ApplicationName=application_name, + InputConfigurations=[ + { + 'Id': input_id, + 'InputStartingPositionConfiguration': { + 'InputStartingPosition': 'NOW' + } + }, + ] + ) + except client.exceptions.ResourceInUseException: + # The application has been started. + return + + try: + KinesisAnalyticsApplicationUpdatedWaiter(client, 'RUNNING').wait(application_name=application_name) + except WaiterError as e: + assert False, f'Failed to start the Kinesis Data Analytics application: {str(e)}.' + + def get_kinesis_analytics_application_input_id(self, application_name: str) -> str: + """ + Get the input ID for the Kenisis Data Analytics application. + :param application_name: Name of the Kenisis Data Analytics application. + :return: Input ID for the Kenisis Data Analytics application. + """ + client = self._aws_util.client('kinesisanalytics') + response = client.describe_application( + ApplicationName=application_name + ) + if not response: + return '' + input_descriptions = response.get('ApplicationDetail', {}).get('InputDescriptions', []) + if len(input_descriptions) != 1: + return '' + + return input_descriptions[0].get('InputId', '') + + def stop_kinesis_data_analytics_application(self, application_name: str) -> None: + """ + Stop the Kenisis Data Analytics application. + :param application_name: Name of the Kenisis Data Analytics application. + """ + client = self._aws_util.client('kinesisanalytics') + client.stop_application( + ApplicationName=application_name + ) + + try: + KinesisAnalyticsApplicationUpdatedWaiter(client, 'READY').wait(application_name=application_name) + except WaiterError as e: + assert False, f'Failed to stop the Kinesis Data Analytics application: {str(e)}.' + + def verify_cloud_watch_delivery(self, namespace: str, metrics_name: str, + dimensions: typing.List[dict], start_time: datetime) -> None: + """ + Verify that the expected metrics is delivered to CloudWatch. + :param namespace: Namespace of the metrics. + :param metrics_name: Name of the metrics. + :param dimensions: Dimensions of the metrics. + :param start_time: Start time for generating the metrics. + """ + client = self._aws_util.client('cloudwatch') + + try: + CloudWatchMetricsDeliveredWaiter(client).wait( + namespace=namespace, + metrics_name=metrics_name, + dimensions=dimensions, + start_time=start_time + ) + except WaiterError as e: + assert False, f'Failed to deliver metrics to CloudWatch: {str(e)}.' + + def verify_s3_delivery(self, analytics_bucket_name: str) -> None: + """ + Verify that metrics are delivered to S3 for batch analytics successfully. + :param analytics_bucket_name: Name of the deployed S3 bucket. + """ + client = self._aws_util.client('s3') + bucket_name = analytics_bucket_name + + try: + DataLakeMetricsDeliveredWaiter(client).wait(bucket_name=bucket_name, prefix=EXPECTED_S3_DIRECTORY) + except WaiterError as e: + assert False, f'Failed to find the S3 directory for storing metrics data: {str(e)}.' + + # Check whether the data is converted to the expected data format. + response = client.list_objects_v2( + Bucket=bucket_name, + Prefix=EXPECTED_S3_DIRECTORY + ) + assert response.get('KeyCount', 0) != 0, f'Failed to deliver metrics to the S3 bucket {bucket_name}.' + + s3_objects = response.get('Contents', []) + for s3_object in s3_objects: + key = s3_object.get('Key', '') + assert pathlib.Path(key).suffix == EXPECTED_S3_OBJECT_EXTENSION, \ + f'Invalid data format is found in the S3 bucket {bucket_name}' + + def run_glue_crawler(self, crawler_name: str) -> None: + """ + Run the Glue crawler and wait for it to finish. + :param crawler_name: Name of the Glue crawler + """ + client = self._aws_util.client('glue') + try: + client.start_crawler( + Name=crawler_name + ) + except client.exceptions.CrawlerRunningException: + # The crawler has already been started. + return + + try: + GlueCrawlerReadyWaiter(client).wait(crawler_name=crawler_name) + except WaiterError as e: + assert False, f'Failed to run the Glue crawler: {str(e)}.' + + def run_named_queries(self, work_group: str) -> None: + """ + Run the named queries under the specific Athena work group. + :param work_group: Name of the Athena work group. + """ + client = self._aws_util.client('athena') + # List all the named queries. + response = client.list_named_queries( + WorkGroup=work_group + ) + named_query_ids = response.get('NamedQueryIds', []) + + # Run each of the queries. + for named_query_id in named_query_ids: + get_named_query_response = client.get_named_query( + NamedQueryId=named_query_id + ) + named_query = get_named_query_response.get('NamedQuery', {}) + + start_query_execution_response = client.start_query_execution( + QueryString=named_query.get('QueryString', ''), + QueryExecutionContext={ + 'Database': named_query.get('Database', '') + }, + WorkGroup=work_group + ) + + # Wait for the query to finish. + state = 'RUNNING' + while state == 'QUEUED' or state == 'RUNNING': + get_query_execution_response = client.get_query_execution( + QueryExecutionId=start_query_execution_response.get('QueryExecutionId', '') + ) + + state = get_query_execution_response.get('QueryExecution', {}).get('Status', {}).get('State', '') + + assert state == 'SUCCEEDED', f'Failed to run the named query {named_query.get("Name", {})}' + + def empty_s3_bucket(self, bucket_name: str) -> None: + """ + Empty the S3 bucket following: + https://boto3.amazonaws.com/v1/documentation/api/latest/guide/migrations3.html + + :param bucket_name: Name of the S3 bucket. + """ + + s3 = self._aws_util.resource('s3') + bucket = s3.Bucket(bucket_name) + + for key in bucket.objects.all(): + key.delete() + + def get_analytics_bucket_name(self, stack_name: str) -> str: + """ + Get the name of the deployed S3 bucket. + :param stack_name: Name of the CloudFormation stack. + :return: Name of the deployed S3 bucket. + """ + + client = self._aws_util.client('cloudformation') + + response = client.describe_stack_resources( + StackName=stack_name + ) + resources = response.get('StackResources', []) + + for resource in resources: + if resource.get('ResourceType') == 'AWS::S3::Bucket': + return resource.get('PhysicalResourceId', '') + + return '' + + +@pytest.fixture(scope='function') +def aws_metrics_utils( + request: pytest.fixture, + aws_utils: pytest.fixture): + """ + Fixture for the AWS metrics util functions. + :param request: _pytest.fixtures.SubRequest class that handles getting + a pytest fixture from a pytest function/fixture. + :param aws_utils: aws_utils fixture. + """ + aws_utils_obj = AWSMetricsUtils(aws_utils) + return aws_utils_obj diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_waiters.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_waiters.py new file mode 100644 index 0000000000..7ce5551fd4 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_waiters.py @@ -0,0 +1,142 @@ +""" +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 botocore.client +import logging + +from datetime import timedelta +from AWS.common.custom_waiter import CustomWaiter, WaitState + +logging.getLogger('boto').setLevel(logging.CRITICAL) + + +class KinesisAnalyticsApplicationUpdatedWaiter(CustomWaiter): + """ + Subclass of the base custom waiter class. + Wait for the Kinesis analytics application being updated to a specific status. + """ + def __init__(self, client: botocore.client, status: str): + """ + Initialize the waiter. + + :param client: Boto3 client to use. + :param status: Expected status. + """ + super().__init__( + 'KinesisAnalyticsApplicationUpdated', + 'DescribeApplication', + 'ApplicationDetail.ApplicationStatus', + {status: WaitState.SUCCESS}, + client) + + def wait(self, application_name: str): + """ + Wait for the expected status. + + :param application_name: Name of the Kinesis analytics application. + """ + self._wait(ApplicationName=application_name) + + +class GlueCrawlerReadyWaiter(CustomWaiter): + """ + Subclass of the base custom waiter class. + Wait for the Glue crawler to finish its processing. + """ + def __init__(self, client: botocore.client): + """ + Initialize the waiter. + + :param client: Boto3 client to use. + """ + super().__init__( + 'GlueCrawlerReady', + 'GetCrawler', + 'Crawler.State', + {'READY': WaitState.SUCCESS}, + client) + + def wait(self, crawler_name): + """ + Wait for the expected status. + + :param crawler_name: Name of the Glue crawler. + """ + self._wait(Name=crawler_name) + + +class DataLakeMetricsDeliveredWaiter(CustomWaiter): + """ + Subclass of the base custom waiter class. + Wait for the expected directory being created in the S3 bucket. + """ + def __init__(self, client: botocore.client): + """ + Initialize the waiter. + + :param client: Boto3 client to use. + """ + super().__init__( + 'DataLakeMetricsDelivered', + 'ListObjectsV2', + 'KeyCount > `0`', + {True: WaitState.SUCCESS}, + client) + + def wait(self, bucket_name, prefix): + """ + Wait for the expected directory being created. + + :param bucket_name: Name of the S3 bucket. + :param prefix: Name of the expected directory prefix. + """ + self._wait(Bucket=bucket_name, Prefix=prefix) + + +class CloudWatchMetricsDeliveredWaiter(CustomWaiter): + """ + Subclass of the base custom waiter class. + Wait for the expected metrics being delivered to CloudWatch. + """ + def __init__(self, client: botocore.client): + """ + Initialize the waiter. + + :param client: Boto3 client to use. + """ + super().__init__( + 'CloudWatchMetricsDelivered', + 'GetMetricStatistics', + 'length(Datapoints) > `0`', + {True: WaitState.SUCCESS}, + client) + + def wait(self, namespace, metrics_name, dimensions, start_time): + """ + Wait for the expected metrics being delivered. + + :param namespace: Namespace of the metrics. + :param metrics_name: Name of the metrics. + :param dimensions: Dimensions of the metrics. + :param start_time: Start time for generating the metrics. + """ + self._wait( + Namespace=namespace, + MetricName=metrics_name, + Dimensions=dimensions, + StartTime=start_time, + EndTime=start_time + timedelta(0, self.timeout), + Period=60, + Statistics=[ + 'SampleCount' + ], + Unit='Count' + ) diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/__init__.py new file mode 100644 index 0000000000..8caef52682 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/__init__.py @@ -0,0 +1,11 @@ +""" +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. +""" + diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py new file mode 100644 index 0000000000..9254c3d4eb --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py @@ -0,0 +1,213 @@ +""" +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 os +import pytest +import boto3 + +import ly_test_tools.environment.process_utils as process_utils +from typing import List + +BOOTSTRAP_STACK_NAME = 'CDKToolkit' +BOOTSTRAP_STAGING_BUCKET_LOGIC_ID = 'StagingBucket' + +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): + """ + :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. + """ + self._cdk_env = os.environ.copy() + self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project + 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'] + + credentials = session.get_credentials().get_frozen_credentials() + 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 + + output = process_utils.check_output( + 'python -m pip install -r requirements.txt', + cwd=self._cdk_path, + env=self._cdk_env, + shell=True) + + 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"]}'] + + process_utils.check_call( + bootstrap_cmd, + cwd=self._cdk_path, + env=self._cdk_env, + shell=True) + + def list(self) -> List[str]: + """ + lists cdk stack names + :return List of cdk stack names + """ + if not self._cdk_path: + return [] + + list_cdk_application_cmd = ['cdk', 'list'] + output = process_utils.check_output( + list_cdk_application_cmd, + cwd=self._cdk_path, + env=self._cdk_env, + shell=True) + + return output.splitlines() + + def synthesize(self) -> None: + """ + Synthesizes all cdk stacks + """ + if not self._cdk_path: + return + + list_cdk_application_cmd = ['cdk', 'synth'] + + process_utils.check_output( + list_cdk_application_cmd, + cwd=self._cdk_path, + env=self._cdk_env, + shell=True) + + def deploy(self, context_variable: str = '', additonal_params: List[str] = None) -> List[str]: + """ + Deploys all the CDK stacks. + :param context_variable: Context variable for enabling optional features. + :param additonal_params: Additonal parameters like --all can be passed in this way. + :return List of deployed stack arns. + """ + if not self._cdk_path: + return [] + + deploy_cdk_application_cmd = ['cdk', 'deploy', '--require-approval', 'never'] + if additonal_params: + deploy_cdk_application_cmd.extend(additonal_params) + if context_variable: + deploy_cdk_application_cmd.extend(['-c', f'{context_variable}']) + + output = process_utils.check_output( + deploy_cdk_application_cmd, + cwd=self._cdk_path, + env=self._cdk_env, + shell=True) + + stacks = [] + for line in output.splitlines(): + line_sections = line.split('/') + assert len(line_sections), 3 + stacks.append(line.split('/')[-2]) + + return stacks + + def destroy(self) -> None: + """ + 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) + + self._stacks = [] + self._cdk_path = '' + + @staticmethod + def remove_bootstrap_stack(aws_utils: pytest.fixture) -> 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( + StackName=BOOTSTRAP_STACK_NAME + ) + stacks = response.get('Stacks', []) + if not stacks: + return + + # Clear the bootstrap staging bucket before deleting the bootstrap stack. + response = aws_utils.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') + 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 diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/__init__.py new file mode 100644 index 0000000000..8caef52682 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/__init__.py @@ -0,0 +1,11 @@ +""" +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. +""" + diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py new file mode 100644 index 0000000000..7b9c549f6c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py @@ -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. +""" +import pytest +import os +import logging +import ly_test_tools.log.log_monitor + +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 assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor + +AWS_PROJECT_NAME = 'AWS-AutomationTest' +AWS_CLIENT_AUTH_FEATURE_NAME = 'AWSClientAuth' +AWS_CLIENT_AUTH_DEFAULT_PROFILE_NAME = 'default' + +GAME_LOG_NAME = 'Game.log' + +logger = logging.getLogger(__name__) + + +@pytest.mark.SUITE_periodic +@pytest.mark.usefixtures('automatic_process_killer') +@pytest.mark.usefixtures('asset_processor') +@pytest.mark.usefixtures('workspace') +@pytest.mark.parametrize('project', ['AutomatedTesting']) +@pytest.mark.parametrize('level', ['AWS/ClientAuth']) +@pytest.mark.usefixtures('cdk') +@pytest.mark.parametrize('feature_name', [AWS_CLIENT_AUTH_FEATURE_NAME]) +@pytest.mark.usefixtures('resource_mappings') +@pytest.mark.parametrize('resource_mappings_filename', ['aws_resource_mappings.json']) +@pytest.mark.usefixtures('aws_utils') +@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 TestAWSClientAuthAnonymousCredentials(object): + """ + Test class to verify AWS Cognito Identity pool anonymous authorization. + """ + + def test_anonymous_credentials(self, + level: str, + launcher: pytest.fixture, + cdk: pytest.fixture, + resource_mappings: pytest.fixture, + workspace: pytest.fixture, + asset_processor: pytest.fixture + ): + """ + Setup: Deploys cdk and updates resource mapping file. + Tests: Getting AWS credentials for no signed in user. + Verification: Log monitor looks for success credentials log. + """ + logger.info(f'Cdk stack names:\n{cdk.list()}') + stacks = cdk.deploy() + resource_mappings.populate_output_keys(stacks) + asset_processor.start() + asset_processor.wait_for_idle() + + file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME) + log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor) + + launcher.args = ['+LoadLevel', level] + launcher.args.extend(['-rhi=null']) + + with launcher.start(launch_ap=False): + result = log_monitor.monitor_log_for_lines( + expected_lines=['(Script) - Success anonymous credentials'], + unexpected_lines=['(Script) - Fail anonymous credentials'], + halt_on_unexpected=True, + ) + assert result, 'Anonymous credentials fetched successfully.' diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py new file mode 100644 index 0000000000..89b859dd0f --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py @@ -0,0 +1,99 @@ +""" +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 os +import logging +import ly_test_tools.log.log_monitor + +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 assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor + +AWS_PROJECT_NAME = 'AWS-AutomationTest' +AWS_CLIENT_AUTH_FEATURE_NAME = 'AWSClientAuth' +AWS_CLIENT_AUTH_DEFAULT_PROFILE_NAME = 'default' + +GAME_LOG_NAME = 'Game.log' + +logger = logging.getLogger(__name__) + + +@pytest.mark.SUITE_periodic +@pytest.mark.usefixtures('automatic_process_killer') +@pytest.mark.usefixtures('asset_processor') +@pytest.mark.usefixtures('workspace') +@pytest.mark.parametrize('project', ['AutomatedTesting']) +@pytest.mark.usefixtures('cdk') +@pytest.mark.parametrize('feature_name', [AWS_CLIENT_AUTH_FEATURE_NAME]) +@pytest.mark.usefixtures('resource_mappings') +@pytest.mark.parametrize('resource_mappings_filename', ['aws_resource_mappings.json']) +@pytest.mark.usefixtures('aws_utils') +@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 TestAWSClientAuthPasswordSignIn(object): + """ + Test class to verify AWS Cognito IDP Password sign in and Cognito Identity pool authenticated authorization. + """ + + def test_password_signin_credentials(self, + launcher: pytest.fixture, + cdk: pytest.fixture, + resource_mappings: pytest.fixture, + workspace: pytest.fixture, + asset_processor: pytest.fixture, + aws_utils: pytest.fixture + ): + """ + Setup: Deploys cdk and updates resource mapping file. + Tests: Sign up new test user, admin confirm the user, sign in and get aws credentials. + Verification: Log monitor looks for success credentials log. + """ + logger.info(f'Cdk stack names:\n{cdk.list()}') + stacks = cdk.deploy() + resource_mappings.populate_output_keys(stacks) + asset_processor.start() + asset_processor.wait_for_idle() + + file_to_monitor = os.path.join(launcher.workspace.paths.project_log(), GAME_LOG_NAME) + log_monitor = ly_test_tools.log.log_monitor.LogMonitor(launcher=launcher, log_file_path=file_to_monitor) + + launcher.args = ['+LoadLevel', 'AWS/ClientAuthPasswordSignUp'] + launcher.args.extend(['-rhi=null']) + + with launcher.start(launch_ap=False): + result = log_monitor.monitor_log_for_lines( + expected_lines=['(Script) - Signup Success'], + unexpected_lines=['(Script) - Signup Fail'], + halt_on_unexpected=True, + ) + assert result, 'Sign Up Success.' + + launcher.stop() + + cognito_idp = aws_utils.client('cognito-idp') + user_pool_id = resource_mappings.get_resource_name_id(f'{AWS_CLIENT_AUTH_FEATURE_NAME}.CognitoUserPoolId') + print(f'UserPoolId:{user_pool_id}') + cognito_idp.admin_confirm_sign_up( + UserPoolId=user_pool_id, + Username='test1' + ) + + launcher.args = ['+LoadLevel', 'AWS/ClientAuthPasswordSignIn'] + launcher.args.extend(['-rhi=null']) + + with launcher.start(launch_ap=False): + result = log_monitor.monitor_log_for_lines( + expected_lines=['(Script) - SignIn Success', '(Script) - Success credentials'], + unexpected_lines=['(Script) - SignIn Fail', '(Script) - Fail credentials'], + halt_on_unexpected=True, + ) + assert result, 'Sign in Success, fetched authenticated AWS temp credentials.' diff --git a/Tests/BuildSystems/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from Tests/BuildSystems/__init__.py rename to AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/__init__.py diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py new file mode 100644 index 0000000000..dc462e0556 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/resource_mappings/resource_mappings.py @@ -0,0 +1,148 @@ +""" +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 os +from os.path import abspath +import pytest +import json +import logging + +logger = logging.getLogger(__name__) + +AWS_RESOURCE_MAPPINGS_KEY = 'AWSResourceMappings' +AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY = 'AccountId' +AWS_RESOURCE_MAPPINGS_REGION_KEY = 'Region' + + +class ResourceMappings: + """ + ResourceMappings class that handles writing Cloud formation outputs to resource mappings json file in a project. + """ + + def __init__(self, file_path: str, region: str, feature_name: str, account_id: str, workspace: pytest.fixture, + cloud_formation_client): + """ + :param file_path: Path for the resource mapping file. + :param region: Region value for the resource mapping file. + :param feature_name: Feature gem name to use to append name to mappings key. + :param account_id: AWS account id value for the resource mapping file. + :param workspace: ly_test_tools workspace fixture. + :param cloud_formation_client: AWS cloud formation client. + """ + self._cdk_env = os.environ.copy() + self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH'] + self._resource_mapping_file_path = file_path + self._region = region + self._feature_name = feature_name + self._account_id = account_id + self._resource_mappings = {} + + assert os.path.exists(self._resource_mapping_file_path), \ + f'Invalid resource mapping file path {self._resource_mapping_file_path}' + self._client = cloud_formation_client + + def populate_output_keys(self, stacks=[]) -> None: + """ + Calls describe stacks on cloud formation service and persists outputs to resource mappings file. + :param stacks List of stack arns to describe and populate resource mappings with. + """ + for stack_name in stacks: + response = self._client.describe_stacks( + StackName=stack_name + ) + stacks = response.get('Stacks', []) + assert len(stacks) == 1, f'{stack_name} is invalid.' + + self._write_resource_mappings(stacks[0].get('Outputs', [])) + + def _write_resource_mappings(self, outputs, append_feature_name = True) -> None: + with open(self._resource_mapping_file_path) as file_content: + resource_mappings = json.load(file_content) + + resource_mappings[AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY] = self._account_id + resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = self._region + + # Append new mappings. + resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = resource_mappings.get(AWS_RESOURCE_MAPPINGS_KEY, {}) + + for output in outputs: + if append_feature_name: + resource_key = f'{self._feature_name}.{output.get("OutputKey", "InvalidKey")}' + else: + resource_key = output.get("OutputKey", "InvalidKey") + resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key] = resource_mappings[ + AWS_RESOURCE_MAPPINGS_KEY].get(resource_key, {}) + resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Type'] = 'AutomationTestType' + resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Name/ID'] = output.get('OutputValue', + 'InvalidId') + + self._resource_mappings = resource_mappings + with open(self._resource_mapping_file_path, 'w') as file_content: + json.dump(resource_mappings, file_content, indent=4) + + def clear_output_keys(self) -> None: + """ + Clears values of all resource mapping keys. Sets region to default to us-west-2 + """ + with open(self._resource_mapping_file_path) as file_content: + resource_mappings = json.load(file_content) + + resource_mappings[AWS_RESOURCE_MAPPINGS_ACCOUNT_ID_KEY] = '' + resource_mappings[AWS_RESOURCE_MAPPINGS_REGION_KEY] = 'us-west-2' + + # Append new mappings. + resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = resource_mappings.get(AWS_RESOURCE_MAPPINGS_KEY, {}) + resource_mappings[AWS_RESOURCE_MAPPINGS_KEY] = {} + + with open(self._resource_mapping_file_path, 'w') as file_content: + json.dump(resource_mappings, file_content, indent=4) + + self._resource_mapping_file_path = '' + self._region = '' + self._client = None + + def get_resource_name_id(self, resource_key: str): + return self._resource_mappings[AWS_RESOURCE_MAPPINGS_KEY][resource_key]['Name/ID'] + + +@pytest.fixture(scope='function') +def resource_mappings( + request: pytest.fixture, + project: str, + feature_name: str, + resource_mappings_filename: str, + workspace: pytest.fixture, + aws_utils: pytest.fixture) -> ResourceMappings: + """ + Fixture for setting up resource mappings file. + :param request: _pytest.fixtures.SubRequest class that handles getting + a pytest fixture from a pytest function/fixture. + :param project: Project to find resource mapping file. + :param feature_name: AWS Gem name that is prepended to resource mapping keys. + :param resource_mappings_filename: Name of resource mapping file. + :param workspace: ly_test_tools workspace fixture. + :param aws_utils: AWS utils fixture. + :return: ResourceMappings class object. + """ + + path = f'{workspace.paths.engine_root()}/{project}/Config/{resource_mappings_filename}' + logger.info(f'Resource mapping path : {path}') + logger.info(f'Resource mapping resolved path : {abspath(path)}') + resource_mappings_obj = ResourceMappings(abspath(path), aws_utils.assume_session().region_name, feature_name, + aws_utils.assume_account_id(), workspace, + aws_utils.client('cloudformation')) + + def teardown(): + resource_mappings_obj.clear_output_keys() + + request.addfinalizer(teardown) + + return resource_mappings_obj diff --git a/AutomatedTesting/Gem/PythonTests/AWS/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/__init__.py new file mode 100644 index 0000000000..8caef52682 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/__init__.py @@ -0,0 +1,11 @@ +""" +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. +""" + diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/__init__.py b/AutomatedTesting/Gem/PythonTests/AWS/common/__init__.py new file mode 100644 index 0000000000..8caef52682 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/__init__.py @@ -0,0 +1,11 @@ +""" +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. +""" + diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py new file mode 100644 index 0000000000..fbce772d40 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_credentials.py @@ -0,0 +1,134 @@ +""" +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 boto3 +import configparser +import logging +import os +import pytest +import typing + +logger = logging.getLogger(__name__) +logging.getLogger('boto').setLevel(logging.CRITICAL) + + +class AwsCredentials: + def __init__(self, profile_name: str): + self._profile_name = profile_name + + self._credentials_path = os.environ.get('AWS_SHARED_CREDENTIALS_FILE') + if not self._credentials_path: + # Home directory location varies based on the operating system, but is referred to using the environment + # variables %UserProfile% in Windows and $HOME or ~ (tilde) in Unix-based systems. + self._credentials_path = os.path.join(os.environ.get('UserProfile', os.path.expanduser('~')), + '.aws', 'credentials') + self._credentials_file_exists = os.path.exists(self._credentials_path) + + self._credentials = configparser.ConfigParser() + self._credentials.read(self._credentials_path) + + def get_aws_credentials(self) -> typing.Tuple[str, str, str]: + """ + Get aws credentials stored in the specific named profile. + + :return AWS credentials. + """ + access_key_id = self._get_aws_credential_attribute_value('aws_access_key_id') + secret_access_key = self._get_aws_credential_attribute_value('aws_secret_access_key') + session_token = self._get_aws_credential_attribute_value('aws_session_token') + + return access_key_id, secret_access_key, session_token + + def set_aws_credentials_by_session(self, session: boto3.Session) -> None: + """ + Set AWS credentials stored in the specific named profile using an assumed role session. + + :param session: assumed role session. + """ + credentials = session.get_credentials().get_frozen_credentials() + self.set_aws_credentials(credentials.access_key, credentials.secret_key, credentials.token) + + def set_aws_credentials(self, aws_access_key_id: str, aws_secret_access_key: str, + aws_session_token: str) -> None: + """ + Set AWS credentials stored in the specific named profile. + + :param aws_access_key_id: AWS access key id. + :param aws_secret_access_key: AWS secrete access key. + :param aws_session_token: AWS assumed role session. + """ + self._set_aws_credential_attribute_value('aws_access_key_id', aws_access_key_id) + self._set_aws_credential_attribute_value('aws_secret_access_key', aws_secret_access_key) + self._set_aws_credential_attribute_value('aws_session_token', aws_session_token) + + if (len(self._credentials.sections()) == 0) and (not self._credentials_file_exists): + os.remove(self._credentials_path) + return + + with open(self._credentials_path, 'w+') as credential_file: + self._credentials.write(credential_file) + + def _get_aws_credential_attribute_value(self, attribute_name: str) -> str: + """ + Get the value of an AWS credential attribute stored in the specific named profile. + + :param attribute_name: Name of the AWS credential attribute. + :return Value of the AWS credential attribute. + """ + try: + value = self._credentials.get(self._profile_name, attribute_name) + except configparser.NoSectionError: + # Named profile or key doesn't exist + value = None + except configparser.NoOptionError: + # Named profile doesn't have the specified attribute + value = None + + return value + + def _set_aws_credential_attribute_value(self, attribute_name: str, attribute_value: str) -> None: + """ + Set the value of an AWS credential attribute stored in the specific named profile. + + :param attribute_name: Name of the AWS credential attribute. + :param attribute_value: Value of the AWS credential attribute. + """ + if self._profile_name not in self._credentials: + self._credentials[self._profile_name] = {} + + if attribute_value is None: + self._credentials.remove_option(self._profile_name, attribute_name) + # Remove the named profile if it doesn't have any AWS credential attribute. + if len(self._credentials[self._profile_name]) == 0: + self._credentials.remove_section(self._profile_name) + else: + self._credentials[self._profile_name][attribute_name] = attribute_value + + +@pytest.fixture(scope='function') +def aws_credentials(request: pytest.fixture, aws_utils: pytest.fixture, profile_name: str): + """ + Fixture for setting up temporary AWS credentials from assume role. + + :param request: _pytest.fixtures.SubRequest class that handles getting + a pytest fixture from a pytest function/fixture. + :param aws_utils: aws_utils fixture. + :param profile_name: Named AWS profile to store temporary credentials. + """ + aws_credentials_obj = AwsCredentials(profile_name) + original_access_key, original_secret_access_key, original_token = aws_credentials_obj.get_aws_credentials() + aws_credentials_obj.set_aws_credentials_by_session(aws_utils.assume_session()) + + def teardown(): + # Reset to the named profile using the original AWS credentials + aws_credentials_obj.set_aws_credentials(original_access_key, original_secret_access_key, original_token) + request.addfinalizer(teardown) + + return aws_credentials_obj diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py new file mode 100644 index 0000000000..ff33f58d1d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py @@ -0,0 +1,90 @@ +""" +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 boto3 +import pytest +import logging + +logger = logging.getLogger(__name__) +logging.getLogger('boto').setLevel(logging.CRITICAL) + + +class AwsUtils: + + def __init__(self, arn: str, session_name: str, region_name: str): + local_session = boto3.Session(profile_name='default') + local_sts_client = local_session.client('sts') + self._local_account_id = local_sts_client.get_caller_identity()["Account"] + logger.info(f'Local Account Id: {self._local_account_id}') + + response = local_sts_client.assume_role(RoleArn=arn, RoleSessionName=session_name) + + self._assume_session = boto3.Session(aws_access_key_id=response['Credentials']['AccessKeyId'], + aws_secret_access_key=response['Credentials']['SecretAccessKey'], + aws_session_token=response['Credentials']['SessionToken'], + region_name=region_name) + + assume_sts_client = self._assume_session.client('sts') + assume_account_id = assume_sts_client.get_caller_identity()["Account"] + logger.info(f'Assume Account Id: {assume_account_id}') + self._assume_account_id = assume_account_id + + def client(self, service: str): + """ + Get the client for a specific AWS service from configured session + :return: Client for the AWS service. + """ + return self._assume_session.client(service) + + def resource(self, service: str): + """ + Get the resource for a specific AWS service from configured session + :return: Client for the AWS service. + """ + return self._assume_session.resource(service) + + def assume_session(self): + return self._assume_session + + def local_account_id(self): + return self._local_account_id + + def assume_account_id(self): + return self._assume_account_id + + def destroy(self) -> None: + """ + clears stored session + """ + self._assume_session = None + + +@pytest.fixture(scope='function') +def aws_utils( + request: pytest.fixture, + assume_role_arn: str, + session_name: str, + region_name: str): + """ + Fixture for AWS util functions + :param request: _pytest.fixtures.SubRequest class that handles getting + a pytest fixture from a pytest function/fixture. + :param assume_role_arn: Role used to fetch temporary aws credentials, configure service clients with obtained credentials. + :param session_name: Session name to set. + :param region_name: AWS account region to set for session. + :return AWSUtils class object. + """ + aws_utils_obj = AwsUtils(assume_role_arn, session_name, region_name) + + def teardown(): + aws_utils_obj.destroy() + + request.addfinalizer(teardown) + + return aws_utils_obj diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/custom_waiter.py b/AutomatedTesting/Gem/PythonTests/AWS/common/custom_waiter.py new file mode 100644 index 0000000000..7c0a65e8a3 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/AWS/common/custom_waiter.py @@ -0,0 +1,91 @@ +""" +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. +""" + +from enum import Enum +import botocore.client +import botocore.waiter +import logging + +logging.getLogger('boto').setLevel(logging.CRITICAL) + + +class WaitState(Enum): + SUCCESS = 'success' + FAILURE = 'failure' + + +class CustomWaiter: + """ + Base class for a custom waiter. + + Modified from: + https://docs.aws.amazon.com/code-samples/latest/catalog/python-demo_tools-custom_waiter.py.html + """ + def __init__( + self, name: str, operation: str, argument: str, + acceptors: dict, client: botocore.client, delay: int = 30, max_tries: int = 10, + matcher='path'): + """ + Subclasses should pass specific operations, arguments, and acceptors to + their superclass. + + :param name: The name of the waiter. This can be any descriptive string. + :param operation: The operation to wait for. This must match the casing of + the underlying operation model, which is typically in + CamelCase. + :param argument: The dict keys used to access the result of the operation, in + dot notation. For example, 'Job.Status' will access + result['Job']['Status']. + :param acceptors: The list of acceptors that indicate the wait is over. These + can indicate either success or failure. The acceptor values + are compared to the result of the operation after the + argument keys are applied. + :param client: The Boto3 client. + :param delay: The number of seconds to wait between each call to the operation. Default to 30 seconds. + :param max_tries: The maximum number of tries before exiting. Default to 10. + :param matcher: The kind of matcher to use. Default to 'path'. + """ + self.name = name + self.operation = operation + self.argument = argument + self.client = client + self.waiter_model = botocore.waiter.WaiterModel({ + 'version': 2, + 'waiters': { + name: { + "delay": delay, + "operation": operation, + "maxAttempts": max_tries, + "acceptors": [{ + "state": state.value, + "matcher": matcher, + "argument": argument, + "expected": expected + } for expected, state in acceptors.items()] + }}}) + self.waiter = botocore.waiter.create_waiter_with_client( + self.name, self.waiter_model, self.client) + + self._timeout = delay * max_tries + + def _wait(self, **kwargs): + """ + Starts the botocore wait loop. + + :param kwargs: Keyword arguments that are passed to the operation being polled. + """ + self.waiter.wait(**kwargs) + + @property + def timeout(self): + return self._timeout + + diff --git a/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt new file mode 100644 index 0000000000..61bb2e8355 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Blast/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::BlastTests + TEST_SUITE main + TEST_SERIAL TRUE + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT Blast + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index 7931aa7178..8142691464 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -15,372 +15,50 @@ ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) +include(${pal_dir}/PAL_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) + +## Asset pipeline ## add_subdirectory(assetpipeline) + +## Atom Renderer ## add_subdirectory(atom_renderer) ## Physics ## -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::PhysicsTests_Main - TEST_SUITE main - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Main.py - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Physics - ) - ly_add_pytest( - NAME AutomatedTesting::PhysicsTests_Periodic - TEST_SUITE periodic - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Periodic.py - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Physics - ) - ly_add_pytest( - NAME AutomatedTesting::PhysicsTests_Sandbox - TEST_SUITE sandbox - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Sandbox.py - TIMEOUT 3600 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Physics - ) -endif() +add_subdirectory(physics) ## ScriptCanvas ## -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::ScriptCanvasTests - TEST_SUITE periodic - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Active.py - TIMEOUT 3000 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - ScriptCanvas - ) - ly_add_pytest( - NAME AutomatedTesting::ScriptCanvasTests_Sandbox - TEST_SUITE sandbox - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Sandbox.py - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - ) -endif() +add_subdirectory(scripting) ## White Box ## -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::WhiteBoxTests - TEST_SUITE main - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/WhiteBox/TestSuite_Active.py - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - WhiteBox - ) -endif() +add_subdirectory(WhiteBox) ## NvCloth ## -# [TODO LYN-1928] Enable when AutomatedTesting runs with Atom -#if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) -# ly_add_pytest( -# NAME AutomatedTesting::NvClothTests -# TEST_SUITE main -# TEST_SERIAL -# PATH ${CMAKE_CURRENT_LIST_DIR}/NvCloth/TestSuite_Active.py -# TIMEOUT 1500 -# RUNTIME_DEPENDENCIES -# Legacy::Editor -# AZ::AssetProcessor -# AutomatedTesting.Assets -# ) -#endif() +add_subdirectory(NvCloth) + +## Prefab ## +add_subdirectory(prefab) ## Editor Python Bindings ## -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::EditorPythonBindings - TEST_SUITE sandbox - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/EditorPythonBindings - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - Gem::EditorPythonBindings.Editor - COMPONENT TestTools - ) -endif() +add_subdirectory(EditorPythonBindings) ## Python Asset Builder ## -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::PythonAssetBuilder - TEST_SUITE periodic - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/PythonAssetBuilder - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - Gem::EditorPythonBindings.Editor - Gem::PythonAssetBuilder.Editor - COMPONENT TestTools - ) -endif() +add_subdirectory(PythonAssetBuilder) ## Blast ## -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::BlastTests - TEST_SUITE main - TEST_SERIAL TRUE - PATH ${CMAKE_CURRENT_LIST_DIR}/Blast/TestSuite_Active.py - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT Blast - ) -endif() - -############# +add_subdirectory(Blast) ## Large Worlds ## - -include(${pal_dir}/PAL_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake) -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_LARGE_WORLDS_TEST_SUPPORTED) - -## DynVeg ## - # Temporarily moving all tests to periodic suite - SPEC-6553 - #ly_add_pytest( - # NAME AutomatedTesting::DynamicVegetationTests_Main - # TEST_SERIAL - # TEST_SUITE main - # PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - # PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" - # TIMEOUT 1500 - # RUNTIME_DEPENDENCIES - # AZ::AssetProcessor - # Legacy::Editor - # AutomatedTesting.GameLauncher - # AutomatedTesting.Assets - # COMPONENT - # LargeWorlds - #) - - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationTests_Sandbox - TEST_SERIAL - TEST_SUITE sandbox - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - PYTEST_MARKS "SUITE_sandbox" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.GameLauncher - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationFilterTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - PYTEST_MARKS "SUITE_periodic and dynveg_filter" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationModifierTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - PYTEST_MARKS "SUITE_periodic and dynveg_modifier" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationRegressionTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - PYTEST_MARKS "SUITE_periodic and dynveg_regression" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationAreaTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - PYTEST_MARKS "SUITE_periodic and dynveg_area" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationMiscTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - PYTEST_MARKS "SUITE_periodic and dynveg_misc" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - - ly_add_pytest( - NAME AutomatedTesting::DynamicVegetationSurfaceTagTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg - PYTEST_MARKS "SUITE_periodic and dynveg_surfacetagemitter" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) -## LandscapeCanvas ## - # Temporarily moving all tests to periodic suite - SPEC-6553 - #ly_add_pytest( - # NAME AutomatedTesting::LandscapeCanvasTests_Main - # TEST_SERIAL - # TEST_SUITE main - # PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas - # PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" - # TIMEOUT 1500 - # RUNTIME_DEPENDENCIES - # AZ::AssetProcessor - # Legacy::Editor - # AutomatedTesting.Assets - # COMPONENT - # LargeWorlds - #) - - ly_add_pytest( - NAME AutomatedTesting::LandscapeCanvasTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas - PYTEST_MARKS "SUITE_periodic" - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - -## GradientSignal ## - ly_add_pytest( - NAME AutomatedTesting::GradientSignalTests_Periodic - TEST_SERIAL - TEST_SUITE periodic - PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/gradient_signal - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - AZ::AssetProcessor - Legacy::Editor - AutomatedTesting.Assets - COMPONENT - LargeWorlds - ) - -endif() +add_subdirectory(largeworlds) ## Editor ## -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED) - ly_add_pytest( - NAME AutomatedTesting::EditorTests_Periodic - TEST_SUITE periodic - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/editor - TIMEOUT 1500 - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - COMPONENT - Editor - ) -endif() +add_subdirectory(editor) -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - # Unstable, SPEC-3838 will restore - #ly_add_pytest( - # NAME AutomatedTesting::asset_load_benchmark_test - # TEST_SERIAL - # TEST_SUITE benchmark - # PATH ${CMAKE_CURRENT_LIST_DIR}/streaming/benchmark/asset_load_benchmark_test.py - # RUNTIME_DEPENDENCIES - # AZ::AssetProcessor - # AZ::AssetProcessorBatch - # AutomatedTesting.GameLauncher - #) -endif() +## Streaming ## +add_subdirectory(streaming) +## Smoke ## +add_subdirectory(smoke) + +## AWS ## +# Enable when AWS Gems work on Linux and Android. +# add_subdirectory(AWS) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CMakeLists.txt new file mode 100644 index 0000000000..20a0ca8e65 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonBindings/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::EditorPythonBindings + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR} + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + Gem::EditorPythonBindings.Editor + COMPONENT TestTools + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_test_helper.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_test_helper.py index 74f34659c0..d375e69ac2 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_test_helper.py @@ -98,11 +98,6 @@ class EditorTestHelper: self.test_success = False success = False - # Turn off any display info like FPS, as that will mess up our image comparisons - # Turn off antialiasing as well - general.run_console("r_displayInfo=0") - general.run_console("r_antialiasingmode=0") - general.idle_wait(1.0) return success # Test Teardown diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py index 05614296b1..2feab75464 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/hydra_editor_utils.py @@ -74,15 +74,23 @@ def add_component(componentName, entityId): typeIdsList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeIdsByEntityType', [componentName], entity.EntityType().Game) typeNamesList = editor.EditorComponentAPIBus(bus.Broadcast, 'FindComponentTypeNames', typeIdsList) + + # If the type name comes back as empty, then it means componentName is invalid + if len(typeNamesList) != 1 or not typeNamesList[0]: + print('Unable to find component TypeId for {}'.format(componentName)) + return None + componentOutcome = editor.EditorComponentAPIBus(bus.Broadcast, 'AddComponentsOfType', entityId, typeIdsList) + if not componentOutcome.IsSuccess(): + print('Failed to add {} component to entity'.format(typeNamesList[0])) + return None + isActive = editor.EditorComponentAPIBus(bus.Broadcast, 'IsComponentEnabled', componentOutcome.GetValue()[0]) hasComponent = editor.EditorComponentAPIBus(bus.Broadcast, 'HasComponentOfType', entityId, typeIdsList[0]) - if componentOutcome.IsSuccess() and isActive: + if isActive: print('{} component was added to entity'.format(typeNamesList[0])) - elif componentOutcome.IsSuccess() and not isActive: + else: print('{} component was added to entity, but the component is disabled'.format(typeNamesList[0])) - elif not componentOutcome.IsSuccess(): - print('Failed to add {} component to entity'.format(typeNamesList[0])) if hasComponent: print('Entity has a {} component'.format(typeNamesList[0])) return componentOutcome.GetValue()[0] @@ -218,7 +226,8 @@ class Entity: def add_component(self, component): new_component = add_component(component, self.id) - self.components.append(new_component) + if new_component: + self.components.append(new_component) def add_component_of_type(self, componentTypeId): new_component = add_component_of_type(componentTypeId, self.id) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py index 10f060bba6..eed6a18614 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/pyside_utils.py @@ -18,7 +18,6 @@ from PySide2 import QtCore, QtWidgets, QtGui, QtTest from PySide2.QtWidgets import QAction, QWidget from PySide2.QtCore import Qt from PySide2.QtTest import QTest -import azlmbr.legacy.general as general import traceback import threading import types diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py index 2677ba5605..5cfc57fd5f 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C18977329 # Test Case Title : Add cloth simulation to a Mesh -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977329 # fmt: off class Tests: @@ -20,7 +19,7 @@ class Tests: exit_game_mode = ("Exited game mode", "Failed to exit game mode") # fmt: on -def run(): +def C18977329_NvCloth_AddClothSimulationToMesh(): """ Summary: Load level with Entity having Mesh and Cloth components already setup. Verify that editor remains stable in Game mode. @@ -89,4 +88,7 @@ def run(): helper.close_editor() if __name__ == "__main__": - run() + import ImportPathHelper as imports + imports.init() + from editor_python_test_tools.utils import Report + Report.start_test(C18977329_NvCloth_AddClothSimulationToMesh) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py index 2d4fa4e325..c21df8ea4c 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/C18977330_NvCloth_AddClothSimulationToActor.py @@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C18977330 # Test Case Title : Add cloth simulation to an Actor -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977330 # fmt: off class Tests: @@ -20,7 +19,7 @@ class Tests: exit_game_mode = ("Exited game mode", "Failed to exit game mode") # fmt: on -def run(): +def C18977330_NvCloth_AddClothSimulationToActor(): """ Summary: Load level with Entity having Actor and Cloth components already setup. Verify that editor remains stable in Game mode. @@ -89,4 +88,7 @@ def run(): helper.close_editor() if __name__ == "__main__": - run() + import ImportPathHelper as imports + imports.init() + from editor_python_test_tools.utils import Report + Report.start_test(C18977330_NvCloth_AddClothSimulationToActor) diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/NvCloth/CMakeLists.txt new file mode 100644 index 0000000000..058cc9ad94 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::NvClothTests_Main + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + NvCloth + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py index 162c54afc8..86bfc48636 100755 --- a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py +++ b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py @@ -21,14 +21,15 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesti from base import TestAutomationBase -@pytest.mark.SUITE_main @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(TestAutomationBase): + @pytest.mark.xfail(reason="Running with atom null renderer is causing this test to fail") def test_C18977329_NvCloth_AddClothSimulationToMesh(self, request, workspace, editor, launcher_platform): from . import C18977329_NvCloth_AddClothSimulationToMesh as test_module self._run_test(request, workspace, editor, test_module) + @pytest.mark.xfail(reason="Running with atom null renderer is causing this test to fail") def test_C18977330_NvCloth_AddClothSimulationToActor(self, request, workspace, editor, launcher_platform): from . import C18977330_NvCloth_AddClothSimulationToActor as test_module self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py index 818dc23079..ecf08cfcbd 100644 --- a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test.py @@ -31,13 +31,13 @@ class TestPythonAssetProcessing(object): unexpected_lines = [] expected_lines = [ 'Mock asset exists', - 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel) found', - 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel) found', - 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel) found', - 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel) found', - 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel) found', - 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel) found', - 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel) found' + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative.azmodel) found', + 'Expected subId for asset (gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel) found' ] timeout = 180 halt_on_unexpected = False diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py index cd9adfdbcf..a7907778b2 100644 --- a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/AssetBuilder_test_case.py @@ -38,16 +38,16 @@ def test_azmodel_product(generatedModelAssetPath, expectedSubId): assetId = azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, 'GetAssetIdByPath', generatedModelAssetPath, azModelAssetType, False) assetIdString = assetId.to_string() if (assetIdString.endswith(':' + expectedSubId) is False): - raise_and_stop(f'Asset has unexpected asset ID ({assetIdString}) for ({generatedModelAssetPath})!') + raise_and_stop(f'Asset at path {generatedModelAssetPath} has unexpected asset ID ({assetIdString}) for ({generatedModelAssetPath}), expected {expectedSubId}!') else: print(f'Expected subId for asset ({generatedModelAssetPath}) found') -test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive_1.azmodel', '10315ae0') -test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative_1.azmodel', '10661093') -test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive_1.azmodel', '10af8810') -test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative_1.azmodel', '10f8c263') -test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive_1.azmodel', '100ac47f') -test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative_1.azmodel', '105d8e0c') -test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center_1.azmodel', '1002d464') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_positive.azmodel', '1024be55') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_z_negative.azmodel', '1052c94e') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_positive.azmodel', '10130556') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_y_negative.azmodel', '1065724d') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_positive.azmodel', '10d16e68') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_x_negative.azmodel', '10a71973') +test_azmodel_product('gem/pythontests/pythonassetbuilder/geom_group_fbx_cube_100cm_center.azmodel', '10412075') azlmbr.editor.EditorToolsApplicationRequestBus(azlmbr.bus.Broadcast, 'ExitNoPrompt') diff --git a/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/CMakeLists.txt new file mode 100644 index 0000000000..0a550de539 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/PythonAssetBuilder/CMakeLists.txt @@ -0,0 +1,27 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::PythonAssetBuilder + TEST_SUITE periodic + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR} + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + Gem::EditorPythonBindings.Editor + Gem::PythonAssetBuilder.Editor + COMPONENT TestTools + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py index dabc04575f..86a27e588e 100755 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798177_WhiteBox_AddComponentToEntity.py @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C28798177 # Test Case Title : White Box Tool Component can be added to an Entity -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798177 # fmt:off diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py index 18a5c3164e..7a2a08a8ce 100755 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/C28798205_WhiteBox_SetInvisible.py @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C28798205 # Test Case Title : From the White Box Component Card the White Box Mesh can be set to be invisible in Game View -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798205 # fmt:off diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py b/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py index e892285dde..635c804914 100755 --- a/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/C29279329_WhiteBox_SetDefaultShape.py @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C29279329 # Test Case Title : White Box mesh shape can be changed with the Default Shape dropdown on the Component -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/29279329 # fmt:off diff --git a/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt new file mode 100644 index 0000000000..a6c0a9aa21 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/WhiteBox/CMakeLists.txt @@ -0,0 +1,26 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::WhiteBoxTests + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Active.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + WhiteBox + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/CMakeLists.txt index 74ef6c97a7..f453a38486 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/CMakeLists.txt @@ -13,8 +13,6 @@ add_subdirectory(asset_processor_tests) if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) ## AP Python Tests ## - - ly_add_pytest( NAME AssetPipelineTests.AuxiliaryContent PATH ${CMAKE_CURRENT_LIST_DIR}/auxiliary_content_tests/auxiliary_content_tests.py @@ -22,7 +20,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) TEST_SUITE periodic ) - ly_add_pytest( NAME AssetPipelineTests.BankInfoParser PATH ${CMAKE_CURRENT_LIST_DIR}/wwise_bank_dependency_tests/bank_info_parser_tests.py @@ -33,4 +30,3 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) ) endif() - diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_all_platforms_setup_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_all_platforms_setup_fixture.py index e729ee9882..9a5b93ca80 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_all_platforms_setup_fixture.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_all_platforms_setup_fixture.py @@ -34,10 +34,10 @@ def ap_all_platforms_setup_fixture(request, workspace, ap_setup_fixture) -> Dict # Specific platform cache locations resources["pc_cache_location"] = os.path.join(cache_dir, "pc") - resources["es3_cache_location"] = os.path.join(cache_dir, "es3") + resources["android_cache_location"] = os.path.join(cache_dir, "android") resources["ios_cache_location"] = os.path.join(cache_dir, "ios") - resources["osx_gl_cache_location"] = os.path.join(cache_dir, "osx_gl") + resources["mac_cache_location"] = os.path.join(cache_dir, "mac") resources["provo_cache_location"] = os.path.join(cache_dir, "provo") - resources["all_platforms"] = ["pc", "es3", "ios", "osx_gl", "provo"] + resources["all_platforms"] = ["pc", "android", "ios", "mac", "provo"] return resources diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py index 580816e7b5..34af4d9115 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py @@ -54,7 +54,7 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) -> platforms = [platform.strip() for platform in platforms.split(",")] else: # No commandline argument provided, default to mac and pc - platforms = ["pc", "osx_gl"] + platforms = ["pc", "mac"] class BundlerBatchFixture: """ @@ -162,7 +162,7 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) -> else: cmd.append(f"--{key}") if append_defaults: - cmd.append(f"--project={workspace.project}") + cmd.append(f"--project-path={workspace.project}") return cmd # ****** @@ -241,11 +241,11 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) -> def get_platform_flag(self, platform_name: str) -> int: if (platform_name == "pc"): return 1 - elif (platform_name == "es3"): + elif (platform_name == "android"): return 2 elif (platform_name == "ios"): return 4 - elif (platform_name == "osx_gl"): + elif (platform_name == "mac"): return 8 elif (platform_name == "server"): return 128 @@ -300,9 +300,9 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) -> workspace.paths.engine_root(), "Code", "Framework", - "AzFramework", - "AzFramework", - "Platform", + "AzCore", + "AzCore", + "PlatformId", "PlatformDefaults.h", ) @@ -318,7 +318,7 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) -> if start_gathering: result = get_platform.match(line) # Try the regex if result: - platform_values[result.group(1).lower()] = counter + platform_values[result.group(1).replace("_ID", "").lower()] = counter counter = counter << 1 elif "(Invalid, -1)" in line: # The line right before the first platform start_gathering = True diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt index 6a865ee690..2e7516db27 100644 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt @@ -128,17 +128,5 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) RUNTIME_DEPENDENCIES AZ::AssetProcessorBatch ) - -# Need performance improvements LYN-1218 -# ly_add_pytest( -# NAME AssetPipelineTests.AssetRelocator -# PATH ${CMAKE_CURRENT_LIST_DIR}/asset_relocator_tests.py -# EXCLUDE_TEST_RUN_TARGET_FROM_IDE -# TEST_SUITE periodic -# TEST_SERIAL -# RUNTIME_DEPENDENCIES -# AZ::AssetProcessorBatch -# ) endif() - diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py index e3d52e8260..fb82f180c6 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_builder_tests.py @@ -64,6 +64,15 @@ class TestsAssetBuilder_WindowsAndMac(object): ): """ Verifying -debug parameter for AssetBuilder + + Test Steps: + 1. Create temporary workspace + 2. Launch Asset Processor GUI + 3. Add test assets to workspace + 4. Run Asset Builder with debug on an intact slice + 5. Check Asset Builder didn't fail to build + 6. Run Asset Builder with debug on a corrupted slice + 7. Verify corrupted slice produced an error """ env = ap_setup_fixture intact_slice_failed = False diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py index d236e87aa2..e1091b9b82 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py @@ -80,6 +80,8 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): def test_WindowsAndMac_RunHelpCmd_ZeroExitCode(self, workspace, bundler_batch_helper): """ Simple calls to all AssetBundlerBatch --help to make sure a non-zero exit codes are returned. + + Test will call each Asset Bundler Batch sub-command with help and will error on a non-0 exit code """ bundler_batch_helper.call_bundlerbatch(help="") bundler_batch_helper.call_seeds(help="") @@ -98,6 +100,12 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): r""" Tests that an asset list created maps dependencies correctly. testdependencieslevel\level.pak and lists of known dependencies are used for validation + + Test Steps: + 1. Create an asset list from the level.pak + 2. Create Lists of expected assets in the level.pak + 3. Add lists of expected assets to a single list + 4. Compare list of expected assets to actual assets """ helper = bundler_batch_helper @@ -300,9 +308,18 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ Validates destructive overwriting for asset lists and that generating debug information does not affect asset list creation + + 1. Create an asset list from seed_list + 2. Validate asset list was created + 3. Read and store contents of asset list into memory + 4. Attempt to create a new asset list in without using --allowOverwrites + 5. Verify that Asset Bundler returns false + 6. Verify that file contents of the orignally created asset list did not change from what was stored in memory + 7. Attempt to create a new asset list without debug while allowing overwrites + 8. Verify that file contents of the orignally created asset list changed from what was stored in memory """ helper = bundler_batch_helper - seed_list = os.path.join(workspace.paths.engine_root(), "Engine", "SeedAssetList.seed") # Engine seed list + seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list asset = r"levels\testdependencieslevel\level.pak" # Create Asset list @@ -375,9 +392,17 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ Validates bundle creation both through the 'bundles' and 'bundlesettings' subcommands. + + Test Steps: + 1. Create an asset list + 2. Create a bundle with the asset list and without a bundle settings file + 3. Create a bundle with the asset list and a bundle settings file + 4. Validate calling bundle doesn't perform destructive overwrite without --allowOverwrites + 5. Calling bundle again with --alowOverwrites performs destructive overwrite + 6. Validate contents of original bundle and overwritten bundle """ helper = bundler_batch_helper - seed_list = os.path.join(workspace.paths.engine_root(), "Engine", "SeedAssetList.seed") # Engine seed list + seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list asset = r"levels\testdependencieslevel\level.pak" # Useful bundle locations / names (2 for comparing contents) @@ -457,15 +482,25 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ Creates bundles using the same asset list and compares that they are created equally. Also validates that platform bundles exclude/include an expected file. (excluded for WIN, included for MAC) + + Test Steps: + 1. Create an asset list + 2. Create bundles for both PC & Mac + 3. Validate that bundles were created + 4. Verify that expected missing file is not in windows bundle + 5. Verify that expected file is in the mac bundle + 6. Create duplicate bundles with allowOverwrites + 7. Verify that files were generated + 8. Verify original bundle checksums are equal to new bundle checksums """ helper = bundler_batch_helper # fmt:off - assert "pc" in helper["platforms"] and "osx_gl" in helper["platforms"], \ + assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \ "This test requires both PC and MAC platforms to be enabled. " \ - "Please rerun with commandline option: '--bundle_platforms=pc,osx_gl'" + "Please rerun with commandline option: '--bundle_platforms=pc,mac'" # fmt:on - seed_list = os.path.join(workspace.paths.engine_root(), "Engine", "SeedAssetList.seed") # Engine seed list + seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed") # Engine seed list # Useful bundle / asset list locations bundle_dir = os.path.dirname(helper["bundle_file"]) @@ -502,21 +537,21 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): for bundle_file in bundle_files.values(): assert os.path.isfile(bundle_file) - # This asset is created on osx_gl platform but not on windows - file_to_check = b"engineassets/shading/defaultprobe_cm.dds.5" # [use byte str because file is in binary] + # This asset is created both on mac and windows platform + file_to_check = b"engineassets/shading/defaultprobe_cm_ibldiffuse.tif.streamingimage" # [use byte str because file is in binary] # Extract the delta catalog file from pc archive. {file_to_check} SHOULD NOT be present for PC file_contents = helper.extract_file_content(bundle_files["pc"], "DeltaCatalog.xml") # fmt:off - assert file_to_check not in file_contents, \ + assert file_to_check in file_contents, \ f"{file_to_check} was found in DeltaCatalog.xml in pc bundle file {bundle_files['pc']}" # fmt:on - # Extract the delta catalog file from osx_gl archive. {file_to_check} SHOULD be present for MAC - file_contents = helper.extract_file_content(bundle_files["osx_gl"], "DeltaCatalog.xml") + # Extract the delta catalog file from mac archive. {file_to_check} SHOULD be present for MAC + file_contents = helper.extract_file_content(bundle_files["mac"], "DeltaCatalog.xml") # fmt:off assert file_to_check in file_contents, \ - f"{file_to_check} was not found in DeltaCatalog.xml in darwin bundle file {bundle_files['osx_gl']}" + f"{file_to_check} was not found in DeltaCatalog.xml in darwin bundle file {bundle_files['mac']}" # fmt:on # Gather checksums for first set of bundles @@ -571,6 +606,24 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ Validates that the 'seeds' subcommand can add and remove seeds and seed platforms properly. Also checks that destructive overwrites require the --allowOverwrites flag + + Test Steps: + + 1. Create a PC Seed List from a test asset + 2. Validate that seed list was generated with proper platform flag + 3. Add Mac & PC as platforms to the seed list + 4. Verify that seed has both Mac & PC platform flags + 5. Remove Mac as a platform from the seed list + 6. Verify that seed only has PC as a platform flag + 7. Attempt to add a platform without using the --platform argument + 8. Verify that asset bundler returns False and file contents did not change + 9. Add Mac platform via --addPlatformToSeeds + 10. Validate that seed has both Mac & PC platform flags + 11. Attempt to remove platform without specifying a platform + 12. Validate that seed has both Mac & PC platform flags + 13. Validate that seed list contents did not change + 14. Remove seed + 15. Validate that seed was removed from the seed list """ helper = bundler_batch_helper @@ -613,20 +666,20 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): helper.call_seeds( seedListFile=helper["seed_list_file"], addSeed=test_asset, - platform="pc,osx_gl", + platform="pc,mac", ) # Validate both mac and pc are activated for seed # fmt:off check_seed_platform(helper["seed_list_file"], test_asset, - helper["platform_values"]["pc"] + helper["platform_values"]["osx"]) + helper["platform_values"]["pc"] + helper["platform_values"]["mac"]) # fmt:on # Remove MAC platform helper.call_seeds( seedListFile=helper["seed_list_file"], removePlatformFromSeeds="", - platform="osx_gl", + platform="mac", ) # Validate only pc platform for seed. Save file contents to variable all_lines = check_seed_platform(helper["seed_list_file"], test_asset, helper["platform_values"]["pc"]) @@ -646,12 +699,12 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): helper.call_seeds( seedListFile=helper["seed_list_file"], addPlatformToSeeds="", - platform="osx_gl", + platform="mac", ) # Validate Mac platform was added back on. Save file contents # fmt:off all_lines = check_seed_platform(helper["seed_list_file"], test_asset, - helper["platform_values"]["pc"] + helper["platform_values"]["osx"]) + helper["platform_values"]["pc"] + helper["platform_values"]["mac"]) # fmt:on # Try to remove platform without specifying a platform to remove (should fail) @@ -670,7 +723,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): helper.call_seeds( seedListFile=helper["seed_list_file"], removeSeed=test_asset, - platform="pc,osx_gl", + platform="pc,mac", ) # Validate seed was removed from file @@ -692,14 +745,20 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ Tests asset list comparison, both by file and by comparison type. Uses a set of controlled test assets to compare resulting output asset lists + + 1. Create comparison rules files + 2. Create seed files for different sets of test assets + 3. Create assetlist files for seed files + 4. Validate assetlists were created properly + 5. Compare using comparison rules files and just command line arguments """ helper = bundler_batch_helper env = ap_setup_fixture # fmt:off - assert "pc" in helper["platforms"] and "osx_gl" in helper["platforms"], \ + assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \ "This test requires both PC and MAC platforms to be enabled. " \ - "Please rerun with commandline option: '--bundle_platforms=pc,osx_gl'" + "Please rerun with commandline option: '--bundle_platforms=pc,mac'" # fmt:on # Test assets arranged in common lists: six (0-5) .txt files and .dat files @@ -717,16 +776,16 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): file_platforms = { "txtfile_0.txt": "pc", "txtfile_1.txt": "pc", - "txtfile_2.txt": "pc,osx_gl", - "txtfile_3.txt": "pc,osx_gl", - "txtfile_4.txt": "osx_gl", - "txtfile_5.txt": "osx_gl", + "txtfile_2.txt": "pc,mac", + "txtfile_3.txt": "pc,mac", + "txtfile_4.txt": "mac", + "txtfile_5.txt": "mac", "datfile_0.dat": "pc", "datfile_1.dat": "pc", - "datfile_2.dat": "pc,osx_gl", - "datfile_3.dat": "pc,osx_gl", - "datfile_4.dat": "osx_gl", - "datfile_5.dat": "osx_gl", + "datfile_2.dat": "pc,mac", + "datfile_3.dat": "pc,mac", + "datfile_4.dat": "mac", + "datfile_5.dat": "mac", } # Comparison rules files and their associated 'comparisonType' flags @@ -741,7 +800,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): # Get our test assets ready and processed utils.prepare_test_assets(env["tests_dir"], "C16877178", env["project_test_assets_dir"]) - asset_processor.batch_process(timeout=timeout, fastscan=False, platforms="pc,osx_gl") + asset_processor.batch_process(timeout=timeout, fastscan=False, platforms="pc,mac") # *** Some helper functions *** # @@ -759,7 +818,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): helper.call_assetLists( assetListFile=os.path.join(helper["test_dir"], asset_list_file_name), seedListFile=os.path.join(helper["test_dir"], seed_file_name), - platform="pc,osx_gl", + platform="pc,mac", ) def get_platform_assets(asset_name_list: List[str]) -> Dict[str, List[str]]: @@ -769,7 +828,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): for asset_name in asset_name_list: if "pc" in file_platforms[asset_name]: win_assets.append(asset_name) - if "osx_gl" in file_platforms[asset_name]: + if "mac" in file_platforms[asset_name]: mac_assets.append(asset_name) return {"win": win_assets, "mac": mac_assets} @@ -798,7 +857,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): # Get platform result file names win_asset_list_file = helper.platform_file_name(request_file, platforms["pc"]) - mac_asset_list_file = helper.platform_file_name(request_file, platforms["osx_gl"]) + mac_asset_list_file = helper.platform_file_name(request_file, platforms["mac"]) # Get expected platforms for each asset in asset_names platform_files = get_platform_assets(asset_names) @@ -879,14 +938,14 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): # fmt:on # End verify_asset_list_contents() - def run_compare_command_and_verify(platform_arg: str, expect_pc_output: bool, expect_osx_gl_output: bool) -> None: + def run_compare_command_and_verify(platform_arg: str, expect_pc_output: bool, expect_mac_output: bool) -> None: # Expected asset list to equal result of comparison expected_pc_asset_list = None - expected_osx_gl_asset_list = None + expected_mac_asset_list = None # Last output file. Use this for comparison to 'expected' output_pc_asset_list = None - output_osx_gl_asset_list = None + output_mac_asset_list = None # Add the platform to the file name to match what the Bundler will create last_output_arg = output_arg.split(",")[-1] @@ -895,10 +954,10 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): expected_pc_asset_list = os.path.join(helper["test_dir"], helper.platform_file_name(expected_asset_list, platform)) output_pc_asset_list = helper.platform_file_name(last_output_arg, platform) - if expect_osx_gl_output: - platform = platforms["osx_gl"] - expected_osx_gl_asset_list = os.path.join(helper["test_dir"], helper.platform_file_name(expected_asset_list, platform)) - output_osx_gl_asset_list = helper.platform_file_name(last_output_arg, platform) + if expect_mac_output: + platform = platforms["mac"] + expected_mac_asset_list = os.path.join(helper["test_dir"], helper.platform_file_name(expected_asset_list, platform)) + output_mac_asset_list = helper.platform_file_name(last_output_arg, platform) # Build execution command cmd = generate_compare_command(platform_arg) @@ -911,15 +970,15 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): verify_asset_list_contents(expected_pc_asset_list, output_pc_asset_list) fs.delete([output_pc_asset_list], True, True) - if expect_osx_gl_output: - verify_asset_list_contents(expected_osx_gl_asset_list, output_osx_gl_asset_list) - fs.delete([output_osx_gl_asset_list], True, True) + if expect_mac_output: + verify_asset_list_contents(expected_mac_asset_list, output_mac_asset_list) + fs.delete([output_mac_asset_list], True, True) # End run_compare_command_and_verify() # Generate command, run and validate for each platform run_compare_command_and_verify("pc", True, False) - run_compare_command_and_verify("osx_gl", False, True) - run_compare_command_and_verify("pc,osx_gl", True, True) + run_compare_command_and_verify("mac", False, True) + run_compare_command_and_verify("pc,mac", True, True) #run_compare_command_and_verify(None, True, True) # End compare_and_check() @@ -1021,6 +1080,16 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): """ Tests that assetlists are created equivalent to the output while being created, and makes sure overwriting an existing file without the --allowOverwrites fails + + Test Steps: + 1. Check that Asset List creation requires PC platform flag + 2. Create a PC Asset List using asset info file and default seed lists using --print + 3. Validate all assets output are present in the asset list + 4. Create a seed file + 5. Attempt to overwrite Asset List without using --allowOverwrites + 6. Validate that command returned an error and file contents did not change + 7. Specifying platform but not "add" or "remove" should fail + 8. Verify file Has changed """ helper = bundler_batch_helper @@ -1046,7 +1115,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): "--addDefaultSeedListFiles", "--platform=pc", "--print", - f"--project={workspace.project}" + f"--project-path={workspace.project}" ], universal_newlines=True, ) @@ -1102,7 +1171,16 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): def test_WindowsAndMac_AP_BundleProcessing_BundleProcessedAtRuntime(self, workspace, bundler_batch_helper, asset_processor, request): # fmt:on - """Test to make sure the AP GUI will process a newly created bundle file""" + """ + Test to make sure the AP GUI will process a newly created bundle file + + Test Steps: + 1. Make asset list file (used for bundle creation) + 2. Start Asset Processor GUI + 3. Make bundle in /Bundles + 4. Validate file was created in Bundles folder + 5. Make sure bundle now exists in cache + """ # Set up helpers and variables helper = bundler_batch_helper @@ -1115,7 +1193,7 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): bundle_result_path = os.path.join(bundles_folder, helper.platform_file_name("bundle.pak", workspace.asset_processor_platform)) - bundle_cache_path = os.path.join(workspace.paths.platform_cache(), workspace.project, + bundle_cache_path = os.path.join(workspace.paths.platform_cache(), "Bundles", helper.platform_file_name("bundle.pak", workspace.asset_processor_platform)) @@ -1131,6 +1209,8 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): addSeed=level_pak, assetListFile=helper["asset_info_file_request"], ) + + # Run Asset Processor GUI result, _ = asset_processor.gui_process() assert result, "AP GUI failed" @@ -1155,14 +1235,22 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): @pytest.mark.assetpipeline # fmt:off def test_WindowsAndMac_FilesMarkedSkip_FilesAreSkipped(self, workspace, bundler_batch_helper): + """ + Test Steps: + 1. Create an asset list with a file marked as skip + 2. Verify file was created + 3. Verify that only the expected assets are present in the created asset list + """ expected_assets = [ - "libs/particles/milestone2particles.xml", - "textures/milestone2/particles/fx_sparkstreak_01.dds" + "ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas", + "ui/textures/prefab/button_normal.sprite" ] bundler_batch_helper.call_assetLists( assetListFile=bundler_batch_helper['asset_info_file_request'], - addSeed="libs/particles/milestone2particles.xml", - skip="textures/milestone2/particles/fx_launchermuzzlering_01.dds,textures/milestone2/particles/fx_launchermuzzlefront_01.dds" + addSeed="ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas", + skip="ui/textures/prefab/button_disabled.sprite,ui/scripts/lyshineexamples/animation/multiplesequences.luac," + "ui/textures/prefab/tooltip_sliced.sprite,ui/scripts/lyshineexamples/unloadthiscanvasbutton.luac,fonts/vera.fontfamily,fonts/vera-italic.font," + "fonts/vera.font,fonts/vera-bold.font,fonts/vera-bold-italic.font,fonts/vera-italic.ttf,fonts/vera.ttf,fonts/vera-bold.ttf,fonts/vera-bold-italic.ttf" ) assert os.path.isfile(bundler_batch_helper["asset_info_file_result"]) assets_in_list = [] @@ -1176,6 +1264,12 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): # fmt:off def test_WindowsAndMac_AssetListSkipOneOfTwoParents_SharedDependencyIsIncluded(self, workspace, bundler_batch_helper): + """ + Test Steps: + 1. Create Asset List with a parent asset that is skipped + 2. Verify that Asset List was created + 3. Verify that only the expected assets are present in the asset list + """ expected_assets = [ "testassets/bundlerskiptest_grandparent.dynamicslice", "testassets/bundlerskiptest_parenta.dynamicslice", @@ -1204,6 +1298,13 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): @pytest.mark.assetpipeline # fmt:off def test_WindowsAndMac_AssetLists_SkipRoot_ExcludesAll(self, workspace, bundler_batch_helper): + """ + Negative scenario test that skips the same file being used as the parent seed. + + Test Steps: + 1. Create an asset list that skips the root asset + 2. Verify that asset list was not generated + """ result, _ = bundler_batch_helper.call_assetLists( assetListFile=bundler_batch_helper['asset_info_file_request'], @@ -1220,6 +1321,13 @@ class TestsAssetBundlerBatch_WindowsAndMac(object): @pytest.mark.assetpipeline # fmt:off def test_WindowsAndMac_AssetLists_SkipUniversalWildcard_ExcludesAll(self, workspace, bundler_batch_helper): + """ + Negative scenario test that uses the all wildcard when generating an asset list. + + Test Steps: + 1. Create an Asset List while using the universal all wildcard "*" + 2. Verify that asset list was not generated + """ result, _ = bundler_batch_helper.call_assetLists( assetListFile=bundler_batch_helper['asset_info_file_request'], diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py index e329846554..0c6924f3a2 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests.py @@ -67,7 +67,19 @@ class TestsAssetProcessorBatch_DependenycyTests(object): libs/materialeffects/surfacetypes.xml is listed as an entry engine_dependencies.xml libs/materialeffects/surfacetypes.xml is not listed as a missing dependency in the 'assetprocessorbatch' console output + + Test Steps: + 1. Assets are pre-processed + 2. Verify that engine_dependencies.xml exists + 3. Verify engine_dependencies.xml has surfacetypes.xml present + 4. Run Missing Dependency scanner against the engine_dependenciese.xml + 5. Verify that Surfacetypes.xml is NOT in the missing depdencies output + 6. Add the schema file which allows our xml parser to understand dependencies for our engine_dependencies file + 7. Process assets + 8. Run Missing Dependency scanner against the engine_dependenciese.xml + 9. Verify that surfacetypes.xml is in the missing dependencies out """ + env = ap_setup_fixture BATCH_LOG_PATH = env["ap_batch_log_file"] asset_processor.create_temp_asset_root() @@ -137,6 +149,11 @@ class TestsAssetProcessorBatch_DependenycyTests(object): def test_WindowsMacPlatforms_BatchCheckSchema_ValidateErrorChecking(self, workspace, asset_processor, ap_setup_fixture, folder, schema): # fmt:on + """ + Test Steps: + 1. Run the Missing Dependency Scanner against everything + 2. Verify that there are no missing dependencies. + """ env = ap_setup_fixture def missing_dependency_log_lines(log) -> [str]: diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests2.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests2.py index 4f33e0df4e..f184ff2392 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests2.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_dependency_tests2.py @@ -60,6 +60,15 @@ class TestsAssetProcessorBatch_DependenycyTests(object): Verify that Schemas can be loaded via Gems utilizing the fonts schema :returns: None + + Test Steps: + 1. Run Missing Dependency Scanner against %fonts%.xml when no fonts are present + 2. Verify fonts are scanned + 3. Verify that missing dependencies are found for fonts + 4. Add fonts to game project + 5. Run Missing Dependency Scanner against %fonts%.xml when fonts are present + 6. Verify that same amount of fonts are scanned + 7. Verify that there are no missing dependencies. """ schema_name = "Font.xmlschema" asset_processor.create_temp_asset_root() diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py index 50b3af1438..3efd9e7fce 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests.py @@ -100,9 +100,17 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.BAT @pytest.mark.assetpipeline def test_RunAPBatch_TwoPlatforms_ExitCodeZero(self, asset_processor): + """ + Tests Process assets for PC & Mac and verifies that processing exited without error + + Test Steps: + 1. Add Mac and PC as enabled platforms + 2. Process Assets + 3. Validate that AP exited cleanly + """ asset_processor.create_temp_asset_root() asset_processor.enable_asset_processor_platform("pc") - asset_processor.enable_asset_processor_platform("osx_gl") + asset_processor.enable_asset_processor_platform("mac") result, _ = asset_processor.batch_process() assert result, "AP Batch failed" @@ -111,6 +119,14 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id('C1571826') def test_RunAPBatch_OnlyIncludeInvalidAssets_NoAssetsAdded(self, asset_processor, ap_setup_fixture): + """ + Tests processing invalid assets and validating that no assets were moved to the cache + + Test Steps: + 1. Create a test environment with invalid assets + 2. Run asset processor + 3. Validate that no assets were found in the cache + """ asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "test_ProcessAssets_OnlyIncludeInvalidAssets_NoAssetsAdded") result, _ = asset_processor.batch_process() @@ -127,6 +143,16 @@ class TestsAssetProcessorBatch_AllPlatforms(object): "recognized as failing in the logs. There appears to be a window where the AutoFailJob doesn't complete" "before the shutdown completes and the failure doesn't end up counting") def test_ProcessAssets_IncludeTwoAssetsWithSameProduct_FailingOnSecondAsset(self, asset_processor, ap_setup_fixture): + """ + Tests processing two source assets with the same product file and validates that the second source will error + + Test Steps: + 1. Create a test environment that has two source files with the same product + 2. Run asset processor + 3. Validate that 1 asset failed to process + 4. Validate that only one product file with the expected name is found in the cache + """ + asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], "test_ProcessAssets_IncludeTwoAssetsWithSameProduct_FailingOnSecondAsset") result, output = asset_processor.batch_process(capture_output = True, expect_failure = True) @@ -143,6 +169,17 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id('C1587615') def test_ProcessAndDeleteCache_APBatchShouldReprocess(self, asset_processor, ap_setup_fixture): + """ + Tests processing once, deleting the generated cache, then processing again and validates the cache is created + + Test Steps: + 1. Run asset processor + 2. Compare the cache with expected output + 3. Delete Cache + 4. Compare the cache with expected output to verify that cache is gone + 5. Run asset processor with fastscan disabled + 6. Compare the cache with expected output + """ # Deleting assets from Cache will make them re-processed in AP (after start) # Copying test assets to project folder and deleting them from cache to make sure APBatch will process them @@ -174,6 +211,18 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id('C1591564') def test_ProcessAndChangeSource_APBatchShouldReprocess(self, asset_processor, ap_setup_fixture): + """ + Tests reprocessing of a modified asset and verifies that it was reprocessed + + Test Steps: + 1. Prepare test environment and copy test asset over + 2. Run asset processor + 3. Verify asset processed + 4. Verify asset is in cache + 4. Modify asset + 5. Re-run asset processor + 6. Verify asset was processed + """ # AP Batch Processing changed files (after start) # Copying test assets to project folder and deleting them from cache to make sure APBatch will process them @@ -208,6 +257,18 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.BAT @pytest.mark.assetpipeline def test_ProcessByBothApAndBatch_Md5ShouldMatch(self, asset_processor, ap_setup_fixture): + """ + Tests that a cache generated by AP GUI is the same as AP Batch + + Test Steps: + 1. Create test environment with test assets + 2. Call asset processor batch + 3. Get checksum for file cache + 4. Clean up test environment + 5. Call asset processor gui with quitonidle + 6. Get checksum for file cache + 7. Verify that checksums are equal + """ # AP Batch and AP app processed assets MD5 sums should be the same # Copying test assets to project folder and deleting them from cache to make sure APBatch will process them @@ -240,6 +301,16 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id('C1612446') def test_AddSameAssetsDifferentNames_ShouldProcess(self, asset_processor, ap_setup_fixture): + """ + Tests Asset Processing of duplicate assets with different names and verifies that both assets are processed + + Test Steps: + 1. Create test environment with two identical source assets with different names + 2. Run asset processor + 3. Verify that assets didn't fail to process + 4. Verify the correct number of jobs were performed + 5. Verify that product files are in the cache + """ # Feed two similar slices and texture with different names - should process without any issues # Copying test assets to project folder and deleting them from cache to make sure APBatch will process them @@ -277,6 +348,19 @@ class TestsAssetProcessorBatch_AllPlatforms(object): "recognized as failing in the logs. There appears to be a window where the AutoFailJob doesn't complete" "before the shutdown completes and the failure doesn't end up counting") def test_AddTwoTexturesWithSameName_ShouldProcessAfterRename(self, asset_processor, ap_setup_fixture): + """ + Tests processing of two textures with the same name then verifies that AP will successfully process after + renaming one of the textures + + Test Steps: + 1. Create test environment with two textures that have the same name + 2. Launch Asset Processor + 3. Validate that Asset Processor generates an error + 4. Rename texture files + 5. Run asset processor + 6. Verify that asset processor does not error + 7. Verify that expected product files are in the cache + """ # Feed two different textures with same name (but different extensions) - ap will fail # Rename one of textures and failure should go away @@ -312,6 +396,15 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.BAT @pytest.mark.assetpipeline def test_InvalidServerAddress_Warning_Logs(self, asset_processor): + """ + Tests running Asset Processor with an invalid server address and verifies that AP returns a warning about + an invalid server address + + Test Steps: + 1. Launch asset processor while providing an invalid server address + 2. Verify asset processor does not fail + 3. Verify that asset processor generated a warning informing the user about an invalid server address + """ asset_processor.create_temp_asset_root() # Launching AP and making sure that the warning exists @@ -327,6 +420,12 @@ class TestsAssetProcessorBatch_AllPlatforms(object): def test_AllSupportedPlatforms_IncludeValidAssets_AssetsProcessed(self, asset_processor, ap_setup_fixture): """ AssetProcessorBatch is successfully processing newly added assets + + Test Steps: + 1. Create a test environment with test assets + 2. Launch Asset Processor + 3. Verify that asset processor does not fail to process + 4. Verify assets are not missing from the cache """ env = ap_setup_fixture @@ -350,6 +449,14 @@ class TestsAssetProcessorBatch_AllPlatforms(object): def test_AllSupportedPlatforms_DeletedAssets_DeletedFromCache(self, asset_processor, ap_setup_fixture): """ AssetProcessor successfully deletes cached items when removed from project + + Test Steps: + 1. Create a test environment with test assets + 2. Run asset processor + 3. Verify expected assets are in the cache + 4. Delete test assets + 5. Run asset processor + 6. Verify expected assets are in the cache """ env = ap_setup_fixture @@ -385,6 +492,10 @@ class TestsAssetProcessorBatch_AllPlatforms(object): """ Tests that when cache is deleted (no cache) and AssetProcessorBatch runs, it successfully starts and processes assets. + + Test Steps: + 1. Run asset processor + 2. Verify asset processor exits cleanly """ asset_processor.create_temp_asset_root() @@ -402,6 +513,14 @@ class TestsAssetProcessorBatch_AllPlatforms(object): # fmt:on """ AssetProcessor successfully recovers assets from cache when deleted. + + Test Steps: + 1. Create test enviornment with test assets + 2. Run Asset Processor and verify it exits cleanly + 3. Make sure cache folder was generated + 4. Delete temp cache assets but leave database behind + 5. Run asset processor and verify it exits cleanly + 6. Verify expected files were generated in the cache """ env = ap_setup_fixture @@ -434,6 +553,14 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.assetpipeline # fmt:off def test_AllSupportedPlatforms_RunFastScanOnEmptyCache_FullScanRuns(self, ap_setup_fixture, asset_processor): + """ + Tests fast scan processing on an empty cache and verifies that a full analyis will be peformed + + Test Steps: + 1. Create a test environment + 2. Execute asset processor batch with fast scan enabled + 3. Verify that a full analysis is performed + """ # fmt:on env = ap_setup_fixture asset_processor.create_temp_asset_root() @@ -455,6 +582,11 @@ class TestsAssetProcessorBatch_AllPlatforms(object): """ After running the APBatch and AP GUI, Logs directory should exist (C1564055), JobLogs, Batch log, and GUI log should exist in the logs directory (C1564056) + + Test Steps: + 1. Run asset processor batch + 2. Run asset processor gui with quit on idle + 3. Verify that logs exist for both AP Batch & AP GUI """ asset_processor.create_temp_asset_root() LOG_PATH = { @@ -536,6 +668,11 @@ class TestsAssetProcessorBatch_AllPlatforms(object): """ Utilizing corrupted test assets, run the batch process to verify the AP logs the failure to process the corrupted file. + + Test Steps: + 1. Create test environment with corrupted slice + 2. Launch Asset Processor + 3. Verify that asset processor fails to process corrupted slice """ env = ap_setup_fixture error_line_found = False @@ -552,6 +689,15 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.BAT @pytest.mark.assetpipeline def test_validateDirectPreloadDependency_Found(self, asset_processor, ap_setup_fixture, workspace): + """ + Tests processing an asset with a circular dependency and verifies that Asset Processor will return an error + notifying the user about a circular dependency. + + Test Steps: + 1. Create test environment with an asset that has a circular dependency + 2. Launch asset processor + 3. Verify that error is returned informing the user that the asset has a circular dependency + """ env = ap_setup_fixture error_line_found = False @@ -567,6 +713,15 @@ class TestsAssetProcessorBatch_AllPlatforms(object): @pytest.mark.BAT @pytest.mark.assetpipeline def test_validateNestedPreloadDependency_Found(self, asset_processor, ap_setup_fixture, workspace): + """ + Tests processing of a nested circular dependency and verifies that Asset Processor will return an error + notifying the user about a circular depdency + + Test Steps: + 1. Create test environment with an asset that has a nested circular dependency + 2. Launch asset processor + 3. Verify that error is returned informing the user that the asset has a circular dependency + """ env = ap_setup_fixture error_line_found = False diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests_2.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests_2.py index 5c42af2139..fec5df8eb7 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests_2.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_batch_tests_2.py @@ -80,6 +80,15 @@ class TestsAssetProcessorBatch_AllPlatforms(object): # fmt:on """ Tests that fast scan mode can be used and is faster than full scan mode. + + Test Steps: + 1. Ensure all assets are processed + 2. Run Asset Processor without fast scan and measure the time it takes to run + 3. Capture Full Analysis was performed and number of assets processed + 4. Run Asset Processor with full scan and measure the time it takes to run + 5. Capture Full Analysis wans't performed and number of assets processed + 6. Verify that fast scan was faster than full scan + 7. Verify that full scan scanned more assets """ asset_processor.create_temp_asset_root() @@ -111,76 +120,23 @@ class TestsAssetProcessorBatch_AllPlatforms(object): assert full_scan_time > fast_scan_time, "Fast scan was slower that full scan" assert full_scan_analysis[0] > fast_scan_analysis[0], "Full scan did not process more assets than fast scan" - @pytest.mark.test_case_id("C18787404") - @pytest.mark.BAT - @pytest.mark.assetpipeline - @pytest.mark.skip(reason="External project is currently broken.") # LY-119863 - def test_AllSupportedPlatforms_ExternalProject_APRuns(self, workspace, ap_external_project_setup_fixture): - - external_resources = ap_external_project_setup_fixture - logger.info(f"Running external project test at path {external_resources['project_dir']}") - # Delete existing "external project" build if it exists - if os.path.exists(external_resources["project_dir"]): - fs.delete([external_resources["project_dir"]], True, True) - - # fmt:off - assert not os.path.exists(external_resources["project_dir"]), \ - f'{external_resources["project_dir"]} was not deleted' - # fmt:on - - lmbr_cmd = [ - workspace.paths.lmbr(), - "projects", - "create", - external_resources["project_name"], - "--template", - "EmptyTemplate", - "--app-root", - external_resources["project_dir"], - ] - - logger.info(f"Running lmbr projects create command '{lmbr_cmd}'") - - try: - subprocess.check_call(lmbr_cmd) - except subprocess.CalledProcessError as e: - assert False, f"lmbr projects create failed\n{e.stderr}" - - logger.info("...lmbr finished") - assert os.path.exists(external_resources["project_dir"]), "Project folder was not created" - - # AssetProcessor for new External project. Uses mock workspace to emulate external project workspace - external_ap = AssetProcessor(external_resources["external_workspace"]) - - # fmt:off - assert external_ap.batch_process(fastscan=False), \ - "Asset Processor Batch failed on external project" - # fmt:on - - # Parse log looking for errors or failures - log = APLogParser(workspace.paths.ap_batch_log()) - failures, errors = log.runs[-1]["Failures"], log.runs[-1]["Errors"] - assert failures == 0, f"There were {failures} asset processing failures" - assert errors == 0, f"There were {errors} asset processing errors" - - # Check that project cache was created (DNE until AP makes it) - project_cache = os.path.join(external_resources["project_dir"], "Cache") - assert os.path.exists(project_cache), f"{project_cache} was not created by AP" - - # Clean up external project - fs.delete([external_resources["project_dir"]], True, True) - - # fmt:off - assert not os.path.exists(external_resources["project_dir"]), \ - f"{external_resources['project_dir']} was not deleted" - # fmt:on - @pytest.mark.test_case_id("C4874121") @pytest.mark.BAT @pytest.mark.assetpipeline @pytest.mark.parametrize("clear_type", ["rewrite", "delete_asset", "delete_dir"]) def test_AllSupportedPlatforms_DeleteBadAssets_BatchFailedJobsCleared( self, workspace, request, ap_setup_fixture, asset_processor, clear_type): + """ + Tests the ability of Asset Processor to recover from processing of bad assets by removing them from scan folder + + Test Steps: + 1. Create testing environment with good and multiple bad assets + 2. Run Asset Processor + 3. Verify that bad assets fail to process + 4. Fix a bad asset & delete the others + 5. Run Asset Processor + 6. Verify Asset Processor does not have any asset failues + """ env = ap_setup_fixture error_search_terms = ["WWWWWWWWWWWW"] @@ -250,6 +206,14 @@ class TestsAssetProcessorBatch_Windows(object): Verify the AP batch and Gui can run and process assets independent of the Editor We do not want or need to kill running Editors here as they can be involved in other tests or simply being run locally in this branch or another + + Test Steps: + 1. Create temporary testing environment + 2. Run asset processor GUI + 3. Verify AP GUI doesn't error + 4. Stop AP GUI + 5. Run Asset Processor Batch with Fast Scan + 5. Verify Asset Processor Batch exits cleanly """ asset_processor.create_temp_asset_root() @@ -272,6 +236,11 @@ class TestsAssetProcessorBatch_Windows(object): """ Request a run for an invalid platform "AssetProcessor: Error: Platform in config file or command line 'notaplatform'" should be present in the logs + + Test Steps: + 1. Create temporary testing environment + 2. Run Asset Processor with an invalid platform + 3. Check that asset processor returns an Error notifying the user that the invalid platform is not supported """ asset_processor.create_temp_asset_root() error_search_terms = 'AssetProcessor: Error: The list of enabled platforms in the settings registry does not contain platform ' \ diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests.py index ed5651755c..88fa1a77b4 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests.py @@ -77,6 +77,13 @@ class TestsAssetProcessorGUI_Windows(object): def test_SendInputOnControlChannel_ReceivedAndResponded(self, asset_processor): """ Test that the control channel connects and that communication works both directions + + Test Steps: + 1. Start Asset Processor + 2. Send a Ping message to Asset Processor + 3. Listen for Asset Processor response + 4. Verify Asset Processor responds + 5. Stop asset Processor """ asset_processor.create_temp_asset_root() @@ -129,7 +136,15 @@ class TestsAssetProcessorGUI_Windows(object): # fmt:on """ Asset Processor Deletes processed assets when source is removed from project folder (while running) + + Test Steps: + 1. Create a temporary test environment + 2. Run Asset Processor GUI set to stay open on idle and verify that it does not fail + 3. Verify that assets were copied to the cache + 4. Delete the source test asset directory + 5. Verify assets are deleted from the cache """ + env = ap_setup_fixture # Copy test assets to project folder and verify test assets folder exists @@ -170,7 +185,18 @@ class TestsAssetProcessorGUI_Windows(object): # fmt:on """ Processing changed files (while running) + + Test Steps: + 1. Create temporary test environment with test assets + 2. Open Asset Processor GUI with set to stay open after idle and verify it does not fail + 3. Verify contents of source asset for later comparison + 4. Verify contents of product asset for later comparison + 5. Modify contents of source asset + 6. Wait for Asset Processor to go back to idle state + 7. Verify contents of source asset are the modified version + 8. Verify contents of product asset are the modified version """ + env = ap_setup_fixture # Copy test assets to project folder and verify test assets folder exists @@ -184,7 +210,7 @@ class TestsAssetProcessorGUI_Windows(object): result, _ = asset_processor.gui_process(quitonidle=False) assert result, "AP GUI failed" - # Verify contents of test asset in project folder before modication + # Verify contents of test asset in project folder before modification with open(project_asset_path, "r") as project_asset_file: assert project_asset_file.read() == "before_state" @@ -217,7 +243,14 @@ class TestsAssetProcessorGUI_Windows(object): def test_WindowsPlatforms_RunAP_ProcessesIdle(self, asset_processor): """ Asset Processor goes idle + + Test Steps: + 1. Create a temporary testing evnironment + 2. Run Asset Processor GUI without quitonidle + 3. Verify AP Goes Idle + 4. Verify AP goes below 1% CPU usage """ + CPU_USAGE_THRESHOLD = 1.0 # CPU usage percentage delimiting idle from active CPU_USAGE_WIND_DOWN = 10 # Time allowed in seconds for idle processes to stop using CPU @@ -245,7 +278,16 @@ class TestsAssetProcessorGUI_Windows(object): ): """ Processing newly added files to project folder (while running) + + Test Steps: + 1. Create a temporary testing environment with test assets + 2. Create a secondary set of testing assets that have not been copied into the the testing environment + 3. Start Asset Processor without quitonidle + 4. While Asset Processor is running add secondary set of testing assets to the testing environment + 5. Wait for Asset Processor to go idle + 6. Verify that all assets are in the cache """ + env = ap_setup_fixture level_name = "C1564064_level" new_asset = "C1564064.scriptcanvas" @@ -316,7 +358,14 @@ class TestsAssetProcessorGUI_Windows(object): def test_WindowsPlatforms_LaunchAP_LogReportsIdle(self, asset_processor, workspace, ap_idle): """ Asset Processor creates a log entry when it goes idle + + Test Steps: + 1. Create temporary testing environment + 2. Run Asset Processor batch to pre-process assets + 3. Run Asset Processor GUI + 4. Check if Asset Processor GUI reports that it has gone idle """ + asset_processor.create_temp_asset_root() # Run batch process to ensure project assets are processed assert asset_processor.batch_process(), "AP Batch failed" @@ -331,6 +380,17 @@ class TestsAssetProcessorGUI_Windows(object): @pytest.mark.assetpipeline def test_APStopTimesOut_ExceptionThrown(self, ap_setup_fixture, asset_processor): + """ + Tests whether or not Asset Processor will Time Out + + Test Steps: + 1. Create a temporary testing environment + 2. Start the Asset Processor + 3. Copy in assets to the test environment + 4. Try to stop the Asset Processor with a timeout of 1 second (This cannot be done manually). + 5. Verify that Asset Processor times out and returns the expected error + """ + asset_processor.create_temp_asset_root() asset_processor.start() @@ -347,9 +407,20 @@ class TestsAssetProcessorGUI_Windows(object): @pytest.mark.assetpipeline def test_APStopDefaultTimeout_NoException(self, asset_processor): - # If this test fails, it means other tests using the default timeout may have issues. - # In that case, either the default timeout should either be raised, or the performance - # of AP launching should be improved. + """ + Tests the default timeout of the Asset Processor + + If this test fails, it means other tests using the default timeout may have issues. + In that case, either the default timeout should either be raised, or the performance + of AP launching should be improved. + + Test Steps: + 1. Create a temporary testing environment + 2. Start the Asset Processor + 3. Stop the asset Processor without sending a timeout to it + 4. Verify that the asset processor times out and returns the expected error + """ + asset_processor.create_temp_asset_root() asset_processor.start() ap_quit_timed_out = False diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py index b25ee081a1..3fb9ae5a81 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py @@ -75,10 +75,17 @@ class TestsAssetProcessorGUI_WindowsAndMac(object): @pytest.mark.test_case_id("C3540434") @pytest.mark.BAT @pytest.mark.assetpipeline - def test_WindowsAndMacPlatforms_AP_GUI_FastScanSettingCreated(self, asset_processor, fast_scan_backup): + def test_WindowsAndMacPlatforms_GUIFastScanNoSettingSet_FastScanSettingCreated(self, asset_processor, fast_scan_backup): """ Tests that a fast scan settings entry gets created for the AP if it does not exist and ensures that the entry is defaulted to fast-scan enabled + + Test Steps: + 1. Create temporary testing environment + 2. Delete existing fast scan setting if exists + 3. Run Asset Processor GUI without setting FastScan setting (default:true) and without quitonidle + 4. Wait and check to see if Windows Registry fast scan setting is created + 5. Verify that Fast Scan setting is set to true """ asset_processor.create_temp_asset_root() @@ -119,6 +126,14 @@ class TestsAssetProcessorGUI_WindowsAndMac(object): Make sure game launcher working with Asset Processor set to turbo mode Validate that no fatal errors (crashes) are reported within a certain time frame for the AP and the GameLauncher + + Test Steps: + 1. Create temporary testing environment + 2. Set fast scan to true + 3. Verify fast scan is set to true + 4. Launch game launcher + 5. Verify launcher has launched without error + 6. Verify that asset processor has launched """ CHECK_ALIVE_SECONDS = 15 @@ -166,6 +181,14 @@ class TestsAssetProcessorGUI_AllPlatforms(object): # fmt:on """ Deleting slices and uicanvases while AP is running + + Test Steps: + 1. Create temporary testing environment with test assets + 2. Launch Asset Processor and wait for it to go idle + 3. Verify product assets were created in the cache + 4. Delete test assets from the cache + 5. Wait for Asset Processor to go idle + 6. Verify product assets were regenerated in the cache """ env = ap_setup_fixture @@ -201,6 +224,15 @@ class TestsAssetProcessorGUI_AllPlatforms(object): ): """ Process slice files and uicanvas files from the additional scanfolder + + Test Steps: + 1. Create temporary testing environment + 2. Run asset processor batch + 3. Validate that product assets were generated in the cache + 4. Create an additional scan folder with assets + 5. Create additional scan folder params to pass to Asset Processor + 6. Run Asset Processor GUI with QuitOnIdle and pass in params for the additional scan folder settings + 7. Verify additional product assets from additional scan folder are present in the cache """ env = ap_setup_fixture # Copy test assets to new folder in dev folder @@ -250,6 +282,12 @@ class TestsAssetProcessorGUI_AllPlatforms(object): """ Launch AP with invalid address in bootstrap.cfg Assets should process regardless of the new address + + Test Steps: + 1. Create a temporary testing environment + 2. Set an invalid ip address in Asset Processor settings file + 3. Launch Asset Processor GUI + 4. Verify that it processes assets and exits cleanly even though it has an invalid IP. """ test_ip_address = "1.1.1.1" # an IP address without Asset Processor @@ -269,6 +307,14 @@ class TestsAssetProcessorGUI_AllPlatforms(object): def test_AllSupportedPlatforms_ModifyAssetInfo_AssetsReprocessed(self, ap_setup_fixture, asset_processor): """ Modifying assetinfo files triggers file reprocessing + + Test Steps: + 1. Create temporary testing environment with test assets + 2. Run Asset Processor GUI + 3. Verify that Asset Processor exited cleanly and product assets are in the cache + 4. Modify the .assetinfo file by adding a newline + 5. Wait for Asset Processor to go idle + 6. Verify that product files were regenerated (Time Stamp compare) """ env = ap_setup_fixture diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_relocator_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_relocator_tests.py index 2d3872bf31..30044fa9e2 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_relocator_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_relocator_tests.py @@ -85,6 +85,18 @@ class TestsAssetRelocator_WindowsAndMac(object): def test_WindowsMacPlatforms_RelocatorMoveFileWithConfirm_MoveSuccess(self, request, workspace, asset_processor, ap_setup_fixture, testId, readonly, confirm, success): + """ + Tests whether tests with Move File Confirm are successful + + Test Steps: + 1. Create temporary testing environment + 2. Set move location + 3. Determine if confirm flag is set + 4. Attempt to move the files + 5. If confirm flag set: + * Validate Move was successful + * Else: Validate move was not successful + """ env = ap_setup_fixture copied_asset = '' @@ -141,6 +153,11 @@ class TestsAssetRelocator_WindowsAndMac(object): User should be warned that LeaveEmptyFolders needs to be used with the move or delete command :return: None + + Test Steps: + 1. Create temporary testing environment + 2. Attempt to move with --LeaveEmptyFolders set + 3. Verify user is given a message that command requires to be used with --move or --delete """ env = ap_setup_fixture expected_message = "Command --leaveEmptyFolders must be used with command --move or --delete" @@ -162,6 +179,11 @@ class TestsAssetRelocator_WindowsAndMac(object): Asset with UUID/AssetId reference in non-standard format is successfully scanned and relocated to the MoveOutput folder. This test uses a pre-corrupted .slice file. + + Test Steps: + 1. Create temporary testing environment with a corrupted slice + 2. Attempt to move the corrupted slice + 3. Verify that corrupted slice was moved successfully """ env = ap_setup_fixture @@ -194,6 +216,11 @@ class TestsAssetRelocator_WindowsAndMac(object): def test_WindowsMacPlatforms_UpdateReferences_MoveCommandMessage(self, ap_setup_fixture, asset_processor): """ UpdateReferences without move or delete + + Test Steps: + 1. Create temporary testing environment + 2. Attempt to move with UpdateReferences but without move or delete flags + 3. Verify that message is returned to the user that additional flags are required """ env = ap_setup_fixture expected_message = "Command --updateReferences must be used with command --move" @@ -215,6 +242,11 @@ class TestsAssetRelocator_WindowsAndMac(object): """ When running the relocator command --AllowBrokenDependencies without the move or delete flags, the user should be warned that the flags are necessary for the functionality to be used + + Test Steps: + 1. Create temporary testing environment + 2. Attempt to move with AllowBrokenDependencies without the move or delete flag + 3. Verify that message is returned to the user that additional flags are required """ env = ap_setup_fixture @@ -302,10 +334,19 @@ class TestsAssetRelocator_WindowsAndMac(object): project ): """ + Dynamic data test for deleting a file with Asset Relocator: + C21968355 Delete a file with confirm C21968356 Delete a file without confirm C21968359 Delete a file that is marked as ReadOnly C21968360 Delete a file that is not marked as ReadOnly + + Test Steps: + 1. Create temporary testing environment + 2. Set the read-only status of the file based on the test case + 3. Run asset relocator with --delete and the confirm status based on the test case + 4. Assert file existence or nonexistence based on the test case + 5. Validate the relocation report based on expected and unexpected messages """ env = ap_setup_fixture test_file = "testFile.txt" @@ -430,6 +471,15 @@ class TestsAssetRelocator_WindowsAndMac(object): Test the LeaveEmptyFolders flag in various configurations :returns: None + + Test Steps: + 1. Create temporary testing environment + 2. Build the various move/delete commands here based on test data + 3. Run the move command with the various triggers based on test data + 4. Verify the original assets folder still exists based on test data + 5. Verify the files successfully moved to new location based on test data + 6. Verify that the files were removed from original location based on test data + 7. Verify the files have not been deleted or moved from original location based on test data """ # # Start test setup # # env = ap_setup_fixture @@ -517,6 +567,12 @@ class TestsAssetRelocator_WindowsAndMac(object): """ The test will attempt to move test assets that are not tracked under P4 source control using the EnableSCM flag Because the files are not tracked by source control, the relocation should fail + + Test Steps: + 1. Create temporary testing environment + 2. Set ReadOnly or Not-ReadOnly for the test files based on test data + 3. Generate and run the enableSCM command + 4. Verify the move failed and expected messages are present """ # Move the test assets into the project folder env = ap_setup_fixture @@ -1037,6 +1093,13 @@ class TestsAssetRelocator_WindowsAndMac(object): C21968370 AllowBrokenDependencies with move and confirm C21968371 AllowBrokenDependencies with move and without confirm C21968375 AllowBrokenDependencies with delete + + Test Steps: + 1. Create temporary testing environment + 2. Run Asset Processor to Process Assets + 3. Build primary AP Batch parameter value and destination paths + 4. Validate resulting file paths in source and output directories + 5. Validate the log based on expected and unexpected messages """ env = ap_setup_fixture all_test_asset_rel_paths = [ @@ -1254,6 +1317,18 @@ class TestsAssetRelocator_WindowsAndMac(object): @pytest.mark.parametrize("test", tests) def test_WindowsAndMac_MoveMetadataFiles_PathExistenceAndMessage(self, workspace, request, ap_setup_fixture, asset_processor, test): + """ + Tests whether moving metadata files can be moved + + Test Steps: + 1. Create temporary testing environment + 2. Determine if using wildcards on paths or not + 3. Determine if excludeMetaDataFiles is set or not + 4. Build primary AP Batch parameter value and destination paths + 5. Build and run the AP Batch command with parameters + 6. Validate resulting file paths in source and output directories + 7. Validate the log based on expected and unexpected messages + """ env = ap_setup_fixture def teardown(): @@ -1342,7 +1417,7 @@ class TestsAssetRelocator_WindowsAndMac(object): @dataclass class MoveTest: - description: str # test case title directly copied from Testrail + description: str # test case title asset_folder: str # which folder in ./assets will be used for this test encoded_command: str # the command to execute encoded_output_dir: str # the destination directory to validate @@ -1350,7 +1425,7 @@ class MoveTest: name_change_map: dict = None files_that_stay: List[str] = field(default_factory=lambda: []) output_messages: List[str] = field(default_factory=lambda: []) - step: str = None # the step of the test from Testrail + step: str = None # the step of the test from test repository prefix_commands: List[str] = field(default_factory=lambda: ["AssetProcessorBatch", "--zeroAnalysisMode"]) suffix_commands: List[str] = field(default_factory=lambda: ["--confirm"]) env: dict = field(init=False, default=None) # inject the ap_setup_fixture at runtime @@ -3718,7 +3793,18 @@ class TestsAssetProcessorMove_WindowsAndMac: # -k C19462747 @pytest.mark.parametrize("test", move_a_file_tests + move_a_folder_tests) - def test_WindowsMacPlatforms_MoveCommand(self, asset_processor, ap_setup_fixture, test: MoveTest, project): + def test_WindowsMacPlatforms_MoveCommand_CommandResult(self, asset_processor, ap_setup_fixture, test: MoveTest, project): + """ + + Test Steps: + 1. Create temporary testing environment based on test data + 2. Validate that temporary testing environment was created successfully + 3. Execute the move command based upon the test data + 4. Validate that files are where they're expected according to the test data + 5. Validate unexpected files are not found according to the test data + 6. Validate output messages according to the test data + 7. Validate move status according to the test data + """ source_folder, _ = asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], test.asset_folder) test.map_env(ap_setup_fixture, source_folder) diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py index 6cc3484d96..74f6de1129 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py @@ -75,6 +75,15 @@ class TestsMissingDependencies_WindowsAndMac(object): def do_missing_dependency_test(self, source_product, expected_dependencies, dsp_param, platforms=None, max_iterations=0): + """ + Test Steps: + 1. Determine what platforms to run against + 2. Process assets for that platform + 3. Determine the missing dependency params to set + 4. Set the max iteration param + 5. Run missing dependency scanner against target platforms and search params based on test data + 6. Validate missing dependencies against test data + """ platforms = platforms or ASSET_PROCESSOR_PLATFORM_MAP[self._workspace.asset_processor_platform] if not isinstance(platforms, list): @@ -84,10 +93,11 @@ class TestsMissingDependencies_WindowsAndMac(object): """Run a single test""" for asset_platform in platforms: - db_product = db_utils.get_product_id_from_relative(self._workspace, source_product, asset_platform) + db_product_path = db_utils.get_db_product_path(self._workspace, source_product, asset_platform) + db_product = db_utils.get_product_id(self._missing_dep_helper.asset_db, db_product_path) if db_product: db_utils.clear_missing_dependencies(self._missing_dep_helper.asset_db, db_product) - expected_product = os.path.join(self._workspace.project, source_product).lower() + expected_product = source_product.lower() dependency_search_params = [f"--dsp={dsp_param}", "--zeroAnalysisMode"] if max_iterations: @@ -103,7 +113,14 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_ValidUUIDNotDependency_ReportsMissingDependency(self): - """Tests that a valid UUID referenced in a file will report any missing dependencies""" + """ + Tests that a valid UUID referenced in a file will report any missing dependencies + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to the txt file with missing dependencies expected_product = f"testassets\\validuuidsnotdependency.txt" @@ -112,17 +129,26 @@ class TestsMissingDependencies_WindowsAndMac(object): # Expected missing dependencies expected_dependencies = [ # String Asset # - ("06E9D6633C875400A532BCB2C0CA19D6", "{06E9D663-3C87-5400-A532-BCB2C0CA19D6}:0"), - ("1CB10C43F3245B93A294C602ADEF95F9:[0", "{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0"), - ("58BE9DA51F1753B98CEEEEB10E63454D", "{58BE9DA5-1F17-53B9-8CEE-EEB10E63454D}:914f19b7"), - ("6BDE282B49C957F7B0714B26579BCA9A", "{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0"), - ("747D31D71E62553592226173C49CF97E", "{747D31D7-1E62-5535-9222-6173C49CF97E}:1"), - ("747D31D71E62553592226173C49CF97E", "{747D31D7-1E62-5535-9222-6173C49CF97E}:2"), - ("9886E132-572D-5746-9377-E629AB6C1981", "{9886E132-572D-5746-9377-E629AB6C1981}:0"), - ("33bcee02F3225688ABEE534F6058593F", "{33BCEE02-F322-5688-ABEE-534F6058593F}:0"), - ("B92667DC-9F5B-5D72-A29D-99219DD9B691", "{B92667DC-9F5B-5D72-A29D-99219DD9B691}:0"), - ("D92C4661C8985E19BD3597CB2318CFA6:[0", "{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0"), - ("7364AB2B092F5B0B80601BBC6E53087C", "{7364AB2B-092F-5B0B-8060-1BBC6E53087C}:0"), + ('1CB10C43F3245B93A294C602ADEF95F9:[0', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'), + ('33bcee02F3225688ABEE534F6058593F', '{33BCEE02-F322-5688-ABEE-534F6058593F}:0'), + ('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3e8'), + ('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3ea'), + ('345E5C660D6254FF8D0F7C8EE66A2249', '{345E5C66-0D62-54FF-8D0F-7C8EE66A2249}:3eb'), + ('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3e8'), + ('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3ea'), + ('37108522F50459499CD6C8D47A960CF1', '{37108522-F504-5949-9CD6-C8D47A960CF1}:3eb'), + ('6BDE282B49C957F7B0714B26579BCA9A', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'), + ('747D31D71E62553592226173C49CF97E', '{747D31D7-1E62-5535-9222-6173C49CF97E}:1'), + ('747D31D71E62553592226173C49CF97E', '{747D31D7-1E62-5535-9222-6173C49CF97E}:2'), + ('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3e8'), + ('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3ea'), + ('A26C73D1837E5AE59E68F916FA7C3699', '{A26C73D1-837E-5AE5-9E68-F916FA7C3699}:3eb'), + ('B076CDDC-14DF-50F4-A5E9-7518ABB3E851', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'), + ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3e8'), + ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3ea'), + ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3eb'), + ('C67BEA9F-09FF-59AA-A7F0-A52B8F987508', '{C67BEA9F-09FF-59AA-A7F0-A52B8F987508}:3ec'), + ('D92C4661C8985E19BD3597CB2318CFA6:[0', '{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0'), ] self.do_missing_dependency_test(expected_product, expected_dependencies, "%ValidUUIDsNotDependency.txt") @@ -131,7 +157,14 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_InvalidUUIDsNotDependencies_NoReportedMessage(self): - """Tests that invalid UUIDs do not count as missing dependencies""" + """ + Tests that invalid UUIDs do not count as missing dependencies + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to the txt file with invalid UUIDs expected_product = f"testassets\\invaliduuidnoreport.txt" expected_dependencies = [] # No expected missing dependencies @@ -143,7 +176,14 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_ValidAssetIdsNotDependencies_ReportsMissingDependency(self): - """Tests that valid asset IDs but not dependencies, show missing dependencies""" + """ + Tests that valid asset IDs but not dependencies, show missing dependencies + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to the txt file with valid asset ids but not dependencies expected_product = f"testassets\\validassetidnotdependency.txt" @@ -151,9 +191,9 @@ class TestsMissingDependencies_WindowsAndMac(object): # Expected missing dependencies expected_dependencies = [ # String Asset # - ("2ef92b8D044E5C278E2BB1AC0374A4E7:131072", "{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:20000"), - ("A2482826-053D-5634-A27B-084B1326AAE5}:[196608", "{A2482826-053D-5634-A27B-084B1326AAE5}:30000"), - ("D83B36F1-61A6-5001-B191-4D0CE282E236}-327680", "{D83B36F1-61A6-5001-B191-4D0CE282E236}:50000"), + ('2ef92b8D044E5C278E2BB1AC0374A4E7:1003', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3eb'), + ('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'), + ('D83B36F1-61A6-5001-B191-4D0CE282E236}-1002', '{D83B36F1-61A6-5001-B191-4D0CE282E236}:3ea'), ] self.do_missing_dependency_test(expected_product, expected_dependencies, @@ -163,7 +203,14 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_InvalidAssetsIDNotDependencies_NoReportedMessage(self): - """Tests that invalid asset IDs do not count as missing dependencies""" + """ + Tests that invalid asset IDs do not count as missing dependencies + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to the txt file with invalid asset IDs expected_product = f"testassets\\invalidassetidnoreport.txt" @@ -178,7 +225,14 @@ class TestsMissingDependencies_WindowsAndMac(object): # fmt:off def test_WindowsAndMac_ValidSourcePathsNotDependencies_ReportsMissingDependencies(self): # fmt:on - """Tests that valid source paths can translate to missing dependencies""" + """ + Tests that valid source paths can translate to missing dependencies + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to the txt file with missing dependencies as source paths expected_product = f"testassets\\relativesourcepathsnotdependencies.txt" @@ -186,16 +240,13 @@ class TestsMissingDependencies_WindowsAndMac(object): # Expected missing dependencies expected_dependencies = [ # String Asset # - ("Config/Editor.xml", "{06E9D663-3C87-5400-A532-BCB2C0CA19D6}:0"), - (r"TestAssets\WildcardScanTest1.txt", "{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0"), - ("TestAssets/RelativeProductPathsNotDependencies.txt", "{B772953C-A08A-5D20-9491-530E87D11504}:0"), - ("textures/_dev_Purple.tif", "{A2482826-053D-5634-A27B-084B1326AAE5}:0"), - ("textures/_dev_Purple.tif", "{A2482826-053D-5634-A27B-084B1326AAE5}:10000"), - ("textures/_dev_Purple.tif", "{A2482826-053D-5634-A27B-084B1326AAE5}:20000"), - ("textures/_dev_Purple.tif", "{A2482826-053D-5634-A27B-084B1326AAE5}:30000"), - ("textures/_dev_Purple.tif", "{A2482826-053D-5634-A27B-084B1326AAE5}:40000"), - ("textures/_dev_Purple.tif", "{A2482826-053D-5634-A27B-084B1326AAE5}:50000"), - ("Config/gAME.XML", "{B92667DC-9F5B-5D72-A29D-99219DD9B691}:0"), + ('TestAssets\\WildcardScanTest1.txt', '{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0'), + ('libs/particles/milestone2PARTICLES.XML', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'), + ('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3e8'), + ('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'), + ('textures/_dev_Purple.tif', '{A2482826-053D-5634-A27B-084B1326AAE5}:3eb'), + ('project.json', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'), + ('TestAssets/RelativeProductPathsNotDependencies.txt', '{B772953C-A08A-5D20-9491-530E87D11504}:0'), ] self.do_missing_dependency_test(expected_product, expected_dependencies, @@ -205,7 +256,14 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_InvalidARelativePathsNotDependencies_NoReportedMessage(self): - """Tests that invalid relative paths do not resolve to missing dependencies""" + """ + Tests that invalid relative paths do not resolve to missing dependencies + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to the txt file with invalid relative paths expected_product = f"testassets\\invalidrelativepathsnoreport.txt" @@ -220,7 +278,14 @@ class TestsMissingDependencies_WindowsAndMac(object): # fmt:off def test_WindowsAndMac_ValidProductPathsNotDependencies_ReportsMissingDependencies(self): # fmt:on - """Tests that valid product paths can resolve to missing dependencies""" + """ + Tests that valid product paths can resolve to missing dependencies + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ self._asset_processor.add_source_folder_assets(f"Gems\\LyShineExamples\\Assets\\UI\\Fonts\\LyShineExamples") self._asset_processor.add_scan_folder(f"Gems\\LyShineExamples\\Assets") @@ -228,24 +293,22 @@ class TestsMissingDependencies_WindowsAndMac(object): expected_product = f"testassets\\relativeproductpathsnotdependencies.txt" expected_dependencies = [ # String Asset # - ("materials/floor_tile.mtl", "{0EFF5E4A-F544-5D87-8696-6DDFA62D6063}:0"), - ("materials/am_grass1.mtl", "{1151F14D-38A6-5579-888A-BE3139882E68}:0"), - ("2ef92b8D044E5C278E2BB1AC0374A4E7:131072", "{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:20000"), - ("ui/milestone2menu.uicanvas", "{445D9AF3-6CA5-5281-82A9-5C570BCD1DB8}:0"), - ("ui/fonts/lyshineexamples/vera.ttf", "{74F5C29E-4749-5EE8-AEC6-A1C540600CE7}:0"), - ("materials/am_rockground.mtl", "{A1DA3D05-A020-5BB5-A608-C4812B7BD733}:0"), - ("textures/_dev_yellow_light.dds.2", "{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:20000"), - (r"automatedtesting\textures\_dev_stucco.dds", "{70114D85-D712-5AEB-A816-8FE3A37087AF}:0"), - ("textures/milestone2/ama_grey_02.dds", "{3EE80AAD-EB9C-56BD-9E9C-65410578998C}:0"), - (r"textures\\_dev_tan.dds", "{8F2BCEF5-C8CE-5B80-8103-8C1D694D012C}:0"), - ("textures/_dev_purple.dds", "{A2482826-053D-5634-A27B-084B1326AAE5}:0"), - ("TEXTURES/_DEV_WHITE.dds", "{D83B36F1-61A6-5001-B191-4D0CE282E236}:0"), - ("textures/_dev_woodland.dds", "{F3DD193C-5845-569C-A974-AA338B30CF86}:0"), - ("A2482826-053D-5634-A27B-084B1326AAE5}:[196608", "{A2482826-053D-5634-A27B-084B1326AAE5}:30000"), - ("B92667DC-9F5B-5D72-A29D-99219DD9B691", "{B92667DC-9F5B-5D72-A29D-99219DD9B691}:0"), - ("CEAA362B4E505BCEB827CB92EF40A50E", "{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:1"), - ("CEAA362B4E505BCEB827CB92EF40A50E", "{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:2"), - ("ui/fonts/lyshineexamples/veramono.ttf", "{BAD7FDC5-7BA6-5490-95AA-89078E2FA876}:0"), + ('materials/floor_tile.mtl', '{0EFF5E4A-F544-5D87-8696-6DDFA62D6063}:0'), + ('materials/am_grass1.mtl', '{1151F14D-38A6-5579-888A-BE3139882E68}:0'), + ('2ef92b8D044E5C278E2BB1AC0374A4E7:1002', '{2EF92B8D-044E-5C27-8E2B-B1AC0374A4E7}:3ea'), + ('textures/milestone2/ama_grey_02.tif.streamingimage', '{3EE80AAD-EB9C-56BD-9E9C-65410578998C}:3e8'), + ('ui/milestone2menu.uicanvas', '{445D9AF3-6CA5-5281-82A9-5C570BCD1DB8}:0'), + ('libs/particles/milestone2particles.xml', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'), + ('textures/_dev_yellow_light.tif.1002.imagemipchain', '{6C40868F-3FC1-5115-96EA-DD0A9E33DEE4}:3ea'), + ('textures\\\\_dev_tan.tif.streamingimage', '{8F2BCEF5-C8CE-5B80-8103-8C1D694D012C}:3e8'), + ('materials/am_rockground.mtl', '{A1DA3D05-A020-5BB5-A608-C4812B7BD733}:0'), + ('textures/_dev_purple.tif.streamingimage', '{A2482826-053D-5634-A27B-084B1326AAE5}:3e8'), + ('A2482826-053D-5634-A27B-084B1326AAE5}:[1002', '{A2482826-053D-5634-A27B-084B1326AAE5}:3ea'), + ('project.json', '{B076CDDC-14DF-50F4-A5E9-7518ABB3E851}:0'), + ('CEAA362B4E505BCEB827CB92EF40A50E', '{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:1'), + ('CEAA362B4E505BCEB827CB92EF40A50E', '{CEAA362B-4E50-5BCE-B827-CB92EF40A50E}:2'), + ('TEXTURES/_DEV_WHITE.tif.streamingimage', '{D83B36F1-61A6-5001-B191-4D0CE282E236}:3e8'), + ('textures/_dev_woodland.tif.streamingimage', '{F3DD193C-5845-569C-A974-AA338B30CF86}:3e8'), ] self.do_missing_dependency_test(expected_product, expected_dependencies, @@ -255,13 +318,20 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_WildcardScan_FindsAllExpectedFiles(self): - """Tests that the wildcard scanning will pick up multiple files""" + """ + Tests that the wildcard scanning will pick up multiple files + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ helper = self._missing_dep_helper # Relative paths to the txt file with no missing dependencies - expected_product_1 = f"{self._workspace.project}\\testassets\\wildcardscantest1.txt" - expected_product_2 = f"{self._workspace.project}\\testassets\\wildcardscantest2.txt" + expected_product_1 = f"testassets\\wildcardscantest1.txt" + expected_product_2 = f"testassets\\wildcardscantest2.txt" expected_dependencies = [] # Neither file has expected missing dependencies # Run missing dependency scanner and validate results for both files @@ -286,21 +356,33 @@ class TestsMissingDependencies_WindowsAndMac(object): For these references that are valid, all but one have available, matching dependencies. This test is primarily meant to verify that the missing dependency reporter checks the product dependency table before emitting missing dependencies. + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test """ # Relative path to target test file - expected_product = f"testassets\\dependencyscannerasset.dynamicslice" + expected_product = f"testassets\\reportonemissingdependency.txt" # The only expected missing dependency - expected_dependencies = [("Config/Game.xml", "{B92667DC-9F5B-5D72-A29D-99219DD9B691}:0")] + expected_dependencies = [('6BDE282B49C957F7B0714B26579BCA9A', '{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0'),] self.do_missing_dependency_test(expected_product, expected_dependencies, - "%DependencyScannerAsset%.dynamicslice") + "%reportonemissingdependency.txt") @pytest.mark.BAT @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_ReferencesSelfPath_NoReportedMessage(self): - """Tests that a file that references itself via relative path does not report itself as a missing dependency""" + """ + Tests that a file that references itself via relative path does not report itself as a missing dependency + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to file that references itself via relative path expected_product = f"testassets\\selfreferencepath.txt" expected_dependencies = [] @@ -312,7 +394,14 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_ReferencesSelfUUID_NoReportedMessage(self): - """Tests that a file that references itself via its UUID does not report itself as a missing dependency""" + """ + Tests that a file that references itself via its UUID does not report itself as a missing dependency + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to file that references itself via its UUID expected_product = f"testassets\\selfreferenceuuid.txt" @@ -325,7 +414,14 @@ class TestsMissingDependencies_WindowsAndMac(object): @pytest.mark.assetpipeline @pytest.mark.test_case_id("C17226567") def test_WindowsAndMac_ReferencesSelfAssetID_NoReportedMessage(self): - """Tests that a file that references itself via its Asset ID does not report itself as a missing dependency""" + """ + Tests that a file that references itself via its Asset ID does not report itself as a missing dependency + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to file that references itself via its Asset ID expected_product = f"testassets\\selfreferenceassetid.txt" @@ -342,6 +438,11 @@ class TestsMissingDependencies_WindowsAndMac(object): Tests that the scan limit fails to find a missing dependency that is out of reach. The max iteration count is set to just under where a valid missing dependency is on a line in the file, so this will not report any missing dependencies. + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test """ # Relative path to file that has a missing dependency at 31 iterations deep @@ -359,14 +460,20 @@ class TestsMissingDependencies_WindowsAndMac(object): Tests that the scan limit succeeds in finding a missing dependency that is barely in reach. In the previous test, the scanner was set to stop recursion just before a missing dependency was found. This test runs with the recursion limit set deep enough to actually find the missing dependency. + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test """ + # Relative path to file that has a missing dependency at 31 iterations deep expected_product = f"testassets\\maxiteration31deep.txt" # Expected missing dependency hiding 31 dependencies deep expected_dependencies = [ # String Asset # - ("B92667DC-9F5B-5D72-A29D-99219DD9B691", "{B92667DC-9F5B-5D72-A29D-99219DD9B691}:0") + ("6BDE282B-49C9-57F7-B071-4B26579BCA9A", "{6BDE282B-49C9-57F7-B071-4B26579BCA9A}:0") ] self.do_missing_dependency_test(expected_product, expected_dependencies, @@ -378,7 +485,14 @@ class TestsMissingDependencies_WindowsAndMac(object): # fmt:off def test_WindowsAndMac_PotentialMatchesLongerThanUUIDString_OnlyReportsCorrectLengthUUIDs(self): # fmt:on - """Tests that dependency references that are longer than expected are ignored""" + """ + Tests that dependency references that are longer than expected are ignored + + Test Steps: + 1. Set the expected product + 2. Set the expected missing dependencies + 3. Execute test + """ # Relative path to text file with varying length UUID references expected_product = f"testassets\\onlymatchescorrectlengthuuids.txt" @@ -386,11 +500,11 @@ class TestsMissingDependencies_WindowsAndMac(object): # Expected dependencies with valid lengths from file expected_dependencies = [ # String Asset # - ("D92C4661C8985E19BD3597CB2318CFA6", "{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0"), - ("58BE9DA51F1753B98CEEEEB10E63454D", "{58BE9DA5-1F17-53B9-8CEE-EEB10E63454D}:914f19b7"), - ("747D31D71E62553592226173C49CF97E", "{747D31D7-1E62-5535-9222-6173C49CF97E}:1"), - ("747D31D71E62553592226173C49CF97E", "{747D31D7-1E62-5535-9222-6173C49CF97E}:2"), - ("1CB10C43-F324-5B93-A294-C602ADEF95F9", "{1CB10C43-F324-5B93-A294-C602ADEF95F9}:0"), + ('D1265251CC14584AB1CECB10746A2BA0', '{D1265251-CC14-584A-B1CE-CB10746A2BA0}:2'), + ('D1265251CC14584AB1CECB10746A2BA0', '{D1265251-CC14-584A-B1CE-CB10746A2BA0}:1'), + ('D92C4661C8985E19BD3597CB2318CFA6', '{D92C4661-C898-5E19-BD35-97CB2318CFA6}:0'), + ('837412DFD05F576D81AAACF360463749', '{837412DF-D05F-576D-81AA-ACF360463749}:0'), + ('785A05D2483E5B43A2B992ACDAE6E938', '{785A05D2-483E-5B43-A2B9-92ACDAE6E938}:0'), ] self.do_missing_dependency_test( expected_product, expected_dependencies, @@ -403,7 +517,14 @@ class TestsMissingDependencies_WindowsAndMac(object): def test_WindowsAndMac_MissingDependencyScanner_GradImageSuccess( self, ap_setup_fixture ): - """Tests the Missing Dependency Scanner can scan gradimage files""" + """ + Tests the Missing Dependency Scanner can scan gradimage files + + Test Steps: + 1. Create temporary testing environment + 2. Run the move dependency scanner against the gradimage + 2. Validate that the expected product files and and expected depdencies match + """ env = ap_setup_fixture helper = self._missing_dep_helper diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/auxiliary_content_tests/auxiliary_content_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/auxiliary_content_tests/auxiliary_content_tests.py index 7e9f65de60..452dc66352 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/auxiliary_content_tests/auxiliary_content_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/auxiliary_content_tests/auxiliary_content_tests.py @@ -51,6 +51,11 @@ class TestAuxiliaryContent: def test_CreateAuxiliaryContent_DontSkipLevelPaks(self, workspace, level): """ This test ensure that Auxiliary Content contain level.pak files + + Test Steps: + 1. Run auxiliary content against project under test + 2. Validate auxiliary content exists + 3. Verifies that level.pak exists """ path_to_dev = workspace.paths.engine_root() @@ -70,6 +75,11 @@ class TestAuxiliaryContent: def test_CreateAuxiliaryContent_SkipLevelPaks(self, workspace, level): """ This test ensure that Auxiliary Content contain no level.pak file + + Test Steps: + 1. Run auxiliary content against project under test with skiplevelPaks flag + 2. Validate auxiliary content exists + 3. Validate level.pak was added to auxiliary content """ path_to_dev = workspace.paths.engine_root() diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py index b66984666b..afd7190c1b 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py @@ -533,6 +533,14 @@ class TestsFBX_AllPlatforms(object): def test_FBXBlackboxTest_SourceFiles_Processed_ResultInExpectedProducts(self, workspace, ap_setup_fixture, asset_processor, project, blackbox_param): + """ + Please see run_fbx_test(...) for details + + Test Steps: + 1. Determine if blackbox is set to none + 2. Run FBX Test + """ + if blackbox_param == None: return self.run_fbx_test(workspace, ap_setup_fixture, @@ -544,6 +552,15 @@ class TestsFBX_AllPlatforms(object): workspace, ap_setup_fixture, asset_processor, project, blackbox_param): + """ + Please see run_fbx_test(...) for details + + Test Steps: + 1. Determine if blackbox is set to none + 2. Run FBX Test + 2. Re-run FBX test and validate the information in override assets + """ + if blackbox_param == None: return self.run_fbx_test(workspace, ap_setup_fixture, @@ -567,6 +584,19 @@ class TestsFBX_AllPlatforms(object): def run_fbx_test(self, workspace, ap_setup_fixture, asset_processor, project, blackbox_params: BlackboxAssetTest, overrideAsset = False): + """ + These tests work by having the test case ingest the test data and determine the run pattern. + Tests will process scene settings files and will additionally do a verification against a provided debug file + Additionally, if an override is passed, the output is checked against the override. + + Test Steps: + 1. Create temporary test environment + 2. Process Assets + 3. Determine what assets to validate based upon test data + 4. Validate assets were created in cache + 5. If debug file provided, verify scene files were generated correctly + 6. Verify that each given source asset resulted in the expected jobs and products + """ test_assets_folder = blackbox_params.override_asset_folder if overrideAsset else blackbox_params.asset_folder logger.info(f"{blackbox_params.test_name}: Processing assets in folder '" diff --git a/AutomatedTesting/Gem/PythonTests/assetpipeline/wwise_bank_dependency_tests/bank_info_parser_tests.py b/AutomatedTesting/Gem/PythonTests/assetpipeline/wwise_bank_dependency_tests/bank_info_parser_tests.py index 0db13bf53c..764b7723bf 100755 --- a/AutomatedTesting/Gem/PythonTests/assetpipeline/wwise_bank_dependency_tests/bank_info_parser_tests.py +++ b/AutomatedTesting/Gem/PythonTests/assetpipeline/wwise_bank_dependency_tests/bank_info_parser_tests.py @@ -26,6 +26,18 @@ def soundbank_metadata_generator_setup_fixture(workspace): def success_case_test(test_folder, expected_dependencies_dict, bank_info, expected_result_code=0): + """ + Test Steps: + 1. Make sure the return code is what was expected, and that the expected number of banks were returned. + 2. Validate bank is in the expected dependencies dictionary. + 3. Validate the path to output the metadata file to was assembled correctly. + 4. Validate metadata object for this bank is set, and that it has an object assigned to its dependencies field + and its includedEvents field + 5. Validate metadata object has the correct number of dependencies, and validated that every expected dependency + exists in the dependencies list of the metadata object. + 6. Validate metadata object has the correct number of events, and validate that every expected event exists in the + events of the metadata object. + """ expected_bank_count = len(expected_dependencies_dict) banks, result_code = bank_info.generate_metadata( @@ -80,8 +92,17 @@ class TestSoundBankMetadataGenerator: def test_NoMetadataTooFewBanks_ReturnCodeIsError(self, workspace, soundbank_metadata_generator_setup_fixture): - # Trying to generate metadata for banks in a folder with one or fewer banks and no metadata is not possible - # and should fail. + """ + Trying to generate metadata for banks in a folder with one or fewer banks and no metadata is not possible + and should fail. + + Test Steps: + 1. Setup testing environment with only 1 bank file + 2. Get Sound Bank Info + 3. Attempt to generate sound bank metadata + 4. Verify that proper error code is returned + """ + # test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_NoMetadataTooFewBanks_ReturnCodeIsError') if not os.path.isdir(test_assets_folder): @@ -97,15 +118,30 @@ class TestSoundBankMetadataGenerator: assert error_code is 2, 'Metadata was generated when there were fewer than two banks in the target directory.' def test_NoMetadataNoContentBank_NoMetadataGenerated(self, workspace, soundbank_metadata_generator_setup_fixture): + """ + Test Steps: + 1. Setup testing environment + 2. No expected dependencies + 3. Call success case test + """ test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_NoMetadataNoContentBank_NoMetadataGenerated') expected_dependencies = dict() success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_NoMetadataOneContentBank_NoStreamedFiles_OneDependency(self, workspace, soundbank_metadata_generator_setup_fixture): - # When no Wwise metadata is present, and there is only one content bank in the target directory with no wem - # files, then only the content bank should have metadata associated with it. The generated metadata should - # only describe a dependency on the init bank. + """ + When no Wwise metadata is present, and there is only one content bank in the target directory with no wem + files, then only the content bank should have metadata associated with it. The generated metadata should + only describe a dependency on the init bank. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_NoMetadataOneContentBank_NoStreamedFiles_OneDependency') @@ -116,9 +152,18 @@ class TestSoundBankMetadataGenerator: def test_NoMetadataOneContentBank_StreamedFiles_MultipleDependencies(self, workspace, soundbank_metadata_generator_setup_fixture): - # When no Wwise metadata is present, and there is only one content bank in the target directory with wem files - # present, then only the content bank should have metadata associated with it. The generated metadata should - # describe a dependency on the init bank and all wem files in the folder. + """ + When no Wwise metadata is present, and there is only one content bank in the target directory with wem files + present, then only the content bank should have metadata associated with it. The generated metadata should + describe a dependency on the init bank and all wem files in the folder. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_NoMetadataOneContentBank_StreamedFiles_MultipleDependencies') @@ -136,10 +181,19 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_NoMetadataMultipleBanks_OneDependency_ReturnCodeIsWarning(self, workspace, soundbank_metadata_generator_setup_fixture): - # When no Wwise metadata is present, and there are multiple content banks in the target directory with wem files - # present, there is no way to tell which bank requires which wem files. A warning should be emitted, - # stating that the full dependency graph could not be created, and only dependencies on the init bank are - # described in the generated metadata files. + """ + When no Wwise metadata is present, and there are multiple content banks in the target directory with wem files + present, there is no way to tell which bank requires which wem files. A warning should be emitted, + stating that the full dependency graph could not be created, and only dependencies on the init bank are + described in the generated metadata files. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_NoMetadataMultipleBanks_OneDependency_ReturnCodeIsWarning') bank_info = get_bank_info(workspace) @@ -150,8 +204,17 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace), expected_result_code=1) def test_OneContentBank_NoStreamedFiles_OneDependency(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes one content bank that contains all media needed by its events. Generated metadata - # describes a dependency only on the init bank. + """ + Wwise metadata describes one content bank that contains all media needed by its events. Generated metadata + describes a dependency only on the init bank. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_OneContentBank_NoStreamedFiles_OneDependency') @@ -165,8 +228,17 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_OneContentBank_StreamedFiles_MultipleDependencies(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes one content bank that references streamed media files needed by its events. Generated - # metadata describes dependencies on the init bank and wems named by the IDs of referenced streamed media. + """ + Wwise metadata describes one content bank that references streamed media files needed by its events. Generated + metadata describes dependencies on the init bank and wems named by the IDs of referenced streamed media. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_OneContentBank_StreamedFiles_MultipleDependencies') @@ -187,8 +259,17 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_MultipleContentBanks_NoStreamedFiles_OneDependency(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes multiple content banks. Each bank contains all media needed by its events. Generated - # metadata describes each bank having a dependency only on the init bank. + """ + Wwise metadata describes multiple content banks. Each bank contains all media needed by its events. Generated + metadata describes each bank having a dependency only on the init bank. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_MultipleContentBanks_NoStreamedFiles_OneDependency') @@ -206,8 +287,17 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_MultipleContentBanks_Bank1StreamedFiles(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes multiple content banks. Bank 1 references streamed media files needed by its events, - # while bank 2 contains all media need by its events. + """ + Wwise metadata describes multiple content banks. Bank 1 references streamed media files needed by its events, + while bank 2 contains all media need by its events. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_MultipleContentBanks_Bank1StreamedFiles') @@ -228,9 +318,18 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_MultipleContentBanks_SplitBanks_OnlyBankDependenices(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes multiple content banks. Bank 3 events require media that is contained in bank 4. - # Generated metadata describes each bank having a dependency on the init bank, while bank 3 has an additional - # dependency on bank 4. + """ + Wwise metadata describes multiple content banks. Bank 3 events require media that is contained in bank 4. + Generated metadata describes each bank having a dependency on the init bank, while bank 3 has an additional + dependency on bank 4. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_MultipleContentBanks_SplitBanks_OnlyBankDependenices') @@ -248,9 +347,18 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_MultipleContentBanks_ReferencedEvent_MediaEmbeddedInBank(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes multiple content banks. Bank 1 contains all media required by its events, while bank - # 5 contains a reference to an event in bank 1, but no media for that event. Generated metadata describes both - # banks having a dependency on the init bank, while bank 5 has an additional dependency on bank 1. + """ + Wwise metadata describes multiple content banks. Bank 1 contains all media required by its events, while bank + 5 contains a reference to an event in bank 1, but no media for that event. Generated metadata describes both + banks having a dependency on the init bank, while bank 5 has an additional dependency on bank 1. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_MultipleContentBanks_ReferencedEvent_MediaEmbeddedInBank') @@ -271,10 +379,19 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_MultipleContentBanks_ReferencedEvent_MediaStreamed(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes multiple content banks. Bank 1 references streamed media files needed by its events, - # while bank 5 contains a reference to an event in bank 1. This causes bank 5 to also describe a reference to - # the streamed media file referenced by the event from bank 1. Generated metadata describes both banks having - # dependencies on the init bank, as well as the wem named by the ID of referenced streamed media. + """ + Wwise metadata describes multiple content banks. Bank 1 references streamed media files needed by its events, + while bank 5 contains a reference to an event in bank 1. This causes bank 5 to also describe a reference to + the streamed media file referenced by the event from bank 1. Generated metadata describes both banks having + dependencies on the init bank, as well as the wem named by the ID of referenced streamed media. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_MultipleContentBanks_ReferencedEvent_MediaStreamed') @@ -298,11 +415,20 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_MultipleContentBanks_ReferencedEvent_MixedSources(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes multiple content banks. Bank 1 references a streamed media files needed by one of its - # events, and contains all media needed for its other events, while bank 5 contains a reference to two events - # in bank 1: one that requires streamed media, and one that requires media embedded in bank 1. Generated - # metadata describes both banks having dependencies on the init bank and the wem named by the ID of referenced - # streamed media, while bank 5 has an additional dependency on bank 1. + """ + Wwise metadata describes multiple content banks. Bank 1 references a streamed media files needed by one of its + events, and contains all media needed for its other events, while bank 5 contains a reference to two events + in bank 1: one that requires streamed media, and one that requires media embedded in bank 1. Generated + metadata describes both banks having dependencies on the init bank and the wem named by the ID of referenced + streamed media, while bank 5 has an additional dependency on bank 1. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_MultipleContentBanks_ReferencedEvent_MixedSources') @@ -332,8 +458,17 @@ class TestSoundBankMetadataGenerator: success_case_test(test_assets_folder, expected_dependencies, get_bank_info(workspace)) def test_MultipleContentBanks_VaryingDependencies_MixedSources(self, workspace, soundbank_metadata_generator_setup_fixture): - # Wwise metadata describes multiple content banks that have varying dependencies on each other, and dependencies - # on streamed media files. + """ + Wwise metadata describes multiple content banks that have varying dependencies on each other, and dependencies + on streamed media files. + + Test Steps: + 1. Setup testing environment + 2. Get current bank info + 3. Build expected dependencies + 4. Call success case test + """ + test_assets_folder = os.path.join(soundbank_metadata_generator_setup_fixture['tests_dir'], 'assets', 'test_MultipleContentBanks_VaryingDependencies_MixedSources') diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt index 7ffc2072f1..91228bc71c 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/CMakeLists.txt @@ -20,7 +20,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT TEST_SUITE main PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_MainSuite.py TEST_SERIAL - TIMEOUT 300 + TIMEOUT 400 RUNTIME_DEPENDENCIES AssetProcessor AutomatedTesting.Assets @@ -31,7 +31,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedT TEST_SUITE sandbox PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_SandboxSuite.py TEST_SERIAL - TIMEOUT 300 + TIMEOUT 400 RUNTIME_DEPENDENCIES AssetProcessor AutomatedTesting.Assets diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py index e701ff8d16..35eaa2e4ce 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_AtomEditorComponents_AddedToEntity.py @@ -77,10 +77,10 @@ def run(): def verify_enter_exit_game_mode(component_name): general.enter_game_mode() - TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 1.0) + TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 2.0) general.log(f"{component_name}_test: Entered game mode: {general.is_in_game_mode()}") general.exit_game_mode() - TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 1.0) + TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 2.0) general.log(f"{component_name}_test: Exit game mode: {not general.is_in_game_mode()}") def verify_hide_unhide_entity(component_name, entity_obj): @@ -97,16 +97,16 @@ def run(): def verify_deletion_undo_redo(component_name, entity_obj): editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", entity_obj.id) - TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.0) + TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 2.0) general.log(f"{component_name}_test: Entity deleted: {not hydra.find_entity_by_name(entity_obj.name)}") general.undo() - TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 1.0) + TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 2.0) general.log(f"{component_name}_test: UNDO entity deletion works: " f"{hydra.find_entity_by_name(entity_obj.name) is not None}") general.redo() - TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.0) + TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 2.0) general.log(f"{component_name}_test: REDO entity deletion works: " f"{not hydra.find_entity_by_name(entity_obj.name)}") @@ -120,7 +120,7 @@ def run(): f"{not is_component_enabled(entity_obj.components[0])}") for component in components_to_add: entity_obj.add_component(component) - TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 1.0) + TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 2.0) general.log( f"{component_name}_test: Entity enabled after adding " f"required components: {is_component_enabled(entity_obj.components[0])}" diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py index aafa2ff9b7..fccd750573 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py @@ -18,7 +18,7 @@ import pytest import editor_python_test_tools.hydra_test_utils as hydra logger = logging.getLogger(__name__) -EDITOR_TIMEOUT = 120 +EDITOR_TIMEOUT = 300 TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") @@ -26,7 +26,161 @@ TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("level", ["auto_test"]) class TestAtomEditorComponentsMain(object): + """Holds tests for Atom components.""" - # It requires at least one test - def test_Dummy(self, request, editor, level, workspace, project, launcher_platform): - pass + def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform): + """ + Please review the hydra script run by this test for more specific test info. + Tests the following Atom components and verifies all "expected_lines" appear in Editor.log: + 1. Display Mapper + 2. Light + 3. Radius Weight Modifier + 4. PostFX Layer + 5. Physical Sky + 6. Global Skylight (IBL) + 7. Exposure Control + 8. Directional Light + 9. DepthOfField + 10. Decal (Atom) + """ + cfg_args = [level] + + expected_lines = [ + # Decal (Atom) Component + "Decal (Atom) Entity successfully created", + "Decal (Atom)_test: Component added to the entity: True", + "Decal (Atom)_test: Component removed after UNDO: True", + "Decal (Atom)_test: Component added after REDO: True", + "Decal (Atom)_test: Entered game mode: True", + "Decal (Atom)_test: Exit game mode: True", + "Decal (Atom) Controller|Configuration|Material: SUCCESS", + "Decal (Atom)_test: Entity is hidden: True", + "Decal (Atom)_test: Entity is shown: True", + "Decal (Atom)_test: Entity deleted: True", + "Decal (Atom)_test: UNDO entity deletion works: True", + "Decal (Atom)_test: REDO entity deletion works: True", + # DepthOfField Component + "DepthOfField Entity successfully created", + "DepthOfField_test: Component added to the entity: True", + "DepthOfField_test: Component removed after UNDO: True", + "DepthOfField_test: Component added after REDO: True", + "DepthOfField_test: Entered game mode: True", + "DepthOfField_test: Exit game mode: True", + "DepthOfField_test: Entity disabled initially: True", + "DepthOfField_test: Entity enabled after adding required components: True", + "DepthOfField Controller|Configuration|Camera Entity: SUCCESS", + "DepthOfField_test: Entity is hidden: True", + "DepthOfField_test: Entity is shown: True", + "DepthOfField_test: Entity deleted: True", + "DepthOfField_test: UNDO entity deletion works: True", + "DepthOfField_test: REDO entity deletion works: True", + # Exposure Control Component + "Exposure Control Entity successfully created", + "Exposure Control_test: Component added to the entity: True", + "Exposure Control_test: Component removed after UNDO: True", + "Exposure Control_test: Component added after REDO: True", + "Exposure Control_test: Entered game mode: True", + "Exposure Control_test: Exit game mode: True", + "Exposure Control_test: Entity disabled initially: True", + "Exposure Control_test: Entity enabled after adding required components: True", + "Exposure Control_test: Entity is hidden: True", + "Exposure Control_test: Entity is shown: True", + "Exposure Control_test: Entity deleted: True", + "Exposure Control_test: UNDO entity deletion works: True", + "Exposure Control_test: REDO entity deletion works: True", + # Global Skylight (IBL) Component + "Global Skylight (IBL) Entity successfully created", + "Global Skylight (IBL)_test: Component added to the entity: True", + "Global Skylight (IBL)_test: Component removed after UNDO: True", + "Global Skylight (IBL)_test: Component added after REDO: True", + "Global Skylight (IBL)_test: Entered game mode: True", + "Global Skylight (IBL)_test: Exit game mode: True", + "Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS", + "Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS", + "Global Skylight (IBL)_test: Entity is hidden: True", + "Global Skylight (IBL)_test: Entity is shown: True", + "Global Skylight (IBL)_test: Entity deleted: True", + "Global Skylight (IBL)_test: UNDO entity deletion works: True", + "Global Skylight (IBL)_test: REDO entity deletion works: True", + # Physical Sky Component + "Physical Sky Entity successfully created", + "Physical Sky component was added to entity", + "Entity has a Physical Sky component", + "Physical Sky_test: Component added to the entity: True", + "Physical Sky_test: Component removed after UNDO: True", + "Physical Sky_test: Component added after REDO: True", + "Physical Sky_test: Entered game mode: True", + "Physical Sky_test: Exit game mode: True", + "Physical Sky_test: Entity is hidden: True", + "Physical Sky_test: Entity is shown: True", + "Physical Sky_test: Entity deleted: True", + "Physical Sky_test: UNDO entity deletion works: True", + "Physical Sky_test: REDO entity deletion works: True", + # PostFX Layer Component + "PostFX Layer Entity successfully created", + "PostFX Layer_test: Component added to the entity: True", + "PostFX Layer_test: Component removed after UNDO: True", + "PostFX Layer_test: Component added after REDO: True", + "PostFX Layer_test: Entered game mode: True", + "PostFX Layer_test: Exit game mode: True", + "PostFX Layer_test: Entity is hidden: True", + "PostFX Layer_test: Entity is shown: True", + "PostFX Layer_test: Entity deleted: True", + "PostFX Layer_test: UNDO entity deletion works: True", + "PostFX Layer_test: REDO entity deletion works: True", + # Radius Weight Modifier Component + "Radius Weight Modifier Entity successfully created", + "Radius Weight Modifier_test: Component added to the entity: True", + "Radius Weight Modifier_test: Component removed after UNDO: True", + "Radius Weight Modifier_test: Component added after REDO: True", + "Radius Weight Modifier_test: Entered game mode: True", + "Radius Weight Modifier_test: Exit game mode: True", + "Radius Weight Modifier_test: Entity is hidden: True", + "Radius Weight Modifier_test: Entity is shown: True", + "Radius Weight Modifier_test: Entity deleted: True", + "Radius Weight Modifier_test: UNDO entity deletion works: True", + "Radius Weight Modifier_test: REDO entity deletion works: True", + # Light Component + "Light Entity successfully created", + "Light_test: Component added to the entity: True", + "Light_test: Component removed after UNDO: True", + "Light_test: Component added after REDO: True", + "Light_test: Entered game mode: True", + "Light_test: Exit game mode: True", + "Light_test: Entity is hidden: True", + "Light_test: Entity is shown: True", + "Light_test: Entity deleted: True", + "Light_test: UNDO entity deletion works: True", + "Light_test: REDO entity deletion works: True", + # Display Mapper Component + "Display Mapper Entity successfully created", + "Display Mapper_test: Component added to the entity: True", + "Display Mapper_test: Component removed after UNDO: True", + "Display Mapper_test: Component added after REDO: True", + "Display Mapper_test: Entered game mode: True", + "Display Mapper_test: Exit game mode: True", + "Display Mapper_test: Entity is hidden: True", + "Display Mapper_test: Entity is shown: True", + "Display Mapper_test: Entity deleted: True", + "Display Mapper_test: UNDO entity deletion works: True", + "Display Mapper_test: REDO entity deletion works: True", + ] + + unexpected_lines = [ + "Trace::Assert", + "Trace::Error", + "Traceback (most recent call last):", + ] + + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "hydra_AtomEditorComponents_AddedToEntity.py", + timeout=EDITOR_TIMEOUT, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + null_renderer=True, + cfg_args=cfg_args, + ) diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py index 8ca5b5aa31..0fb873e677 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_SandboxSuite.py @@ -19,170 +19,6 @@ import pytest @pytest.mark.parametrize("level", ["auto_test"]) class TestAtomEditorComponentsSandbox(object): - @pytest.mark.test_case_id( - "C32078117", # Area Light - "C32078130", # Display Mapper - "C32078129", # Light - "C32078131", # Radius Weight Modifier - "C32078127", # PostFX Layer - "C32078126", # Point Light - "C32078125", # Physical Sky - "C32078115", # Global Skylight (IBL) - "C32078121", # Exposure Control - "C32078120", # Directional Light - "C32078119", # DepthOfField - "C32078118") # Decal - def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform): - cfg_args = [level] - - expected_lines = [ - # Decal Component - "Decal (Atom) Entity successfully created", - "Decal (Atom)_test: Component added to the entity: True", - "Decal (Atom)_test: Component removed after UNDO: True", - "Decal (Atom)_test: Component added after REDO: True", - "Decal (Atom)_test: Entered game mode: True", - "Decal (Atom)_test: Exit game mode: True", - "Decal (Atom) Controller|Configuration|Material: SUCCESS", - "Decal (Atom)_test: Entity is hidden: True", - "Decal (Atom)_test: Entity is shown: True", - "Decal (Atom)_test: Entity deleted: True", - "Decal (Atom)_test: UNDO entity deletion works: True", - "Decal (Atom)_test: REDO entity deletion works: True", - # DepthOfField Component - "DepthOfField Entity successfully created", - "DepthOfField_test: Component added to the entity: True", - "DepthOfField_test: Component removed after UNDO: True", - "DepthOfField_test: Component added after REDO: True", - "DepthOfField_test: Entered game mode: True", - "DepthOfField_test: Exit game mode: True", - "DepthOfField_test: Entity disabled initially: True", - "DepthOfField_test: Entity enabled after adding required components: True", - "DepthOfField Controller|Configuration|Camera Entity: SUCCESS", - "DepthOfField_test: Entity is hidden: True", - "DepthOfField_test: Entity is shown: True", - "DepthOfField_test: Entity deleted: True", - "DepthOfField_test: UNDO entity deletion works: True", - "DepthOfField_test: REDO entity deletion works: True", - # Directional Light Component - "Directional Light Entity successfully created", - "Directional Light_test: Component added to the entity: True", - "Directional Light_test: Component removed after UNDO: True", - "Directional Light_test: Component added after REDO: True", - "Directional Light_test: Entered game mode: True", - "Directional Light_test: Exit game mode: True", - "Directional Light Controller|Configuration|Shadow|Camera: SUCCESS", - "Directional Light_test: Entity is hidden: True", - "Directional Light_test: Entity is shown: True", - "Directional Light_test: Entity deleted: True", - "Directional Light_test: UNDO entity deletion works: True", - "Directional Light_test: REDO entity deletion works: True", - # Exposure Control Component - "Exposure Control Entity successfully created", - "Exposure Control_test: Component added to the entity: True", - "Exposure Control_test: Component removed after UNDO: True", - "Exposure Control_test: Component added after REDO: True", - "Exposure Control_test: Entered game mode: True", - "Exposure Control_test: Exit game mode: True", - "Exposure Control_test: Entity disabled initially: True", - "Exposure Control_test: Entity enabled after adding required components: True", - "Exposure Control_test: Entity is hidden: True", - "Exposure Control_test: Entity is shown: True", - "Exposure Control_test: Entity deleted: True", - "Exposure Control_test: UNDO entity deletion works: True", - "Exposure Control_test: REDO entity deletion works: True", - # Global Skylight (IBL) Component - "Global Skylight (IBL) Entity successfully created", - "Global Skylight (IBL)_test: Component added to the entity: True", - "Global Skylight (IBL)_test: Component removed after UNDO: True", - "Global Skylight (IBL)_test: Component added after REDO: True", - "Global Skylight (IBL)_test: Entered game mode: True", - "Global Skylight (IBL)_test: Exit game mode: True", - "Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS", - "Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS", - "Global Skylight (IBL)_test: Entity is hidden: True", - "Global Skylight (IBL)_test: Entity is shown: True", - "Global Skylight (IBL)_test: Entity deleted: True", - "Global Skylight (IBL)_test: UNDO entity deletion works: True", - "Global Skylight (IBL)_test: REDO entity deletion works: True", - # Physical Sky Component - "Physical Sky Entity successfully created", - "Physical Sky component was added to entity", - "Entity has a Physical Sky component", - "Physical Sky_test: Component added to the entity: True", - "Physical Sky_test: Component removed after UNDO: True", - "Physical Sky_test: Component added after REDO: True", - "Physical Sky_test: Entered game mode: True", - "Physical Sky_test: Exit game mode: True", - "Physical Sky_test: Entity is hidden: True", - "Physical Sky_test: Entity is shown: True", - "Physical Sky_test: Entity deleted: True", - "Physical Sky_test: UNDO entity deletion works: True", - "Physical Sky_test: REDO entity deletion works: True", - # PostFX Layer Component - "PostFX Layer Entity successfully created", - "PostFX Layer_test: Component added to the entity: True", - "PostFX Layer_test: Component removed after UNDO: True", - "PostFX Layer_test: Component added after REDO: True", - "PostFX Layer_test: Entered game mode: True", - "PostFX Layer_test: Exit game mode: True", - "PostFX Layer_test: Entity is hidden: True", - "PostFX Layer_test: Entity is shown: True", - "PostFX Layer_test: Entity deleted: True", - "PostFX Layer_test: UNDO entity deletion works: True", - "PostFX Layer_test: REDO entity deletion works: True", - # Radius Weight Modifier Component - "Radius Weight Modifier Entity successfully created", - "Radius Weight Modifier_test: Component added to the entity: True", - "Radius Weight Modifier_test: Component removed after UNDO: True", - "Radius Weight Modifier_test: Component added after REDO: True", - "Radius Weight Modifier_test: Entered game mode: True", - "Radius Weight Modifier_test: Exit game mode: True", - "Radius Weight Modifier_test: Entity is hidden: True", - "Radius Weight Modifier_test: Entity is shown: True", - "Radius Weight Modifier_test: Entity deleted: True", - "Radius Weight Modifier_test: UNDO entity deletion works: True", - "Radius Weight Modifier_test: REDO entity deletion works: True", - # Light Component - "Light Entity successfully created", - "Light_test: Component added to the entity: True", - "Light_test: Component removed after UNDO: True", - "Light_test: Component added after REDO: True", - "Light_test: Entered game mode: True", - "Light_test: Exit game mode: True", - "Light_test: Entity is hidden: True", - "Light_test: Entity is shown: True", - "Light_test: Entity deleted: True", - "Light_test: UNDO entity deletion works: True", - "Light_test: REDO entity deletion works: True", - # Display Mapper Component - "Display Mapper Entity successfully created", - "Display Mapper_test: Component added to the entity: True", - "Display Mapper_test: Component removed after UNDO: True", - "Display Mapper_test: Component added after REDO: True", - "Display Mapper_test: Entered game mode: True", - "Display Mapper_test: Exit game mode: True", - "Display Mapper_test: Entity is hidden: True", - "Display Mapper_test: Entity is shown: True", - "Display Mapper_test: Entity deleted: True", - "Display Mapper_test: UNDO entity deletion works: True", - "Display Mapper_test: REDO entity deletion works: True", - ] - - unexpected_lines = [ - "failed to open", - "Traceback (most recent call last):", - ] - - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_AtomEditorComponents_AddedToEntity.py", - timeout=EDITOR_TIMEOUT, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - null_renderer=True, - cfg_args=cfg_args, - ) + # It requires at least one test + def test_Dummy(self, request, editor, level, workspace, project, launcher_platform): + pass diff --git a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/asset_database_utils.py b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/asset_database_utils.py index 75df510db1..38df3906a8 100755 --- a/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/asset_database_utils.py +++ b/AutomatedTesting/Gem/PythonTests/automatedtesting_shared/asset_database_utils.py @@ -47,7 +47,7 @@ def get_active_platforms_from_db(asset_db_path) -> List[str]: # Convert a source product path into a db product path # cache_platform/projectname/product_path def get_db_product_path(workspace, source_path, cache_platform): - product_path = os.path.join(cache_platform, workspace.project, source_path) + product_path = os.path.join(cache_platform, source_path) product_path = product_path.replace('\\', '/') return product_path diff --git a/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt new file mode 100644 index 0000000000..834254134e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/CMakeLists.txt @@ -0,0 +1,57 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED) + ly_add_pytest( + NAME AutomatedTesting::EditorTests_Main + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR} + PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Editor + ) + + ly_add_pytest( + NAME AutomatedTesting::EditorTests_Periodic + TEST_SUITE periodic + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR} + PYTEST_MARKS "SUITE_periodic" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Editor + ) + + ly_add_pytest( + NAME AutomatedTesting::EditorTests_Sandbox + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR} + PYTEST_MARKS "SUITE_sandbox" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Editor + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py new file mode 100644 index 0000000000..5d4218efd0 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/BasicEditorWorkflows_LevelEntityComponentCRUD.py @@ -0,0 +1,160 @@ +""" +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. +""" + +""" +C6351273: Create a new level +C6384955: Basic Workflow: Entity Manipulation in the Outliner +C16929880: Add Delete Components +C15167490: Save a level +C15167491: Export a level +""" + +import os +import sys +from PySide2 import QtWidgets + +import azlmbr.bus as bus +import azlmbr.editor as editor +import azlmbr.entity as entity +import azlmbr.math as math +import azlmbr.paths + +sys.path.append(os.path.join(azlmbr.paths.devroot, 'AutomatedTesting', 'Gem', 'PythonTests')) +from editor_python_test_tools.editor_test_helper import EditorTestHelper +import editor_python_test_tools.pyside_utils as pyside_utils +import editor_python_test_tools.hydra_editor_utils as hydra + + +class TestBasicEditorWorkflows(EditorTestHelper): + def __init__(self): + EditorTestHelper.__init__(self, log_prefix="BasicEditorWorkflows_LevelEntityComponent", args=["level"]) + + @pyside_utils.wrap_async + async def run_test(self): + """ + Summary: + Open Lumberyard editor and check if basic Editor workflows are completable. + + Expected Behavior: + - A new level can be created + - A new entity can be created + - Entity hierarchy can be adjusted + - Components can be added/removed/updated + - Level can be saved + - Level can be exported + + Note: + - This test file must be called from the Lumberyard Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + def find_entity_by_name(entity_name): + search_filter = entity.SearchFilter() + search_filter.names = [entity_name] + results = entity.SearchBus(bus.Broadcast, 'SearchEntities', search_filter) + if len(results) > 0: + return results[0] + return None + + # 1) Create a new level + editor_window = pyside_utils.get_editor_main_window() + new_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "New Level") + pyside_utils.trigger_action_async(new_level_action) + active_modal_widget = await pyside_utils.wait_for_modal_widget() + new_level_dlg = active_modal_widget.findChild(QtWidgets.QWidget, "CNewLevelDialog") + if new_level_dlg: + if new_level_dlg.windowTitle() == "New Level": + self.log("New Level dialog opened") + grp_box = new_level_dlg.findChild(QtWidgets.QGroupBox, "STATIC_GROUP1") + level_name = grp_box.findChild(QtWidgets.QLineEdit, "LEVEL") + level_name.setText(self.args["level"]) + level_folders = grp_box.findChild(QtWidgets.QComboBox, "LEVEL_FOLDERS") + level_folders.setCurrentText("Levels/") + button_box = new_level_dlg.findChild(QtWidgets.QDialogButtonBox, "buttonBox") + button_box.button(QtWidgets.QDialogButtonBox.Ok).click() + + # Verify new level was created successfully + level_create_success = await pyside_utils.wait_for_condition(lambda: editor.EditorToolsApplicationRequestBus( + bus.Broadcast, "GetCurrentLevelName") == self.args["level"], 5.0) + self.test_success = level_create_success + self.log(f"Create and load new level: {level_create_success}") + + # Execute EditorTestHelper setup since level was created outside of EditorTestHelper's methods + self.test_success = self.test_success and self.after_level_load() + + # 2) Delete existing entities, and create and manipulate new entities via Entity Inspector + search_filter = azlmbr.entity.SearchFilter() + all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter) + editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities) + entity_outliner_widget = editor_window.findChild(QtWidgets.QWidget, "OutlinerWidgetUI") + outliner_object_list = entity_outliner_widget.findChild(QtWidgets.QWidget, "m_objectList_Contents") + outliner_tree = outliner_object_list.findChild(QtWidgets.QWidget, "m_objectTree") + await pyside_utils.trigger_context_menu_entry(outliner_tree, "Create entity") + + # Find the new entity + parent_entity_id = find_entity_by_name("Entity1") + parent_entity_success = await pyside_utils.wait_for_condition(lambda: parent_entity_id is not None, 5.0) + self.test_success = self.test_success and parent_entity_success + self.log(f"New entity creation: {parent_entity_success}") + + # TODO: Replace Hydra call to creates child entity and add components with context menu triggering - LYN-3951 + # Create a new child entity + child_entity = hydra.Entity("Child") + entity_position = math.Vector3(0.0, 0.0, 0.0) + components_to_add = [] + child_entity.create_entity(entity_position, components_to_add, parent_entity_id) + + # Verify entity hierarchy + child_entity.get_parent_info() + self.test_success = self.test_success and child_entity.parent_id == parent_entity_id + self.log(f"Create entity hierarchy: {child_entity.parent_id == parent_entity_id}") + + # 3) Add/configure a component on an entity + # Add component and verify success + child_entity.add_component("Box Shape") + component_add_success = self.wait_for_condition(lambda: hydra.has_components(child_entity.id, ["Box Shape"]), 5.0) + self.test_success = self.test_success and component_add_success + self.log(f"Add component: {component_add_success}") + + # Update the component + dimensions_to_set = math.Vector3(16.0, 16.0, 16.0) + child_entity.get_set_test(0, "Box Shape|Box Configuration|Dimensions", dimensions_to_set) + box_shape_dimensions = hydra.get_component_property_value(child_entity.components[0], "Box Shape|Box Configuration|Dimensions") + self.test_success = self.test_success and box_shape_dimensions == dimensions_to_set + self.log(f"Component update: {box_shape_dimensions == dimensions_to_set}") + + # Remove the component + child_entity.remove_component("Box Shape") + component_rem_success = self.wait_for_condition(lambda: not hydra.has_components(child_entity.id, ["Box Shape"]), + 5.0) + self.test_success = self.test_success and component_rem_success + self.log(f"Remove component: {component_rem_success}") + + # 4) Save the level + save_level_action = pyside_utils.get_action_for_menu_path(editor_window, "File", "Save") + pyside_utils.trigger_action_async(save_level_action) + + # 5) Export the level + export_action = pyside_utils.get_action_for_menu_path(editor_window, "Game", "Export to Engine") + pyside_utils.trigger_action_async(export_action) + level_pak_file = os.path.join( + "AutomatedTesting", "Levels", self.args["level"], "level.pak" + ) + export_success = self.wait_for_condition(lambda: os.path.exists(level_pak_file), 5.0) + self.test_success = self.test_success and export_success + self.log(f"Save and Export: {export_success}") + + +test = TestBasicEditorWorkflows() +test.run() diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py index 208ef40d41..3eeb3ddf84 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_EditMenuOptions.py @@ -64,8 +64,6 @@ class TestEditMenuOptions(EditorTestHelper): ("Modify", "Transform Mode", "Move"), ("Modify", "Transform Mode", "Rotate"), ("Modify", "Transform Mode", "Scale"), - ("Lock Selection",), - ("Unlock All Entities",), ("Editor Settings", "Global Preferences"), ("Editor Settings", "Graphics Settings"), ("Editor Settings", "Editor Settings Manager"), diff --git a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py index 05ee802d19..173d658b3c 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py +++ b/AutomatedTesting/Gem/PythonTests/editor/EditorScripts/Menus_ViewMenuOptions.py @@ -50,7 +50,6 @@ class TestViewMenuOptions(EditorTestHelper): ("Center on Selection",), ("Show Quick Access Bar",), ("Viewport", "Wireframe"), - ("Viewport", "Grid Settings"), ("Viewport", "Go to Position"), ("Viewport", "Center on Selection"), ("Viewport", "Go to Location"), diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py b/AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py index ac499d734f..90ca3690e4 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py +++ b/AutomatedTesting/Gem/PythonTests/editor/test_AssetPicker.py @@ -42,6 +42,7 @@ class TestAssetPicker(object): @pytest.mark.test_case_id("C13751579", "C1508814") @pytest.mark.SUITE_periodic + @pytest.mark.xfail # ATOM-15493 def test_AssetPicker_UI_UX(self, request, editor, level, launcher_platform): expected_lines = [ "TestEntity Entity successfully created", diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_BasicEditorWorkflows.py b/AutomatedTesting/Gem/PythonTests/editor/test_BasicEditorWorkflows.py new file mode 100644 index 0000000000..b045b364a3 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/editor/test_BasicEditorWorkflows.py @@ -0,0 +1,63 @@ +""" +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 os +import pytest + +# Bail on the test if ly_test_tools doesn't exist. +pytest.importorskip('ly_test_tools') +import ly_test_tools.environment.file_system as file_system +import editor_python_test_tools.hydra_test_utils as hydra + +test_directory = os.path.join(os.path.dirname(__file__), "EditorScripts") +log_monitor_timeout = 180 + + +@pytest.mark.parametrize('project', ['AutomatedTesting']) +@pytest.mark.parametrize('level', ['tmp_level']) +@pytest.mark.usefixtures("automatic_process_killer") +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +class TestBasicEditorWorkflows(object): + + @pytest.fixture(autouse=True) + def setup_teardown(self, request, workspace, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) + + request.addfinalizer(teardown) + + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) + + @pytest.mark.test_case_id("C6351273", "C6384955", "C16929880", "C15167490", "C15167491") + @pytest.mark.SUITE_main + def test_BasicEditorWorkflows_LevelEntityComponentCRUD(self, request, editor, level, launcher_platform): + + expected_lines = [ + "Create and load new level: True", + "New entity creation: True", + "Create entity hierarchy: True", + "Add component: True", + "Component update: True", + "Remove component: True", + "Save and Export: True", + "BasicEditorWorkflows_LevelEntityComponent: result=SUCCESS", + ] + + hydra.launch_and_validate_results( + request, + test_directory, + editor, + "BasicEditorWorkflows_LevelEntityComponentCRUD.py", + expected_lines, + cfg_args=[level], + timeout=log_monitor_timeout, + auto_test_mode=False + ) diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_Docking.py b/AutomatedTesting/Gem/PythonTests/editor/test_Docking.py index a75b3b36cd..f887560a19 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/test_Docking.py +++ b/AutomatedTesting/Gem/PythonTests/editor/test_Docking.py @@ -39,8 +39,8 @@ class TestDocking(object): file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) @pytest.mark.test_case_id("C6376081") - @pytest.mark.SUITE_periodic - def test_basic_docked_tools(self, request, editor, level, launcher_platform): + @pytest.mark.SUITE_sandbox + def test_Docking_BasicDockedTools(self, request, editor, level, launcher_platform): expected_lines = [ "The tools are all docked together in a tabbed widget", "Entity Outliner works when docked, can select an Entity", diff --git a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py b/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py index 251bd7cfed..c2da1343de 100644 --- a/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py +++ b/AutomatedTesting/Gem/PythonTests/editor/test_Menus.py @@ -39,7 +39,7 @@ class TestMenus(object): file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) @pytest.mark.test_case_id("C16780783", "C2174438") - @pytest.mark.SUITE_periodic + @pytest.mark.SUITE_sandbox def test_Menus_EditMenuOptions_Work(self, request, editor, level, launcher_platform): expected_lines = [ "Undo Action triggered", @@ -59,8 +59,6 @@ class TestMenus(object): "Move Action triggered", "Rotate Action triggered", "Scale Action triggered", - "Lock Selection Action triggered", - "Unlock All Entities Action triggered", "Global Preferences Action triggered", "Graphics Settings Action triggered", "Editor Settings Manager Action triggered", @@ -93,7 +91,6 @@ class TestMenus(object): "Center on Selection Action triggered", "Show Quick Access Bar Action triggered", "Wireframe Action triggered", - "Grid Settings Action triggered", "Go to Position Action triggered", "Center on Selection Action triggered", "Go to Location Action triggered", @@ -116,7 +113,7 @@ class TestMenus(object): ) @pytest.mark.test_case_id("C16780778") - @pytest.mark.SUITE_periodic + @pytest.mark.SUITE_sandbox def test_Menus_FileMenuOptions_Work(self, request, editor, level, launcher_platform): expected_lines = [ "New Level Action triggered", diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt new file mode 100644 index 0000000000..c7fd43c7b2 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt @@ -0,0 +1,185 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_LARGE_WORLDS_TEST_SUPPORTED) + +## DynVeg ## + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationTests_Main + TEST_SERIAL + TEST_SUITE main + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.GameLauncher + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationTests_Sandbox + TEST_SERIAL + TEST_SUITE sandbox + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "SUITE_sandbox" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.GameLauncher + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationFilterTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "SUITE_periodic and dynveg_filter" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationModifierTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "SUITE_periodic and dynveg_modifier" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationRegressionTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "SUITE_periodic and dynveg_regression" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationAreaTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "SUITE_periodic and dynveg_area" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationMiscTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "SUITE_periodic and dynveg_misc" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationSurfaceTagTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg + PYTEST_MARKS "SUITE_periodic and dynveg_surfacetagemitter" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) +## LandscapeCanvas ## + + ly_add_pytest( + NAME AutomatedTesting::LandscapeCanvasTests_Main + TEST_SERIAL + TEST_SUITE main + PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas + PYTEST_MARKS "not SUITE_sandbox and not SUITE_periodic and not SUITE_benchmark" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + + ly_add_pytest( + NAME AutomatedTesting::LandscapeCanvasTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/landscape_canvas + PYTEST_MARKS "SUITE_periodic" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + +## GradientSignal ## + ly_add_pytest( + NAME AutomatedTesting::GradientSignalTests_Periodic + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/gradient_signal + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + COMPONENT + LargeWorlds + ) + +endif() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py index 1ccfc43585..d0c6fc3c5a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilterOverrides_InstancesPlantAtSpecifiedRadius.py @@ -82,42 +82,34 @@ class TestDistanceBetweenFilterComponentOverrides(EditorTestHelper): editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", veg_system_settings_component, 'Configuration|Area System Settings|Sector Point Density', 16) - # Add a Vegetation Debugger component to allow area refreshes - hydra.add_level_component("Vegetation Debugger") - # 5) Add a Vegetation Distance Between Filter, toggle overrides on both the component and descriptor, # and verify initial instance counts are accurate spawner_entity.add_component("Vegetation Distance Between Filter") spawner_entity.get_set_test(3, "Configuration|Allow Per-Item Overrides", True) spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Override Enabled", True) - general.run_console('veg_debugClearAllAreas') - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 2), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 2), 5.0) and \ - self.test_success + num_expected = 16 * 16 + initial_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected), 5.0) + self.test_success = self.test_success and initial_success # 6) Change Radius Min to 1.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 1.0) - general.run_console('veg_debugClearAllAreas') - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 7) Change Radius Min to 2.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 2.0) - general.run_console('veg_debugClearAllAreas') - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 8) Change Radius Min to 16.0, refresh, and verify instance counts are accurate, only a single instance should plant spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]|Distance Between Filter (Radius)|Radius Min", 16.0) - general.run_console('veg_debugClearAllAreas') num_expected_instances = 1 final_check_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected_instances), 5.0) - self.test_success = final_check_success and self.test_success + self.test_success = self.test_success and final_check_success test = TestDistanceBetweenFilterComponentOverrides() diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py index 09c5fd63cf..d342afd7ca 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DistanceBetweenFilter_InstancesPlantAtSpecifiedRadius.py @@ -80,35 +80,29 @@ class TestDistanceBetweenFilterComponent(EditorTestHelper): editor.EditorComponentAPIBus(bus.Broadcast, "SetComponentProperty", veg_system_settings_component, 'Configuration|Area System Settings|Sector Point Density', 16) - # Add a Vegetation Debugger component to allow area refreshes - hydra.add_level_component("Vegetation Debugger") - # 5) Add a Vegetation Distance Between Filter and verify initial instance counts are accurate spawner_entity.add_component("Vegetation Distance Between Filter") - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 2), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 2), 5.0) and \ - self.test_success + num_expected = 16 * 16 + num_expected = 16 * 16 + initial_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected), 5.0) + self.test_success = self.test_success and initial_success # 6) Change Radius Min to 1.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 1.0) - general.run_console('veg_debugClearAllAreas') - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 1), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 7) Change Radius Min to 2.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 2.0) - general.run_console('veg_debugClearAllAreas') - self.test_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) and \ - self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) and \ - self.test_success + point_a_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_a, 0.5, 1), 5.0) + point_b_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_b, 0.5, 0), 5.0) + point_c_success = self.wait_for_condition(lambda: dynveg.validate_instance_count(instance_query_point_c, 0.5, 0), 5.0) + self.test_success = self.test_success and point_a_success and point_b_success and point_c_success # 8) Change Radius Min to 16.0, refresh, and verify instance counts are accurate spawner_entity.get_set_test(3, "Configuration|Radius Min", 16.0) - general.run_console('veg_debugClearAllAreas') num_expected_instances = 1 final_check_success = self.wait_for_condition(lambda: dynveg.validate_instance_count_in_entity_shape(spawner_entity.id, num_expected_instances), 5.0) self.test_success = final_check_success and self.test_success diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py index 4f58a23a19..730a557a9e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/SurfaceMaskFilter_BasicSurfaceTagCreation.py @@ -23,6 +23,25 @@ class TestSurfaceMaskFilter_BasicSurfaceTagCreation(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="TestSurfaceMaskFilter_BasicSurfaceTagCreation", args=["level"]) def run_test(self): + """ + Summary: + Verifies basic surface tag value equality + + Expected Behavior: + Surface tags of the same name are equal, and different names aren't. + + Test Steps: + 1) Open level + 2) Create 2 new surface tags of identical names and verify they resolve as equal. + 3) Create another new tag of a different name and verify they resolve as different. + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ self.log("SurfaceTag test started") # Create a level diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py index c25761d655..46c5483988 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/VegetationInstances_DespawnWhenOutOfRange.py @@ -33,6 +33,25 @@ class TestVegetationInstances_DespawnWhenOutOfRange(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix='VegetationInstances_DespawnWhenOutOfRange', args=['level']) def run_test(self): + """ + Summary: + Verifies that vegetation instances properly spawn/despawn based on camera range. + + Expected Behavior: + Vegetation instances despawn when out of camera range. + + Test Steps: + 1) Create a new level + 2) Create a simple vegetation area, and set the view position near the spawner. Verify instances plant. + 3) Move the view position away from the spawner. Verify instances despawn. + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ # Create a new level self.test_success = self.create_level( diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py index 9898570692..ead1e8779c 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_DynamicSliceInstanceSpawner.py @@ -41,7 +41,7 @@ class TestDynamicSliceInstanceSpawner(object): return console @pytest.mark.test_case_id("C28851763") - @pytest.mark.SUITE_periodic + @pytest.mark.SUITE_main @pytest.mark.dynveg_area @pytest.mark.parametrize("launcher_platform", ['windows_editor']) def test_DynamicSliceInstanceSpawner_DynamicSliceSpawnerWorks(self, request, editor, level, workspace, project, diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_EmptyInstanceSpawner.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_EmptyInstanceSpawner.py index 7bd8484cf4..ca71cd2137 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_EmptyInstanceSpawner.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/test_EmptyInstanceSpawner.py @@ -37,7 +37,7 @@ class TestEmptyInstanceSpawner(object): file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) @pytest.mark.test_case_id("C28851762") - @pytest.mark.SUITE_periodic + @pytest.mark.SUITE_main @pytest.mark.dynveg_area def test_EmptyInstanceSpawner_EmptySpawnerWorks(self, request, editor, level, launcher_platform): cfg_args = [level] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py index cc9a15bba0..c37bc9780f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientGenerators_Incompatibilities.py @@ -28,8 +28,21 @@ class TestGradientGeneratorIncompatibilities(EditorTestHelper): def run_test(self): """ Summary: - Verify that Entities are not active when a Gradient Generator and incompatible component are both present - on the same Entity. + This test verifies that components are disabled when conflicting components are present on the same entity. + + Expected Behavior: + Gradient Generator components are incompatible with Vegetation area components. + + Test Steps: + 1) Create a new level + 2) Create a new entity in the level + 3) Add each Gradient Generator component to an entity, and add a Vegetation Area component to the same entity + 4) Verify that components are only enabled when entity is free of a conflicting component + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. :return: None """ diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py index b7d12d074a..f2edc2924e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientModifiers_Incompatibilities.py @@ -28,8 +28,21 @@ class TestGradientModifiersIncompatibilities(EditorTestHelper): def run_test(self): """ Summary: - Verify that Entities are not active when a Gradient Modifier and incompatible component are both present - on the same Entity. + This test verifies that components are disabled when conflicting components are present on the same entity. + + Expected Behavior: + Gradient Modifier components are incompatible with Vegetation area components. + + Test Steps: + 1) Create a new level + 2) Create a new entity in the level + 3) Add each Gradient Modifier component to an entity, and add a Vegetation Area component to the same entity + 4) Verify that components are only enabled when entity is free of a conflicting component + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. :return: None """ diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py index c37ee36265..45da74d6cd 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_ClearingPinnedEntitySetsPreviewToOrigin.py @@ -9,19 +9,6 @@ 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. """ -""" -The below cases are combined in this script -C2676829 -C3961326 -C3980659 -C3980664 -C3980669 -C3416548 -C2676823 -C3961321 -C2676826 -""" - import os import sys diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py index 5a758b9d89..b8f4114d30 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientPreviewSettings_DefaultPinnedEntityIsSelf.py @@ -44,7 +44,21 @@ class TestGradientPreviewSettings(EditorTestHelper): def run_test(self): """ Summary: - Verify if the current entity is set to the pin preview to shape entity by default for several components. + This test verifies default values for the pinned entity for Gradient Preview settings. + + Expected Behavior: + Pinned entity is self for all gradient generator/modifiers. + + Test Steps: + 1) Create a new level + 2) Create a new entity in the level + 3) Add each Gradient Generator component to an entity, and verify the Pin Preview to Shape property is set to + self + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. :return: None """ diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py index a16e37e0fc..8e2d0611af 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientSurfaceTagEmitter_ComponentDependencies.py @@ -31,11 +31,21 @@ class TestGradientSurfaceTagEmitterDependencies(EditorTestHelper): def run_test(self): """ Summary: - Component has a dependency on a Gradient component + This test verifies that the Gradient Surface Tag Emitter component is dependent on a gradient component. Expected Result: - Component is disabled until a Gradient Generator, Modifier or Gradient Reference component - (and any sub-dependencies) is added to the entity. + Gradient Surface Tag Emitter component is disabled until a Gradient Generator, Modifier or Gradient Reference + component (and any sub-dependencies) is added to the entity. + + Test Steps: + 1) Open level + 2) Create a new entity with a Gradient Surface Tag Emitter component + 3) Verify the component is disabled until a dependent component is also added to the entity + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. :return: None """ diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py index e1e901f2f7..2311363db9 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/GradientTransform_RequiresShape.py @@ -28,8 +28,20 @@ class TestGradientTransformRequiresShape(EditorTestHelper): def run_test(self): """ Summary: - Verify that Gradient Transform Modifier component requires a - Shape component before the Entity can become active. + This test verifies that the Gradient Transform Modifier component is dependent on a shape component. + + Expected Result: + Gradient Transform Modifier component is disabled until a shape component is added to the entity. + + Test Steps: + 1) Open level + 2) Create a new entity with a Gradient Transform Modifier component + 3) Verify the component is disabled until a shape component is also added to the entity + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. :return: None """ diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py index dab8e6928a..a5d9632fd6 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/gradient_signal/EditorScripts/ImageGradient_RequiresShape.py @@ -28,8 +28,20 @@ class TestImageGradientRequiresShape(EditorTestHelper): def run_test(self): """ Summary: - Verify that Image Gradient component requires a - Shape component before the Entity can become active. + This test verifies that the Image Gradient component is dependent on a shape component. + + Expected Result: + Gradient Transform Modifier component is disabled until a shape component is added to the entity. + + Test Steps: + 1) Open level + 2) Create a new entity with a Image Gradient component + 3) Verify the component is disabled until a shape component is also added to the entity + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. :return: None """ diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py index d1e0b68ef4..c41d153cfa 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_DependentComponentsAdded.py @@ -33,6 +33,26 @@ class TestAreaNodeComponentDependency(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="AreaNodeComponentDependency", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with + proper dependent components. + + Expected Behavior: + All expected component dependencies are met when adding an area node to a graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the area nodes to the graph area, and ensure the proper dependent components are added + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py index 4e429a192b..fb977b4987 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityCreatedOnNodeAdd.py @@ -33,7 +33,25 @@ class TestGradientNodeEntityCreate(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityCreate", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities. + Expected Behavior: + New entities are created when dragging area nodes to graph area. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the area nodes to the graph area, and ensure a new entity is created + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId newEntityId = parameters[0] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py index 38f8641b4c..57ba8fc006 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/AreaNodes_EntityRemovedOnNodeDelete.py @@ -34,7 +34,26 @@ class TestAreaNodeEntityDelete(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="AreaNodeEntityDelete", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor. + Expected Behavior: + Entities are removed when area nodes are deleted from a graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the area nodes to the graph area, and ensure a new entity is created + 4) Delete the nodes, and ensure the newly created entities are removed + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global createdEntityId createdEntityId = parameters[0] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py index 26062c01f8..60527b64d2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ComponentUpdates_UpdateGraph.py @@ -9,24 +9,6 @@ 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. """ - -""" -C22602072 - Graph is updated when underlying components are added/removed - -1. Open Level. -2. Find LandscapeCanvas named entity. -3. Ensure Vegetation Distribution Component is present on the BushSpawner entity. -4. Open graph and ensure Distribution Filter wrapped node is present. -5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector. -6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is no longer -present in the graph. -7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector. -8. Ensure Altitude Filter was added to the BushSpawner node in the open graph. -9. Add a new entity with unique name as a child of the Landscape Canvas entity. -10. Add a Box Shape component to the new child entity. -11. Ensure Box Shape node is present on the open graph. -""" - import os import sys @@ -50,6 +32,36 @@ class TestComponentUpdatesUpdateGraph(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="ComponentUpdatesUpdateGraph", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas graphs update properly when components are added/removed outside of + Landscape Canvas. + + Expected Behavior: + Graphs properly reflect component changes made to entities outside of Landscape Canvas. + + Test Steps: + 1. Open Level + 2. Find LandscapeCanvas named entity + 3. Ensure Vegetation Distribution Component is present on the BushSpawner entity + 4. Open graph and ensure Distribution Filter wrapped node is present + 5. Delete the Vegetation Distribution Filter component from the BushSpawner entity via Entity Inspector + 6. Ensure the Vegetation Distribution Filter component was deleted from the BushSpawner entity and node is + no longer present in the graph + 7. Add Vegetation Altitude Filter to the BushSpawner entity through Entity Inspector + 8. Ensure Altitude Filter was added to the BushSpawner node in the open graph + 9. Add a new entity with unique name as a child of the Landscape Canvas entity + 10. Add a Box Shape component to the new child entity + 11. Ensure Box Shape node is present on the open graph + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + # Create a new empty level and instantiate LC_BushFlowerBlender.slice self.test_success = self.create_level( self.args["level"], diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/CreateNewGraph.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/CreateNewGraph.py index 5fed13985d..4b5e03abbc 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/CreateNewGraph.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/CreateNewGraph.py @@ -37,6 +37,25 @@ class TestCreateNewGraph(EditorTestHelper): print("New root entity created") def run_test(self): + """ + Summary: + This test verifies that new graphs can be created in Landscape Canvas. + + Expected Behavior: + New graphs can be created, and proper entity is created to hold graph data with a Landscape Canvas component. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Ensures the root entity created contains a Landscape Canvas component + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ self.test_success = self.create_level( self.args["level"], heightmap_resolution=128, diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py index 7fd3f075e0..81e24b20e1 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_DisabledNodeDuplication.py @@ -33,7 +33,25 @@ class TestDisabledNodeDuplication(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="DisabledNodeDuplication", args=["level"]) def run_test(self): + """ + Summary: + This test verifies Editor stability after duplicating disabled Landscape Canvas nodes. + Expected Behavior: + Editor remains stable and free of crashes. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Create several new nodes, disable the nodes via disabling/deleting components, and duplicate the nodes + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId newEntityId = parameters[0] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_SliceEntity.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_SliceEntity.py index 27ab6fded3..61c4cf9ac2 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_SliceEntity.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/Edit_UndoNodeDelete_SliceEntity.py @@ -9,17 +9,6 @@ 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. """ - -""" -C30813586 - Editor remains stable after Undoing deletion of a node on a slice entity - -1. Open level with instantiated slice. -2. Open the graph. -3. Find the BushSpawner's Vegetation Layer Spawner node. -4. Delete the node. -5. Undo to restore the node. -""" - import os import sys @@ -44,7 +33,26 @@ class TestUndoNodeDeleteSlice(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="UndoNodeDeleteSlice", args=["level"]) def run_test(self): + """ + Summary: + This test verifies Editor stability after undoing the deletion of nodes on a slice entity. + Expected Behavior: + Editor remains stable and free of crashes. + + Test Steps: + 1) Create a new level + 2) Instantiate a slice with a Landscape Canvas setup + 3) Find a specific node on the graph, and delete it + 4) Restore the node with Undo + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ # Create a new empty level and instantiate LC_BushFlowerBlender.slice self.test_success = self.create_level( self.args["level"], diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py index ca3bc04f47..124baf9d2e 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientMixer_NodeConstruction.py @@ -34,6 +34,27 @@ class TestGradientMixerNodeConstruction(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GradientMixerNodeConstruction", args=["level"]) def run_test(self): + """ + Summary: + This test verifies a Gradient Mixer vegetation setup can be constructed through Landscape Canvas. + + Expected Behavior: + Entities contain all required components and component references after creating nodes and setting connections + on a Landscape Canvas graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Add all necessary nodes to the graph and set connections to form a Gradient Mixer setup + 4) Verify all components and component references were properly set during graph construction + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py index d40b19e7db..aa98eb3dc3 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityCreatedOnNodeAdd.py @@ -33,6 +33,25 @@ class TestGradientModifierNodeEntityCreate(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityCreate", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities. + + Expected Behavior: + New entities are created when dragging Gradient Modifier nodes to graph area. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py index dc263924d1..6a82b05039 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientModifierNodes_EntityRemovedOnNodeDelete.py @@ -34,7 +34,26 @@ class TestGradientModifierNodeEntityDelete(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GradientModifierNodeEntityDelete", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor. + Expected Behavior: + Entities are removed when Gradient Modifier nodes are deleted from a graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the Gradient Modifier nodes to the graph area, and ensure a new entity is created + 4) Delete the nodes, and ensure the newly created entities are removed + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global createdEntityId createdEntityId = parameters[0] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py index 5e203e1892..f9360fe356 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_DependentComponentsAdded.py @@ -33,6 +33,27 @@ class TestGradientNodeComponentDependency(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GradientNodeComponentDependency", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities with + proper dependent components. + + Expected Behavior: + All expected component dependencies are met when adding a Gradient Modifier node to a graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the Gradient Modifier nodes to the graph area, and ensure the proper dependent components are + added + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py index 6d4a2f58a7..8aaad9b81d 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityCreatedOnNodeAdd.py @@ -32,6 +32,25 @@ class TestGradientNodeEntityCreate(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityCreate", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities. + + Expected Behavior: + New entities are created when dragging Gradient nodes to graph area. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py index 2b49e3a911..d74b86d0bf 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GradientNodes_EntityRemovedOnNodeDelete.py @@ -34,6 +34,26 @@ class TestGradientNodeEntityDelete(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GradientNodeEntityDelete", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor. + + Expected Behavior: + Entities are removed when Gradient nodes are deleted from a graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the Gradient nodes to the graph area, and ensure a new entity is created + 4) Delete the nodes, and ensure the newly created entities are removed + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global createdEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py index d3ad5c1c1e..6aa539b554 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnEntityDelete.py @@ -31,6 +31,26 @@ class TestGraphClosedOnEntityDelete(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GraphClosedOnEntityDelete", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that Landscape Canvas graphs are auto-closed when the corresponding entity is deleted. + + Expected Behavior: + When a Landscape Canvas root entity is deleted, the corresponding graph automatically closes. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Delete the automatically created entity + 4) Verify the open graph is closed + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newRootEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py index b7b0008eb2..ebc75ab621 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_OnLevelChange.py @@ -29,7 +29,26 @@ class TestGraphClosedOnLevelChange(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GraphClosedOnLevelChange", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that Landscape Canvas graphs are auto-closed when the currently open level changes. + Expected Behavior: + When a new level is loaded in the Editor, open Landscape Canvas graphs are automatically closed. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Open a different level + 4) Verify the open graph is closed + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ # Create a new empty level self.test_success = self.create_level( self.args["level"], diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py index efd1cc5a55..4b018aeb45 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphClosed_TabbedGraph.py @@ -29,6 +29,26 @@ class TestGraphClosedTabbedGraph(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GraphClosedTabbedGraph", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that Landscape Canvas tabbed graphs can be independently closed. + + Expected Behavior: + Closing a tabbed graph only closes the appropriate graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create several new graphs + 3) Close one of the open graphs + 4) Ensure the graph properly closed, and other open graphs remain open + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ # Create a new empty level self.test_success = self.create_level( diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py index f350d37178..f94a6c2e3a 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/GraphUpdates_UpdateComponents.py @@ -9,21 +9,6 @@ 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. """ - -""" -C22715182 - Components are updated when nodes are added/removed/updated - -1. Open Level. -2. Open the graph on LC_BushFlowerBlender.slice -3. Find the Rotation Modifier node on the BushSpawner entity -4. Delete the Rotation Modifier node -5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity -6. Delete the Vegetation Layer Spawner node from the graph -7. Ensure BushSpawner entity is deleted -8. Change connection from second Rotation Modifier node to a different Gradient -9. Ensure Gradient reference on component is updated -""" - import os import sys @@ -50,6 +35,31 @@ class TestGraphUpdatesUpdateComponents(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="GraphUpdatesUpdateComponents", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that components are properly updated as nodes are added/removed/updated. + + Expected Behavior: + Landscape Canvas node CRUD properly updates component entities. + + Test Steps: + 1. Open Level. + 2. Open the graph on LC_BushFlowerBlender.slice + 3. Find the Rotation Modifier node on the BushSpawner entity + 4. Delete the Rotation Modifier node + 5. Ensure the Vegetation Rotation Modifier component is removed from the BushSpawner entity + 6. Delete the Vegetation Layer Spawner node from the graph + 7. Ensure BushSpawner entity is deleted + 8. Change connection from second Rotation Modifier node to a different Gradient + 9. Ensure Gradient reference on component is updated + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ # Create a new empty level and instantiate LC_BushFlowerBlender.slice self.test_success = self.create_level( self.args["level"], diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvasComponent_AddedRemoved.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvasComponent_AddedRemoved.py index 176429885f..c3857e1393 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvasComponent_AddedRemoved.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvasComponent_AddedRemoved.py @@ -30,6 +30,26 @@ class TestLandscapeCanvasComponentAddedRemoved(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="LandscapeCanvasComponentAddedRemoved", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas component can be added to/removed from an entity. + + Expected Behavior: + Closing a tabbed graph only closes the appropriate graph. + + Test Steps: + 1) Create a new level + 2) Create a new entity + 3) Add a Landscape Canvas component to the entity + 4) Remove the Landscape Canvas component from the entity + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ # Create a new empty level self.test_success = self.create_level( diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvas_SliceCreateInstantiate.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvas_SliceCreateInstantiate.py index e0f13adaa9..f174a52610 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvas_SliceCreateInstantiate.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LandscapeCanvas_SliceCreateInstantiate.py @@ -30,12 +30,21 @@ class TestLandscapeCanvasSliceCreateInstantiate(EditorTestHelper): def run_test(self): """ Summary: - C22602016 A slice containing the LandscapeCanvas component can be created/instantiated. + A slice containing the LandscapeCanvas component can be created/instantiated. Expected Result: - Slice is created and processed successfully and free of errors/warnings. - Another copy of the slice is instantiated. + Slice is created/processed/instantiated successfully and free of errors/warnings. + Test Steps: + 1) Create a new level + 2) Create a new entity with a Landscape Canvas component + 3) Create a slice of the new entity + 4) Instantiate a new copy of the slice + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. :return: None """ diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py index ecc529b9b4..82a2abf5ea 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerBlender_NodeConstruction.py @@ -34,6 +34,27 @@ class TestLayerBlenderNodeConstruction(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="LayerBlenderNodeConstruction", args=["level"]) def run_test(self): + """ + Summary: + This test verifies a Layer Blender vegetation setup can be constructed through Landscape Canvas. + + Expected Behavior: + Entities contain all required components and component references after creating nodes and setting connections + on a Landscape Canvas graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Add all necessary nodes to the graph and set connections to form a Layer Blender setup + 4) Verify all components and component references were properly set during graph construction + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py index 00fcb5170c..df3c549fff 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/LayerExtenderNodes_ComponentEntitySync.py @@ -34,6 +34,25 @@ class TestLayerExtenderNodeComponentEntitySync(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="LayerExtenderNodeComponentEntitySync", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that all wrapped nodes can be successfully added to/removed from parent nodes. + + Expected Behavior: + All wrapped extender nodes can be added to/removed from appropriate parent nodes. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Add Area Blender and Layer Spawner nodes to the graph, and add/remove each extender node to/from each + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py index bd10e5f4c6..cd4915ea24 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityCreatedOnNodeAdd.py @@ -33,6 +33,25 @@ class TestShapeNodeEntityCreate(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="ShapeNodeEntityCreate", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas nodes can be added to a graph, and correctly create entities. + + Expected Behavior: + New entities are created when dragging shape nodes to graph area. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the shape nodes to the graph area, and ensure a new entity is created + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ def onEntityCreated(parameters): global newEntityId diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py index f71f5ae906..fcfbe03576 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/ShapeNodes_EntityRemovedOnNodeDelete.py @@ -34,7 +34,27 @@ class TestShapeNodeEntityDelete(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="ShapeNodeEntityDelete", args=["level"]) def run_test(self): - + """ + Summary: + This test verifies that the Landscape Canvas node deletion properly cleans up entities in the Editor. + + Expected Behavior: + Entities are removed when shape nodes are deleted from a graph. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Drag each of the shape nodes to the graph area, and ensure a new entity is created + 4) Delete the nodes, and ensure the newly created entities are removed + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + def onEntityCreated(parameters): global createdEntityId createdEntityId = parameters[0] diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py index 968f39c64d..183c3f7ccb 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/EditorScripts/SlotConnections_UpdateComponentReferences.py @@ -33,6 +33,27 @@ class TestSlotConnectionsUpdateComponents(EditorTestHelper): EditorTestHelper.__init__(self, log_prefix="SlotConnectionsUpdateComponents", args=["level"]) def run_test(self): + """ + Summary: + This test verifies that the Landscape Canvas slot connections properly update component references. + + Expected Behavior: + A reference created through slot connections in Landscape Canvas is reflected in the Entity Inspector. + + Test Steps: + 1) Create a new level + 2) Open Landscape Canvas and create a new graph + 3) Several nodes are added to a graph, and connections are set between the nodes + 4) Component references are verified via Entity Inspector + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + # Retrieve the proper component TypeIds per component name componentNames = [ 'Random Noise Gradient', diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GraphComponentSync.py b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GraphComponentSync.py index efeba3b74a..855764fa6f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GraphComponentSync.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/landscape_canvas/test_GraphComponentSync.py @@ -118,7 +118,7 @@ class TestGraphComponentSync(object): @pytest.mark.test_case_id('C15987206') @pytest.mark.SUITE_main - def test_LandscapeCanvas_GradientMixerNodeConstruction(self, request, editor, level, launcher_platform): + def test_LandscapeCanvas_GradientMixer_NodeConstruction(self, request, editor, level, launcher_platform): """ Verifies a Gradient Mixer can be setup in Landscape Canvas and all references are property set. """ @@ -141,7 +141,7 @@ class TestGraphComponentSync(object): @pytest.mark.test_case_id('C21333743') @pytest.mark.SUITE_periodic - def test_LandscapeCanvas_LayerBlenderNodeConstruction(self, request, editor, level, launcher_platform): + def test_LandscapeCanvas_LayerBlender_NodeConstruction(self, request, editor, level, launcher_platform): """ Verifies a Layer Blender can be setup in Landscape Canvas and all references are property set. """ diff --git a/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py b/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py index e415687001..bc7b1b5e00 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C14861501_PhysXCollider_RenderMeshAutoAssigned.py @@ -98,5 +98,5 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report + from editor_python_test_tools.utils import Report Report.start_test(C14861501_PhysXCollider_RenderMeshAutoAssigned) diff --git a/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py b/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py index c76c5cab80..8400364626 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C14976308_ScriptCanvas_SetKinematicTargetTransform.py @@ -68,7 +68,7 @@ def C14976308_ScriptCanvas_SetKinematicTargetTransform(): the script deactivates Signal, Sphere's transform will update to that of Transform_Target. NOTE: There is a known bug (LY-107723) which causes the rotation to update to a value that is not sufficiently close to the expected result when using Set Kinematic Target which will cause the test to fail: - https://jira.agscollab.com/browse/LY-107723 + LY-107723 Test Steps: 1) Open level and enter game mode diff --git a/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py b/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py index 4ae10288bd..e714da9de7 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C3510644_Collider_CollisionGroups.py @@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # Test case ID : C3510644 # Test Case Title : Check that the collision layer and collision group of the terrain can be changed # and the collision behavior of the terrain changes accordingly -# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/3510644 # fmt: off diff --git a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py index d65e9050bd..57cdc8f9c5 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py @@ -114,5 +114,5 @@ if __name__ == "__main__": import ImportPathHelper as imports imports.init() - from utils import Report + from editor_python_test_tools.utils import Report Report.start_test(C4044695_PhysXCollider_AddMultipleSurfaceFbx) diff --git a/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py b/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py index 4b0b036970..08083a7868 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py +++ b/AutomatedTesting/Gem/PythonTests/physics/C6321601_Force_HighValuesDirectionAxes.py @@ -239,7 +239,7 @@ def C6321601_Force_HighValuesDirectionAxes(): force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force) # Wait for 3 secs, because there is a known bug identified and filed in - # JIRA https://jira.agscollab.com/browse/LY-107677 + # JIRA LY-107677 # The error "[Error] Huge object being added to a COctreeNode, name: 'MeshComponentRenderNode', objBox:" # will show (if occured) in about 3 sec into the game mode. helper.wait_for_condition(has_physx_error, 3.0) diff --git a/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt new file mode 100644 index 0000000000..4f89e841df --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt @@ -0,0 +1,52 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::PhysicsTests_Main + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Physics + ) + ly_add_pytest( + NAME AutomatedTesting::PhysicsTests_Periodic + TEST_SUITE periodic + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Physics + ) + ly_add_pytest( + NAME AutomatedTesting::PhysicsTests_Sandbox + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Physics + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py index 8f098941ea..8986c1024a 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py +++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_InDevelopment.py @@ -50,7 +50,7 @@ class TestAutomation(TestAutomationBase): unexpected_lines = ["Assert"] self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines) - # BUG: https://jira.agscollab.com/browse/LY-107723") + # BUG: LY-107723") def test_C14976308_ScriptCanvas_SetKinematicTargetTransform(self, request, workspace, editor): from . import C14976308_ScriptCanvas_SetKinematicTargetTransform as test_module diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main.py index 8f1f2f7481..2cf55c7a58 100644 --- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main.py @@ -42,6 +42,7 @@ class TestAutomation(TestAutomationBase): self._run_test(request, workspace, editor, test_module) @revert_physics_config + @fm.file_override('physxsystemconfiguration.setreg','C4044459_Material_DynamicFriction.setreg_override', 'AutomatedTesting/Registry') def test_C4044459_Material_DynamicFriction(self, request, workspace, editor, launcher_platform): from . import C4044459_Material_DynamicFriction as test_module self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py index 3bbfe64e38..2b82c3e596 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py +++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py @@ -429,6 +429,8 @@ class TestAutomation(TestAutomationBase): from . import C4976236_AddPhysxColliderComponent as test_module self._run_test(request, workspace, editor, test_module) + @pytest.mark.xfail( + reason="This will fail due to this issue ATOM-15487.") def test_C14861502_PhysXCollider_AssetAutoAssigned(self, request, workspace, editor, launcher_platform): from . import C14861502_PhysXCollider_AssetAutoAssigned as test_module self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py b/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py index 5f24f41083..b6d7c610e3 100755 --- a/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py +++ b/AutomatedTesting/Gem/PythonTests/physics/UtilTest_Physmaterial_Editor.py @@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ''' This unittest might have to be refactored once changes to Physmaterial_Editor.py are made. These changes will occur after the but, reverence below is resloved. -Bug: https://jira.agscollab.com/browse/LY-107392 +Bug: LY-107392 ''' class Tests: opening_bad_file = ("Bad file could not be opened", "Bad file was opened") diff --git a/AutomatedTesting/Gem/PythonTests/prefab/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/prefab/CMakeLists.txt new file mode 100644 index 0000000000..61f1944974 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/CMakeLists.txt @@ -0,0 +1,25 @@ +# +# 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. +# + +## Prefab ## +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::PrefabTests + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py new file mode 100644 index 0000000000..3401c6a0a9 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/PrefabLevel_OpensLevelWithEntities.py @@ -0,0 +1,76 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + +# fmt:off +class Tests(): + find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level") + empty_entity_pos = ("'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position") + find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level") + pxentity_component = ("Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' does *not* have a Physx Collider") + +# fmt:on + +def PrefabLevel_OpensLevelWithEntities(): + """ + Opens the level that contains 2 entities, "EmptyEntity" and "EntityWithPxCollider". + This test makes sure that both entities exist after opening the level and that: + - EmptyEntity is at Position: (10, 20, 30) + - EntityWithPxCollider has a PhysXCollider component + """ + + import os + import sys + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + + import editor_python_test_tools.hydra_editor_utils as hydra + + import azlmbr.entity as entity + import azlmbr.bus as bus + from azlmbr.math import Vector3 + + EXPECTED_EMPTY_ENTITY_POS = Vector3(10.00, 20.0, 30.0) + + helper.init_idle() + helper.open_level("prefab", "PrefabLevel_OpensLevelWithEntities") + + def find_entity(entity_name): + searchFilter = entity.SearchFilter() + searchFilter.names = [entity_name] + entityIds = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter) + if entityIds[0].IsValid(): + return entityIds[0] + return None +#Checks for an entity called "EmptyEntity" + helper.wait_for_condition(lambda: find_entity("EmptyEntity").IsValid(), 5.0) + empty_entity_id = find_entity("EmptyEntity") + Report.result(Tests.find_empty_entity, empty_entity_id.IsValid()) + +# Checks if the EmptyEntity is in the correct position and if it fails, it will provide the expected postion and the actual postion of the entity in the Editor log + empty_entity_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", empty_entity_id) + is_at_position = empty_entity_pos.IsClose(EXPECTED_EMPTY_ENTITY_POS) + Report.result(Tests.empty_entity_pos, is_at_position) + if not is_at_position: + Report.info(f'Expected position: {EXPECTED_EMPTY_ENTITY_POS.ToString()}, actual position: {empty_entity_pos.ToString()}') + +#Checks for an entity called "EntityWithPxCollider" and if it has the PhysX Collider component + pxentity = find_entity("EntityWithPxCollider") + Report.result(Tests.find_pxentity, pxentity.IsValid()) + + pxcollider_id = hydra.get_component_type_id("PhysX Collider") + hasComponent = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'HasComponentOfType', pxentity, pxcollider_id) + Report.result(Tests.pxentity_component, hasComponent) + +if __name__ == "__main__": + + from editor_python_test_tools.utils import Report + Report.start_test (PrefabLevel_OpensLevelWithEntities) diff --git a/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py new file mode 100644 index 0000000000..51c78a99e2 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/TestSuite_Main.py @@ -0,0 +1,35 @@ +""" + All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + its licensors. + + For complete copyright and license terms please see the LICENSE at the root of this + distribution (the "License"). All use of this software is governed by the License, + or, if provided, by the license below or the license accompanying this file. Do not + remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + + """ + +# This suite consists of all test cases that are passing and have been verified. + +import pytest +import os +import sys + +from ly_test_tools import LAUNCHERS + +sys.path.append (os.path.dirname (os.path.abspath (__file__)) + '/../automatedtesting_shared') + +from base import TestAutomationBase + +@pytest.mark.SUITE_main +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(TestAutomationBase): + + def _run_prefab_test(self, request, workspace, editor, test_module): + self._run_test(request, workspace, editor, test_module, ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"]) + + def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform): + from . import PrefabLevel_OpensLevelWithEntities as test_module + self._run_prefab_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/prefab/__init__.py b/AutomatedTesting/Gem/PythonTests/prefab/__init__.py new file mode 100644 index 0000000000..79f8fa4422 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/prefab/__init__.py @@ -0,0 +1,10 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py deleted file mode 100644 index dcbbf47f0c..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_CreateScriptEventFile.py +++ /dev/null @@ -1,124 +0,0 @@ -""" -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. - -Test case ID: T92569013 -Test Case Title: Script Event file can be created -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569013 -""" - - -# fmt: off -class Tests(): - new_event_created = ("New Script Event created", "New Script Event not created") - child_event_created = ("Child Event created", "Child not created") - file_saved = ("Script event file saved", "Script event file did not save") - console_error = ("No unexpected error in console", "Error found in console") - console_warning = ("No unexpected warning in console", "Warning found in console") -# fmt: on - - -def CreateScriptEventFile(): - """ - Summary: - Script Event file can be created - - Expected Behavior: - File is created without any errors and warnings in Console - - Test Steps: - 1) Open Asset Editor - 2) Get Asset Editor Qt object - 3) Create new Script Event Asset - 4) Add new child event - 5) Save the Script Event file - 6) Verify if file is created - 7) Verify console for errors/warnings - 8) Close Asset Editor - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - import os - from utils import Report - from utils import TestHelper as helper - from utils import Tracer - import pyside_utils - - # Open 3D Engine imports - import azlmbr.legacy.general as general - import azlmbr.editor as editor - import azlmbr.bus as bus - - # Pyside imports - from PySide2 import QtWidgets - - GENERAL_WAIT = 1.0 # seconds - - FILE_PATH = os.path.join("AutomatedTesting", "ScriptCanvas", "test_file.scriptevent") - - # 1) Open Asset Editor - general.idle_enable(True) - # Initially close the Asset Editor and then reopen to ensure we don't have any existing assets open - general.close_pane("Asset Editor") - general.open_pane("Asset Editor") - helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), 5.0) - - # 2) Get Asset Editor Qt object - editor_window = pyside_utils.get_editor_main_window() - asset_editor_widget = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor").findChild( - QtWidgets.QWidget, "AssetEditorWindowClass" - ) - container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") - menu_bar = asset_editor_widget.findChild(QtWidgets.QMenuBar) - - # 3) Create new Script Event Asset - action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "text": "Script Events"}) - action.trigger() - result = helper.wait_for_condition( - lambda: container.findChild(QtWidgets.QFrame, "Events") is not None, 3 * GENERAL_WAIT - ) - Report.result(Tests.new_event_created, result) - - # 4) Add new child event - add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") - add_event.click() - result = helper.wait_for_condition( - lambda: asset_editor_widget.findChild(QtWidgets.QFrame, "EventName") is not None, GENERAL_WAIT - ) - Report.result(Tests.child_event_created, result) - - with Tracer() as section_tracer: - # 5) Save the Script Event file - editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", FILE_PATH) - - # 6) Verify if file is created - result = helper.wait_for_condition(lambda: os.path.exists(FILE_PATH), 3 * GENERAL_WAIT) - Report.result(Tests.file_saved, result) - - # 7) Verify console for errors/warnings - Report.result(Tests.console_error, not section_tracer.has_errors) - Report.result(Tests.console_warning, not section_tracer.has_warnings) - - # 8) Close Asset Editor - general.close_pane("Asset Editor") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(CreateScriptEventFile) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py b/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py deleted file mode 100644 index 1f801d4eeb..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/AssetEditor_NewScriptEvent.py +++ /dev/null @@ -1,129 +0,0 @@ -""" -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. - - -Test case ID: T92568942 -Test Case Title: Clicking the "+" button and selecting "New Script Event" opens the -Asset Editor with a new Script Event asset -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568942 -""" - -from PySide2 import QtWidgets -import azlmbr.legacy.general as general - -import editor_python_test_tools.pyside_utils as pyside_utils -from editor_python_test_tools.utils import TestHelper as helper -from editor_python_test_tools.utils import Report - - -class Tests: - action_found = "New Script event action found" - asset_editor_opened = "Asset Editor opened" - new_asset = "Asset Editor created with new asset" - script_event = "New Script event created in Asset Editor" - - -GENERAL_WAIT = 0.5 # seconds - - -class TestAssetEditor_NewScriptEvent: - """ - Summary: - Clicking the "+" button in Node Palette and creating New Script Event opens Asset Editor - - Expected Behavior: - Clicking the "+" button and selecting "New Script Event" opens the Asset Editor with a - new Script Event asset - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Close any existing AssetEditor window - 3) Get the SC window object - 4) Click on New Script Event on Node palette - 5) Verify if Asset Editor opened - 6) Verify if a new asset with Script Canvas category is opened - 7) Close Script Canvas and Asset Editor - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - @pyside_utils.wrap_async - async def run_test(self): - # 1) Open Script Canvas window (Tools > Script Canvas) - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Close any existing AssetEditor window - general.close_pane("Asset Editor") - helper.wait_for_condition(lambda: not general.is_pane_visible("Asset Editor"), 5.0) - - # 3) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") - frame = node_palette.findChild(QtWidgets.QFrame, "searchCustomization") - button = frame.findChild(QtWidgets.QToolButton) - pyside_utils.click_button_async(button) - - # 4) Click on New Script Event on Node palette - menu = None - - def menu_has_focus(): - nonlocal menu - for fw in [ - QtWidgets.QApplication.activePopupWidget(), - QtWidgets.QApplication.activeModalWidget(), - QtWidgets.QApplication.focusWidget(), - QtWidgets.QApplication.activeWindow(), - ]: - print(fw) - if fw and isinstance(fw, QtWidgets.QMenu) and fw.isVisible(): - menu = fw - return True - return False - - await pyside_utils.wait_for_condition(menu_has_focus, GENERAL_WAIT) - action = await pyside_utils.wait_for_action_in_menu(menu, {"text": "New Script Event"}) - Report.info(f"{Tests.action_found}: {action is not None}") - action.trigger() - pyside_utils.queue_hide_event(menu) - - # 5) Verify if Asset Editor opened - result = helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), GENERAL_WAIT) - Report.info(f"{Tests.asset_editor_opened}: {result}") - - # 6) Verify if a new asset with Script Canvas category is opened - asset_editor = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor") - row_container = asset_editor.findChild(QtWidgets.QWidget, "ContainerForRows") - # NOTE: QWidget ContainerForRows will have frames of Name, Category, ToolTip etc. - # To validate if a new script event file is generated, we check for - # QFrame Category and its value - categories = row_container.findChildren(QtWidgets.QFrame, "Category") - Report.info(f"{Tests.new_asset}: {len(categories)>0}") - result = False - for frame in categories: - line_edit = frame.findChild(QtWidgets.QLineEdit) - result = True if (line_edit and line_edit.text() == "Script Events") else False - Report.info(f"{Tests.script_event}: {result}") - - # 7) Close Script Canvas and Asset Editor - general.close_pane("Script Canvas") - general.close_pane("Asset Editor") - - -test = TestAssetEditor_NewScriptEvent() -test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/scripting/CMakeLists.txt new file mode 100644 index 0000000000..58507c680c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/CMakeLists.txt @@ -0,0 +1,37 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::ScriptCanvasTests_Perodic + TEST_SUITE periodic + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Periodic.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + ScriptCanvas + ) + ly_add_pytest( + NAME AutomatedTesting::ScriptCanvasTests_Sandbox + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + ) +endif() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleEntities.py new file mode 100644 index 0000000000..2c36062acf --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleEntities.py @@ -0,0 +1,138 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("New level created", "New level not created") + entities_found = ("Entities are found in Logging window", "Entities are not found in Logging window") + select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected") +# fmt: on + + +GENERAL_WAIT = 0.5 # seconds + + +def Debugger_HappyPath_TargetMultipleEntities(): + """ + Summary: + Multiple Entities can be targeted in the Debugger tool + + Expected Behavior: + Multiple selected files can be checked for logging. + Upon checking, checkboxes of the parent folders change to either full or partial check. + + Test Steps: + 1) Create temp level + 2) Create two entities with scriptcanvas components + 3) Set values for scriptcanvas + 4) Open Script Canvas window and get sc object + 5) Open Debugging(Logging) window + 6) Click on Entities tab in logging window + 7) Verify if the scriptcanvas exist under entities + 8) Verify if the entities can be selected + 9) Close Debugging window and Script Canvas window + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from PySide2 import QtWidgets + from PySide2.QtCore import Qt + import azlmbr.legacy.general as general + import azlmbr.math as math + import azlmbr.asset as asset + import azlmbr.bus as bus + + import os + import pyside_utils + import hydra_editor_utils as hydra + from utils import TestHelper as helper + from utils import Report + + LEVEL_NAME = "tmp_level" + ASSET_NAME_1 = "ScriptCanvas_TwoComponents0.scriptcanvas" + ASSET_NAME_2 = "ScriptCanvas_TwoComponents1.scriptcanvas" + ASSET_1 = os.path.join("scriptcanvas", ASSET_NAME_1) + ASSET_2 = os.path.join("scriptcanvas", ASSET_NAME_2) + WAIT_TIME = 3.0 + + def get_asset(asset_path): + return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create two entities with scriptcanvas components + position = math.Vector3(512.0, 512.0, 32.0) + test_entity_1 = hydra.Entity("test_entity_1") + test_entity_1.create_entity(position, ["Script Canvas"]) + test_entity_2 = hydra.Entity("test_entity_2") + test_entity_2.create_entity(position, ["Script Canvas"]) + + # 3) Set values for scriptcanvas + test_entity_1.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_1)) + test_entity_2.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_2)) + + # 4) Open Script Canvas window and get sc opbject + general.open_pane("Script Canvas") + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 5) Open Debugging(Logging) window + if ( + sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") is None + or not sc.findChild(QtWidgets.QDockWidget, "LoggingWindow").isVisible() + ): + action = pyside_utils.find_child_by_pattern(sc, {"text": "Debugging", "type": QtWidgets.QAction}) + action.trigger() + logging_window = sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") + + # 6) Click on Entities tab in logging window + button = pyside_utils.find_child_by_pattern(logging_window, {"type": QtWidgets.QPushButton, "text": "Entities"}) + button.click() + + # 7) Verify if the scriptcanvas exist under entities + entities = logging_window.findChild(QtWidgets.QWidget, "entitiesPage") + tree = entities.findChild(QtWidgets.QTreeView, "pivotTreeView") + asset_1_mi = pyside_utils.find_child_by_pattern(tree, ASSET_NAME_1.lower()) + asset_2_mi = pyside_utils.find_child_by_pattern(tree, ASSET_NAME_2.lower()) + result = asset_1_mi is not None and asset_2_mi is not None + Report.critical_result(Tests.entities_found, result) + + # 8) Verify if the entities can be selected + tree.expandAll() + tree.model().setData(asset_1_mi, 2, Qt.CheckStateRole) + tree.model().setData(asset_2_mi, 2, Qt.CheckStateRole) + checklist = [asset_1_mi, asset_1_mi.parent(), asset_2_mi, asset_2_mi.parent()] + result = all([index.data(Qt.CheckStateRole) == 2 for index in checklist]) + Report.critical_result(Tests.select_multiple_targets, result) + + # 9) Close Debugging window and Script Canvas window + logging_window.close() + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(Debugger_HappyPath_TargetMultipleEntities) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleGraphs.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleGraphs.py new file mode 100644 index 0000000000..906c198d43 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Debugger_HappyPath_TargetMultipleGraphs.py @@ -0,0 +1,106 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected") +# fmt: on + + +GENERAL_WAIT = 0.5 # seconds + + +def Debugger_HappyPath_TargetMultipleGraphs(): + """ + Summary: + Multiple Graphs can be targeted in the Debugger tool + + Expected Behavior: + Multiple elected files can be checked for logging. + Upon checking, checkboxes of the parent folders change to either full or partial check. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Debugging Tool if not opened already + 4) Select Graphs tab under logging window + 5) Select multiple targets from levels and scriptcanvas + 6) Verify if multiple targets are selected + 7) Close Debugging window and Script Canvas window + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from PySide2 import QtWidgets + from PySide2.QtCore import Qt + import azlmbr.legacy.general as general + + import pyside_utils + from utils import TestHelper as helper + from utils import Report + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 6.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 3) Open Debugging Tool if not opened already + if ( + sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") is None + or not sc.findChild(QtWidgets.QDockWidget, "LoggingWindow").isVisible() + ): + action = pyside_utils.find_child_by_pattern(sc, {"text": "Debugging", "type": QtWidgets.QAction}) + action.trigger() + logging_window = sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") + + # 4) Select Graphs tab under logging window + button = pyside_utils.find_child_by_pattern(logging_window, {"type": QtWidgets.QPushButton, "text": "Graphs"}) + button.click() + + # 5) Select multiple targets from levels and scriptcanvas + graphs = logging_window.findChild(QtWidgets.QWidget, "graphsPage") + tree = graphs.findChild(QtWidgets.QTreeView, "pivotTreeView") + # Select the first child under levels + level_model_index = pyside_utils.find_child_by_pattern(tree, "levels") + level_child_index = pyside_utils.get_item_view_index(tree, 0, 0, level_model_index) + tree.model().setData(level_child_index, 2, Qt.CheckStateRole) + # Select the first child under scriptcanvas + sc_model_index = pyside_utils.find_child_by_pattern(tree, "scriptcanvas") + sc_child_index = pyside_utils.get_item_view_index(tree, 0, 0, sc_model_index) + tree.model().setData(sc_child_index, 2, Qt.CheckStateRole) + + # 6) Verify if multiple targets are selected + result = all([index.data(Qt.CheckStateRole) != 0 for index in (level_model_index, sc_model_index)]) + result = result and all([index.data(Qt.CheckStateRole) == 2 for index in (level_child_index, sc_child_index)]) + Report.result(Tests.select_multiple_targets, result) + + # 7) Close Debugging window and Script Canvas window + logging_window.close() + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(Debugger_HappyPath_TargetMultipleGraphs) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py deleted file mode 100644 index a26cb4f923..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleEntities.py +++ /dev/null @@ -1,144 +0,0 @@ -""" -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. - - -Test case ID: T92568856 -Test Case Title: Multiple Entities can be targeted in the Debugger tool -URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568856 -""" - - -# fmt: off -class Tests(): - level_created = ("New level created", "New level not created") - entities_found = ("Entities are found in Logging window", "Entities are not found in Logging window") - select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected") -# fmt: on - - -GENERAL_WAIT = 0.5 # seconds - - -def Debugging_TargetMultipleEntities(): - """ - Summary: - Multiple Entities can be targeted in the Debugger tool - - Expected Behavior: - Selected files can be checked for logging. - Upon checking, checkboxes of the parent folders change to either full or partial check. - - Test Steps: - 1) Create temp level - 2) Create two entities with scriptcanvas components - 3) Set values for scriptcanvas - 4) Open Script Canvas window and get sc opbject - 5) Open Debugging(Logging) window - 6) Click on Entities tab in logging window - 7) Verify if the scriptcanvas exist under entities - 8) Verify if the entities can be selected - 9) Close Debugging window and Script Canvas window - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from PySide2 import QtWidgets - from PySide2.QtCore import Qt - import azlmbr.legacy.general as general - import azlmbr.math as math - import azlmbr.asset as asset - import azlmbr.bus as bus - - import os - import pyside_utils - import hydra_editor_utils as hydra - from utils import TestHelper as helper - from utils import Report - - LEVEL_NAME = "tmp_level" - ASSET_NAME_1 = "ScriptCanvas_TwoComponents0.scriptcanvas" - ASSET_NAME_2 = "ScriptCanvas_TwoComponents1.scriptcanvas" - ASSET_1 = os.path.join("scriptcanvas", ASSET_NAME_1) - ASSET_2 = os.path.join("scriptcanvas", ASSET_NAME_2) - WAIT_TIME = 3.0 - - def get_asset(asset_path): - return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) - - # 1) Create temp level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Create two entities with scriptcanvas components - position = math.Vector3(512.0, 512.0, 32.0) - test_entity_1 = hydra.Entity("test_entity_1") - test_entity_1.create_entity(position, ["Script Canvas"]) - test_entity_2 = hydra.Entity("test_entity_2") - test_entity_2.create_entity(position, ["Script Canvas"]) - - # 3) Set values for scriptcanvas - test_entity_1.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_1)) - test_entity_2.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_2)) - - # 4) Open Script Canvas window and get sc opbject - general.open_pane("Script Canvas") - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - - # 5) Open Debugging(Logging) window - if ( - sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") is None - or not sc.findChild(QtWidgets.QDockWidget, "LoggingWindow").isVisible() - ): - action = pyside_utils.find_child_by_pattern(sc, {"text": "Debugging", "type": QtWidgets.QAction}) - action.trigger() - logging_window = sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") - - # 6) Click on Entities tab in logging window - button = pyside_utils.find_child_by_pattern(logging_window, {"type": QtWidgets.QPushButton, "text": "Entities"}) - button.click() - - # 7) Verify if the scriptcanvas exist under entities - entities = logging_window.findChild(QtWidgets.QWidget, "entitiesPage") - tree = entities.findChild(QtWidgets.QTreeView, "pivotTreeView") - asset_1_mi = pyside_utils.find_child_by_pattern(tree, ASSET_NAME_1.lower()) - asset_2_mi = pyside_utils.find_child_by_pattern(tree, ASSET_NAME_2.lower()) - result = asset_1_mi is not None and asset_2_mi is not None - Report.critical_result(Tests.entities_found, result) - - # 8) Verify if the entities can be selected - tree.expandAll() - tree.model().setData(asset_1_mi, 2, Qt.CheckStateRole) - tree.model().setData(asset_2_mi, 2, Qt.CheckStateRole) - checklist = [asset_1_mi, asset_1_mi.parent(), asset_2_mi, asset_2_mi.parent()] - result = all([index.data(Qt.CheckStateRole) == 2 for index in checklist]) - Report.critical_result(Tests.select_multiple_targets, result) - - # 9) Close Debugging window and Script Canvas window - logging_window.close() - general.close_pane("Script Canvas") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - from utils import Report - - Report.start_test(Debugging_TargetMultipleEntities) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py b/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py deleted file mode 100644 index 4aa5c822a7..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Debugging_TargetMultipleGraphs.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -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. - - -Test case ID: T92569137 -Test Case Title: Multiple Graphs can be targeted in the Debugger tool -URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569137 -""" - - -# fmt: off -class Tests(): - select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected") -# fmt: on - - -GENERAL_WAIT = 0.5 # seconds - - -def Debugging_TargetMultipleGraphs(): - """ - Summary: - Multiple Graphs can be targeted in the Debugger tool - - Expected Behavior: - Selected files can be checked for logging. - Upon checking, checkboxes of the parent folders change to either full or partial check. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Open Debugging Tool if not opened already - 4) Select Graphs tab under logging window - 5) Select multiple targets from levels and scriptcanvas - 6) Verify if multiple targets are selected - 7) Close Debugging window and Script Canvas window - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from PySide2 import QtWidgets - from PySide2.QtCore import Qt - import azlmbr.legacy.general as general - - import pyside_utils - from utils import TestHelper as helper - from utils import Report - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 6.0) - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - - # 3) Open Debugging Tool if not opened already - if ( - sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") is None - or not sc.findChild(QtWidgets.QDockWidget, "LoggingWindow").isVisible() - ): - action = pyside_utils.find_child_by_pattern(sc, {"text": "Debugging", "type": QtWidgets.QAction}) - action.trigger() - logging_window = sc.findChild(QtWidgets.QDockWidget, "LoggingWindow") - - # 4) Select Graphs tab under logging window - button = pyside_utils.find_child_by_pattern(logging_window, {"type": QtWidgets.QPushButton, "text": "Graphs"}) - button.click() - - # 5) Select multiple targets from levels and scriptcanvas - graphs = logging_window.findChild(QtWidgets.QWidget, "graphsPage") - tree = graphs.findChild(QtWidgets.QTreeView, "pivotTreeView") - # Select the first child under levels - level_model_index = pyside_utils.find_child_by_pattern(tree, "levels") - level_child_index = pyside_utils.get_item_view_index(tree, 0, 0, level_model_index) - tree.model().setData(level_child_index, 2, Qt.CheckStateRole) - # Select the first child under scriptcanvas - sc_model_index = pyside_utils.find_child_by_pattern(tree, "scriptcanvas") - sc_child_index = pyside_utils.get_item_view_index(tree, 0, 0, sc_model_index) - tree.model().setData(sc_child_index, 2, Qt.CheckStateRole) - - # 6) Verify if multiple targets are selected - result = all([index.data(Qt.CheckStateRole) != 0 for index in (level_model_index, sc_model_index)]) - result = result and all([index.data(Qt.CheckStateRole) == 2 for index in (level_child_index, sc_child_index)]) - Report.result(Tests.select_multiple_targets, result) - - # 7) Close Debugging window and Script Canvas window - logging_window.close() - general.close_pane("Script Canvas") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(Debugging_TargetMultipleGraphs) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py deleted file mode 100755 index 4fa1e1257f..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Docking_Pane.py +++ /dev/null @@ -1,117 +0,0 @@ -""" -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. - -Test case ID: C1702824 -Test Case Title: Docking -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702824 -""" - - -# fmt: off -class Tests(): - pane_opened = ("Pane is opened successfully", "Failed to open pane") - dock_pane = ("Pane is docked successfully", "Failed to dock Pane into one or more allowed area") -# fmt: on - - -def Docking_Pane(): - """ - Summary: - The Script Canvas window is opened to verify if Script canvas panes can be docked into - every possible area of Script Canvas main window. - - Expected Behavior: - The pane docks successfully. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Make sure Node Palette pane is opened - 3) Dock the Node Palette pane into every possible area of main window - 4) Restore default layout - 5) Close Script Canvas window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - # Helper imports - import ImportPathHelper as imports - - imports.init() - - from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper - import editor_python_test_tools.pyside_utils as pyside_utils - - # Open 3D Engine imports - import azlmbr.legacy.general as general - - # Pyside imports - from PySide2 import QtCore, QtWidgets - from PySide2.QtCore import Qt - - PANE_WIDGET = "NodePalette" # Chosen most commonly used pane - DOCKAREAS = [Qt.TopDockWidgetArea, Qt.BottomDockWidgetArea, Qt.RightDockWidgetArea, Qt.LeftDockWidgetArea] - DOCKED = True - - def click_menu_option(window, option_text): - action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) - action.trigger() - - def find_pane(window, pane_name): - return window.findChild(QtWidgets.QDockWidget, pane_name) - - # Test starts here - general.idle_enable(True) - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Make sure Node Palette pane is opened - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - sc_main = sc.findChild(QtWidgets.QMainWindow) - pane = find_pane(sc_main, PANE_WIDGET) - if not pane.isVisible(): - click_menu_option(sc, "Node Palette") - pane = find_pane(sc_main, PANE_WIDGET) # New reference - - Report.result(Tests.pane_opened, pane.isVisible()) - - # 3) Dock the Node Palette pane into every possible area of main window - for area in DOCKAREAS: - sc_main.addDockWidget(area, find_pane(sc_main, PANE_WIDGET), QtCore.Qt.Vertical) - if not (sc_main.dockWidgetArea(find_pane(sc_main, PANE_WIDGET)) == area): - Report.info(f"Failed to dock into {str(area)}") - DOCKED = DOCKED and (sc_main.dockWidgetArea(find_pane(sc_main, PANE_WIDGET)) == area) - - Report.result(Tests.dock_pane, DOCKED) - - # 4) Restore default layout - # Need this step to restore to default in case of test failure - click_menu_option(sc, "Restore Default Layout") - - # 5) Close Script Canvas window - sc.close() - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from editor_python_test_tools.utils import Report - - Report.start_test(Docking_Pane) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py new file mode 100644 index 0000000000..34345cf36b --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py @@ -0,0 +1,113 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + variable_created = ("New variable created", "New variable not created") + undo_worked = ("Undo action working", "Undo action did not work") + redo_worked = ("Redo action working", "Redo action did not work") +# fmt: on + + +def EditMenu_Default_UndoRedo(): + """ + Summary: + Edit > Undo undoes the last action + Edit > Redo redoes the last undone action + We create a new variable in variable manager, undo and verify if variable is removed, + redo it and verify if the variable is created again. + + Expected Behavior: + The last action is undone upon selecting Undo. + The last undone action is redone upon selecting Redo. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Variable Manager if not opened already + 4) Create Graph + 5) Create new variable + 6) Verify if the variable is created initially + 7) Trigger Undo action and verify if variable is removed in Variable Manager + 8) Trigger Redo action and verify if variable is re-added in Variable Manager + 9) Close SC window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from PySide2 import QtWidgets, QtCore + + import pyside_utils + + import azlmbr.legacy.general as general + + # 1) Open Script Canvas window + general.idle_enable(True) + general.open_pane("Script Canvas") + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 3) Open Variable Manager if not opened already + if sc.findChild(QtWidgets.QDockWidget, "VariableManager") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Variable Manager", "type": QtWidgets.QAction}) + action.trigger() + variable_manager = sc.findChild(QtWidgets.QDockWidget, "VariableManager") + + # 4) Create Graph + action = pyside_utils.find_child_by_pattern(sc, {"objectName": "action_New_Script", "type": QtWidgets.QAction}) + action.trigger() + + # 5) Create new variable + add_button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") + add_button.click() # Click on Create Variable button + # Select variable type + table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") + model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") + # Click on it to create variable + pyside_utils.item_view_index_mouse_click(table_view, model_index) + + # 6) Verify if the variable is created initially + graph_vars = variable_manager.findChild(QtWidgets.QTableView, "graphVariables") + result = graph_vars.model().rowCount(QtCore.QModelIndex()) == 1 # since we added 1 variable, rowcount=1 + Report.result(Tests.variable_created, result) + + # 7) Trigger Undo action and verify if variable is removed in Variable Manager + action = sc.findChild(QtWidgets.QAction, "action_Undo") + action.trigger() + result = graph_vars.model().rowCount(QtCore.QModelIndex()) == 0 # since we triggered undo, rowcount=0 + Report.result(Tests.undo_worked, result) + + # 8) Trigger Redo action and verify if variable is readded in Variable Manager + action = sc.findChild(QtWidgets.QAction, "action_Redo") + action.trigger() + result = ( + graph_vars.model().rowCount(QtCore.QModelIndex()) == 1 + ) # since action is redone 1 variable is readded, rowcount=1 + Report.result(Tests.redo_worked, result) + + # 9) Close SC window + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(EditMenu_Default_UndoRedo) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py b/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py deleted file mode 100644 index a87d9e9be9..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/EditMenu_UndoRedo.py +++ /dev/null @@ -1,123 +0,0 @@ -""" -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. - - -Test case ID: T92569049 -Test Case Title: Edit > Undo undoes the last action -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569049 -Test case ID: T92569051 -Test Case Title: Edit > Redo redoes the last undone action -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569051 -""" - - -# fmt: off -class Tests(): - variable_created = ("New variable created", "New variable not created") - undo_worked = ("Undo action working", "Undo action did not work") - redo_worked = ("Redo action working", "Redo action did not work") -# fmt: on - - -def EditMenu_UndoRedo(): - """ - Summary: - Edit > Undo undoes the last action - Edit > Redo redoes the last undone action - We create a new variable in variable manager, undo and verify if variable is removed, - redo it and verify if the variable is created again. - - Expected Behavior: - The last action is undone. - The last undone action is redone. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Open Variable Manager if not opened already - 4) Create Graph - 5) Create new variable - 6) Verify if the variable is created initially - 7) Trigger Undo action and verify if variable is removed in Variable Manager - 8) Trigger Redo action and verify if variable is readded in Variable Manager - 9) Close SC window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from PySide2 import QtWidgets, QtCore - - import azlmbr.legacy.general as general - - import pyside_utils - - # 1) Open Script Canvas window - general.idle_enable(True) - general.open_pane("Script Canvas") - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - - # 3) Open Variable Manager if not opened already - if sc.findChild(QtWidgets.QDockWidget, "VariableManager") is None: - action = pyside_utils.find_child_by_pattern(sc, {"text": "Variable Manager", "type": QtWidgets.QAction}) - action.trigger() - variable_manager = sc.findChild(QtWidgets.QDockWidget, "VariableManager") - - # 4) Create Graph - action = pyside_utils.find_child_by_pattern(sc, {"objectName": "action_New_Script", "type": QtWidgets.QAction}) - action.trigger() - - # 5) Create new variable - add_button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") - add_button.click() # Click on Create Variable button - # Select variable type - table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") - model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") - # Click on it to create variable - pyside_utils.item_view_index_mouse_click(table_view, model_index) - - # 6) Verify if the variable is created initially - graph_vars = variable_manager.findChild(QtWidgets.QTableView, "graphVariables") - result = graph_vars.model().rowCount(QtCore.QModelIndex()) == 1 # since we added 1 variable, rowcount=1 - Report.result(Tests.variable_created, result) - - # 7) Trigger Undo action and verify if variable is removed in Variable Manager - action = sc.findChild(QtWidgets.QAction, "action_Undo") - action.trigger() - result = graph_vars.model().rowCount(QtCore.QModelIndex()) == 0 # since we triggered undo, rowcount=0 - Report.result(Tests.undo_worked, result) - - # 8) Trigger Redo action and verify if variable is readded in Variable Manager - action = sc.findChild(QtWidgets.QAction, "action_Redo") - action.trigger() - result = ( - graph_vars.model().rowCount(QtCore.QModelIndex()) == 1 - ) # since action is redone 1 variable is readded, rowcount=1 - Report.result(Tests.redo_worked, result) - - # 9) Close SC window - general.close_pane("Script Canvas") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(EditMenu_UndoRedo) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py b/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py deleted file mode 100644 index fd8e9b1173..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Entity_AddScriptCanvasComponent.py +++ /dev/null @@ -1,88 +0,0 @@ -""" -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. - -Test case ID: T92562978 -Test Case Title: Script Canvas Component can be added to an entity -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562978 -""" - - -# fmt: off -class Tests(): - level_created = ("New level created", "Failed to create new level") - entity_created = ("Test Entity created", "Failed to create test entity") - add_sc_component = ("Script Canvas component added to entity", "Failed to add SC component to entity") - no_errors_found = ("Tracer found no errors", "One or more errors found by Tracer") - no_warnings_found = ("Tracer found no warnings", "One or more warnings found by Tracer") -# fmt: on - - -def Entity_AddScriptCanvasComponent(): - """ - Summary: - verify if Script Canvas component can be added to Entity without any issue - - Expected Behavior: - Script Canvas Component is added to the entity successfully without issue. - - Test Steps: - 1) Create temp level - 2) Create test entity - 3) Start Tracer - 4) Add Script Canvas component to test entity - 5) Search for errors and warnings - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from utils import TestHelper as helper - from utils import Tracer - from editor_entity_utils import EditorEntity - import azlmbr.legacy.general as general - - LEVEL_NAME = "tmp_level" - WAIT_TIME = 3.0 # SECONDS - - # 1) Create temp level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Create new entity - test_entity = EditorEntity.create_editor_entity("test_entity") - Report.result(Tests.entity_created, test_entity.id.IsValid()) - - # 3) Start Tracer - with Tracer() as section_tracer: - - # 4) Add Script Canvas component to test entity - test_entity.add_component("Script Canvas") - Report.result(Tests.add_sc_component, test_entity.has_component("Script Canvas")) - - # 5) Search for errors and warnings - Report.result(Tests.no_errors_found, not section_tracer.has_errors) - Report.result(Tests.no_warnings_found, not section_tracer.has_warnings) - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - from utils import Report - - Report.start_test(Entity_AddScriptCanvasComponent) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Entity_HappyPath_AddScriptCanvasComponent.py b/AutomatedTesting/Gem/PythonTests/scripting/Entity_HappyPath_AddScriptCanvasComponent.py new file mode 100644 index 0000000000..22530c90c1 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Entity_HappyPath_AddScriptCanvasComponent.py @@ -0,0 +1,83 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("New level created", "Failed to create new level") + entity_created = ("Test Entity created", "Failed to create test entity") + add_sc_component = ("Script Canvas component added to entity", "Failed to add SC component to entity") + no_errors_found = ("Tracer found no errors", "One or more errors found by Tracer") + no_warnings_found = ("Tracer found no warnings", "One or more warnings found by Tracer") +# fmt: on + + +def Entity_HappyPath_AddScriptCanvasComponent(): + """ + Summary: + Script Canvas Component can be added to an entity + + Expected Behavior: + Script Canvas Component is added to the entity successfully without issue + + Test Steps: + 1) Create temp level + 2) Create test entity + 3) Start Tracer + 4) Add Script Canvas component to test entity + 5) Search for errors and warnings + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from utils import TestHelper as helper + from utils import Tracer + from editor_entity_utils import EditorEntity + import azlmbr.legacy.general as general + + LEVEL_NAME = "tmp_level" + WAIT_TIME = 3.0 # SECONDS + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create new entity + test_entity = EditorEntity.create_editor_entity("test_entity") + Report.result(Tests.entity_created, test_entity.id.IsValid()) + + # 3) Start Tracer + with Tracer() as section_tracer: + + # 4) Add Script Canvas component to test entity + test_entity.add_component("Script Canvas") + Report.result(Tests.add_sc_component, test_entity.has_component("Script Canvas")) + + # 5) Search for errors and warnings + Report.result(Tests.no_errors_found, not section_tracer.has_errors) + Report.result(Tests.no_warnings_found, not section_tracer.has_warnings) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(Entity_HappyPath_AddScriptCanvasComponent) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py new file mode 100644 index 0000000000..4771a95ab7 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py @@ -0,0 +1,90 @@ +""" +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. +""" +from PySide2 import QtWidgets + +import editor_python_test_tools.pyside_utils as pyside_utils +from editor_python_test_tools.utils import Report + +import azlmbr.legacy.general as general + + +# fmt: off +class Tests(): + new_action = "File->New action working as expected" + open_action = "File->Open action working as expected" +# fmt: on + + +GENERAL_WAIT = 0.5 # seconds + + +class TestFileMenuDefaultNewOpen: + """ + Summary: + When clicked on File->New, new script opens + File->Open should open the FileBrowser + + Expected Behavior: + New and Open actions should work as expected. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Trigger File->New action + 4) Verify if New tab is opened + 5) Trigger File->Open action + 6) Close Script Canvas window + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + @pyside_utils.wrap_async + async def run_test(self): + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + sc_tabs = sc_main.findChild(QtWidgets.QTabWidget, "ScriptCanvasTabs") + + # 3) Trigger File->New action + initial_tabs_count = sc_tabs.count() + action = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} + ) + action.trigger() + + # 4) Verify if New tab is opened + general.idle_wait(GENERAL_WAIT) + Report.info(f"{Tests.new_action}: {sc_tabs.count() == initial_tabs_count + 1}") + + # 5) Trigger File->Open action + action = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_Open", "type": QtWidgets.QAction}) + pyside_utils.trigger_action_async(action) + general.idle_wait(GENERAL_WAIT) + popup = await pyside_utils.wait_for_modal_widget() + Report.info(f"{Tests.open_action}: {popup and 'Open' in popup.windowTitle()}") + popup.close() + + # 6) Close Script Canvas window + general.close_pane("Script Canvas") + + +test = TestFileMenuDefaultNewOpen() +test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py deleted file mode 100644 index f72ac8ea01..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_New_Open.py +++ /dev/null @@ -1,98 +0,0 @@ -""" -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. - - -Test case ID: T92569037 -Test Case Title: File > New Script creates a new script -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569037 -Test case ID: T92569039 -Test Case Title: File > Open opens the Open... dialog -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569039 -""" - -import os -import sys -from PySide2 import QtWidgets -import azlmbr.legacy.general as general - -import editor_python_test_tools.pyside_utils as pyside_utils -from editor_python_test_tools.utils import Report - -# fmt: off -class Tests(): - new_action = "File->New action working as expected" - open_action = "File->Open action working as expected" -# fmt: on - - -GENERAL_WAIT = 0.5 # seconds - - -class TestFileMenuNewOpen: - """ - Summary: - When clicked on File->New, new script opens and File->Open should open the FileBrowser - - Expected Behavior: - New and Open actions should work as expected. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Trigger File->New action - 4) Verify if New tab is opened - 5) Trigger File->Open action - 6) Close Script Canvas window - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - @pyside_utils.wrap_async - async def run_test(self): - # 1) Open Script Canvas window (Tools > Script Canvas) - general.open_pane("Script Canvas") - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - sc_main = sc.findChild(QtWidgets.QMainWindow) - sc_tabs = sc_main.findChild(QtWidgets.QTabWidget, "ScriptCanvasTabs") - - # 3) Trigger File->New action - initial_tabs_count = sc_tabs.count() - action = pyside_utils.find_child_by_pattern( - sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} - ) - action.trigger() - - # 4) Verify if New tab is opened - general.idle_wait(GENERAL_WAIT) - Report.info(f"{Tests.new_action}: {sc_tabs.count() == initial_tabs_count + 1}") - - # 5) Trigger File->Open action - action = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_Open", "type": QtWidgets.QAction}) - pyside_utils.trigger_action_async(action) - general.idle_wait(GENERAL_WAIT) - popup = await pyside_utils.wait_for_modal_widget() - Report.info(f"{Tests.open_action}: {popup and 'Open' in popup.windowTitle()}") - popup.close() - - # 6) Close Script Canvas window - general.close_pane("Script Canvas") - - -test = TestFileMenuNewOpen() -test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_Default_SavePrompt.py b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_Default_SavePrompt.py new file mode 100644 index 0000000000..9720c846c7 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_Default_SavePrompt.py @@ -0,0 +1,102 @@ +""" +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. +""" + +from PySide2 import QtWidgets + +import editor_python_test_tools.pyside_utils as pyside_utils +from editor_python_test_tools.utils import TestHelper as helper +from editor_python_test_tools.utils import Report + +import azlmbr.legacy.general as general + + +# fmt: off +class Tests(): + new_graph = "New graph created" + save_prompt = "Save prompt opened as expected" + close_graph = "Close button worked as expected" +# fmt: on + + +GENERAL_WAIT = 0.5 # seconds + + +class TestGraphClose_Default_SavePrompt: + """ + Summary: + The graph is closed when x button is clicked. + Save Prompt is opened before closing. + + Expected Behavior: + The Graph is closed. + Upon closing the graph, User is prompted whether or not to save changes. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Trigger File->New action + 4) Verify if New tab is opened + 5) Close new tab using X on top of graph and check for save dialog + 6) Check if tab is closed + 7) Close Script Canvas window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + @pyside_utils.wrap_async + async def run_test(self): + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + sc_tabs = sc_main.findChild(QtWidgets.QTabWidget, "ScriptCanvasTabs") + tab_bar = sc_tabs.findChild(QtWidgets.QTabBar) + + # 3) Trigger File->New action + initial_tabs_count = sc_tabs.count() + action = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} + ) + action.trigger() + + # 4) Verify if New tab is opened + result = helper.wait_for_condition(lambda: sc_tabs.count() == initial_tabs_count + 1, GENERAL_WAIT) + Report.info(f"{Tests.new_graph}: {result}") + + # 5) Close new tab using X on top of graph and check for save dialog + close_button = tab_bar.findChildren(QtWidgets.QAbstractButton)[0] + pyside_utils.click_button_async(close_button) + popup = await pyside_utils.wait_for_modal_widget() + if popup: + Report.info(f"{Tests.save_prompt}: {popup.findChild(QtWidgets.QDialog, 'SaveChangesDialog') is not None}") + dont_save = popup.findChild(QtWidgets.QPushButton, "m_continueButton") + dont_save.click() + + # 6) Check if tab is closed + await pyside_utils.wait_for_condition(lambda: sc_tabs.count() == initial_tabs_count, 5.0) + Report.info(f"{Tests.close_graph}: {sc_tabs.count()==initial_tabs_count}") + + # 7) Close Script Canvas window + general.close_pane("Script Canvas") + + +test = TestGraphClose_Default_SavePrompt() +test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py b/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py deleted file mode 100644 index ce610b159b..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/GraphClose_SavePrompt.py +++ /dev/null @@ -1,110 +0,0 @@ -""" -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. - - -Test case ID: T92563070 -Test Case Title: Graphs can be closed by clicking X on the Graph name tab -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563070 -Test case ID: T92563068 -Test Case Title: Save Prompt: User is prompted to save a graph on close after -creating a new graph -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563068 -""" - -import os -import sys -from PySide2 import QtWidgets -import azlmbr.legacy.general as general - -import editor_python_test_tools.pyside_utils as pyside_utils -from editor_python_test_tools.utils import TestHelper as helper -from editor_python_test_tools.utils import Report - -# fmt: off -class Tests(): - new_graph = "New graph created" - save_prompt = "Save prompt opened as expected" - close_graph = "Close button worked as expected" -# fmt: on - - -GENERAL_WAIT = 0.5 # seconds - - -class TestGraphCloseSavePrompt: - """ - Summary: - The graph is closed when x button is clicked. - Save Prompt is opened before closing. - - Expected Behavior: - New and Open actions should work as expected. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Trigger File->New action - 4) Verify if New tab is opened - 5) Close new tab using X on top of graph and check for save dialog - 6) Check if tab is closed - 7) Close Script Canvas window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - @pyside_utils.wrap_async - async def run_test(self): - # 1) Open Script Canvas window (Tools > Script Canvas) - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - sc_main = sc.findChild(QtWidgets.QMainWindow) - sc_tabs = sc_main.findChild(QtWidgets.QTabWidget, "ScriptCanvasTabs") - tab_bar = sc_tabs.findChild(QtWidgets.QTabBar) - - # 3) Trigger File->New action - initial_tabs_count = sc_tabs.count() - action = pyside_utils.find_child_by_pattern( - sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} - ) - action.trigger() - - # 4) Verify if New tab is opened - result = helper.wait_for_condition(lambda: sc_tabs.count() == initial_tabs_count + 1, GENERAL_WAIT) - Report.info(f"{Tests.new_graph}: {result}") - - # 5) Close new tab using X on top of graph and check for save dialog - close_button = tab_bar.findChildren(QtWidgets.QAbstractButton)[0] - pyside_utils.click_button_async(close_button) - popup = await pyside_utils.wait_for_modal_widget() - if popup: - Report.info(f"{Tests.save_prompt}: {popup.findChild(QtWidgets.QDialog, 'SaveChangesDialog') is not None}") - dont_save = popup.findChild(QtWidgets.QPushButton, "m_continueButton") - dont_save.click() - - # 6) Check if tab is closed - await pyside_utils.wait_for_condition(lambda: sc_tabs.count() == initial_tabs_count, 5.0) - Report.info(f"{Tests.close_graph}: {sc_tabs.count()==initial_tabs_count}") - - # 7) Close Script Canvas window - general.close_pane("Script Canvas") - - -test = TestGraphCloseSavePrompt() -test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Graph_HappyPath_ZoomInZoomOut.py b/AutomatedTesting/Gem/PythonTests/scripting/Graph_HappyPath_ZoomInZoomOut.py new file mode 100644 index 0000000000..11c83bb779 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Graph_HappyPath_ZoomInZoomOut.py @@ -0,0 +1,111 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + zoom_in = ("Zoom In action working as expected", "Zoom In action not working as expected") + zoom_out = ("Zoom Out action working as expected", "Zoom Out action not working as expected") +# fmt: on + + +GENERAL_WAIT = 0.5 # seconds + + +def Graph_HappyPath_ZoomInZoomOut(): + """ + Summary: + The graph can be zoomed in and zoomed out. + + Expected Behavior: + The graph is zoomed in when when we click View->ZoomIn + The graph is zoomed out when when we click View->ZoomOut + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Create new graph + 4) Get initial graph transform values + 5) Trigger Zoom In and verify if the graph transform scale is increased + 6) Trigger Zoom Out and verify if the graph transform scale is decreased + 7) Close Script Canvas window + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + # Helper imports + import ImportPathHelper as imports + + imports.init() + + from PySide2 import QtWidgets + import azlmbr.legacy.general as general + + import pyside_utils + from utils import TestHelper as helper + from utils import Report + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + + # 3) Create new graph + create_new_graph = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} + ) + create_new_graph.trigger() + + # 4) Get initial graph transform values + graphics_view = sc_main.findChild(QtWidgets.QGraphicsView) + # NOTE: transform m11 and m22 are horizontal and vertical scales of graph + # they increase when zoomed in and decreased when zoomed out + curr_m11, curr_m22 = graphics_view.transform().m11(), graphics_view.transform().m22() + + # 5) Trigger Zoom In and verify if the graph transform scale is increased + zin = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomIn", "type": QtWidgets.QAction}) + zin.trigger() + result = helper.wait_for_condition( + lambda: curr_m11 < graphics_view.transform().m11() and curr_m22 < graphics_view.transform().m22(), GENERAL_WAIT + ) + Report.result(Tests.zoom_in, result) + + # 6) Trigger Zoom Out and verify if the graph transform scale is decreased + curr_m11, curr_m22 = graphics_view.transform().m11(), graphics_view.transform().m22() + zout = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomOut", "type": QtWidgets.QAction}) + zout.trigger() + result = helper.wait_for_condition( + lambda: curr_m11 > graphics_view.transform().m11() and curr_m22 > graphics_view.transform().m22(), GENERAL_WAIT + ) + Report.result(Tests.zoom_out, result) + + # 7) Close Script Canvas window + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(Graph_HappyPath_ZoomInZoomOut) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py b/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py deleted file mode 100644 index a93b6e61d1..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Graph_ZoomInZoomOut.py +++ /dev/null @@ -1,120 +0,0 @@ -""" -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. - - -Test case ID: T92569079 -Test Case Title: View > Zoom In zooms the graph in -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569079 -Test case ID: T92569081 -Test Case Title: View > Zoom In zooms the graph out -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569081 -""" - - -# fmt: off -class Tests(): - zoom_in = ("Zoom In action working as expected", "Zoom In action not working as expected") - zoom_out = ("Zoom Out action working as expected", "Zoom Out action not working as expected") -# fmt: on - - -GENERAL_WAIT = 0.5 # seconds - - -def Graph_ZoomInZoomOut(): - """ - Summary: - The graph can be zoomed in and zoomed out. - - Expected Behavior: - The graph is zoomed in when when we click View->ZoomIn - The graph is zoomed out when when we click View->ZoomOut - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Create new graph - 4) Get initial graph transform values - 5) Trigger Zoom In and verify if the graph transform scale is increased - 6) Trigger Zoom Out and verify if the graph transform scale is decreased - 7) Close Script Canvas window - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - # Helper imports - import ImportPathHelper as imports - - imports.init() - - from PySide2 import QtWidgets - import azlmbr.legacy.general as general - - import pyside_utils - from utils import TestHelper as helper - from utils import Report - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - sc_main = sc.findChild(QtWidgets.QMainWindow) - - # 3) Create new graph - create_new_graph = pyside_utils.find_child_by_pattern( - sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} - ) - create_new_graph.trigger() - - # 4) Get initial graph transform values - graphics_view = sc_main.findChild(QtWidgets.QGraphicsView) - # NOTE: transform m11 and m22 are horizontal and vertical scales of graph - # they increase when zoomed in and decreased when zoomed out - curr_m11, curr_m22 = graphics_view.transform().m11(), graphics_view.transform().m22() - - # 5) Trigger Zoom In and verify if the graph transform scale is increased - zin = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomIn", "type": QtWidgets.QAction}) - zin.trigger() - result = helper.wait_for_condition( - lambda: curr_m11 < graphics_view.transform().m11() and curr_m22 < graphics_view.transform().m22(), GENERAL_WAIT, - ) - Report.result(Tests.zoom_in, result) - - # 6) Trigger Zoom Out and verify if the graph transform scale is decreased - curr_m11, curr_m22 = graphics_view.transform().m11(), graphics_view.transform().m22() - zout = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomOut", "type": QtWidgets.QAction}) - zout.trigger() - result = helper.wait_for_condition( - lambda: curr_m11 > graphics_view.transform().m11() and curr_m22 > graphics_view.transform().m22(), GENERAL_WAIT, - ) - Report.result(Tests.zoom_out, result) - - # 7) Close Script Canvas window - general.close_pane("Script Canvas") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(Graph_ZoomInZoomOut) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py b/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py index a45024cebf..ef794433f0 100755 --- a/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/ImportPathHelper.py @@ -9,9 +9,10 @@ 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. """ + def init(): import os import sys - sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') - sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../EditorPythonTestTools/editor_python_test_tools') - \ No newline at end of file + + sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../automatedtesting_shared") + sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../EditorPythonTestTools/editor_python_test_tools") diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NewScriptEventButton_HappyPath_ContainsSCCategory.py b/AutomatedTesting/Gem/PythonTests/scripting/NewScriptEventButton_HappyPath_ContainsSCCategory.py new file mode 100644 index 0000000000..acc0880a73 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/NewScriptEventButton_HappyPath_ContainsSCCategory.py @@ -0,0 +1,122 @@ +""" +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. +""" + +from PySide2 import QtWidgets +import azlmbr.legacy.general as general + +import editor_python_test_tools.pyside_utils as pyside_utils +from editor_python_test_tools.utils import TestHelper as helper +from editor_python_test_tools.utils import Report + + +class Tests: + action_found = "New Script event action found" + asset_editor_opened = "Asset Editor opened" + new_asset = "Asset Editor created with new asset" + script_event = "New Script event created in Asset Editor" + + +GENERAL_WAIT = 0.5 # seconds + + +class TestAssetEditor_NewScriptEvent: + """ + Summary: + Verifying logic flow of the "+" button on the Script Canvas pane's Node Palette is as expected + + Expected Behavior: + Clicking the "+" button and selecting "New Script Event" opens the Asset Editor with a new Script Event asset + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Close any existing AssetEditor window + 3) Get the SC window object + 4) Click on New Script Event on Node palette + 5) Verify if Asset Editor opened + 6) Verify if a new asset with Script Canvas category is opened + 7) Close Script Canvas and Asset Editor + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + @pyside_utils.wrap_async + async def run_test(self): + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Close any existing AssetEditor window + general.close_pane("Asset Editor") + helper.wait_for_condition(lambda: not general.is_pane_visible("Asset Editor"), 5.0) + + # 3) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + frame = node_palette.findChild(QtWidgets.QFrame, "searchCustomization") + button = frame.findChild(QtWidgets.QToolButton) + pyside_utils.click_button_async(button) + + # 4) Click on New Script Event on Node palette + menu = None + + def menu_has_focus(): + nonlocal menu + for fw in [ + QtWidgets.QApplication.activePopupWidget(), + QtWidgets.QApplication.activeModalWidget(), + QtWidgets.QApplication.focusWidget(), + QtWidgets.QApplication.activeWindow(), + ]: + print(fw) + if fw and isinstance(fw, QtWidgets.QMenu) and fw.isVisible(): + menu = fw + return True + return False + + await pyside_utils.wait_for_condition(menu_has_focus, GENERAL_WAIT) + action = await pyside_utils.wait_for_action_in_menu(menu, {"text": "New Script Event"}) + Report.info(f"{Tests.action_found}: {action is not None}") + action.trigger() + pyside_utils.queue_hide_event(menu) + + # 5) Verify if Asset Editor opened + result = helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), GENERAL_WAIT) + Report.info(f"{Tests.asset_editor_opened}: {result}") + + # 6) Verify if a new asset with Script Canvas category is opened + asset_editor = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor") + row_container = asset_editor.findChild(QtWidgets.QWidget, "ContainerForRows") + # NOTE: QWidget ContainerForRows will have frames of Name, Category, ToolTip etc. + # To validate if a new script event file is generated, we check for + # QFrame Category and its value + categories = row_container.findChildren(QtWidgets.QFrame, "Category") + Report.info(f"{Tests.new_asset}: {len(categories)>0}") + result = False + for frame in categories: + line_edit = frame.findChild(QtWidgets.QLineEdit) + result = True if (line_edit and line_edit.text() == "Script Events") else False + Report.info(f"{Tests.script_event}: {result}") + + # 7) Close Script Canvas and Asset Editor + general.close_pane("Script Canvas") + general.close_pane("Asset Editor") + + +test = TestAssetEditor_NewScriptEvent() +test.run_test() diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodeCategory_ExpandOnClick.py b/AutomatedTesting/Gem/PythonTests/scripting/NodeCategory_ExpandOnClick.py new file mode 100644 index 0000000000..81e23dc35e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodeCategory_ExpandOnClick.py @@ -0,0 +1,127 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + pane_open = ("Script Canvas pane successfully opened", "Script Canvas pane failed to open") + click_expand = ("Category expanded on left click", "Category failed to expand on left click") + click_collapse = ("Category collapsed on left click", "Category failed to collapse on left click") + dClick_expand = ("Category expanded on double click", "Category failed to expand on double click") + dClick_collapse = ("Category collapsed on double click", "Category failed to collapse on double click") +# fmt: on + + +def NodeCategory_ExpandOnClick(): + """ + Summary: + Verifying the expand/collapse functionality on node categories + + Expected Behavior: + The node category should expand when double clicked or when the drop down indicator is + left-clicked. Once expanded, it should be collapsed via the same actions. + + Test Steps: + 1) Open Script Canvas pane + 2) Get the SC window objects + 3) Ensure all categories are collapsed for a clean state + 4) Left-Click on a node category arrow to expand it + 5) Verify it expanded + 6) Left-Click on a node category arrow to collapse it + 7) Verify it collapsed + 8) Double-Click on a node category to expand it + 9) Verify it expanded + 10) Double-Click on a node category to collapse it + 11) Verify it collapsed + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from utils import Report + from PySide2 import QtCore, QtWidgets, QtTest + from PySide2.QtTest import QTest + import pyside_utils + import azlmbr.legacy.general as general + + def left_click_arrow(item_view, index): + original_state = item_view.isExpanded(index) + rect_center_y = item_view.visualRect(index).center().y() + rect_left_x = item_view.visualRect(index).left() + for i in range(5): # this range can be increased for safe side + QtTest.QTest.mouseClick( + item_view.viewport(), + QtCore.Qt.LeftButton, + QtCore.Qt.NoModifier, + QtCore.QPoint(rect_left_x - i, rect_center_y), + ) + if item_view.isExpanded(index) != original_state: + break + + def double_click(item_view, index): + item_index_center = item_view.visualRect(index).center() + # Left click on the item before trying to double click, will otherwise fail to expand + # as first click would highlight and second click would be a 'single click' + pyside_utils.item_view_index_mouse_click(item_view, index) + QTest.mouseDClick(item_view.viewport(), QtCore.Qt.LeftButton, QtCore.Qt.NoModifier, item_index_center) + + # 1) Open Script Canvas pane + general.open_pane("Script Canvas") + Report.critical_result(Tests.pane_open, general.is_pane_visible("Script Canvas")) + + # 2) Get the SC window objects + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + nodeTree = node_palette.findChild(QtWidgets.QTreeView, "treeView") + ai_index = pyside_utils.find_child_by_pattern(nodeTree, "AI") + + # 3) Ensure all categories are collapsed for a clean state + nodeTree.collapseAll() + + # 4) Left-Click on a node category arrow to expand it + left_click_arrow(nodeTree, ai_index) + + # 5) Verify it expanded + Report.result(Tests.click_expand, nodeTree.isExpanded(ai_index)) + + # 6) Left-Click on a node category arrow to collapse it + left_click_arrow(nodeTree, ai_index) + + # 7) Verify it collapsed + Report.result(Tests.click_collapse, not nodeTree.isExpanded(ai_index)) + + # 8) Double-Click on a node category to expand it + double_click(nodeTree, ai_index) + + # 9) Verify it expanded + Report.result(Tests.dClick_expand, nodeTree.isExpanded(ai_index)) + + # 10) Double-Click on a node category to collapse it + double_click(nodeTree, ai_index) + + # 11) Verify it collapsed + Report.result(Tests.dClick_collapse, not nodeTree.isExpanded(ai_index)) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(NodeCategory_ExpandOnClick) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_HappyPath_VariableRenames.py b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_HappyPath_VariableRenames.py new file mode 100644 index 0000000000..c235db6256 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_HappyPath_VariableRenames.py @@ -0,0 +1,126 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + variable_created = ("New variable created", "New variable is not created") + node_inspector_rename = ("Variable is renamed in Node Inspector", "Variable is not renamed in Node Inspector") + variable_manager_rename = ("Variable is renamed in Variable Manager", "Variable is not renamed in Variable Manager") +# fmt: on + + +GENERAL_WAIT = 0.5 # seconds + + +def NodeInspector_HappyPath_VariableRenames(): + """ + Summary: + Renaming variables in the Node Inspector, renames the actual variable. + + Expected Behavior: + The Variable's name is changed in both Node Inspector and Variable Manager. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Variable Manager if not opened already + 4) Open Node Inspector if not opened already + 5) Create new graph and a new variable in Variable manager + 6) Click on the variable + 7) Update name in Node Inspector and click on ENTER + 8) Verify if the name is updated in Node inspector and Variable manager + 9) Close Script Canvas window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from PySide2 import QtWidgets, QtCore, QtTest + from PySide2.QtCore import Qt + + import pyside_utils + from utils import TestHelper as helper + + import azlmbr.legacy.general as general + + TEST_NAME = "test name" + + def open_tool(sc, dock_widget_name, pane_name): + if sc.findChild(QtWidgets.QDockWidget, dock_widget_name) is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": pane_name, "type": QtWidgets.QAction}) + action.trigger() + tool = sc.findChild(QtWidgets.QDockWidget, dock_widget_name) + return tool + + # 1) Open Script Canvas window + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 3) Open Variable Manager if not opened already + variable_manager = open_tool(sc, "VariableManager", "Variable Manager") + + # 4) Open Node Inspector if not opened already + node_inspector = open_tool(sc, "NodeInspector", "Node Inspector") + + # 5) Create new graph and a new variable in Variable manager + action = pyside_utils.find_child_by_pattern(sc, {"objectName": "action_New_Script", "type": QtWidgets.QAction}) + action.trigger() + graph_vars = variable_manager.findChild(QtWidgets.QTableView, "graphVariables") + add_button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") + add_button.click() + # Select variable type + table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") + model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") + # Click on it to create variable + pyside_utils.item_view_index_mouse_click(table_view, model_index) + result = graph_vars.model().rowCount(QtCore.QModelIndex()) == 1 + var_mi = pyside_utils.find_child_by_pattern(graph_vars, "Variable 1") + result = result and (var_mi is not None) + Report.critical_result(Tests.variable_created, result) + + # 6) Click on the variable + pyside_utils.item_view_index_mouse_click(graph_vars, var_mi) + + # 7) Update name in Node Inspector and click on ENTER + helper.wait_for_condition( + lambda: node_inspector.findChild(QtWidgets.QWidget, "ContainerForRows") is not None, GENERAL_WAIT + ) + row_container = node_inspector.findChild(QtWidgets.QWidget, "ContainerForRows") + name_frame = row_container.findChild(QtWidgets.QWidget, "Name") + name_line_edit = name_frame.findChild(QtWidgets.QLineEdit) + name_line_edit.setText(TEST_NAME) + QtTest.QTest.keyClick(name_line_edit, Qt.Key_Return, Qt.NoModifier) + + # 8) Verify if the name is updated in Node inspector and Variable manager + helper.wait_for_condition(lambda: var_mi.data(Qt.DisplayRole) == TEST_NAME, GENERAL_WAIT) + Report.critical_result(Tests.node_inspector_rename, name_line_edit.text() == TEST_NAME) + Report.critical_result(Tests.variable_manager_rename, var_mi.data(Qt.DisplayRole) == TEST_NAME) + + # 9) Close Script Canvas window + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(NodeInspector_HappyPath_VariableRenames) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py b/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py deleted file mode 100644 index 33d3f4137a..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodeInspector_RenameVariable.py +++ /dev/null @@ -1,132 +0,0 @@ -""" -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. - -Test case ID: T92568982 -Test Case Title: Renaming variables in the Node Inspector -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568982 -""" - - -# fmt: off -class Tests(): - variable_created = ("New variable created", "New variable is not created") - node_inspector_rename = ("Variable is renamed in Node Inspector", "Variable is not renamed in Node Inspector") - variable_manager_rename = ("Variable is renamed in Variable Manager", "Variable is not renamed in Variable Manager") -# fmt: on - - -GENERAL_WAIT = 0.5 # seconds - - -def NodeInspector_RenameVariable(): - """ - Summary: - Renaming variables in the Node Inspector, renames the actual variable. - - Expected Behavior: - The Variable's name is changed in both Node Inspector and Variable Manager. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Open Variable Manager if not opened already - 4) Open Node Inspector if not opened already - 5) Create new graph and a new variable in Variable manager - 6) Click on the variable - 7) Update name in Node Inspector and click on ENTER - 8) Verify if the name is updated in Node inspector and Variable manager - 9) Close Script Canvas window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - TEST_NAME = "test name" - - from PySide2 import QtWidgets, QtCore, QtTest - from PySide2.QtCore import Qt - import azlmbr.legacy.general as general - - import pyside_utils - from utils import TestHelper as helper - - def open_tool(sc, dock_widget_name, pane_name): - if sc.findChild(QtWidgets.QDockWidget, dock_widget_name) is None: - action = pyside_utils.find_child_by_pattern(sc, {"text": pane_name, "type": QtWidgets.QAction}) - action.trigger() - tool = sc.findChild(QtWidgets.QDockWidget, dock_widget_name) - return tool - - # 1) Open Script Canvas window - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - - # 3) Open Variable Manager if not opened already - variable_manager = open_tool(sc, "VariableManager", "Variable Manager") - - # 4) Open Node Inspector if not opened already - node_inspector = open_tool(sc, "NodeInspector", "Node Inspector") - - # 5) Create new graph and a new variable in Variable manager - action = pyside_utils.find_child_by_pattern(sc, {"objectName": "action_New_Script", "type": QtWidgets.QAction}) - action.trigger() - graph_vars = variable_manager.findChild(QtWidgets.QTableView, "graphVariables") - add_button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") - add_button.click() - # Select variable type - table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") - model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") - # Click on it to create variable - pyside_utils.item_view_index_mouse_click(table_view, model_index) - result = graph_vars.model().rowCount(QtCore.QModelIndex()) == 1 - var_mi = pyside_utils.find_child_by_pattern(graph_vars, "Variable 1") - result = result and (var_mi is not None) - Report.critical_result(Tests.variable_created, result) - - # 6) Click on the variable - pyside_utils.item_view_index_mouse_click(graph_vars, var_mi) - - # 7) Update name in Node Inspector and click on ENTER - helper.wait_for_condition( - lambda: node_inspector.findChild(QtWidgets.QWidget, "ContainerForRows") is not None, GENERAL_WAIT - ) - row_container = node_inspector.findChild(QtWidgets.QWidget, "ContainerForRows") - name_frame = row_container.findChild(QtWidgets.QWidget, "Name") - name_line_edit = name_frame.findChild(QtWidgets.QLineEdit) - name_line_edit.setText(TEST_NAME) - QtTest.QTest.keyClick(name_line_edit, Qt.Key_Return, Qt.NoModifier) - - # 8) Verify if the name is updated in Node inspector and Variable manager - helper.wait_for_condition(lambda: var_mi.data(Qt.DisplayRole) == TEST_NAME, GENERAL_WAIT) - Report.critical_result(Tests.node_inspector_rename, name_line_edit.text() == TEST_NAME) - Report.critical_result(Tests.variable_manager_rename, var_mi.data(Qt.DisplayRole) == TEST_NAME) - - # 9) Close Script Canvas window - general.close_pane("Script Canvas") - - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(NodeInspector_RenameVariable) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py deleted file mode 100644 index de30e46767..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_ClearSelection.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -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. - -Test case ID: T92562993 -Test Case Title: Clicking the X button on the Search Box clears the currently entered string -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562993 -""" - - -# fmt: off -class Tests(): - set_search_string = ("Search string is set", "Search string is not set") - search_string_cleared = ("Search string cleared as expected", "Search string not cleared") -# fmt: on - - -def NodePalette_ClearSelection(): - """ - Summary: - We enter some string in the Node Palette Search box, and click on the X button to verify if the - search string got cleared. - - Expected Behavior: - Clicking the X button on the Search Box clears the currently entered string - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Open Node Manager if not opened already - 4) Set some string in the Search box - 5) Verify if the test string is set - 6) Clear search string and verify if it is cleared - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from PySide2 import QtWidgets - - from utils import TestHelper as helper - - import azlmbr.legacy.general as general - - import pyside_utils - - TEST_STRING = "Test String" - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0) - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - - # 3) Open Node Manager if not opened already - if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: - action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) - action.trigger() - node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") - search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame") - - # 4) Set some string in the Search box - search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter") - search_box.setText(TEST_STRING) - - # 5) Verify if the test string is set - Report.result(Tests.set_search_string, search_box.text() == TEST_STRING) - - # 6) Clear search string and verify if it is cleared - clear_text_button = search_frame.findChild(QtWidgets.QToolButton, "ClearToolButton") - clear_text_button.click() - Report.result(Tests.search_string_cleared, search_box.text() == "") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - from utils import Report - - Report.start_test(NodePalette_ClearSelection) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_CanSelectNode.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_CanSelectNode.py new file mode 100644 index 0000000000..2fb1830b8f --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_CanSelectNode.py @@ -0,0 +1,100 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + category_selected = ("Category can be selected", "Category cannot be selected") + node_selected = ("Node can be selected", "Node cannot be selected") +# fmt: on + + +GENERAL_WAIT = 0.5 # seconds + + +def NodePalette_HappyPath_CanSelectNode(): + """ + Summary: + Categories and Nodes can be selected + + Expected Behavior: + A category can be selected inside the Node Palette + A Node can be selected inside the Node Palette + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Expand QTreeView + 4) Click on category and check if it is selected + 5) Click on node and check if it is selected + 6) Close Script Canvas window + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + CATEGORY = "AI" + NODE = "Find Path To Entity" + + from PySide2 import QtWidgets + + import pyside_utils + from utils import TestHelper as helper + + import azlmbr.legacy.general as general + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + tree = node_palette.findChild(QtWidgets.QTreeView, "treeView") + + # 3) Expand QTreeView + tree.expandAll() + + # 4) Click on category and check if it is selected + category_index = pyside_utils.find_child_by_hierarchy(tree, CATEGORY) + tree.scrollTo(category_index) + pyside_utils.item_view_index_mouse_click(tree, category_index) + pyside_utils.wait_for_condition(tree.selectedIndexes() and tree.selectedIndexes()[0] == category_index) + Report.result(Tests.category_selected, tree.selectedIndexes()[0] == category_index) + + # 5) Click on node and check if it is selected + node_index = pyside_utils.find_child_by_pattern(tree, NODE) + helper.wait_for_condition(lambda: tree.isExpanded(node_index), GENERAL_WAIT) + pyside_utils.item_view_index_mouse_click(tree, node_index) + pyside_utils.wait_for_condition(tree.selectedIndexes()[0] == node_index) + Report.result(Tests.node_selected, tree.selectedIndexes()[0] == node_index) + + # 6) Close Script Canvas window + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(NodePalette_HappyPath_CanSelectNode) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py new file mode 100644 index 0000000000..93254dd377 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py @@ -0,0 +1,88 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + set_search_string = ("Search string is set", "Search string is not set") + search_string_cleared = ("Search string cleared as expected", "Search string not cleared") +# fmt: on + + +def NodePalette_HappyPath_ClearSelection(): + """ + Summary: + Clicking the X button on the Search Box clears the currently entered string + + Expected Behavior: + After entering a string value into the Node Palette's search box and click on + the X button, the search box should be cleared + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Node Manager if not opened already + 4) Set some string in the Search box + 5) Verify if the test string is set + 6) Clear search string and verify if it is cleared + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from PySide2 import QtWidgets + + import pyside_utils + from utils import TestHelper as helper + + import azlmbr.legacy.general as general + + TEST_STRING = "Test String" + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 3) Open Node Manager if not opened already + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame") + + # 4) Set some string in the Search box + search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter") + search_box.setText(TEST_STRING) + + # 5) Verify if the test string is set + Report.result(Tests.set_search_string, search_box.text() == TEST_STRING) + + # 6) Clear search string and verify if it is cleared + clear_text_button = search_frame.findChild(QtWidgets.QToolButton, "ClearToolButton") + clear_text_button.click() + Report.result(Tests.search_string_cleared, search_box.text() == "") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(NodePalette_HappyPath_ClearSelection) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SearchText_Deletion.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SearchText_Deletion.py new file mode 100644 index 0000000000..0739a8e637 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SearchText_Deletion.py @@ -0,0 +1,91 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + set_search_string = ("Search string is set", "Search string is not set") + search_string_deleted = ("Search string deleted as expected", "Search string not deleted") +# fmt: on + + +def NodePalette_SearchText_Deletion(): + """ + Summary: + We enter some string in the Node Palette Search box, select that text and delete it. + + Expected Behavior: + After RightClick->Delete the text in the Searchbox should be deleted. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Node Manager if not opened already + 4) Set some string in the Search box + 5) Verify if the test string is set + 6) Delete search string using right click and verify if it is cleared + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets, QtTest, QtCore + + from utils import TestHelper as helper + + import azlmbr.legacy.general as general + + import pyside_utils + + TEST_STRING = "TestString" + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 3) Open Node Manager if not opened already + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame") + + # 4) Set some string in the Search box + search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter") + search_box.setText(TEST_STRING) + + # 5) Verify if the test string is set + result = helper.wait_for_condition(lambda: search_box.text() == TEST_STRING, 1.0) + Report.result(Tests.set_search_string, result) + + # 6) Delete search string using right click and verify if it is cleared + QtTest.QTest.keyClick(search_box, QtCore.Qt.Key_A, QtCore.Qt.ControlModifier) + pyside_utils.trigger_context_menu_entry(search_box, "Delete") + result = helper.wait_for_condition(lambda: search_box.text() == "", 2.0) + Report.result(Tests.search_string_deleted, result) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(NodePalette_SearchText_Deletion) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py b/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py deleted file mode 100644 index 2ab76071a6..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/NodePalette_SelectNode.py +++ /dev/null @@ -1,104 +0,0 @@ -""" -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. - - -Test case ID: T92568940 -Test Case Title: Categories and Nodes can be selected -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568940 -""" - - -# fmt: off -class Tests(): - category_selected = ("Category can be selected", "Category cannot be selected") - node_selected = ("Node can be selected", "Node cannot be selected") -# fmt: on - - -GENERAL_WAIT = 0.5 # seconds - - -def NodePalette_SelectNode(): - """ - Summary: - Categories and Nodes can be selected - - Expected Behavior: - When clicked on Node Palette, nodes and categories can be selected. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Expand QTreeView - 4) Click on category and check if it is selected - 5) Click on node and check if it is selected - 6) Close Script Canvas window - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - CATEGORY = "AI" - NODE = "Find Path To Entity" - - from PySide2 import QtWidgets - import azlmbr.legacy.general as general - - import pyside_utils - from utils import TestHelper as helper - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: - action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) - action.trigger() - node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") - tree = node_palette.findChild(QtWidgets.QTreeView, "treeView") - - # 3) Expand QTreeView - tree.expandAll() - - # 4) Click on category and check if it is selected - category_index = pyside_utils.find_child_by_hierarchy(tree, CATEGORY) - tree.scrollTo(category_index) - pyside_utils.item_view_index_mouse_click(tree, category_index) - pyside_utils.wait_for_condition(tree.selectedIndexes() and tree.selectedIndexes()[0] == category_index) - Report.result(Tests.category_selected, tree.selectedIndexes()[0] == category_index) - - # 5) Click on node and check if it is selected - node_index = pyside_utils.find_child_by_pattern(tree, NODE) - helper.wait_for_condition(lambda: tree.isExpanded(node_index), GENERAL_WAIT) - pyside_utils.item_view_index_mouse_click(tree, node_index) - pyside_utils.wait_for_condition(tree.selectedIndexes()[0] == node_index) - Report.result(Tests.node_selected, tree.selectedIndexes()[0] == node_index) - - # 6) Close Script Canvas window - general.close_pane("Script Canvas") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(NodePalette_SelectNode) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py b/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py new file mode 100644 index 0000000000..77d3b2fcde --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Node_HappyPath_DuplicateNode.py @@ -0,0 +1,117 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + node_duplicated = ("Successfully duplicated node", "Failed to duplicate the node") +# fmt: on + + +def Node_HappyPath_DuplicateNode(): + """ + Summary: + Duplicating node in graph + + Expected Behavior: + Upon selecting a node and pressing Ctrl+D, the node will be duplicated + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Open a new graph + 3) Add node to graph + 4) Duplicate node + 5) Verify the node was duplicated6) Verify the node was duplicated + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from PySide2 import QtWidgets, QtTest + from PySide2.QtCore import Qt + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + import editor_python_test_tools.pyside_utils as pyside_utils + + import azlmbr.legacy.general as general + + WAIT_FRAMES = 200 + + NODE_NAME = "Print" + NODE_CATEGORY = "Debug" + EXPECTED_STRING = f"{NODE_NAME} - {NODE_CATEGORY} (2 Selected)" + + def command_line_input(command_str): + cmd_action = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_ViewCommandLine", "type": QtWidgets.QAction} + ) + cmd_action.trigger() + textbox = sc.findChild(QtWidgets.QLineEdit, "commandText") + QtTest.QTest.keyClicks(textbox, command_str) + QtTest.QTest.keyClick(textbox, Qt.Key_Enter, Qt.NoModifier) + + def grab_title_text(): + scroll_area = node_inspector.findChild(QtWidgets.QScrollArea, "") + QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES) + background = scroll_area.findChild(QtWidgets.QFrame, "Background") + title = background.findChild(QtWidgets.QLabel, "Title") + text = title.findChild(QtWidgets.QLabel, "Title") + return text.text() + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Open a new graph + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + create_new_graph = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} + ) + if sc.findChild(QtWidgets.QDockWidget, "NodeInspector") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Inspector", "type": QtWidgets.QAction}) + action.trigger() + node_inspector = sc.findChild(QtWidgets.QDockWidget, "NodeInspector") + create_new_graph.trigger() + + # 3) Add node + command_line_input("add_node Print") + + # 4) Duplicate node + graph_view = sc.findChild(QtWidgets.QFrame, "graphicsViewFrame") + graph = graph_view.findChild(QtWidgets.QWidget, "") + # There are currently no utilities available to directly duplicate the node, + # therefore the node is selected using CTRL+A on the graph to select + # it and then CTRL+D to duplicate + sc_main.activateWindow() + QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES) + QtTest.QTest.keyClick(graph, "d", Qt.ControlModifier, WAIT_FRAMES) + + # 5) Verify the node was duplicated + # As direct interaction with node is not available the text on the label + # inside the Node Inspector is validated showing two nodes exist + after_dup = grab_title_text() + Report.result(Tests.node_duplicated, after_dup == EXPECTED_STRING) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from editor_python_test_tools.utils import Report + + Report.start_test(Node_HappyPath_DuplicateNode) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py b/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py deleted file mode 100644 index 51b63c4268..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/OnEntityActivatedDeactivated_PrintMessage.py +++ /dev/null @@ -1,184 +0,0 @@ -""" -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. - -Test case ID: T92569253 // T92569254 -Test Case Title: On Entity Activated // On Entity Deactivated -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569253 // https://testrail.agscollab.com/index.php?/tests/view/92569254 -""" - - -# fmt: off -class Tests(): - level_created = ("Successfully created temp level", "Failed to create temp level") - controller_exists = ("Successfully found controller entity", "Failed to find controller entity") - activated_exists = ("Successfully found activated entity", "Failed to find activated entity") - deactivated_exists = ("Successfully found deactivated entity","Failed to find deactivated entity") - start_states_correct = ("Start states set up successfully", "Start states set up incorrectly") - game_mode_entered = ("Successfully entered game mode" "Failed to enter game mode") - lines_found = ("Successfully found expected prints", "Failed to find expected prints") - game_mode_exited = ("Successfully exited game mode" "Failed to exit game mode") -# fmt: on - - -def OnEntityActivatedDeactivated_PrintMessage(): - """ - Summary: - Verify that the On Entity Activation node is working as expected - - Expected Behavior: - Upon entering game mode, the Controller entity will wait 1 second and then activate the ActivationTest - entity. The script attached to ActivationTest will print out a message on activation. The Controller - will also deactivate the DeactivationTest entity, which should print a message. - - Test Steps: - 1) Create temp level - 2) Setup the level - 3) Validate the entities - 4) Start the Tracer - 5) Enter Game Mode - 6) Validate Print message - 7) Exit game mode - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - import os - - from utils import TestHelper as helper - from editor_entity_utils import EditorEntity as Entity - from utils import Report - from utils import Tracer - - import azlmbr.legacy.general as general - - EditorEntity = str - LEVEL_NAME = "tmp_level" - WAIT_TIME = 3.0 # SECONDS - EXPECTED_LINES = ["Activator Script: Activated", "Deactivator Script: Deactivated"] - controller_dict = { - "name": "Controller", - "status": "active", - "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "controller.scriptcanvas") - } - activated_dict = { - "name": "ActivationTest", - "status": "inactive", - "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "activator.scriptcanvas") - } - deactivated_dict = { - "name": "DeactivationTest", - "status": "active", - "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "deactivator.scriptcanvas") - } - - def get_asset(asset_path): - return azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False) - - def setup_level(): - def create_editor_entity(entity_dict:dict, entity_to_activate:EditorEntity=None, entity_to_deactivate:EditorEntity=None) -> EditorEntity: - entity = Entity.create_editor_entity(entity_dict["name"]) - entity.set_start_status(entity_dict["status"]) - sc_component = entity.add_component("Script Canvas") - sc_component.set_component_property_value("Script Canvas Asset|Script Canvas Asset", get_asset(entity_dict["path"])) - - if entity_dict["name"] == "Controller": - sc_component.get_property_tree() - sc_component.set_component_property_value("Properties|Variable Fields|Variables|[0]|Name,Value|Datum|Datum|EntityToActivate", entity_to_activate.id) - sc_component.set_component_property_value("Properties|Variable Fields|Variables|[1]|Name,Value|Datum|Datum|EntityToDeactivate", entity_to_deactivate.id) - return entity - - activated = create_editor_entity(activated_dict) - deactivated = create_editor_entity(deactivated_dict) - create_editor_entity(controller_dict, activated, deactivated) - - def validate_entity_exist(entity_name: str, test_tuple: tuple): - """ - Validate the entity with the given name exists in the level - :return: entity: editor entity object - """ - entity = Entity.find_editor_entity(entity_name) - Report.critical_result(test_tuple, entity.id.IsValid()) - return entity - - def validate_start_state(entity:EditorEntity, expected_state:str): - """ - Validate that the starting state of the entity is correct, if it isn't then attempt to rectify and recheck. - :return: bool: Whether state is set as expected - """ - state_options = { - "active": azlmbr.globals.property.EditorEntityStartStatus_StartActive, - "inactive": azlmbr.globals.property.EditorEntityStartStatus_StartInactive, - "editor": azlmbr.globals.property.EditorEntityStartStatus_EditorOnly, - } - if expected_state.lower() not in state_options.keys(): - raise ValueError(f"{expected_state} is an invalid option; valid options: active, inactive, or editor.") - - state = entity.get_start_status() - if state != state_options[expected_state]: - # If state fails to set, set_start_status will assert - entity.set_start_status(expected_state) - return True - - def validate_entities_in_level(): - controller = validate_entity_exist(controller_dict["name"], Tests.controller_exists) - state1_correct = validate_start_state(controller, controller_dict["status"]) - - act_tester = validate_entity_exist(activated_dict["name"], Tests.activated_exists) - state2_correct = validate_start_state(act_tester, activated_dict["status"]) - - deac_tester = validate_entity_exist(deactivated_dict["name"], Tests.deactivated_exists) - state3_correct = validate_start_state(deac_tester, deactivated_dict["status"]) - - all_states_correct = state1_correct and state2_correct and state3_correct - Report.critical_result(Tests.start_states_correct, all_states_correct) - - def locate_expected_lines(line_list: list): - found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] - return all(line in found_lines for line in line_list) - - # 1) Create temp level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Setup the level - setup_level() - - # 3) Validate the entities - validate_entities_in_level() - - # 4) Start the Tracer - with Tracer() as section_tracer: - - # 5) Enter Game Mode - helper.enter_game_mode(Tests.game_mode_entered) - - # 6) Validate Print message - helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME) - - Report.result(Tests.lines_found, locate_expected_lines(EXPECTED_LINES)) - - # 7) Exit game mode - helper.exit_game_mode(Tests.game_mode_exited) - - -if __name__ == "__main__": - import ImportPathHelper as imports - imports.init() - - from utils import Report - - Report.start_test(OnEntityActivatedDeactivated_PrintMessage) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py deleted file mode 100755 index 666f052240..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Opening_Closing_Pane.py +++ /dev/null @@ -1,121 +0,0 @@ -""" -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. - -Test case ID: C1702834 // C1702823 -Test Case Title: Opening pane // Closing pane -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702834 and - https://testrail.agscollab.com/index.php?/cases/view/1702823 -""" - - -# fmt: off -class Tests(): - default_visible = ("All the panes visible by default", "One or more panes do not visible by default") - open_panes = ("All the Panes opened successfully", "Failed to open one or more panes") - close_pane = ("All the Panes closed successfully", "Failed to close one or more panes") -# fmt: on - - -def Opening_Closing_Pane(): - """ - Summary: - The Script Canvas window is opened to verify if Script canvas panes can be opened and closed. - - Expected Behavior: - The pane opens and closes successfully. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Restore default layout - 3) Verify if panes were opened by default - 4) Close the opened panes - 5) Open Script Canvas panes (Tools > ) - 6) Restore default layout - 7) Close Script Canvas window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper - import editor_python_test_tools.pyside_utils as pyside_utils - - # Open 3D Engine Imports - import azlmbr.legacy.general as general - - # Pyside imports - from PySide2 import QtWidgets - - PANE_WIDGETS = ("NodePalette", "VariableManager") - - def click_menu_option(window, option_text): - action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) - action.trigger() - - def find_pane(window, pane_name): - return window.findChild(QtWidgets.QDockWidget, pane_name) - - def is_pane_visible(window, pane_name): - pane = find_pane(window, pane_name) - return pane.isVisible() - - # Test starts here - general.idle_enable(True) - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Restore default layout - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - click_menu_option(sc, "Restore Default Layout") - - # 3) Verify if panes were opened by default - PANES_VISIBLE = all(is_pane_visible(sc, pane) for pane in PANE_WIDGETS) - Report.critical_result(Tests.default_visible, PANES_VISIBLE) - - # 4) Close the opened panes - for item in PANE_WIDGETS: - pane = sc.findChild(QtWidgets.QDockWidget, item) - pane.close() - if pane.isVisible(): - Report.info(f"Failed to close pane : {item}") - - PANES_VISIBLE = any(is_pane_visible(sc, pane) for pane in PANE_WIDGETS) - Report.result(Tests.close_pane, not PANES_VISIBLE) - - # 5) Open Script Canvas panes (Tools > ) - click_menu_option(sc, "Node Palette") - click_menu_option(sc, "Variable Manager") - PANES_VISIBLE = helper.wait_for_condition(lambda: all(is_pane_visible(sc, pane) for pane in PANE_WIDGETS), 2.0) - Report.result(Tests.open_panes, PANES_VISIBLE) - - # 6) Restore default layout - # Needed this step to restore to default in case of test failure - click_menu_option(sc, "Restore Default Layout") - - # 7) Close Script Canvas window - sc.close() - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from editor_python_test_tools.utils import Report - - Report.start_test(Opening_Closing_Pane) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_Default_RetainOnSCRestart.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Default_RetainOnSCRestart.py new file mode 100644 index 0000000000..626b1cf0bd --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Default_RetainOnSCRestart.py @@ -0,0 +1,157 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + relaunch_sc = ("Script Canvas window is relaunched", "Failed to relaunch Script Canvas window") + test_panes_visible = ("All the test panes are opened", "Failed to open one or more test panes") + close_pane_1 = ("Test pane 1 is closed", "Failed to close test pane 1") + visibility_retained = ("Test pane retained its visibility on SC restart", "Failed to retain visibility of test pane on SC restart") + resize_pane_3 = ("Test pane 3 resized successfully", "Failed to resize Test pane 3") + size_retained = ("Test pane retained its size on SC restart", "Failed to retain size of test pane on SC restart") + location_changed = ("Location of test pane 2 changed successfully", "Failed to change location of test pane 2") + location_retained = ("Test pane retained its location on SC restart", "Failed to retain location of test pane on SC restart") +# fmt: on + + +def Pane_Default_RetainOnSCRestart(): + """ + Summary: + The Script Canvas window is opened to verify if Script canvas panes can retain its visibility, size and location + upon ScriptCanvas restart. + + Expected Behavior: + The ScriptCanvas pane retain it's visibility, size and location upon ScriptCanvas restart. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Make sure test panes are open and visible + 3) Close test pane 1 + 4) Change dock location of test pane 2 + 5) Resize test pane 3 + 6) Relaunch Script Canvas + 7) Verify if test pane 1 retain its visibility + 8) Verify if location of test pane 2 is retained + 9) Verify if size of test pane 3 is retained + 10) Restore default layout and close SC window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + # Pyside imports + from PySide2 import QtCore, QtWidgets + from PySide2.QtCore import Qt + + # Helper imports + from utils import Report + from utils import TestHelper as helper + import pyside_utils + + # Open 3D Engine Imports + import azlmbr.legacy.general as general + + TEST_PANE_1 = "NodePalette" # test visibility + TEST_PANE_2 = "VariableManager" # test location + TEST_PANE_3 = "NodeInspector" # test size + SCALE_INT = 10 # Random resize scale integer + DOCKAREA = Qt.TopDockWidgetArea # Preferred top area since no widget is docked on top + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + # Test starts here + general.idle_enable(True) + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0) + + # 2) Make sure test panes are open and visible + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + click_menu_option(sc, "Restore Default Layout") + test_pane_1 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_1) + test_pane_2 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_2) + test_pane_3 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_3) + + Report.result( + Tests.test_panes_visible, test_pane_1.isVisible() and test_pane_2.isVisible() and test_pane_3.isVisible() + ) + + # Initiate try block here to restore default in finally block + try: + # 3) Close test pane + test_pane_1.close() + Report.result(Tests.close_pane_1, not test_pane_1.isVisible()) + + # 4) Change dock location of test pane 2 + sc_main = sc.findChild(QtWidgets.QMainWindow) + sc_main.addDockWidget(DOCKAREA, find_pane(sc_main, TEST_PANE_2), QtCore.Qt.Vertical) + Report.result(Tests.location_changed, sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA) + + # 5) Resize test pane 3 + initial_size = test_pane_3.frameSize() + test_pane_3.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT) + new_size = test_pane_3.frameSize() + resize_success = ( + abs(initial_size.width() - new_size.width()) == abs(initial_size.height() - new_size.height()) == SCALE_INT + ) + Report.result(Tests.resize_pane_3, resize_success) + + # 6) Relaunch Script Canvas + general.close_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 2.0) + + general.open_pane("Script Canvas") + sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + Report.result(Tests.relaunch_sc, sc_visible) + + # 7) Verify if test pane 1 retain its visibility + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + Report.result(Tests.visibility_retained, not find_pane(sc, TEST_PANE_1).isVisible()) + + # 8) Verify if location of test pane 2 is retained + sc_main = sc.findChild(QtWidgets.QMainWindow) + Report.result(Tests.location_retained, sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA) + + # 9) Verify if size of test pane 3 is retained + test_pane_3 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_3) + retained_size = test_pane_3.frameSize() + retain_success = retained_size != initial_size + Report.result(Tests.size_retained, retain_success) + + finally: + # 10) Restore default layout and close SC window + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + click_menu_option(sc, "Restore Default Layout") + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(Pane_Default_RetainOnSCRestart) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_DocksProperly.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_DocksProperly.py new file mode 100644 index 0000000000..2186a8a54a --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_DocksProperly.py @@ -0,0 +1,106 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + pane_opened = ("Pane is opened successfully", "Failed to open pane") + dock_pane = ("Pane is docked successfully", "Failed to dock Pane into one or more allowed area") +# fmt: on + + +def Pane_HappyPath_DocksProperly(): + """ + Summary: + The Script Canvas window is opened to verify if Script canvas panes can be docked into every + possible area of Script Canvas main window. (top, bottom, right and left sides of the window) + + Expected Behavior: + The pane docks successfully. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Make sure Node Palette pane is opened + 3) Dock the Node Palette pane into every possible area of main window + 4) Restore default layout + 5) Close Script Canvas window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + import editor_python_test_tools.pyside_utils as pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + + # Pyside imports + from PySide2 import QtCore, QtWidgets + from PySide2.QtCore import Qt + + PANE_WIDGET = "NodePalette" # Chosen most commonly used pane + DOCKAREAS = [Qt.TopDockWidgetArea, Qt.BottomDockWidgetArea, Qt.RightDockWidgetArea, Qt.LeftDockWidgetArea] + DOCKED = True + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + # Test starts here + general.idle_enable(True) + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Make sure Node Palette pane is opened + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + pane = find_pane(sc_main, PANE_WIDGET) + if not pane.isVisible(): + click_menu_option(sc, "Node Palette") + pane = find_pane(sc_main, PANE_WIDGET) # New reference + + Report.result(Tests.pane_opened, pane.isVisible()) + + # 3) Dock the Node Palette pane into every possible area of main window + for area in DOCKAREAS: + sc_main.addDockWidget(area, find_pane(sc_main, PANE_WIDGET), QtCore.Qt.Vertical) + if not (sc_main.dockWidgetArea(find_pane(sc_main, PANE_WIDGET)) == area): + Report.info(f"Failed to dock into {str(area)}") + DOCKED = DOCKED and (sc_main.dockWidgetArea(find_pane(sc_main, PANE_WIDGET)) == area) + + Report.result(Tests.dock_pane, DOCKED) + + # 4) Restore default layout + # Need this step to restore to default in case of test failure + click_menu_option(sc, "Restore Default Layout") + + # 5) Close Script Canvas window + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from editor_python_test_tools.utils import Report + + Report.start_test(Pane_HappyPath_DocksProperly) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_OpenCloseSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_OpenCloseSuccessfully.py new file mode 100644 index 0000000000..cedd68cd87 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_OpenCloseSuccessfully.py @@ -0,0 +1,115 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + default_visible = ("All the panes visible by default", "One or more panes do not visible by default") + open_panes = ("All the Panes opened successfully", "Failed to open one or more panes") + close_pane = ("All the Panes closed successfully", "Failed to close one or more panes") +# fmt: on + + +def Pane_HappyPath_OpenCloseSuccessfully(): + """ + Summary: + The Script Canvas window is opened to verify if Script Canvas panes can be opened and closed. + + Expected Behavior: + The panes open and close successfully. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Restore default layout + 3) Verify if panes were opened by default + 4) Close the opened panes + 5) Open Script Canvas panes (Tools > ) + 6) Restore default layout + 7) Close Script Canvas window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + import editor_python_test_tools.pyside_utils as pyside_utils + + # Open 3D Engine Imports + import azlmbr.legacy.general as general + + # Pyside imports + from PySide2 import QtWidgets + + PANE_WIDGETS = ("NodePalette", "VariableManager") + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + def is_pane_visible(window, pane_name): + pane = find_pane(window, pane_name) + return pane.isVisible() + + # Test starts here + general.idle_enable(True) + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Restore default layout + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + click_menu_option(sc, "Restore Default Layout") + + # 3) Verify if panes were opened by default + PANES_VISIBLE = all(is_pane_visible(sc, pane) for pane in PANE_WIDGETS) + Report.critical_result(Tests.default_visible, PANES_VISIBLE) + + # 4) Close the opened panes + for item in PANE_WIDGETS: + pane = sc.findChild(QtWidgets.QDockWidget, item) + pane.close() + if pane.isVisible(): + Report.info(f"Failed to close pane : {item}") + + PANES_VISIBLE = any(is_pane_visible(sc, pane) for pane in PANE_WIDGETS) + Report.result(Tests.close_pane, not PANES_VISIBLE) + + # 5) Open Script Canvas panes (Tools > ) + click_menu_option(sc, "Node Palette") + click_menu_option(sc, "Variable Manager") + PANES_VISIBLE = helper.wait_for_condition(lambda: all(is_pane_visible(sc, pane) for pane in PANE_WIDGETS), 2.0) + Report.result(Tests.open_panes, PANES_VISIBLE) + + # 6) Restore default layout + # Needed this step to restore to default in case of test failure + click_menu_option(sc, "Restore Default Layout") + + # 7) Close Script Canvas window + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from editor_python_test_tools.utils import Report + + Report.start_test(Pane_HappyPath_OpenCloseSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_ResizesProperly.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_ResizesProperly.py new file mode 100644 index 0000000000..36d734049d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_HappyPath_ResizesProperly.py @@ -0,0 +1,108 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + open_pane = ("Pane opened successfully", "Failed to open pane") + resize_pane = ("Pane window resized successfully", "Failed to resize pane window") +# fmt: on + + +def Pane_HappyPath_ResizesProperly(): + """ + Summary: + The Script Canvas window is opened to verify if Script Canvas panes can be resized and scaled + + Expected Behavior: + The pane is resized and scaled appropriately. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Restore default layout + 3) Make sure pane is opened + 4) Resize pane and verify change + 5) Restore default layout + 6) Close Script Canvas window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + import editor_python_test_tools.pyside_utils as pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + + PANE_WIDGET = "NodePalette" + SCALE_INT = 10 + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + # Test starts here + general.idle_enable(True) + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Restore default layout + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + click_menu_option(sc, "Restore Default Layout") + + # 3) Make sure pane is opened + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + pane = find_pane(sc, PANE_WIDGET) + if not pane.isVisible(): + click_menu_option(sc, "Node Palette") + pane = find_pane(sc, PANE_WIDGET) # New reference + + Report.result(Tests.open_pane, pane.isVisible()) + + # 4) Resize pane and verify change + initial_size = pane.frameSize() + pane.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT) + new_size = pane.frameSize() + test_success = ( + abs(initial_size.width() - new_size.width()) == abs(initial_size.height() - new_size.height()) == SCALE_INT + ) + Report.result(Tests.resize_pane, test_success) + + # 5) Restore default layout + # Needed this step to restore to default in case of test failure + click_menu_option(sc, "Restore Default Layout") + + # 6) Close Script Canvas window + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from editor_python_test_tools.utils import Report + + Report.start_test(Pane_HappyPath_ResizesProperly) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_PropertiesChanged_RetainsOnRestart.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_PropertiesChanged_RetainsOnRestart.py new file mode 100644 index 0000000000..3750fd290b --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_PropertiesChanged_RetainsOnRestart.py @@ -0,0 +1,161 @@ +""" +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. +""" + + +class Tests: + test_panes_visible = "All the test panes are opened" + close_pane_1 = "Test pane 1 is closed" + resize_pane_3 = "Test pane 3 resized successfully" + location_changed = "Location of test pane 2 changed successfully" + visiblity_retained = "Test pane retained its visiblity on Editor restart" + location_retained = "Test pane retained its location on Editor restart" + size_retained = "Test pane retained its size on Editor restart" + + +def Pane_PropertiesChanged_RetainsOnRestart(): + """ + Summary: + The Script Canvas window is opened to verify if Script canvas panes can retain its visibility, size and location + upon Editor restart. + + Expected Behavior: + The ScriptCanvas pane retain it's visiblity, size and location upon Editor restart. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Make sure test panes are open and visible + 3) Close test pane 1 + 4) Change dock location of test pane 2 + 5) Resize test pane 3 + 6) Restart Editor + 7) Verify if test pane 1 retain its visiblity + 8) Verify if location of test pane 2 is retained + 9) Verify if size of test pane 3 is retained + 10) Restore default layout and close SC window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + import sys + + # Helper imports + from utils import Report + from utils import TestHelper as helper + import pyside_utils + + # Lumberyard Imports + import azlmbr.legacy.general as general + + # Pyside imports + from PySide2 import QtCore, QtWidgets + from PySide2.QtCore import Qt + + # Constants + TEST_CONDITION = sys.argv[1] + TEST_PANE_1 = "NodePalette" # pane used to test visibility + TEST_PANE_2 = "VariableManager" # pane used to test location + TEST_PANE_3 = "NodeInspector" # pane used to test size + SCALE_INT = 10 # Random resize scale integer + DOCKAREA = Qt.TopDockWidgetArea # Preferred top area since no widget is docked on top + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + # Test starts here + general.idle_enable(True) + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + if TEST_CONDITION == "before_restart": + # 2) Make sure test panes are open and visible + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + click_menu_option(sc, "Restore Default Layout") + test_pane_1 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_1) + test_pane_2 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_2) + test_pane_3 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_3) + + result = test_pane_1.isVisible() and test_pane_2.isVisible() and test_pane_3.isVisible() + Report.info(f"{Tests.test_panes_visible}: {result}") + + # 3) Close test pane + test_pane_1.close() + Report.info(f"{Tests.close_pane_1}: {not test_pane_1.isVisible()}") + + # 4) Change dock location of test pane 2 + sc_main = sc.findChild(QtWidgets.QMainWindow) + sc_main.addDockWidget(DOCKAREA, find_pane(sc_main, TEST_PANE_2), QtCore.Qt.Vertical) + Report.info(f"{Tests.location_changed}: {sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA}") + + # 5) Resize test pane 3 + initial_size = test_pane_3.frameSize() + test_pane_3.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT) + new_size = test_pane_3.frameSize() + resize_success = ( + abs(initial_size.width() - new_size.width()) == abs(initial_size.height() - new_size.height()) == SCALE_INT + ) + Report.info(f"{Tests.resize_pane_3}: {resize_success}") + + if TEST_CONDITION == "after_restart": + try: + # 6) Restart Editor + # Restart is not possible through script and hence it is done by running the same file as 2 tests with a + # condition as before_test and after_test + + # 7) Verify if test pane 1 retain its visiblity + # This pane closed before restart and expected that pane should not be visible. + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + Report.info(f"{Tests.visiblity_retained}: {not find_pane(sc, TEST_PANE_1).isVisible()}") + + # 8) Verify if location of test pane 2 is retained + # This pane was set at DOCKAREA lcoation before restart + sc_main = sc.findChild(QtWidgets.QMainWindow) + Report.info( + f"{Tests.location_retained}: {sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA}" + ) + + # 9) Verify if size of test pane 3 is retained + # Verifying if size retained by checking current size not matching with default size + test_pane_3 = find_pane(sc, TEST_PANE_3) + retained_size = test_pane_3.frameSize() + click_menu_option(sc, "Restore Default Layout") + actual_size = test_pane_3.frameSize() + Report.info(f"{Tests.size_retained}: {retained_size != actual_size}") + + finally: + # 10) Restore default layout and close SC window + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + click_menu_option(sc, "Restore Default Layout") + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + + from utils import Report + + Report.start_test(Pane_PropertiesChanged_RetainsOnRestart) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py deleted file mode 100644 index fa5e9e6068..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Pane_RetainOnSCRestart.py +++ /dev/null @@ -1,164 +0,0 @@ -""" -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. - -Test case ID: C1702821 // C1702832 -Test Case Title: Retain visibility, size and location upon Script Canvas restart -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702821 and - https://testrail.agscollab.com/index.php?/cases/view/1702832 -""" - - -# fmt: off -class Tests(): - relaunch_sc = ("Script Canvas window is relaunched", "Failed to relaunch Script Canvas window") - test_panes_visible = ("All the test panes are opened", "Failed to open one or more test panes") - close_pane_1 = ("Test pane 1 is closed", "Failed to close test pane 1") - visiblity_retained = ("Test pane retained its visiblity on SC restart", "Failed to retain visiblity of test pane on SC restart") - resize_pane_3 = ("Test pane 3 resized successfully", "Failed to resize Test pane 3") - size_retained = ("Test pane retained its size on SC restart", "Failed to retain size of test pane on SC restart") - location_changed = ("Location of test pane 2 changed successfully", "Failed to change locatio of test pane 2") - location_retained = ("Test pane retained its location on SC restart", "Failed to retain location of test pane on SC restart") -# fmt: on - - -def Pane_RetainOnSCRestart(): - """ - Summary: - The Script Canvas window is opened to verify if Script canvas panes can retain its visibility, size and location - upon ScriptCanvas restart. - - Expected Behavior: - The ScriptCanvas pane retain it's visiblity, size and location upon ScriptCanvas restart. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Make sure test panes are open and visible - 3) Close test pane 1 - 4) Change dock location of test pane 2 - 5) Resize test pane 3 - 6) Relaunch Script Canvas - 7) Verify if test pane 1 retain its visiblity - 8) Verify if location of test pane 2 is retained - 9) Verify if size of test pane 3 is retained - 10) Restore default layout and close SC window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - # Helper imports - from utils import Report - from utils import TestHelper as helper - import pyside_utils - - # Open 3D Engine Imports - import azlmbr.legacy.general as general - - # Pyside imports - from PySide2 import QtCore, QtWidgets - from PySide2.QtCore import Qt - - # Constants - TEST_PANE_1 = "NodePalette" # test visibility - TEST_PANE_2 = "VariableManager" # test location - TEST_PANE_3 = "NodeInspector" # test size - SCALE_INT = 10 # Random resize scale integer - DOCKAREA = Qt.TopDockWidgetArea # Preferred top area since no widget is docked on top - - def click_menu_option(window, option_text): - action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) - action.trigger() - - def find_pane(window, pane_name): - return window.findChild(QtWidgets.QDockWidget, pane_name) - - # Test starts here - general.idle_enable(True) - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0) - - # 2) Make sure test panes are open and visible - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - click_menu_option(sc, "Restore Default Layout") - test_pane_1 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_1) - test_pane_2 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_2) - test_pane_3 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_3) - - Report.result( - Tests.test_panes_visible, test_pane_1.isVisible() and test_pane_2.isVisible() and test_pane_3.isVisible() - ) - - # Initiate try block here to restore default in finally block - try: - # 3) Close test pane - test_pane_1.close() - Report.result(Tests.close_pane_1, not test_pane_1.isVisible()) - - # 4) Change dock location of test pane 2 - sc_main = sc.findChild(QtWidgets.QMainWindow) - sc_main.addDockWidget(DOCKAREA, find_pane(sc_main, TEST_PANE_2), QtCore.Qt.Vertical) - Report.result(Tests.location_changed, sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA) - - # 5) Resize test pane 3 - initial_size = test_pane_3.frameSize() - test_pane_3.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT) - new_size = test_pane_3.frameSize() - resize_success = ( - abs(initial_size.width() - new_size.width()) == abs(initial_size.height() - new_size.height()) == SCALE_INT - ) - Report.result(Tests.resize_pane_3, resize_success) - - # 6) Relaunch Script Canvas - general.close_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 2.0) - - general.open_pane("Script Canvas") - sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - Report.result(Tests.relaunch_sc, sc_visible) - - # 7) Verify if test pane 1 retain its visiblity - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - Report.result(Tests.visiblity_retained, not find_pane(sc, TEST_PANE_1).isVisible()) - - # 8) Verify if location of test pane 2 is retained - sc_main = sc.findChild(QtWidgets.QMainWindow) - Report.result(Tests.location_retained, sc_main.dockWidgetArea(find_pane(sc_main, TEST_PANE_2)) == DOCKAREA) - - # 9) Verify if size of test pane 3 is retained - test_pane_3 = sc.findChild(QtWidgets.QDockWidget, TEST_PANE_3) - retained_size = test_pane_3.frameSize() - retain_success = retained_size != initial_size - Report.result(Tests.size_retained, retain_success) - - finally: - # 10) Restore default layout and close SC window - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - click_menu_option(sc, "Restore Default Layout") - sc.close() - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(Pane_RetainOnSCRestart) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Pane_Undocked_ClosesSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Undocked_ClosesSuccessfully.py new file mode 100644 index 0000000000..0ddbe7e34f --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/Pane_Undocked_ClosesSuccessfully.py @@ -0,0 +1,121 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + undock_pane = ("Pane is undocked successfully", "Failed to undock pane") + close_sc_window = ("Script Canvas window is closed", "Failed to close Script Canvas window") + pane_closed = ("Pane is closed successfully", "Failed to close the pane") +# fmt: on + + +def Pane_Undocked_ClosesSuccessfully(): + """ + Summary: + The Script Canvas window is opened with one of the pane undocked. + Verify if undocked pane closes upon closing Script canvas window. + + Expected Behavior: + The undocked pane closes when Script Canvas window closed. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Undock Node Palette pane + 3) Connect to Pane visibility signal emitter to verify pane closed + 4) Close Script Canvas window + 5) Restore default layout + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets + + # Helper imports + from utils import Report + from utils import TestHelper as helper + import pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + + TEST_PANE = "NodePalette" # Chosen most commonly used pane + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + def on_top_level_changed(): + # This function has test condition always True since it gets emitted only when condition satisfied + Report.result(Tests.undock_pane, True) + + def on_pane_closed(): + # This function has test condition always True since it gets emitted only when condition satisfied + Report.result(Tests.pane_closed, True) + + # Test starts here + general.idle_enable(True) + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Undock Node Palette pane + # Make sure Node Palette pane is opened + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + pane = find_pane(sc, TEST_PANE) + if not pane.isVisible(): + click_menu_option(sc, "Node Palette") + pane = find_pane(sc, TEST_PANE) # New reference + + # We drag/drop pane over the graph since it doesn't allow docking, so this will undock it + try: + graph = find_pane(sc, "GraphCanvasEditorCentralWidget") + try: + pane.topLevelChanged.connect(on_top_level_changed) + pyside_utils.drag_and_drop(pane, graph) + finally: + pane.topLevelChanged.disconnect(on_top_level_changed) + + # 3) Connect to Pane visibility signal emitter to verify pane closed + # No need to disconnect this since pane widget gets deleted when SC window closed + pane.visibilityChanged.connect(on_pane_closed) + + # 4) Close Script Canvas window + sc.close() + is_sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 2.0) + Report.result(Tests.close_sc_window, not is_sc_visible) + + finally: + # 5) Restore default layout + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + click_menu_option(sc, "Restore Default Layout") + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(Pane_Undocked_ClosesSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py b/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py deleted file mode 100755 index 180f577953..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Resizing_Pane.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -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. - -Test case ID: C1702829 -Test Case Title: Resizing pane -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702829 -""" - - -# fmt: off -class Tests(): - open_pane = ("Pane opened successfully", "Failed to open pane") - resize_pane = ("Pane window resized successfully", "Failed to resize pane window") -# fmt: on - - -def Resizing_Pane(): - """ - Summary: - The Script Canvas window is opened to verify if Script canvas panes can be resized and scaled - - Expected Behavior: - The pane is resized and scaled appropriately. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Restore default layout - 3) Make sure pane is opened - 4) Resize pane - 5) Restore default layout - 6) Close Script Canvas window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from editor_python_test_tools.utils import Report - from editor_python_test_tools.utils import TestHelper as helper - import editor_python_test_tools.pyside_utils as pyside_utils - - # Open 3D Engine imports - import azlmbr.legacy.general as general - - # Pyside imports - from PySide2 import QtWidgets - - PANE_WIDGET = "NodePalette" - SCALE_INT = 10 - - def click_menu_option(window, option_text): - action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) - action.trigger() - - def find_pane(window, pane_name): - return window.findChild(QtWidgets.QDockWidget, pane_name) - - # Test starts here - general.idle_enable(True) - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Restore default layout - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - click_menu_option(sc, "Restore Default Layout") - - # 3) Make sure pane is opened - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - pane = find_pane(sc, PANE_WIDGET) - if not pane.isVisible(): - click_menu_option(sc, "Node Palette") - pane = find_pane(sc, PANE_WIDGET) # New reference - - Report.result(Tests.open_pane, pane.isVisible()) - - # 4) Resize pane - initial_size = pane.frameSize() - pane.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT) - new_size = pane.frameSize() - test_success = ( - abs(initial_size.width() - new_size.width()) == abs(initial_size.height() - new_size.height()) == SCALE_INT - ) - Report.result(Tests.resize_pane, test_success) - - # 5) Restore default layout - # Needed this step to restore to default in case of test failure - click_menu_option(sc, "Restore Default Layout") - - # 6) Close Script Canvas window - sc.close() - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - from editor_python_test_tools.utils import Report - - Report.start_test(Resizing_Pane) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage.py new file mode 100644 index 0000000000..14e0c849e3 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage.py @@ -0,0 +1,192 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("Successfully created temp level", "Failed to create temp level") + controller_exists = ("Successfully found controller entity", "Failed to find controller entity") + activated_exists = ("Successfully found activated entity", "Failed to find activated entity") + deactivated_exists = ("Successfully found deactivated entity", "Failed to find deactivated entity") + start_states_correct = ("Start states set up successfully", "Start states set up incorrectly") + game_mode_entered = ("Successfully entered game mode" "Failed to enter game mode") + lines_found = ("Successfully found expected prints", "Failed to find expected prints") + game_mode_exited = ("Successfully exited game mode" "Failed to exit game mode") +# fmt: on + + +def ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage(): + """ + Summary: + Verify that the On Entity Activated/On Entity Deactivated nodes are working as expected + + Expected Behavior: + Upon entering game mode, the Controller entity will wait 1 second and then activate the ActivationTest + entity. The script attached to ActivationTest will print out a message on activation. The Controller + will also deactivate the DeactivationTest entity, which should print a message. + + Test Steps: + 1) Create temp level + 2) Setup the level + 3) Validate the entities + 4) Start the Tracer + 5) Enter Game Mode + 6) Validate Print message + 7) Exit game mode + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + + from editor_entity_utils import EditorEntity as Entity + from utils import Report + from utils import TestHelper as helper + from utils import Tracer + + import azlmbr.legacy.general as general + + EditorEntity = str + LEVEL_NAME = "tmp_level" + WAIT_TIME = 3.0 # SECONDS + EXPECTED_LINES = ["Activator Script: Activated", "Deactivator Script: Deactivated"] + controller_dict = { + "name": "Controller", + "status": "active", + "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "controller.scriptcanvas"), + } + activated_dict = { + "name": "ActivationTest", + "status": "inactive", + "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "activator.scriptcanvas"), + } + deactivated_dict = { + "name": "DeactivationTest", + "status": "active", + "path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "deactivator.scriptcanvas"), + } + + def get_asset(asset_path): + return azlmbr.asset.AssetCatalogRequestBus( + azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False + ) + + def setup_level(): + def create_editor_entity( + entity_dict: dict, entity_to_activate: EditorEntity = None, entity_to_deactivate: EditorEntity = None + ) -> EditorEntity: + entity = Entity.create_editor_entity(entity_dict["name"]) + entity.set_start_status(entity_dict["status"]) + sc_component = entity.add_component("Script Canvas") + sc_component.set_component_property_value( + "Script Canvas Asset|Script Canvas Asset", get_asset(entity_dict["path"]) + ) + + if entity_dict["name"] == "Controller": + sc_component.get_property_tree() + sc_component.set_component_property_value( + "Properties|Variable Fields|Variables|[0]|Name,Value|Datum|Datum|EntityToActivate", + entity_to_activate.id, + ) + sc_component.set_component_property_value( + "Properties|Variable Fields|Variables|[1]|Name,Value|Datum|Datum|EntityToDeactivate", + entity_to_deactivate.id, + ) + return entity + + activated = create_editor_entity(activated_dict) + deactivated = create_editor_entity(deactivated_dict) + create_editor_entity(controller_dict, activated, deactivated) + + def validate_entity_exist(entity_name: str, test_tuple: tuple): + """ + Validate the entity with the given name exists in the level + :return: entity: editor entity object + """ + entity = Entity.find_editor_entity(entity_name) + Report.critical_result(test_tuple, entity.id.IsValid()) + return entity + + def validate_start_state(entity: EditorEntity, expected_state: str): + """ + Validate that the starting state of the entity is correct, if it isn't then attempt to rectify and recheck. + :return: bool: Whether state is set as expected + """ + state_options = { + "active": azlmbr.globals.property.EditorEntityStartStatus_StartActive, + "inactive": azlmbr.globals.property.EditorEntityStartStatus_StartInactive, + "editor": azlmbr.globals.property.EditorEntityStartStatus_EditorOnly, + } + if expected_state.lower() not in state_options.keys(): + raise ValueError(f"{expected_state} is an invalid option; valid options: active, inactive, or editor.") + + state = entity.get_start_status() + if state != state_options[expected_state]: + # If state fails to set, set_start_status will assert + entity.set_start_status(expected_state) + return True + + def validate_entities_in_level(): + controller = validate_entity_exist(controller_dict["name"], Tests.controller_exists) + state1_correct = validate_start_state(controller, controller_dict["status"]) + + act_tester = validate_entity_exist(activated_dict["name"], Tests.activated_exists) + state2_correct = validate_start_state(act_tester, activated_dict["status"]) + + deac_tester = validate_entity_exist(deactivated_dict["name"], Tests.deactivated_exists) + state3_correct = validate_start_state(deac_tester, deactivated_dict["status"]) + + all_states_correct = state1_correct and state2_correct and state3_correct + Report.critical_result(Tests.start_states_correct, all_states_correct) + + def locate_expected_lines(line_list: list): + found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] + return all(line in found_lines for line in line_list) + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Setup the level + setup_level() + + # 3) Validate the entities + validate_entities_in_level() + + # 4) Start the Tracer + with Tracer() as section_tracer: + + # 5) Enter Game Mode + helper.enter_game_mode(Tests.game_mode_entered) + + # 6) Validate Print message + helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME) + + Report.result(Tests.lines_found, locate_expected_lines(EXPECTED_LINES)) + + # 7) Exit game mode + helper.exit_game_mode(Tests.game_mode_exited) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasTools_Toggle_OpenCloseSuccess.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasTools_Toggle_OpenCloseSuccess.py new file mode 100644 index 0000000000..a105f1ef18 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvasTools_Toggle_OpenCloseSuccess.py @@ -0,0 +1,124 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + node_palette_opened = ("NodePalette is opened successfully", "Failed to open NodePalette") + node_inspector_opened = ("NodeInspector is opened successfully", "Failed to open NodeInspector") + bookmark_opened = ("Bookmarks is opened successfully", "Failed to open Bookmarks") + variable_manager_opened = ("VariableManager is opened successfully", "Failed to open VariableManager") + node_palette_closed_by_start = ("NodePalette is closed successfully", "Failed to close NodePalette") + node_inspector_closed_by_start = ("NodeInspector is closed successfully", "Failed to close NodeInspector") + bookmark_closed_by_start = ("Bookmarks is closed successfully", "Failed to close Bookmarks") + variable_manager_closed_by_start = ("VariableManager is closed successfully", "Failed to close VariableManager") + node_palette_closed_by_end = ("NodePalette is closed successfully", "Failed to close NodePalette") + node_inspector_closed_by_end = ("NodeInspector is closed successfully", "Failed to close NodeInspector") + bookmark_closed_by_end = ("Bookmarks is closed successfully", "Failed to close Bookmarks") + variable_manager_closed_by_end = ("VariableManager is closed successfully", "Failed to close VariableManager") +# fmt: on + + +def ScriptCanvasTools_Toggle_OpenCloseSuccess(): + """ + Summary: + Toggle Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas. + Make sure each pane opens and closes successfully. + + Expected Behavior: + Each pane opens and closes successfully. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Make sure Node Palette, Node Inspector, Bookmarks and Variable Manager panes are closed in Script Canvas window + 3) Open Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window + 4) Close Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window + 5) Restore default layout + 6) Close Script Canvas window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets + + from utils import Report + from utils import TestHelper as helper + import pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + def close_tool(window, pane_widget, test_tuple): + pane = find_pane(window, pane_widget) + pane.close() + Report.result(test_tuple, not pane.isVisible()) + + def open_tool(window, pane_widget, tool, test_tuple): + pane = find_pane(window, pane_widget) + if not pane.isVisible(): + click_menu_option(window, tool) + pane = find_pane(window, pane_widget) + Report.result(test_tuple, pane.isVisible()) + + # Test starts here + general.idle_enable(True) + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + + # 2) Make sure Node Palette, Node Inspector, Bookmarks and Variable Manager panes are closed in Script Canvas window + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + close_tool(sc, "NodePalette", Tests.node_palette_closed_by_start) + close_tool(sc, "NodeInspector", Tests.node_inspector_closed_by_start) + close_tool(sc, "BookmarkDockWidget", Tests.bookmark_closed_by_start) + close_tool(sc, "VariableManager", Tests.variable_manager_closed_by_start) + + # 3) Open Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window + open_tool(sc, "NodePalette", "Node Palette", Tests.node_palette_opened) + open_tool(sc, "NodeInspector", "Node Inspector", Tests.node_inspector_opened) + open_tool(sc, "BookmarkDockWidget", "Bookmarks", Tests.bookmark_opened) + open_tool(sc, "VariableManager", "Variable Manager", Tests.variable_manager_opened) + + # 4) Close Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window + close_tool(sc, "NodePalette", Tests.node_palette_closed_by_end) + close_tool(sc, "NodeInspector", Tests.node_inspector_closed_by_end) + close_tool(sc, "BookmarkDockWidget", Tests.bookmark_closed_by_end) + close_tool(sc, "VariableManager", Tests.variable_manager_closed_by_end) + + # 5) Restore default layout + # Need this step to restore to default in case of test failure + click_menu_option(sc, "Restore Default Layout") + + # 6) Close Script Canvas window + sc.close() + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptCanvasTools_Toggle_OpenCloseSuccess) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py deleted file mode 100644 index 38d60ad871..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets.py +++ /dev/null @@ -1,116 +0,0 @@ -""" -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. - -Test case ID: T92562986 -Test Case Title: Changing the assigned Script Canvas Asset on an entity properly updates -level functionality -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562986 -""" - - -# fmt: off -class Tests(): - level_created = ("New level created", "New level not created") - entity_created = ("Test Entity created", "Test Entity not created") - game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter") - game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited") - found_lines = ("Expected log lines were found", "Expected log lines were not found") -# fmt: on - - -def ScriptCanvas_ChangingAssets(): - """ - Summary: - Changing the assigned Script Canvas Asset on an entity properly updates level functionality - - Expected Behavior: - When game mode is entered, respective strings of assigned assets should be printed - - Test Steps: - 1) Create temp level - 2) Create new entity - 3) Start Tracer - 4) Set first script and evaluate - 5) Set second script and evaluate - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - import os - - from utils import TestHelper as helper - from utils import Tracer - import hydra_editor_utils as hydra - import azlmbr.legacy.general as general - import azlmbr.math as math - import azlmbr.asset as asset - import azlmbr.bus as bus - import azlmbr.paths as paths - - LEVEL_NAME = "tmp_level" - ASSET_1 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents0.scriptcanvas") - ASSET_2 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents1.scriptcanvas") - EXP_LINE_1 = "Greetings from the first script" - EXP_LINE_2 = "Greetings from the second script" - WAIT_TIME = 3.0 # SECONDS - - def get_asset(asset_path): - return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) - - def find_expected_line(expected_line): - found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] - return expected_line in found_lines - - def set_asset_evaluate(test_entity, ASSET_PATH, EXP_LINE): - # Set Script Canvas entity - test_entity.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_PATH)) - - # Enter/exit game mode - helper.enter_game_mode(Tests.game_mode_entered) - helper.wait_for_condition(lambda: find_expected_line(EXP_LINE), WAIT_TIME) - Report.result(Tests.found_lines, find_expected_line(EXP_LINE)) - helper.exit_game_mode(Tests.game_mode_exited) - - - # 1) Create temp level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Create new entity - position = math.Vector3(512.0, 512.0, 32.0) - test_entity = hydra.Entity("test_entity") - test_entity.create_entity(position, ["Script Canvas"]) - - # 3) Start Tracer - with Tracer() as section_tracer: - - # 4) Set first script and evaluate - set_asset_evaluate(test_entity, ASSET_1, EXP_LINE_1) - - # 5) Set second script and evaluate - set_asset_evaluate(test_entity, ASSET_2, EXP_LINE_2) - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - from utils import Report - - Report.start_test(ScriptCanvas_ChangingAssets) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets_ComponentStable.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets_ComponentStable.py new file mode 100644 index 0000000000..d39c3d2590 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_ChangingAssets_ComponentStable.py @@ -0,0 +1,109 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("New level created", "New level not created") + entity_created = ("Test Entity created", "Test Entity not created") + game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter") + game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited") + found_lines = ("Expected log lines were found", "Expected log lines were not found") +# fmt: on + + +def ScriptCanvas_ChangingAssets_ComponentStable(): + """ + Summary: + Changing the assigned Script Canvas Asset on an entity properly updates level functionality + + Expected Behavior: + When game mode is entered, respective strings of assigned assets should be printed + + Test Steps: + 1) Create temp level + 2) Create new entity + 3) Start Tracer + 4) Set first script and evaluate + 5) Set second script and evaluate + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + import os + + from utils import TestHelper as helper + from utils import Tracer + import hydra_editor_utils as hydra + import azlmbr.legacy.general as general + import azlmbr.math as math + import azlmbr.asset as asset + import azlmbr.bus as bus + + LEVEL_NAME = "tmp_level" + ASSET_1 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents0.scriptcanvas") + ASSET_2 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents1.scriptcanvas") + EXP_LINE_1 = "Greetings from the first script" + EXP_LINE_2 = "Greetings from the second script" + WAIT_TIME = 3.0 # SECONDS + + def get_asset(asset_path): + return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) + + def find_expected_line(expected_line): + found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] + return expected_line in found_lines + + def set_asset_evaluate(test_entity, ASSET_PATH, EXP_LINE): + # Set Script Canvas entity + test_entity.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_PATH)) + + # Enter/exit game mode + helper.enter_game_mode(Tests.game_mode_entered) + helper.wait_for_condition(lambda: find_expected_line(EXP_LINE), WAIT_TIME) + Report.result(Tests.found_lines, find_expected_line(EXP_LINE)) + helper.exit_game_mode(Tests.game_mode_exited) + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create new entity + position = math.Vector3(512.0, 512.0, 32.0) + test_entity = hydra.Entity("test_entity") + test_entity.create_entity(position, ["Script Canvas"]) + + # 3) Start Tracer + with Tracer() as section_tracer: + + # 4) Set first script and evaluate + set_asset_evaluate(test_entity, ASSET_1, EXP_LINE_1) + + # 5) Set second script and evaluate + set_asset_evaluate(test_entity, ASSET_2, EXP_LINE_2) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptCanvas_ChangingAssets_ComponentStable) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py deleted file mode 100644 index 896bee96e5..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents.py +++ /dev/null @@ -1,118 +0,0 @@ -""" -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. - -Test case ID: T92563190 -Test Case Title: A single Entity with two Script Canvas components works properly -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563190 -""" - - -# fmt: off -class Tests(): - level_created = ("New level created", "New level not created") - game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter") - game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited") - found_lines = ("Expected log lines were found", "Expected log lines were not found") -# fmt: on - - -class LogLines: - expected_lines = ["Greetings from the first script", "Greetings from the second script"] - - -def ScriptCanvas_TwoComponents(): - """ - Summary: - A test entity contains two Script Canvas components with different unique script canvas files. - Each of these files will have a print node set to activate on graph start. - - Expected Behavior: - When game mode is entered, two unique strings should be printed out to the console - - Test Steps: - 1) Create level - 2) Create entity with SC components - 3) Start Tracer - 4) Enter game mode - 5) Wait for expected lines to be found - 6) Report if expected lines were found - 7) Exit game mode - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - import os - - from utils import TestHelper as helper - import hydra_editor_utils as hydra - from utils import Report - from utils import Tracer - import azlmbr.legacy.general as general - import azlmbr.math as math - import azlmbr.asset as asset - import azlmbr.bus as bus - - LEVEL_NAME = "tmp_level" - ASSET_1 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents0.scriptcanvas") - ASSET_2 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents1.scriptcanvas") - WAIT_TIME = 3.0 # SECONDS - - def get_asset(asset_path): - return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) - - def locate_expected_lines(): - found_lines = [] - for printInfo in section_tracer.prints: - found_lines.append(printInfo.message.strip()) - - return all(line in found_lines for line in LogLines.expected_lines) - - # 1) Create level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Create entity with SC components - position = math.Vector3(512.0, 512.0, 32.0) - test_entity = hydra.Entity("test_entity") - test_entity.create_entity(position, ["Script Canvas", "Script Canvas"]) - test_entity.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_1)) - test_entity.get_set_test(1, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_2)) - - # 3) Start Tracer - with Tracer() as section_tracer: - - # 4) Enter game mode - helper.enter_game_mode(Tests.game_mode_entered) - - # 5) Wait for expected lines to be found - helper.wait_for_condition(locate_expected_lines, WAIT_TIME) - - # 6) Report if expected lines were found - Report.result(Tests.found_lines, locate_expected_lines()) - - # 7) Exit game mode - helper.exit_game_mode(Tests.game_mode_exited) - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(ScriptCanvas_TwoComponents) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents_InteractSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents_InteractSuccessfully.py new file mode 100644 index 0000000000..9bbda9bdbd --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoComponents_InteractSuccessfully.py @@ -0,0 +1,114 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("New level created", "New level not created") + game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter") + game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited") + found_lines = ("Expected log lines were found", "Expected log lines were not found") +# fmt: on + + +class LogLines: + expected_lines = ["Greetings from the first script", "Greetings from the second script"] + + +def ScriptCanvas_TwoComponents_InteractSuccessfully(): + """ + Summary: + A test entity contains two Script Canvas components with different unique script canvas files. + Each of these files will have a print node set to activate on graph start. + + Expected Behavior: + When game mode is entered, two unique strings should be printed out to the console + + Test Steps: + 1) Create level + 2) Create entity with SC components + 3) Start Tracer + 4) Enter game mode + 5) Wait for expected lines to be found + 6) Report if expected lines were found + 7) Exit game mode + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + + from utils import TestHelper as helper + import hydra_editor_utils as hydra + from utils import Report + from utils import Tracer + + import azlmbr.legacy.general as general + import azlmbr.math as math + import azlmbr.asset as asset + import azlmbr.bus as bus + + LEVEL_NAME = "tmp_level" + ASSET_1 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents0.scriptcanvas") + ASSET_2 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents1.scriptcanvas") + WAIT_TIME = 3.0 # SECONDS + + def get_asset(asset_path): + return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) + + def locate_expected_lines(): + found_lines = [] + for printInfo in section_tracer.prints: + found_lines.append(printInfo.message.strip()) + + return all(line in found_lines for line in LogLines.expected_lines) + + # 1) Create level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create entity with SC components + position = math.Vector3(512.0, 512.0, 32.0) + test_entity = hydra.Entity("test_entity") + test_entity.create_entity(position, ["Script Canvas", "Script Canvas"]) + test_entity.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_1)) + test_entity.get_set_test(1, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_2)) + + # 3) Start Tracer + with Tracer() as section_tracer: + + # 4) Enter game mode + helper.enter_game_mode(Tests.game_mode_entered) + + # 5) Wait for expected lines to be found + helper.wait_for_condition(locate_expected_lines, WAIT_TIME) + + # 6) Report if expected lines were found + Report.result(Tests.found_lines, locate_expected_lines()) + + # 7) Exit game mode + helper.exit_game_mode(Tests.game_mode_exited) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptCanvas_TwoComponents_InteractSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py deleted file mode 100644 index 401e6c0271..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities.py +++ /dev/null @@ -1,107 +0,0 @@ -""" -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. - -Test case ID: T92563191 -Test Case Title: Two Entities can use the same Graph asset successfully at RunTime -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563191 -""" - - -# fmt: off -class Tests(): - level_created = ("New level created", "New level not created") - game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter") - game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited") - found_lines = ("Expected log lines were found", "Expected log lines were not found") -# fmt: on - - -def ScriptCanvas_TwoEntities(): - """ - Summary: - Two Entities can use the same Graph asset successfully at RunTime. The script canvas asset - attached to the enties will print the respective entity names. - - Expected Behavior: - When game mode is entered, respective strings of different entities should be printed. - - Test Steps: - 1) Create temp level - 2) Create two new entities with different names - 3) Set ScriptCanvas asset to both the entities - 4) Enter/Exit game mode and verify log lines - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - import os - - from utils import TestHelper as helper - from utils import Tracer - import hydra_editor_utils as hydra - import azlmbr.legacy.general as general - import azlmbr.math as math - import azlmbr.asset as asset - import azlmbr.bus as bus - - LEVEL_NAME = "tmp_level" - ASSET_PATH = os.path.join("scriptcanvas", "T92563191_test.scriptcanvas") - EXPECTED_LINES = ["Entity Name: test_entity_1", "Entity Name: test_entity_2"] - WAIT_TIME = 0.5 # SECONDS - - def get_asset(asset_path): - return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) - - # 1) Create temp level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Create two new entities with different names - position = math.Vector3(512.0, 512.0, 32.0) - test_entity_1 = hydra.Entity("test_entity_1") - test_entity_1.create_entity(position, ["Script Canvas"]) - - test_entity_2 = hydra.Entity("test_entity_2") - test_entity_2.create_entity(position, ["Script Canvas"]) - - # 3) Set ScriptCanvas asset to both the entities - test_entity_1.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_PATH)) - test_entity_2.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_PATH)) - - # 4) Enter/Exit game mode and verify log lines - with Tracer() as section_tracer: - - helper.enter_game_mode(Tests.game_mode_entered) - # wait for WAIT_TIME to let the script print strings - general.idle_wait(WAIT_TIME) - helper.exit_game_mode(Tests.game_mode_exited) - - found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] - result = all(line in found_lines for line in EXPECTED_LINES) - - Report.result(Tests.found_lines, result) - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - from utils import Report - - Report.start_test(ScriptCanvas_TwoEntities) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities_UseSimultaneously.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities_UseSimultaneously.py new file mode 100644 index 0000000000..d25ef64c4a --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptCanvas_TwoEntities_UseSimultaneously.py @@ -0,0 +1,104 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("New level created successfully", "New level failed to create") + game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter") + game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited") + found_lines = ("Expected log lines were found", "Expected log lines were not found") +# fmt: on + + +def ScriptCanvas_TwoEntities_UseSimultaneously(): + """ + Summary: + Two Entities can use the same Graph asset successfully at RunTime. The script canvas asset + attached to the entities will print the respective entity names. + + Expected Behavior: + When game mode is entered, respective strings of different entities should be printed. + + Test Steps: + 1) Create temp level + 2) Create two new entities with different names + 3) Set ScriptCanvas asset to both the entities + 4) Enter/Exit game mode and verify log lines + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + import os + + import hydra_editor_utils as hydra + from utils import TestHelper as helper + from utils import Tracer + + import azlmbr.legacy.general as general + import azlmbr.math as math + import azlmbr.asset as asset + import azlmbr.bus as bus + + LEVEL_NAME = "tmp_level" + ASSET_PATH = os.path.join("scriptcanvas", "T92563191_test.scriptcanvas") + EXPECTED_LINES = ["Entity Name: test_entity_1", "Entity Name: test_entity_2"] + WAIT_TIME = 0.5 # SECONDS + + def get_asset(asset_path): + return asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", asset_path, math.Uuid(), False) + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create two new entities with different names + position = math.Vector3(512.0, 512.0, 32.0) + test_entity_1 = hydra.Entity("test_entity_1") + test_entity_1.create_entity(position, ["Script Canvas"]) + + test_entity_2 = hydra.Entity("test_entity_2") + test_entity_2.create_entity(position, ["Script Canvas"]) + + # 3) Set ScriptCanvas asset to both the entities + test_entity_1.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_PATH)) + test_entity_2.get_set_test(0, "Script Canvas Asset|Script Canvas Asset", get_asset(ASSET_PATH)) + + # 4) Enter/Exit game mode and verify log lines + with Tracer() as section_tracer: + + helper.enter_game_mode(Tests.game_mode_entered) + # wait for WAIT_TIME to let the script print strings + general.idle_wait(WAIT_TIME) + helper.exit_game_mode(Tests.game_mode_exited) + + found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] + result = all(line in found_lines for line in EXPECTED_LINES) + + Report.result(Tests.found_lines, result) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptCanvas_TwoEntities_UseSimultaneously) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py new file mode 100644 index 0000000000..21ad40014e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py @@ -0,0 +1,202 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + new_event_created = ("New Script Event created", "New Script Event not created") + child_1_created = ("Initial Child Event created", "Initial Child Event not created") + child_2_created = ("Second Child Event created", "Second Child Event not created") + file_saved = ("Script event file saved", "Script event file did not save") + method_added = ("Method added to scriptevent file", "Method not added to scriptevent file") + method_removed = ("Method removed from scriptevent file", "Method not removed from scriptevent file") +# fmt: on + + +def ScriptEvent_AddRemoveMethod_UpdatesInSC(): + """ + Summary: + Method can be added/removed to an existing .scriptevents file + + Expected Behavior: + The Method is correctly added/removed to the asset, and Script Canvas nodes are updated accordingly. + + Test Steps: + 1) Open Asset Editor and Script Canvas windows + 2) Initially create new Script Event file with one method + 3) Verify if file is created and saved + 4) Add a new child element + 5) Update MethodNames and save file + 6) Verify if the new node exist in SC (search in node palette) + 7) Delete one method and save + 8) Verify if the node is removed in SC + 9) Close Asset Editor + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + from utils import TestHelper as helper + import pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + import azlmbr.editor as editor + import azlmbr.bus as bus + + # Pyside imports + from PySide2 import QtWidgets, QtTest, QtCore + + GENERAL_WAIT = 1.0 # seconds + + FILE_PATH = os.path.join("AutomatedTesting", "TestAssets", "test_file.scriptevents") + METHOD_NAME = "test_method_name" + + editor_window = pyside_utils.get_editor_main_window() + asset_editor = asset_editor_widget = container = menu_bar = None + sc = node_palette = tree = search_frame = search_box = None + + def initialize_asset_editor_qt_objects(): + nonlocal asset_editor, asset_editor_widget, container, menu_bar + asset_editor = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor") + asset_editor_widget = asset_editor.findChild(QtWidgets.QWidget, "AssetEditorWindowClass") + container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") + menu_bar = asset_editor_widget.findChild(QtWidgets.QMenuBar) + + def initialize_sc_qt_objects(): + nonlocal sc, node_palette, tree, search_frame, search_box + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + tree = node_palette.findChild(QtWidgets.QTreeView, "treeView") + search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame") + search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter") + + def save_file(): + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", FILE_PATH) + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "iconText": "Save"}) + action.trigger() + # wait till file is saved, to validate that check the text of QLabel at the bottom of the AssetEditor, + # if there are no unsaved changes we will not have any * in the text + label = asset_editor.findChild(QtWidgets.QLabel, "textEdit") + return helper.wait_for_condition(lambda: "*" not in label.text(), 3.0) + + def expand_container_rows(object_name): + children = container.findChildren(QtWidgets.QFrame, object_name) + for child in children: + check_box = child.findChild(QtWidgets.QCheckBox) + if check_box and not check_box.isChecked(): + QtTest.QTest.mouseClick(check_box, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier) + + def node_palette_search(node_name): + search_box.setText(node_name) + helper.wait_for_condition(lambda: search_box.text() == node_name, 1.0) + # Try clicking ENTER in search box multiple times + for _ in range(10): + QtTest.QTest.keyClick(search_box, QtCore.Qt.Key_Enter, QtCore.Qt.NoModifier) + if pyside_utils.find_child_by_pattern(tree, {"text": node_name}) is not None: + break + + # 1) Open Asset Editor + general.idle_enable(True) + # Initially close the Asset Editor and then reopen to ensure we don't have any existing assets open + general.close_pane("Asset Editor") + general.open_pane("Asset Editor") + helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), 5.0) + + # 2) Initially create new Script Event file with one method + initialize_asset_editor_qt_objects() + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "text": "Script Events"}) + action.trigger() + result = helper.wait_for_condition( + lambda: container.findChild(QtWidgets.QFrame, "Events") is not None + and container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") is not None, + 3 * GENERAL_WAIT, + ) + Report.result(Tests.new_event_created, result) + # Add new method + add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") + add_event.click() + result = helper.wait_for_condition( + lambda: asset_editor_widget.findChild(QtWidgets.QFrame, "EventName") is not None, GENERAL_WAIT + ) + Report.result(Tests.child_1_created, result) + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", FILE_PATH) + + # 3) Verify if file is created and saved + result = helper.wait_for_condition(lambda: os.path.exists(FILE_PATH), 3 * GENERAL_WAIT) + Report.result(Tests.file_saved, result and save_file()) + + # 4) Add a new child element + add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") + add_event.click() + result = helper.wait_for_condition( + lambda: len(asset_editor_widget.findChildren(QtWidgets.QFrame, "EventName")) == 2, 2 * GENERAL_WAIT + ) + Report.result(Tests.child_2_created, result) + + # 5) Update MethodNames and save file, (update all Method names to make it easier to search in SC later) + # Expand the EventName initially + expand_container_rows("EventName") + # Expand Name fields under it + expand_container_rows("Name") + count = 0 # 2 Method names will be updated Ex: test_method_name_0, test_method_name_1 + container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") + children = container.findChildren(QtWidgets.QFrame, "Name") + for child in children: + line_edit = child.findChild(QtWidgets.QLineEdit) + if line_edit and line_edit.text() == "MethodName": + line_edit.setText(f"{METHOD_NAME}_{count}") + count += 1 + save_file() + + # 6) Verify if the new node exist in SC (search in node palette) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + initialize_sc_qt_objects() + node_palette_search(f"{METHOD_NAME}_1") + get_node_index = lambda: pyside_utils.find_child_by_pattern(tree, {"text": f"{METHOD_NAME}_1"}) is not None + result = helper.wait_for_condition(get_node_index, GENERAL_WAIT) + Report.result(Tests.method_added, result) + + # 7) Delete one method and save + initialize_asset_editor_qt_objects() + for child in container.findChildren(QtWidgets.QFrame, "EventName"): + if child.findChild(QtWidgets.QToolButton, ""): + child.findChild(QtWidgets.QToolButton, "").click() + break + save_file() + + # 8) Verify if the node is removed in SC (search in node palette) + initialize_sc_qt_objects() + node_palette_search(f"{METHOD_NAME}_0") + get_node_index = lambda: pyside_utils.find_child_by_pattern(tree, {"text": f"{METHOD_NAME}_0"}) is None + result = helper.wait_for_condition(get_node_index, GENERAL_WAIT) + Report.result(Tests.method_removed, result) + + # 9) Close Asset Editor + general.close_pane("Asset Editor") + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptEvent_AddRemoveMethod_UpdatesInSC) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveParameter_ActionsSuccessful.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveParameter_ActionsSuccessful.py new file mode 100644 index 0000000000..638c69e8f3 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveParameter_ActionsSuccessful.py @@ -0,0 +1,131 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + new_event_created = ("Successfully created a new event", "Failed to create a new event") + child_event_created = ("Successfully created Child Event", "Failed to create Child Event") + file_saved = ("Successfully saved event asset", "Failed to save event asset") + parameter_created = ("Successfully added parameter", "Failed to add parameter") + parameter_removed = ("Successfully removed parameter", "Failed to remove parameter") +# fmt: on + + +def ScriptEvent_AddRemoveParameter_ActionsSuccessful(): + """ + Summary: + Parameter can be removed from a Script Event method + + Expected Behavior: + Upon saving the updated .scriptevents asset the removed paramenter should no longer be present on the Script Event + + Test Steps: + 1) Open Asset Editor + 2) Get Asset Editor Qt object + 3) Create new Script Event Asset + 4) Add Parameter to Event + 5) Remove Parameter from Event + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + from PySide2 import QtWidgets + + from editor_python_test_tools.utils import Report + from editor_python_test_tools.utils import TestHelper as helper + import editor_python_test_tools.pyside_utils as pyside_utils + + import azlmbr.bus as bus + import azlmbr.editor as editor + import azlmbr.legacy.general as general + + GENERAL_WAIT = 1.0 # seconds + FILE_PATH = os.path.join("AutomatedTesting", "ScriptCanvas", "test_file.scriptevent") + QtObject = object + + def create_script_event(asset_editor: QtObject, file_path: str) -> None: + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "text": "Script Events"}) + action.trigger() + result = helper.wait_for_condition( + lambda: container.findChild(QtWidgets.QFrame, "Events") is not None, 3 * GENERAL_WAIT + ) + Report.result(Tests.new_event_created, result) + + # Add new child event + add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") + add_event.click() + result = helper.wait_for_condition( + lambda: asset_editor.findChild(QtWidgets.QFrame, "EventName") is not None, GENERAL_WAIT + ) + Report.result(Tests.child_event_created, result) + # Save the Script Event file + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", file_path) + + # Verify if file is created + result = helper.wait_for_condition(lambda: os.path.exists(file_path), 3 * GENERAL_WAIT) + Report.result(Tests.file_saved, result) + + def create_parameter(file_path: str) -> None: + add_param = container.findChild(QtWidgets.QFrame, "Parameters").findChild(QtWidgets.QToolButton, "") + add_param.click() + result = helper.wait_for_condition( + lambda: asset_editor_widget.findChild(QtWidgets.QFrame, "[0]") is not None, GENERAL_WAIT + ) + Report.result(Tests.parameter_created, result) + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", file_path) + + def remove_parameter(file_path: str) -> None: + remove_param = container.findChild(QtWidgets.QFrame, "[0]").findChild(QtWidgets.QToolButton, "") + remove_param.click() + result = helper.wait_for_condition( + lambda: asset_editor_widget.findChild(QtWidgets.QFrame, "[0]") is None, GENERAL_WAIT + ) + Report.result(Tests.parameter_removed, result) + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", file_path) + + # 1) Open Asset Editor + general.idle_enable(True) + # Initially close the Asset Editor and then reopen to ensure we don't have any existing assets open + general.close_pane("Asset Editor") + general.open_pane("Asset Editor") + helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), 5.0) + + # 2) Get Asset Editor Qt object + editor_window = pyside_utils.get_editor_main_window() + asset_editor_widget = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor").findChild( + QtWidgets.QWidget, "AssetEditorWindowClass" + ) + container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") + menu_bar = asset_editor_widget.findChild(QtWidgets.QMenuBar) + + # 3) Create new Script Event Asset + create_script_event(asset_editor_widget, FILE_PATH) + + # 4) Add Parameter to Event + create_parameter(FILE_PATH) + + # 5) Remove Parameter from Event + remove_parameter(FILE_PATH) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from editor_python_test_tools.utils import Report + + Report.start_test(ScriptEvent_AddRemoveParameter_ActionsSuccessful) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_HappyPath_CreatedWithoutError.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_HappyPath_CreatedWithoutError.py new file mode 100644 index 0000000000..72144ebc0e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_HappyPath_CreatedWithoutError.py @@ -0,0 +1,119 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + new_event_created = ("New Script Event created", "New Script Event not created") + child_event_created = ("Child Event created", "Child not created") + file_saved = ("Script event file saved", "Script event file did not save") + console_error = ("No unexpected error in console", "Error found in console") + console_warning = ("No unexpected warning in console", "Warning found in console") +# fmt: on + + +def CreateScriptEventFile(): + """ + Summary: + Script Event file can be created + + Expected Behavior: + File is created without any errors and warnings in Console + + Test Steps: + 1) Open Asset Editor + 2) Get Asset Editor Qt object + 3) Create new Script Event Asset + 4) Add new child event + 5) Save the Script Event file + 6) Verify if file is created + 7) Verify console for errors/warnings + 8) Close Asset Editor + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + from utils import Report + from utils import TestHelper as helper + from utils import Tracer + import pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + import azlmbr.editor as editor + import azlmbr.bus as bus + + # Pyside imports + from PySide2 import QtWidgets + + GENERAL_WAIT = 1.0 # seconds + + FILE_PATH = os.path.join("AutomatedTesting", "ScriptCanvas", "test_file.scriptevent") + + # 1) Open Asset Editor + general.idle_enable(True) + # Initially close the Asset Editor and then reopen to ensure we don't have any existing assets open + general.close_pane("Asset Editor") + general.open_pane("Asset Editor") + helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), 5.0) + + # 2) Get Asset Editor Qt object + editor_window = pyside_utils.get_editor_main_window() + asset_editor_widget = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor").findChild( + QtWidgets.QWidget, "AssetEditorWindowClass" + ) + container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") + menu_bar = asset_editor_widget.findChild(QtWidgets.QMenuBar) + + # 3) Create new Script Event Asset + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "text": "Script Events"}) + action.trigger() + result = helper.wait_for_condition( + lambda: container.findChild(QtWidgets.QFrame, "Events") is not None, 3 * GENERAL_WAIT + ) + Report.result(Tests.new_event_created, result) + + # 4) Add new child event + add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") + add_event.click() + result = helper.wait_for_condition( + lambda: asset_editor_widget.findChild(QtWidgets.QFrame, "EventName") is not None, GENERAL_WAIT + ) + Report.result(Tests.child_event_created, result) + + with Tracer() as section_tracer: + # 5) Save the Script Event file + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", FILE_PATH) + + # 6) Verify if file is created + result = helper.wait_for_condition(lambda: os.path.exists(FILE_PATH), 3 * GENERAL_WAIT) + Report.result(Tests.file_saved, result) + + # 7) Verify console for errors/warnings + Report.result(Tests.console_error, not section_tracer.has_errors) + Report.result(Tests.console_warning, not section_tracer.has_warnings) + + # 8) Close Asset Editor + general.close_pane("Asset Editor") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(CreateScriptEventFile) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_AllParamDatatypes_CreationSuccess.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_AllParamDatatypes_CreationSuccess.py new file mode 100644 index 0000000000..4beedec7cf --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_AllParamDatatypes_CreationSuccess.py @@ -0,0 +1,210 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + new_event_created = ("New Script Event created", "New Script Event not created") + child_event_created = ("Child Event created", "Child Event not created") + params_added = ("New parameters added", "New parameters are not added") + file_saved = ("Script event file saved", "Script event file did not save") + node_found = ("Node found in Script Canvas", "Node not found in Script Canvas") +# fmt: on + + +def ScriptEvents_AllParamDatatypes_CreationSuccess(): + """ + Summary: + Parameters of all types can be created. + + Expected Behavior: + The Method handles the large number of Parameters gracefully. + Parameters of all data types can be successfully created. + Updated ScriptEvent toast appears in Script Canvas. + + Test Steps: + 1) Open Asset Editor + 2) Initially create new Script Event file with one method + 3) Add new method and set name to it + 4) Add new parameters of each type + 5) Verify if parameters are added + 6) Expand the parameter rows + 7) Set different names and datatypes for each parameter + 8) Save file and verify node in SC Node Palette + 9) Close Asset Editor + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + from utils import TestHelper as helper + import pyside_utils + + # Open 3D Engine imports + import azlmbr.legacy.general as general + import azlmbr.editor as editor + import azlmbr.bus as bus + + # Pyside imports + from PySide2 import QtWidgets, QtTest, QtCore + + GENERAL_WAIT = 1.0 # seconds + + FILE_PATH = os.path.join("AutomatedTesting", "TestAssets", "test_file.scriptevents") + N_VAR_TYPES = 10 # Top 10 variable types + TEST_METHOD_NAME = "test_method_name" + + editor_window = pyside_utils.get_editor_main_window() + asset_editor = asset_editor_widget = container = menu_bar = None + sc = node_palette = tree = search_frame = search_box = None + + def initialize_asset_editor_qt_objects(): + nonlocal asset_editor, asset_editor_widget, container, menu_bar + asset_editor = editor_window.findChild(QtWidgets.QDockWidget, "Asset Editor") + asset_editor_widget = asset_editor.findChild(QtWidgets.QWidget, "AssetEditorWindowClass") + container = asset_editor_widget.findChild(QtWidgets.QWidget, "ContainerForRows") + menu_bar = asset_editor_widget.findChild(QtWidgets.QMenuBar) + + def initialize_sc_qt_objects(): + nonlocal sc, node_palette, tree, search_frame, search_box + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction}) + action.trigger() + node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette") + tree = node_palette.findChild(QtWidgets.QTreeView, "treeView") + search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame") + search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter") + + def save_file(): + editor.AssetEditorWidgetRequestsBus(bus.Broadcast, "SaveAssetAs", FILE_PATH) + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "iconText": "Save"}) + action.trigger() + # wait till file is saved, to validate that check the text of QLabel at the bottom of the AssetEditor, + # if there are no unsaved changes we will not have any * in the text + label = asset_editor.findChild(QtWidgets.QLabel, "textEdit") + return helper.wait_for_condition(lambda: "*" not in label.text(), 3.0) + + def expand_container_rows(object_name): + children = container.findChildren(QtWidgets.QFrame, object_name) + for child in children: + check_box = child.findChild(QtWidgets.QCheckBox) + if check_box and not check_box.isChecked(): + QtTest.QTest.mouseClick(check_box, QtCore.Qt.LeftButton, QtCore.Qt.NoModifier) + + def node_palette_search(node_name): + search_box.setText(node_name) + helper.wait_for_condition(lambda: search_box.text() == node_name, 1.0) + # Try clicking ENTER in search box multiple times + for _ in range(20): + QtTest.QTest.keyClick(search_box, QtCore.Qt.Key_Enter, QtCore.Qt.NoModifier) + if pyside_utils.find_child_by_pattern(tree, {"text": node_name}) is not None: + break + + def verify_added_params(): + for index in range(N_VAR_TYPES): + if container.findChild(QtWidgets.QFrame, f"[{index}]") is None: + return False + return True + + # 1) Open Asset Editor + general.idle_enable(True) + # Initially close the Asset Editor and then reopen to ensure we don't have any existing assets open + general.close_pane("Asset Editor") + general.open_pane("Asset Editor") + helper.wait_for_condition(lambda: general.is_pane_visible("Asset Editor"), 5.0) + + # 2) Initially create new Script Event file with one method + initialize_asset_editor_qt_objects() + action = pyside_utils.find_child_by_pattern(menu_bar, {"type": QtWidgets.QAction, "text": "Script Events"}) + action.trigger() + result = helper.wait_for_condition( + lambda: container.findChild(QtWidgets.QFrame, "Events") is not None + and container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") is not None, + 3 * GENERAL_WAIT, + ) + Report.result(Tests.new_event_created, result) + + # 3) Add new method and set name to it + add_event = container.findChild(QtWidgets.QFrame, "Events").findChild(QtWidgets.QToolButton, "") + add_event.click() + result = helper.wait_for_condition( + lambda: asset_editor_widget.findChild(QtWidgets.QFrame, "EventName") is not None, GENERAL_WAIT + ) + Report.result(Tests.child_event_created, result) + expand_container_rows("EventName") + expand_container_rows("Name") + initialize_asset_editor_qt_objects() + children = container.findChildren(QtWidgets.QFrame, "Name") + for child in children: + line_edit = child.findChild(QtWidgets.QLineEdit) + if line_edit is not None and line_edit.text() == "MethodName": + line_edit.setText(TEST_METHOD_NAME) + + # 4) Add new parameters of each type + helper.wait_for_condition(lambda: container.findChild(QtWidgets.QFrame, "Parameters") is not None, 2.0) + parameters = container.findChild(QtWidgets.QFrame, "Parameters") + add_param = parameters.findChild(QtWidgets.QToolButton, "") + for _ in range(N_VAR_TYPES): + add_param.click() + + # 5) Verify if parameters are added + result = helper.wait_for_condition(verify_added_params, 3.0) + Report.result(Tests.params_added, result) + + # 6) Expand the parameter rows (to render QFrame 'Type' for each param) + for index in range(N_VAR_TYPES): + expand_container_rows(f"[{index}]") + + # 7) Set different names and datatypes for each parameter + expand_container_rows("Name") + children = container.findChildren(QtWidgets.QFrame, "Name") + index = 0 + for child in children: + line_edit = child.findChild(QtWidgets.QLineEdit) + if line_edit is not None and line_edit.text() == "ParameterName": + line_edit.setText(f"param_{index}") + index += 1 + + children = container.findChildren(QtWidgets.QFrame, "Type") + index = 0 + for child in children: + combo_box = child.findChild(QtWidgets.QComboBox) + if combo_box is not None and index < N_VAR_TYPES: + combo_box.setCurrentIndex(index) + index += 1 + + # 8) Save file and verify node in SC Node Palette + Report.result(Tests.file_saved, save_file()) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) + initialize_sc_qt_objects() + node_palette_search(TEST_METHOD_NAME) + get_node_index = lambda: pyside_utils.find_child_by_pattern(tree, {"text": TEST_METHOD_NAME}) is not None + result = helper.wait_for_condition(get_node_index, 2.0) + Report.result(Tests.node_found, result) + + # 9) Close Asset Editor + general.close_pane("Asset Editor") + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptEvents_AllParamDatatypes_CreationSuccess) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_Default_SendReceiveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_Default_SendReceiveSuccessfully.py new file mode 100644 index 0000000000..e0730b284c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_Default_SendReceiveSuccessfully.py @@ -0,0 +1,105 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("Successfully created temporary level", "Failed to create temporary level") + entity_created = ("Successfully created test entity", "Failed to create test entity") + enter_game_mode = ("Successfully entered game mode", "Failed to enter game mode") + lines_found = ("Successfully found expected message", "Failed to find expected message") + exit_game_mode = ("Successfully exited game mode", "Failed to exit game mode") +# fmt: on + + +def ScriptEvents_Default_SendReceiveSuccessfully(): + """ + Summary: + An entity exists in the level that contains a Script Canvas component. In the graph is both a Send Event + and a Receive Event. + + Expected Behavior: + After entering game mode the graph on the entity should print an expected message to the console + + Test Steps: + 1) Create test level + 2) Create test entity + 3) Start Tracer + 4) Enter Game Mode + 5) Read for line + 6) Exit Game Mode + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + from editor_entity_utils import EditorEntity as Entity + from utils import Report + from utils import TestHelper as helper + from utils import Tracer + + import azlmbr.legacy.general as general + import azlmbr.asset as asset + import azlmbr.math as math + import azlmbr.bus as bus + + LEVEL_NAME = "tmp_level" + WAIT_TIME = 3.0 # SECONDS + EXPECTED_LINES = ["T92567320: Message Received"] + SC_ASSET_PATH = os.path.join("ScriptCanvas", "T92567320.scriptcanvas") + + def create_editor_entity(name, sc_asset): + entity = Entity.create_editor_entity(name) + sc_comp = entity.add_component("Script Canvas") + asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", sc_asset, math.Uuid(), False) + sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", asset_id) + Report.critical_result(Tests.entity_created, entity.id.isValid()) + + def locate_expected_lines(line_list: list): + found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] + + return all(line in found_lines for line in line_list) + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create test entity + create_editor_entity("TestEntity", SC_ASSET_PATH) + + # 3) Start Tracer + with Tracer() as section_tracer: + + # 4) Enter Game Mode + helper.enter_game_mode(Tests.enter_game_mode) + + # 5) Read for line + lines_located = helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME) + Report.result(Tests.lines_found, lines_located) + + # 6) Exit Game Mode + helper.exit_game_mode(Tests.exit_game_mode) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptEvents_Default_SendReceiveSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_HappyPath_SendReceiveAcrossMultiple.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_HappyPath_SendReceiveAcrossMultiple.py new file mode 100644 index 0000000000..be2665899f --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_HappyPath_SendReceiveAcrossMultiple.py @@ -0,0 +1,116 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + level_created = ("Successfully created temporary level", "Failed to create temporary level") + entitya_created = ("Successfully created EntityA", "Failed to create EntityA") + entityb_created = ("Successfully created EntityB", "Failed to create EntityB") + enter_game_mode = ("Successfully entered game mode", "Failed to enter game mode") + lines_found = ("Successfully found expected message", "Failed to find expected message") + exit_game_mode = ("Successfully exited game mode", "Failed to exit game mode") +# fmt: on + + +def ScriptEvents_HappyPath_SendReceiveAcrossMultiple(): + """ + Summary: + EntityA and EntityB will be created in a level. Attached to both will be a Script Canvas component. + The Script Event created for the test will be sent from EntityA to EntityB. + + Expected Behavior: + The output of the Script Event should be printed to the console + + Test Steps: + 1) Create test level + 2) Create EntityA/EntityB (add scriptcanvas files part of entity setup) + 3) Start Tracer + 4) Enter Game Mode + 5) Read for line + 6) Exit Game Mode + + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + + from editor_entity_utils import EditorEntity as Entity + from utils import Report + from utils import TestHelper as helper + from utils import Tracer + + import azlmbr.legacy.general as general + + LEVEL_NAME = "tmp_level" + WAIT_TIME = 3.0 + ASSET_PREFIX = "T92567321" + asset_paths = { + "event": os.path.join("TestAssets", f"{ASSET_PREFIX}.scriptevents"), + "assetA": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}A.scriptcanvas"), + "assetB": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}B.scriptcanvas"), + } + sc_for_entities = {"EntityA": asset_paths["assetA"], "EntityB": asset_paths["assetB"]} + EXPECTED_LINES = ["Incoming Message Received"] + + def get_asset(asset_path): + return azlmbr.asset.AssetCatalogRequestBus( + azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False + ) + + def create_editor_entity(name, sc_asset): + entity = Entity.create_editor_entity(name) + sc_comp = entity.add_component("Script Canvas") + sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", get_asset(sc_asset)) + Report.critical_result(Tests.__dict__[name.lower() + "_created"], entity.id.isValid()) + + def locate_expected_lines(line_list: list): + found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] + + return all(line in found_lines for line in line_list) + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create EntityA/EntityB + for key in sc_for_entities.keys(): + create_editor_entity(key, sc_for_entities[key]) + + # 3) Start Tracer + with Tracer() as section_tracer: + + # 4) Enter Game Mode + helper.enter_game_mode(Tests.enter_game_mode) + + # 5) Read for line + lines_located = helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME) + Report.result(Tests.lines_found, lines_located) + + # 6) Exit Game Mode + helper.exit_game_mode(Tests.exit_game_mode) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptEvents_HappyPath_SendReceiveAcrossMultiple) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_ReturnSetType_Successfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_ReturnSetType_Successfully.py new file mode 100644 index 0000000000..ee63684ace --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_ReturnSetType_Successfully.py @@ -0,0 +1,111 @@ +""" +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. + +Test Case Title: Event can return a value of set type successfully +""" + + +# fmt: off +class Tests(): + level_created = ("Successfully created temporary level", "Failed to create temporary level") + entity_created = ("Successfully created test entity", "Failed to create test entity") + enter_game_mode = ("Successfully entered game mode", "Failed to enter game mode") + lines_found = ("Successfully found expected message", "Failed to find expected message") + exit_game_mode = ("Successfully exited game mode", "Failed to exit game mode") +# fmt: on + + +def ScriptEvents_ReturnSetType_Successfully(): + """ + Summary: A temporary level is created with an Entity having ScriptCanvas component. + ScriptEvent(T92569006_ScriptEvent.scriptevents) is created with one Method that has a return value. + ScriptCanvas(T92569006_ScriptCanvas.scriptcanvas) is attached to Entity. Graph has Send node that sends the Method + of the ScriptEvent and prints the returned result ( On Entity Activated -> Send node -> Print) and Receive node is + set to return custom value ( Receive node -> Print). + Verify that the entity containing T92569006_ScriptCanvas.scriptcanvas should print the custom value set in both + Send and Receive nodes. + + Expected Behavior: + After entering game mode, the graph on the entity should print an expected message to the console + + Test Steps: + 1) Create test level + 2) Create test entity + 3) Start Tracer + 4) Enter Game Mode + 5) Read for line + 6) Exit Game Mode + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + import os + from editor_entity_utils import EditorEntity as Entity + from utils import Report + from utils import TestHelper as helper + from utils import Tracer + + import azlmbr.legacy.general as general + import azlmbr.asset as asset + import azlmbr.math as math + import azlmbr.bus as bus + + LEVEL_NAME = "tmp_level" + WAIT_TIME = 3.0 # SECONDS + EXPECTED_LINES = ["T92569006_ScriptEvent_Sent", "T92569006_ScriptEvent_Received"] + SC_ASSET_PATH = os.path.join("ScriptCanvas", "T92569006_ScriptCanvas.scriptcanvas") + + def create_editor_entity(name, sc_asset): + entity = Entity.create_editor_entity(name) + sc_comp = entity.add_component("Script Canvas") + asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", sc_asset, math.Uuid(), False) + sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", asset_id) + Report.critical_result(Tests.entity_created, entity.id.isValid()) + + def locate_expected_lines(line_list: list): + found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] + + return all(line in found_lines for line in line_list) + + # 1) Create temp level + general.idle_enable(True) + result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) + Report.critical_result(Tests.level_created, result == 0) + helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) + general.close_pane("Error Report") + + # 2) Create test entity + create_editor_entity("TestEntity", SC_ASSET_PATH) + + # 3) Start Tracer + with Tracer() as section_tracer: + + # 4) Enter Game Mode + helper.enter_game_mode(Tests.enter_game_mode) + + # 5) Read for line + lines_located = helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME) + Report.result(Tests.lines_found, lines_located) + + # 6) Exit Game Mode + helper.exit_game_mode(Tests.exit_game_mode) + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(ScriptEvents_ReturnSetType_Successfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py deleted file mode 100644 index d671229cdf..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveAcrossMultiple.py +++ /dev/null @@ -1,120 +0,0 @@ -""" -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. - -Test case ID: T92567321 -Test Case Title: Script Events: Can send and receive a script event across multiple entities successfully -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567321 -""" - - -# fmt: off -class Tests(): - level_created = ("Successfully created temporary level", "Failed to create temporary level") - entitya_created = ("Successfully created EntityA", "Failed to create EntityA") - entityb_created = ("Successfully created EntityB", "Failed to create EntityB") - enter_game_mode = ("Successfully entered game mode", "Failed to enter game mode") - lines_found = ("Successfully found expected message", "Failed to find expected message") - exit_game_mode = ("Successfully exited game mode", "Failed to exit game mode") -# fmt: on - - -def ScriptEvents_SendReceiveAcrossMultiple(): - """ - Summary: - EntityA and EntityB will be created in a level. Attached to both will be a Script Canvas component. The Script Event created for the test will be sent from EntityA to EntityB. - - Expected Behavior: - The output of the Script Event should be printed to the console - - Test Steps: - 1) Create test level - 2) Create EntityA/EntityB (add scriptcanvas files part of entity setup) - 3) Start Tracer - 4) Enter Game Mode - 5) Read for line - 6) Exit Game Mode - - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - import os - - from editor_entity_utils import EditorEntity as Entity - from utils import Report - from utils import TestHelper as helper - from utils import Tracer - - import azlmbr.legacy.general as general - - LEVEL_NAME = "tmp_level" - WAIT_TIME = 3.0 - ASSET_PREFIX = "T92567321" - asset_paths = { - "event": os.path.join("TestAssets", f"{ASSET_PREFIX}.scriptevents"), - "assetA": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}A.scriptcanvas"), - "assetB": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}B.scriptcanvas"), - } - sc_for_entities = { - "EntityA": asset_paths["assetA"], - "EntityB": asset_paths["assetB"] - } - EXPECTED_LINES = ["Incoming Message Received"] - - def get_asset(asset_path): - return azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False) - - def create_editor_entity(name, sc_asset): - entity = Entity.create_editor_entity(name) - sc_comp = entity.add_component("Script Canvas") - sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", get_asset(sc_asset)) - Report.critical_result(Tests.__dict__[name.lower()+"_created"], entity.id.isValid()) - - def locate_expected_lines(line_list: list): - found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] - - return all(line in found_lines for line in line_list) - - # 1) Create temp level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Create EntityA/EntityB - for key in sc_for_entities.keys(): - create_editor_entity(key, sc_for_entities[key]) - - # 3) Start Tracer - with Tracer() as section_tracer: - - # 4) Enter Game Mode - helper.enter_game_mode(Tests.enter_game_mode) - - # 5) Read for line - lines_located = helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME) - Report.result(Tests.lines_found, lines_located) - - # 6) Exit Game Mode - helper.exit_game_mode(Tests.exit_game_mode) - - -if __name__ == "__main__": - import ImportPathHelper as imports - imports.init() - - from utils import Report - - Report.start_test(ScriptEvents_SendReceiveAcrossMultiple) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py b/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py deleted file mode 100644 index b5e26d14ae..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/ScriptEvents_SendReceiveSuccessfully.py +++ /dev/null @@ -1,110 +0,0 @@ -""" -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. - -Test case ID: T92567320 -Test Case Title: Script Events: Can send and receive a script event successfully -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567320 -""" - - -# fmt: off -class Tests(): - level_created = ("Successfully created temporary level", "Failed to create temporary level") - entity_created = ("Successfully created test entity", "Failed to create test entity") - enter_game_mode = ("Successfully entered game mode", "Failed to enter game mode") - lines_found = ("Successfully found expected message", "Failed to find expected message") - exit_game_mode = ("Successfully exited game mode", "Failed to exit game mode") -# fmt: on - - -def ScriptEvents_SendReceiveSuccessfully(): - """ - Summary: - An entity exists in the level that contains a Script Canvas component. In the graph is both a Send Event - and a Receive Event. - - Expected Behavior: - After entering game mode the graph on the entity should print an expected message to the console - - Test Steps: - 1) Create test level - 2) Create test entity - 3) Start Tracer - 4) Enter Game Mode - 5) Read for line - 6) Exit Game Mode - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - import os - from editor_entity_utils import EditorEntity as Entity - from utils import Report - from utils import TestHelper as helper - from utils import Tracer - - import azlmbr.legacy.general as general - import azlmbr.asset as asset - import azlmbr.math as math - import azlmbr.bus as bus - - LEVEL_NAME = "tmp_level" - WAIT_TIME = 3.0 # SECONDS - EXPECTED_LINES = ["T92567320: Message Received"] - SC_ASSET_PATH = os.path.join("ScriptCanvas", "T92567320.scriptcanvas") - - def create_editor_entity(name, sc_asset): - entity = Entity.create_editor_entity(name) - sc_comp = entity.add_component("Script Canvas") - asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", sc_asset, math.Uuid(), False) - sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", asset_id) - Report.critical_result(Tests.entity_created, entity.id.isValid()) - - def locate_expected_lines(line_list: list): - found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints] - - return all(line in found_lines for line in line_list) - - # 1) Create temp level - general.idle_enable(True) - result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True) - Report.critical_result(Tests.level_created, result == 0) - helper.wait_for_condition(lambda: general.get_current_level_name() == LEVEL_NAME, WAIT_TIME) - general.close_pane("Error Report") - - # 2) Create test entity - create_editor_entity("TestEntity", SC_ASSET_PATH) - - # 3) Start Tracer - with Tracer() as section_tracer: - - # 4) Enter Game Mode - helper.enter_game_mode(Tests.enter_game_mode) - - # 5) Read for line - lines_located = helper.wait_for_condition(lambda: locate_expected_lines(EXPECTED_LINES), WAIT_TIME) - Report.result(Tests.lines_found, lines_located) - - # 6) Exit Game Mode - helper.exit_game_mode(Tests.exit_game_mode) - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(ScriptEvents_SendReceiveSuccessfully) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py deleted file mode 100755 index d87f2986bf..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Active.py +++ /dev/null @@ -1,254 +0,0 @@ -""" -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 os -import sys -sys.path.append(os.path.dirname(__file__)) - -import ImportPathHelper as imports -imports.init() - -import hydra_test_utils as hydra -import ly_test_tools.environment.file_system as file_system -from ly_test_tools import LAUNCHERS -from base import TestAutomationBase - -TEST_DIRECTORY = os.path.dirname(__file__) - - -@pytest.mark.SUITE_periodic -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(TestAutomationBase): - @pytest.mark.test_case_id("C1702834", "C1702823") - def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform): - from . import Opening_Closing_Pane as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("C1702824") - def test_Docking_Pane(self, request, workspace, editor, launcher_platform): - from . import Docking_Pane as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("C1702829") - def test_Resizing_Pane(self, request, workspace, editor, launcher_platform): - from . import Resizing_Pane as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92563190") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptCanvas_TwoComponents(self, request, workspace, editor, launcher_platform, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptCanvas_TwoComponents as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92562986") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptCanvas_ChangingAssets(self, request, workspace, editor, launcher_platform, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptCanvas_ChangingAssets as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92569079", "T92569081") - def test_Graph_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): - from . import Graph_ZoomInZoomOut as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92568940") - def test_NodePalette_SelectNode(self, request, workspace, editor, launcher_platform): - from . import NodePalette_SelectNode as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92569253") - @pytest.mark.test_case_id("T92569254") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import OnEntityActivatedDeactivated_PrintMessage as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92562993") - def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project): - from . import NodePalette_ClearSelection as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92563191") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptCanvas_TwoEntities(self, request, workspace, editor, launcher_platform, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptCanvas_TwoEntities as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92569013") - def test_AssetEditor_CreateScriptEventFile(self, request, workspace, editor, launcher_platform, project): - def teardown(): - file_system.delete( - [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True - ) - request.addfinalizer(teardown) - file_system.delete( - [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True - ) - from . import AssetEditor_CreateScriptEventFile as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92569165", "T92569167", "T92569168", "T92569170") - def test_Toggle_ScriptCanvasTools(self, request, workspace, editor, launcher_platform): - from . import Toggle_ScriptCanvasTools as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92568982") - def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project): - from . import NodeInspector_RenameVariable as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92569137") - def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): - from . import Debugging_TargetMultipleGraphs as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92568856") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_Debugging_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import Debugging_TargetMultipleEntities as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92569049", "T92569051") - def test_EditMenu_UndoRedo(self, request, workspace, editor, launcher_platform, project): - from . import EditMenu_UndoRedo as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("C1702825", "C1702831") - def test_UnDockedPane_CloseSCWindow(self, request, workspace, editor, launcher_platform): - from . import UnDockedPane_CloseSCWindow as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92562978") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_Entity_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import Entity_AddScriptCanvasComponent as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("C1702821", "C1702832") - def test_Pane_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): - from . import Pane_RetainOnSCRestart as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92567321") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptEvents_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptEvents_SendReceiveAcrossMultiple as test_module - self._run_test(request, workspace, editor, test_module) - - @pytest.mark.test_case_id("T92567320") - @pytest.mark.parametrize("level", ["tmp_level"]) - def test_ScriptEvents_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): - def teardown(): - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - request.addfinalizer(teardown) - file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) - from . import ScriptEvents_SendReceiveSuccessfully as test_module - self._run_test(request, workspace, editor, test_module) - -# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method -# fails because of pyside_utils import -@pytest.mark.SUITE_periodic -@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestScriptCanvasTests(object): - """ - The following tests use hydra_test_utils.py to launch the editor and validate the results. - """ - - @pytest.mark.test_case_id("T92569037", "T92569039") - def test_FileMenu_New_Open(self, request, editor, launcher_platform): - expected_lines = [ - "File->New action working as expected: True", - "File->Open action working as expected: True", - ] - hydra.launch_and_validate_results( - request, TEST_DIRECTORY, editor, "FileMenu_New_Open.py", expected_lines, auto_test_mode=False, timeout=60, - ) - - @pytest.mark.test_case_id("T92568942") - def test_AssetEditor_NewScriptEvent(self, request, editor, launcher_platform): - expected_lines = [ - "New Script event action found: True", - "Asset Editor opened: True", - "Asset Editor created with new asset: True", - "New Script event created in Asset Editor: True", - ] - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "AssetEditor_NewScriptEvent.py", - expected_lines, - auto_test_mode=False, - timeout=60, - ) - - @pytest.mark.test_case_id("T92563068", "T92563070") - def test_GraphClose_SavePrompt(self, request, editor, launcher_platform): - expected_lines = [ - "New graph created: True", - "Save prompt opened as expected: True", - "Close button worked as expected: True", - ] - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "GraphClose_SavePrompt.py", - expected_lines, - auto_test_mode=False, - timeout=60, - ) - - @pytest.mark.test_case_id("T92564789", "T92568873") - def test_VariableManager_CreateDeleteVars(self, request, editor, launcher_platform): - var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"] - expected_lines = [f"Success: {var_type} variable is created" for var_type in var_types] - expected_lines.extend([f"Success: {var_type} variable is deleted" for var_type in var_types]) - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "VariableManager_CreateDeleteVars.py", - expected_lines, - auto_test_mode=False, - timeout=60, - ) \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py new file mode 100755 index 0000000000..e3a8d874da --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/TestSuite_Periodic.py @@ -0,0 +1,354 @@ +""" +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 os +import sys +sys.path.append(os.path.dirname(__file__)) + +import ImportPathHelper as imports +imports.init() + +import hydra_test_utils as hydra +import ly_test_tools.environment.file_system as file_system +from ly_test_tools import LAUNCHERS +from base import TestAutomationBase + +TEST_DIRECTORY = os.path.dirname(__file__) + + +@pytest.mark.SUITE_periodic +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(TestAutomationBase): + def test_Pane_HappyPath_OpenCloseSuccessfully(self, request, workspace, editor, launcher_platform): + from . import Pane_HappyPath_OpenCloseSuccessfully as test_module + self._run_test(request, workspace, editor, test_module) + + def test_Pane_HappyPath_DocksProperly(self, request, workspace, editor, launcher_platform): + from . import Pane_HappyPath_DocksProperly as test_module + self._run_test(request, workspace, editor, test_module) + + def test_Pane_HappyPath_ResizesProperly(self, request, workspace, editor, launcher_platform): + from . import Pane_HappyPath_ResizesProperly as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptCanvas_TwoComponents_InteractSuccessfully(self, request, workspace, editor, launcher_platform, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptCanvas_TwoComponents_InteractSuccessfully as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptCanvas_ChangingAssets_ComponentStable(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptCanvas_ChangingAssets_ComponentStable as test_module + self._run_test(request, workspace, editor, test_module) + + def test_Graph_HappyPath_ZoomInZoomOut(self, request, workspace, editor, launcher_platform): + from . import Graph_HappyPath_ZoomInZoomOut as test_module + self._run_test(request, workspace, editor, test_module) + + def test_NodePalette_HappyPath_CanSelectNode(self, request, workspace, editor, launcher_platform): + from . import NodePalette_HappyPath_CanSelectNode as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage as test_module + self._run_test(request, workspace, editor, test_module) + + def test_NodePalette_HappyPath_ClearSelection(self, request, workspace, editor, launcher_platform, project): + from . import NodePalette_HappyPath_ClearSelection as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptCanvas_TwoEntities_UseSimultaneously(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptCanvas_TwoEntities_UseSimultaneously as test_module + self._run_test(request, workspace, editor, test_module) + + def test_ScriptEvent_HappyPath_CreatedWithoutError(self, request, workspace, editor, launcher_platform, project): + def teardown(): + file_system.delete( + [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True + ) + request.addfinalizer(teardown) + file_system.delete( + [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True + ) + from . import ScriptEvent_HappyPath_CreatedWithoutError as test_module + self._run_test(request, workspace, editor, test_module) + + def test_ScriptCanvasTools_Toggle_OpenCloseSuccess(self, request, workspace, editor, launcher_platform): + from . import ScriptCanvasTools_Toggle_OpenCloseSuccess as test_module + self._run_test(request, workspace, editor, test_module) + + def test_NodeInspector_HappyPath_VariableRenames(self, request, workspace, editor, launcher_platform, project): + from . import NodeInspector_HappyPath_VariableRenames as test_module + self._run_test(request, workspace, editor, test_module) + + def test_Debugger_HappyPath_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project): + from . import Debugger_HappyPath_TargetMultipleGraphs as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_Debugger_HappyPath_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import Debugger_HappyPath_TargetMultipleEntities as test_module + self._run_test(request, workspace, editor, test_module) + + def test_EditMenu_Default_UndoRedo(self, request, workspace, editor, launcher_platform, project): + from . import EditMenu_Default_UndoRedo as test_module + self._run_test(request, workspace, editor, test_module) + + def test_Pane_Undocked_ClosesSuccessfully(self, request, workspace, editor, launcher_platform): + from . import Pane_Undocked_ClosesSuccessfully as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_Entity_HappyPath_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import Entity_HappyPath_AddScriptCanvasComponent as test_module + self._run_test(request, workspace, editor, test_module) + + def test_Pane_Default_RetainOnSCRestart(self, request, workspace, editor, launcher_platform): + from . import Pane_Default_RetainOnSCRestart as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptEvents_HappyPath_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptEvents_HappyPath_SendReceiveAcrossMultiple as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptEvents_Default_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptEvents_Default_SendReceiveSuccessfully as test_module + self._run_test(request, workspace, editor, test_module) + + @pytest.mark.parametrize("level", ["tmp_level"]) + def test_ScriptEvents_ReturnSetType_Successfully(self, request, workspace, editor, launcher_platform, project, level): + def teardown(): + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True) + from . import ScriptEvents_ReturnSetType_Successfully as test_module + self._run_test(request, workspace, editor, test_module) + + def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform): + from . import NodeCategory_ExpandOnClick as test_module + self._run_test(request, workspace, editor, test_module) + + def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform): + from . import NodePalette_SearchText_Deletion as test_module + self._run_test(request, workspace, editor, test_module) + + def test_VariableManager_UnpinVariableType_Works(self, request, workspace, editor, launcher_platform): + from . import VariableManager_UnpinVariableType_Works as test_module + self._run_test(request, workspace, editor, test_module) + + def test_Node_HappyPath_DuplicateNode(self, request, workspace, editor, launcher_platform): + from . import Node_HappyPath_DuplicateNode as test_module + self._run_test(request, workspace, editor, test_module) + + def test_ScriptEvent_AddRemoveParameter_ActionsSuccessful(self, request, workspace, editor, launcher_platform): + def teardown(): + file_system.delete( + [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True + ) + request.addfinalizer(teardown) + file_system.delete( + [os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True + ) + from . import ScriptEvent_AddRemoveParameter_ActionsSuccessful as test_module + self._run_test(request, workspace, editor, test_module) + +# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method +# fails because of pyside_utils import +@pytest.mark.SUITE_periodic +@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestScriptCanvasTests(object): + """ + The following tests use hydra_test_utils.py to launch the editor and validate the results. + """ + + def test_FileMenu_Default_NewAndOpen(self, request, editor, launcher_platform): + expected_lines = [ + "File->New action working as expected: True", + "File->Open action working as expected: True", + ] + hydra.launch_and_validate_results( + request, TEST_DIRECTORY, editor, "FileMenu_Default_NewAndOpen.py", expected_lines, auto_test_mode=False, timeout=60, + ) + + def test_NewScriptEventButton_HappyPath_ContainsSCCategory(self, request, editor, launcher_platform): + expected_lines = [ + "New Script event action found: True", + "Asset Editor opened: True", + "Asset Editor created with new asset: True", + "New Script event created in Asset Editor: True", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "NewScriptEventButton_HappyPath_ContainsSCCategory.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) + + def test_GraphClose_Default_SavePrompt(self, request, editor, launcher_platform): + expected_lines = [ + "New graph created: True", + "Save prompt opened as expected: True", + "Close button worked as expected: True", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "GraphClose_Default_SavePrompt.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) + + def test_VariableManager_Default_CreateDeleteVars(self, request, editor, launcher_platform): + var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"] + expected_lines = [f"Success: {var_type} variable is created" for var_type in var_types] + expected_lines.extend([f"Success: {var_type} variable is deleted" for var_type in var_types]) + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "VariableManager_Default_CreateDeleteVars.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) + + @pytest.mark.parametrize( + "config", + [ + { + "cfg_args": "before_restart", + "expected_lines": [ + "All the test panes are opened: True", + "Test pane 1 is closed: True", + "Location of test pane 2 changed successfully: True", + "Test pane 3 resized successfully: True", + ], + }, + { + "cfg_args": "after_restart", + "expected_lines": [ + "Test pane retained its visiblity on Editor restart: True", + "Test pane retained its location on Editor restart: True", + "Test pane retained its size on Editor restart: True", + ], + }, + ], + ) + + def test_Pane_PropertiesChanged_RetainsOnRestart(self, request, editor, config, project, launcher_platform): + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "Pane_PropertiesChanged_RetainsOnRestart.py", + config.get('expected_lines'), + cfg_args=[config.get('cfg_args')], + auto_test_mode=False, + timeout=60, + ) + + def test_ScriptEvent_AddRemoveMethod_UpdatesInSC(self, request, workspace, editor, launcher_platform): + def teardown(): + file_system.delete( + [os.path.join(workspace.paths.project(), "TestAssets", "test_file.scriptevents")], True, True + ) + request.addfinalizer(teardown) + file_system.delete( + [os.path.join(workspace.paths.project(), "TestAssets", "test_file.scriptevents")], True, True + ) + expected_lines = [ + "Success: New Script Event created", + "Success: Initial Child Event created", + "Success: Second Child Event created", + "Success: Script event file saved", + "Success: Method added to scriptevent file", + "Success: Method removed from scriptevent file", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "ScriptEvent_AddRemoveMethod_UpdatesInSC.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) + + def test_ScriptEvents_AllParamDatatypes_CreationSuccess(self, request, workspace, editor, launcher_platform): + def teardown(): + file_system.delete( + [os.path.join(workspace.paths.project(), "TestAssets", "test_file.scriptevents")], True, True + ) + request.addfinalizer(teardown) + file_system.delete( + [os.path.join(workspace.paths.project(), "TestAssets", "test_file.scriptevents")], True, True + ) + expected_lines = [ + "Success: New Script Event created", + "Success: Child Event created", + "Success: New parameters added", + "Success: Script event file saved", + "Success: Node found in Script Canvas", + ] + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "ScriptEvents_AllParamDatatypes_CreationSuccess.py", + expected_lines, + auto_test_mode=False, + timeout=60, + ) + \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py b/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py deleted file mode 100644 index 4024e28277..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/Toggle_ScriptCanvasTools.py +++ /dev/null @@ -1,137 +0,0 @@ -""" -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. - -Test case ID: C92569165, C92569167, C92569168, C92569170 -Test Case Title: Tools > Node Palette toggles the Node Palette - Tools > Node Inspector toggles the Node Inspector - Tools > Bookmarks toggles the Bookmarks - Tools > Variable Manager toggles the Variable Manager - -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/92569165 - https://testrail.agscollab.com/index.php?/cases/view/92569167 - https://testrail.agscollab.com/index.php?/cases/view/92569168 - https://testrail.agscollab.com/index.php?/cases/view/92569170 -""" - - -# fmt: off -class Tests(): - node_palette_opened = ("NodePalette is opened successfully", "Failed to open NodePalette") - node_inspector_opened = ("NodeInspector is opened successfully", "Failed to open NodeInspector") - bookmark_opened = ("Bookmarks is opened successfully", "Failed to open Bookmarks") - variable_manager_opened = ("VariableManager is opened successfully", "Failed to open VariableManager") - node_palette_closed_by_start = ("NodePalette is closed successfully", "Failed to close NodePalette") - node_inspector_closed_by_start = ("NodeInspector is closed successfully", "Failed to close NodeInspector") - bookmark_closed_by_start = ("Bookmarks is closed successfully", "Failed to close Bookmarks") - variable_manager_closed_by_start = ("VariableManager is closed successfully", "Failed to close VariableManager") - node_palette_closed_by_end = ("NodePalette is closed successfully", "Failed to close NodePalette") - node_inspector_closed_by_end = ("NodeInspector is closed successfully", "Failed to close NodeInspector") - bookmark_closed_by_end = ("Bookmarks is closed successfully", "Failed to close Bookmarks") - variable_manager_closed_by_end = ("VariableManager is closed successfully", "Failed to close VariableManager") -# fmt: on - - -def Toggle_ScriptCanvasTools(): - """ - Summary: - Toggle Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas. - Make sure each pane opens and closes successfully. - - Expected Behavior: - Each pane opens and closes successfully. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Make sure Node Palette, Node Inspector, Bookmarks and Variable Manager panes are closed in Script Canvas window - 3) Open Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window - 4) Close Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window - 5) Restore default layout - 6) Close Script Canvas window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from utils import Report - from utils import TestHelper as helper - import pyside_utils - - # Open 3D Engine imports - import azlmbr.legacy.general as general - - # Pyside imports - from PySide2 import QtWidgets - - def click_menu_option(window, option_text): - action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) - action.trigger() - - def find_pane(window, pane_name): - return window.findChild(QtWidgets.QDockWidget, pane_name) - - def close_tool(window, pane_widget, test_tuple): - pane = find_pane(window, pane_widget) - pane.close() - Report.result(test_tuple, not pane.isVisible()) - - def open_tool(window, pane_widget, tool, test_tuple): - pane = find_pane(window, pane_widget) - if not pane.isVisible(): - click_menu_option(window, tool) - pane = find_pane(window, pane_widget) - Report.result(test_tuple, pane.isVisible()) - - # Test starts here - general.idle_enable(True) - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Make sure Node Palette, Node Inspector, Bookmarks and Variable Manager panes are closed in Script Canvas window - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - close_tool(sc, "NodePalette", Tests.node_palette_closed_by_start) - close_tool(sc, "NodeInspector", Tests.node_inspector_closed_by_start) - close_tool(sc, "BookmarkDockWidget", Tests.bookmark_closed_by_start) - close_tool(sc, "VariableManager", Tests.variable_manager_closed_by_start) - - # 3) Open Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window - open_tool(sc, "NodePalette", "Node Palette", Tests.node_palette_opened) - open_tool(sc, "NodeInspector", "Node Inspector", Tests.node_inspector_opened) - open_tool(sc, "BookmarkDockWidget", "Bookmarks", Tests.bookmark_opened) - open_tool(sc, "VariableManager", "Variable Manager", Tests.variable_manager_opened) - - # 4) Close Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas window - close_tool(sc, "NodePalette", Tests.node_palette_closed_by_end) - close_tool(sc, "NodeInspector", Tests.node_inspector_closed_by_end) - close_tool(sc, "BookmarkDockWidget", Tests.bookmark_closed_by_end) - close_tool(sc, "VariableManager", Tests.variable_manager_closed_by_end) - - # 5) Restore default layout - # Need this step to restore to default in case of test failure - click_menu_option(sc, "Restore Default Layout") - - # 6) Close Script Canvas window - sc.close() - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(Toggle_ScriptCanvasTools) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py b/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py deleted file mode 100644 index 875f28ec95..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/UnDockedPane_CloseSCWindow.py +++ /dev/null @@ -1,128 +0,0 @@ -""" -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. - -Test case ID: C1702825 // C1702831 -Test Case Title: Undocking // Closing script canvas with the pane floating -URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702825 & - https://testrail.agscollab.com/index.php?/cases/view/1702831 -""" - - -# fmt: off -class Tests(): - undock_pane = ("Pane is undocked successfully", "Failed to undock pane") - close_sc_window = ("Script Canvas window is closed", "Failed to close Script Canvas window") - pane_closed = ("Pane is closed successfully", "Failed to close the pane") -# fmt: on - - -def UnDockedPane_CloseSCWindow(): - """ - Summary: - The Script Canvas window is opened with one of the pane undocked. - Verify if undocked pane closes upon closing Script canvas window. - - Expected Behavior: - The undocked pane closes when Script Canvas window closed. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Undock Node Palette pane - 3) Connect to Pane visibility signal emitter to verify pane closed - 4) Close Script Canvas window - 5) Restore default layout - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - # Helper imports - from utils import Report - from utils import TestHelper as helper - import pyside_utils - - # Open 3D Engine imports - import azlmbr.legacy.general as general - - # Pyside imports - from PySide2 import QtWidgets - - TEST_PANE = "NodePalette" # Chosen most commonly used pane - - def click_menu_option(window, option_text): - action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) - action.trigger() - - def find_pane(window, pane_name): - return window.findChild(QtWidgets.QDockWidget, pane_name) - - def on_top_level_changed(): - # This function has test condition always True since it gets emitted only when condition satisfied - Report.result(Tests.undock_pane, True) - - def on_pane_closed(): - # This function has test condition always True since it gets emitted only when condition satisfied - Report.result(Tests.pane_closed, True) - - # Test starts here - general.idle_enable(True) - - # 1) Open Script Canvas window (Tools > Script Canvas) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - - # 2) Undock Node Palette pane - # Make sure Node Palette pane is opened - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - pane = find_pane(sc, TEST_PANE) - if not pane.isVisible(): - click_menu_option(sc, "Node Palette") - pane = find_pane(sc, TEST_PANE) # New reference - - # We drag/drop pane over the graph since it doesn't allow docking, so this will undock it - try: - graph = find_pane(sc, "GraphCanvasEditorCentralWidget") - try: - pane.topLevelChanged.connect(on_top_level_changed) - pyside_utils.drag_and_drop(pane, graph) - finally: - pane.topLevelChanged.disconnect(on_top_level_changed) - - # 3) Connect to Pane visibility signal emitter to verify pane closed - # No need to disconnect this since pane widget gets deleted when SC window closed - pane.visibilityChanged.connect(on_pane_closed) - - # 4) Close Script Canvas window - sc.close() - is_sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 2.0) - Report.result(Tests.close_sc_window, not is_sc_visible) - - finally: - # 5) Restore default layout - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0) - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - click_menu_option(sc, "Restore Default Layout") - sc.close() - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - - from utils import Report - - Report.start_test(UnDockedPane_CloseSCWindow) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py deleted file mode 100644 index 6facc324d4..0000000000 --- a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_CreateDeleteVars.py +++ /dev/null @@ -1,123 +0,0 @@ -""" -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. - -Test case ID: T92564789 -Test Case Title: Each Variable type can be created -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92564789 -Test case ID: T92568873 -Test Case Title: Each Variable type can be deleted -URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568873 -""" - - -def VariableManager_CreateDeleteVars(): - """ - Summary: - Each variable type can be created and deleted in variable manager. - - Expected Behavior: - Each variable type can be created and deleted in variable manager. - - Test Steps: - 1) Open Script Canvas window (Tools > Script Canvas) - 2) Get the SC window object - 3) Open Variable Manager if not opened already - 4) Create Graph - 5) Create variable of each type and verify if it is created - 6) Delete each type of variable and verify if it is deleted - 7) Close SC window - - Note: - - This test file must be called from the Open 3D Engine Editor command terminal - - Any passed and failed tests are written to the Editor.log file. - Parsing the file or running a log_monitor are required to observe the test results. - - :return: None - """ - - from PySide2 import QtWidgets, QtCore, QtTest - - from PySide2.QtCore import Qt - - from utils import TestHelper as helper - - import azlmbr.legacy.general as general - - import pyside_utils - - def generate_test_tuple(var_type, action): - return (f"{var_type} variable is {action}d", f"{var_type} variable is not {action}d") - - # 1) Open Script Canvas window - general.idle_enable(True) - general.open_pane("Script Canvas") - helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 10.0) - - # 2) Get the SC window object - editor_window = pyside_utils.get_editor_main_window() - sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") - - # 3) Open Variable Manager if not opened already - if sc.findChild(QtWidgets.QDockWidget, "VariableManager") is None: - action = pyside_utils.find_child_by_pattern(sc, {"text": "Variable Manager", "type": QtWidgets.QAction}) - action.trigger() - variable_manager = sc.findChild(QtWidgets.QDockWidget, "VariableManager") - - # 4) Create Graph - action = pyside_utils.find_child_by_pattern(sc, {"objectName": "action_New_Script", "type": QtWidgets.QAction}) - action.trigger() - - graph_vars = variable_manager.findChild(QtWidgets.QTableView, "graphVariables") - - var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"] - - # 5) Create variable of each type and verify if it is created - for index, var_type in enumerate(var_types): - # Create new variable - add_button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") - add_button.click() # Click on Create Variable button - # Select variable type - table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") - model_index = pyside_utils.find_child_by_pattern(table_view, var_type) - # Click on it to create variable - pyside_utils.item_view_index_mouse_click(table_view, model_index) - # Verify if the variable is created - # NOTE: To check if variable of a type is created, we are checking 1) rowcount - # 2) If we have row with variable "Variable " - # 3) Type of variable, which is next column of the variable name - result = graph_vars.model().rowCount(QtCore.QModelIndex()) == ( - index + 1 - ) # since we added 1 variable, rowcount will increase by 1 - var_mi = pyside_utils.find_child_by_pattern(graph_vars, f"Variable {index+1}") - result = result and (var_mi is not None) and (var_mi.siblingAtColumn(1).data(Qt.DisplayRole) == var_type) - Report.result(generate_test_tuple(var_type, "create"), result) - - # 6) Delete each type of variable and verify if it is deleted - for index, var_type in enumerate(var_types): - # Delete variable and verify if its deleted - # NOTE: To check if variable of a type is deleted, we are checking rowcount - var_mi = pyside_utils.find_child_by_pattern(graph_vars, f"Variable {index+1}") - pyside_utils.item_view_index_mouse_click(graph_vars, var_mi) - QtTest.QTest.keyClick(graph_vars, Qt.Key_Delete, Qt.NoModifier) - # since variable is deleted, rowcount will decrease by 1 - result = graph_vars.model().rowCount(QtCore.QModelIndex()) == (len(var_types) - (index + 1)) - Report.result(generate_test_tuple(var_type, "delete"), result) - - # 7) Close SC window - general.close_pane("Script Canvas") - - -if __name__ == "__main__": - import ImportPathHelper as imports - - imports.init() - from utils import Report - - Report.start_test(VariableManager_CreateDeleteVars) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_Default_CreateDeleteVars.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_Default_CreateDeleteVars.py new file mode 100644 index 0000000000..e53939172e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_Default_CreateDeleteVars.py @@ -0,0 +1,114 @@ +""" +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. +""" + + +def VariableManager_Default_CreateDeleteVars(): + """ + Summary: + Creating and deleting each type of variable in the Variable Manager pane + + Expected Behavior: + Each variable type can be created and deleted in variable manager. + + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Variable Manager if not opened already + 4) Create Graph + 5) Create variable of each type and verify if it is created + 6) Delete each type of variable and verify if it is deleted + 7) Close SC window + + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + from PySide2 import QtWidgets, QtCore, QtTest + from PySide2.QtCore import Qt + + from utils import TestHelper as helper + import pyside_utils + + import azlmbr.legacy.general as general + + def generate_test_tuple(var_type, action): + return (f"{var_type} variable is {action}d", f"{var_type} variable is not {action}d") + + # 1) Open Script Canvas window + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 10.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + + # 3) Open Variable Manager if not opened already + if sc.findChild(QtWidgets.QDockWidget, "VariableManager") is None: + action = pyside_utils.find_child_by_pattern(sc, {"text": "Variable Manager", "type": QtWidgets.QAction}) + action.trigger() + variable_manager = sc.findChild(QtWidgets.QDockWidget, "VariableManager") + + # 4) Create Graph + action = pyside_utils.find_child_by_pattern(sc, {"objectName": "action_New_Script", "type": QtWidgets.QAction}) + action.trigger() + + graph_vars = variable_manager.findChild(QtWidgets.QTableView, "graphVariables") + + var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"] + + # 5) Create variable of each type and verify if it is created + for index, var_type in enumerate(var_types): + # Create new variable + add_button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") + add_button.click() # Click on Create Variable button + # Select variable type + table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") + model_index = pyside_utils.find_child_by_pattern(table_view, var_type) + # Click on it to create variable + pyside_utils.item_view_index_mouse_click(table_view, model_index) + # Verify if the variable is created + # NOTE: To check if variable of a type is created, we are checking 1) rowcount + # 2) If we have row with variable "Variable " + # 3) Type of variable, which is next column of the variable name + result = graph_vars.model().rowCount(QtCore.QModelIndex()) == ( + index + 1 + ) # since we added 1 variable, rowcount will increase by 1 + var_mi = pyside_utils.find_child_by_pattern(graph_vars, f"Variable {index+1}") + result = result and (var_mi is not None) and (var_mi.siblingAtColumn(1).data(Qt.DisplayRole) == var_type) + Report.result(generate_test_tuple(var_type, "create"), result) + + # 6) Delete each type of variable and verify if it is deleted + for index, var_type in enumerate(var_types): + # Delete variable and verify if its deleted + # NOTE: To check if variable of a type is deleted, we are checking rowcount + var_mi = pyside_utils.find_child_by_pattern(graph_vars, f"Variable {index+1}") + pyside_utils.item_view_index_mouse_click(graph_vars, var_mi) + QtTest.QTest.keyClick(graph_vars, Qt.Key_Delete, Qt.NoModifier) + # since variable is deleted, rowcount will decrease by 1 + result = graph_vars.model().rowCount(QtCore.QModelIndex()) == (len(var_types) - (index + 1)) + Report.result(generate_test_tuple(var_type, "delete"), result) + + # 7) Close SC window + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(VariableManager_Default_CreateDeleteVars) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py new file mode 100644 index 0000000000..a7c72ce134 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py @@ -0,0 +1,120 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" + + +# fmt: off +class Tests(): + variable_manager_opened = ("VariableManager is opened successfully", "Failed to open VariableManager") + variable_pinned = ("Variable is pinned", "Variable is not pinned, But it should be unpinned") + variable_unpinned = ("Variable is unpinned", "Variable is not unpinned, But it should be pinned") + variable_unpinned_after_reopen = ("Variable is unpinned after reopening create variable menu", "Variable is not unpinned after reopening create variable menu") +# fmt: on + + +def VariableManager_UnpinVariableType_Works(): + """ + Summary: + Unpin variable types in create variable menu. + Expected Behavior: + The variable unpinned in create variable menu remains unpinned after reopening create variable menu. + Test Steps: + 1) Open Script Canvas window (Tools > Script Canvas) + 2) Get the SC window object + 3) Open Variable Manager in Script Canvas window + 4) Create new graph + 5) Click on the Create Variable button in the Variable Manager + 6) Unpin Boolean by clicking the "Pin" icon on its left side + 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu + 8) Restore default layout and close SC window + Note: + - This test file must be called from the Open 3D Engine Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + :return: None + """ + + from PySide2 import QtWidgets + import azlmbr.legacy.general as general + + import pyside_utils + from utils import TestHelper as helper + from utils import Report + from PySide2.QtCore import Qt + + GENERAL_WAIT = 1.0 # seconds + + def find_pane(window, pane_name): + return window.findChild(QtWidgets.QDockWidget, pane_name) + + def click_menu_option(window, option_text): + action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction}) + action.trigger() + + # 1) Open Script Canvas window (Tools > Script Canvas) + general.idle_enable(True) + general.open_pane("Script Canvas") + helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 6.0) + + # 2) Get the SC window object + editor_window = pyside_utils.get_editor_main_window() + sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas") + sc_main = sc.findChild(QtWidgets.QMainWindow) + + # 3) Open Variable Manager in Script Canvas window + pane = find_pane(sc, "VariableManager") + if not pane.isVisible(): + click_menu_option(sc, "Variable Manager") + pane = find_pane(sc, "VariableManager") + Report.result(Tests.variable_manager_opened, pane.isVisible()) + + # 4) Create new graph + create_new_graph = pyside_utils.find_child_by_pattern( + sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} + ) + create_new_graph.trigger() + + # 5) Click on the Create Variable button in the Variable Manager + variable_manager = sc_main.findChild(QtWidgets.QDockWidget, "VariableManager") + button = variable_manager.findChild(QtWidgets.QPushButton, "addButton") + button.click() + + # 6) Unpin Boolean by clicking the "Pin" icon on its left side + table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette") + model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") + # Make sure Boolean is pinned + is_boolean = model_index.siblingAtColumn(0) + result = helper.wait_for_condition(lambda: is_boolean.data(Qt.DecorationRole) is not None, GENERAL_WAIT) + Report.result(Tests.variable_pinned, result) + # Unpin Boolean and make sure Boolean is unpinned. + pyside_utils.item_view_index_mouse_click(table_view, is_boolean) + result = helper.wait_for_condition(lambda: is_boolean.data(Qt.DecorationRole) is None, GENERAL_WAIT) + Report.result(Tests.variable_unpinned, result) + + # 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu + button.click() + button.click() + model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean") + result = helper.wait_for_condition( + lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is None, GENERAL_WAIT + ) + Report.result(Tests.variable_unpinned_after_reopen, result) + + # 8) Restore default layout and close SC window + click_menu_option(sc, "Restore Default Layout") + general.close_pane("Script Canvas") + + +if __name__ == "__main__": + import ImportPathHelper as imports + + imports.init() + from utils import Report + + Report.start_test(VariableManager_UnpinVariableType_Works) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt new file mode 100644 index 0000000000..a3b6e36250 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/CMakeLists.txt @@ -0,0 +1,45 @@ +# +# 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. + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + ly_add_pytest( + NAME AutomatedTesting::SmokeTest + TEST_SUITE smoke + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR} + PYTEST_MARKS "SUITE_smoke" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + AZ::PythonBindingsExample + Legacy::Editor + AutomatedTesting.GameLauncher + AutomatedTesting.Assets + COMPONENT + Smoke + ) + + ly_add_pytest( + NAME AutomatedTesting::SandboxTest + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR} + PYTEST_MARKS "SUITE_sandbox" + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + AZ::PythonBindingsExample + Legacy::Editor + AutomatedTesting.GameLauncher + AutomatedTesting.Assets + COMPONENT + Smoke + ) +endif() \ No newline at end of file diff --git a/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py new file mode 100644 index 0000000000..db0284f14c --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/Editor_NewExistingLevels_Works.py @@ -0,0 +1,147 @@ +""" +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. + + +Test Case Title: Create Test for UI apps- Editor +""" + + +class Tests(): + level_created = ("Level created", "Failed to create level") + entity_found = ("New Entity created in level", "Failed to create New Entity in level") + mesh_added = ("Mesh Component added", "Failed to add Mesh Component") + enter_game_mode = ("Game Mode successfully entered", "Failed to enter in Game Mode") + exit_game_mode = ("Game Mode successfully exited", "Failed to exit in Game Mode") + level_opened = ("Level opened successfully", "Failed to open level") + level_exported = ("Level exported successfully", "Failed to export level") + mesh_removed = ("Mesh Component removed", "Failed to remove Mesh Component") + entity_deleted = ("Entity deleted", "Failed to delete Entity") + level_edits_present = ("Level edits persist after saving", "Failed to save level edits after saving") + + +def Editor_NewExistingLevels_Works(): + """ + Summary: Perform the below operations on Editor + + 1) Launch & Close editor + 2) Create new level + 3) Saving and loading levels + 4) Level edits persist after saving + 5) Export Level + 6) Can switch to play mode (ctrl+g) and exit that + 7) Run editor python bindings test + 8) Create an Entity + 9) Delete an Entity + 10) Add a component to an Entity + + Expected Behavior: + All operations succeed and do not cause a crash + + Test Steps: + 1) Launch editor and Create a new level + 2) Create a new entity + 3) Add Mesh component + 4) Verify enter/exit game mode + 5) Save, Load and Export level + 6) Remove Mesh component + 7) Delete entity + 8) Open an existing level + 9) Create a new entity in an existing level + 10) Save, Load and Export an existing level and close editor + + Note: + - This test file must be called from the Lumberyard Editor command terminal + - Any passed and failed tests are written to the Editor.log file. + Parsing the file or running a log_monitor are required to observe the test results. + + :return: None + """ + + import os + import editor_python_test_tools.hydra_editor_utils as hydra + from editor_python_test_tools.utils import TestHelper as helper + from editor_python_test_tools.utils import Report + import azlmbr.bus as bus + import azlmbr.editor as editor + import azlmbr.legacy.general as general + import azlmbr.math as math + + # 1) Launch editor and Create a new level + helper.init_idle() + test_level_name = "temp_level" + general.create_level_no_prompt(test_level_name, 128, 1, 128, False) + helper.wait_for_condition(lambda: general.get_current_level_name() == test_level_name, 2.0) + Report.result(Tests.level_created, general.get_current_level_name() == test_level_name) + + # 2) Create a new entity + entity_position = math.Vector3(200.0, 200.0, 38.0) + new_entity = hydra.Entity("Entity1") + new_entity.create_entity(entity_position, []) + test_entity = hydra.find_entity_by_name("Entity1") + Report.result(Tests.entity_found, test_entity.IsValid()) + + # 3) Add Mesh component + new_entity.add_component("Mesh") + Report.result(Tests.mesh_added, hydra.has_components(new_entity.id, ["Mesh"])) + + # 4) Verify enter/exit game mode + helper.enter_game_mode(Tests.enter_game_mode) + helper.exit_game_mode(Tests.exit_game_mode) + + # 5) Save, Load and Export level + # Save Level + general.save_level() + # Open Level + general.open_level(test_level_name) + Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name) + # Export Level + general.export_to_engine() + level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak") + Report.result(Tests.level_exported, os.path.exists(level_pak_file)) + + # 6) Remove Mesh component + new_entity.remove_component("Mesh") + Report.result(Tests.mesh_removed, not hydra.has_components(new_entity.id, ["Mesh"])) + + # 7) Delete entity + editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", new_entity.id) + test_entity = hydra.find_entity_by_name("Entity1") + Report.result(Tests.entity_deleted, len(test_entity) == 0) + + # 8) Open an existing level + general.open_level(test_level_name) + Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name) + + # 9) Create a new entity in an existing level + entity_position = math.Vector3(200.0, 200.0, 38.0) + new_entity_2 = hydra.Entity("Entity2") + new_entity_2.create_entity(entity_position, []) + test_entity = hydra.find_entity_by_name("Entity2") + Report.result(Tests.entity_found, test_entity.IsValid()) + + # 10) Save, Load and Export an existing level + # Save Level + general.save_level() + # Open Level + general.open_level(test_level_name) + Report.result(Tests.level_opened, general.get_current_level_name() == test_level_name) + entity_id = hydra.find_entity_by_name(new_entity_2.name) + Report.result(Tests.level_edits_present, entity_id == new_entity_2.id) + # Export Level + general.export_to_engine() + level_pak_file = os.path.join("AutomatedTesting", "Levels", test_level_name, "level.pak") + Report.result(Tests.level_exported, os.path.exists(level_pak_file)) + + +if __name__ == "__main__": + + from editor_python_test_tools.utils import Report + + Report.start_test(Editor_NewExistingLevels_Works) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/__init__.py b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py new file mode 100644 index 0000000000..79f8fa4422 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/__init__.py @@ -0,0 +1,10 @@ +""" +All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or +its licensors. + +For complete copyright and license terms please see the LICENSE at the root of this +distribution (the "License"). All use of this software is governed by the License, +or, if provided, by the license below or the license accompanying this file. Do not +remove or modify any license notices. This file is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +""" diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBuilder_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBuilder_Works.py new file mode 100644 index 0000000000..5381fd9fd8 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBuilder_Works.py @@ -0,0 +1,32 @@ +""" +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. + + +CLI tool - AssetBuilder +Launch AssetBuilder and Verify the help message +""" + +import os +import pytest +import subprocess + + +@pytest.mark.SUITE_smoke +class TestCLIToolAssetBuilderWorks(object): + def test_CLITool_AssetBuilder_Works(self, build_directory): + file_path = os.path.join(build_directory, "AssetBuilder") + help_message = "AssetBuilder is part of the Asset Processor" + # Launch AssetBuilder + output = subprocess.run([file_path, "-help"], capture_output=True, timeout=10) + assert ( + len(output.stderr) == 0 and output.returncode == 0 + ), f"Error occurred while launching {file_path}: {output.stderr}" + # Verify help message + assert help_message in str(output.stdout), f"Help Message: {help_message} is not present" diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBundlerBatch_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBundlerBatch_Works.py new file mode 100644 index 0000000000..fd69bb973f --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetBundlerBatch_Works.py @@ -0,0 +1,32 @@ +""" +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. + + +CLI tool - AssetBundlerBatch +Launch AssetBundlerBatch and Verify the help message +""" + +import os +import pytest +import subprocess + + +@pytest.mark.SUITE_smoke +class TestCLIToolAssetBundlerBatchWorks(object): + def test_CLITool_AssetBundlerBatch_Works(self, build_directory): + file_path = os.path.join(build_directory, "AssetBundlerBatch") + help_message = "Specifies the Seed List file to operate on by path" + # Launch AssetBundlerBatch + output = subprocess.run([file_path, "--help"], capture_output=True, timeout=10) + assert ( + len(output.stderr) == 0 and output.returncode == 0 + ), f"Error occurred while launching {file_path}: {output.stderr}" + # Verify help message + assert help_message in str(output.stdout), f"Help Message: {help_message} is not present" diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetProcessorBatch_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetProcessorBatch_Works.py new file mode 100644 index 0000000000..c828800639 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AssetProcessorBatch_Works.py @@ -0,0 +1,26 @@ +""" +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. + + +CLI tool - AssetProcessorBatch +Launch AssetProcessorBatch and Shutdown AssetProcessorBatch without any crash +""" + +import pytest + + +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.SUITE_smoke +class TestsCLIToolAssetProcessorBatchWorks(object): + def test_CLITool_AssetProcessorBatch_Works(self, workspace): + """ + Test Launching AssetProcessorBatch and verifies that is shuts down without issue + """ + workspace.asset_processor.batch_process() diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py new file mode 100644 index 0000000000..fd15c7701d --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_AzTestRunner_Works.py @@ -0,0 +1,34 @@ +""" +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. + + +CLI tool - AzTestRunner +Launch AzTestRunner and Verify the help message +""" + +import os +import pytest +import subprocess + + +@pytest.mark.SUITE_smoke +class TestCLIToolAzTestRunnerWorks(object): + def test_CLITool_AzTestRunner_Works(self, build_directory): + file_path = os.path.join(build_directory, "AzTestRunner") + help_message = "OKAY Symbol found: AzRunUnitTests" + # Launch AzTestRunner + output = subprocess.run( + [file_path, "AzTestRunner.Tests", "AzRunUnitTests", "--gtest_list_tests"], capture_output=True, timeout=10 + ) + assert ( + len(output.stderr) == 0 and output.returncode == 0 + ), f"Error occurred while launching {file_path}: {output.stderr}" + # Verify help message + assert help_message in str(output.stdout), f"Help Message: {help_message} is not present" diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_PythonBindingsExample_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_PythonBindingsExample_Works.py new file mode 100644 index 0000000000..bef683537e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_PythonBindingsExample_Works.py @@ -0,0 +1,32 @@ +""" +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. + + +CLI tool - PythonBindingsExample +Launch PythonBindingsExample and Verify the help message +""" + +import os +import pytest +import subprocess + + +@pytest.mark.SUITE_smoke +class TestCLIToolPythonBindingsExampleWorks(object): + def test_CLITool_PythonBindingsExample_Works(self, build_directory): + file_path = os.path.join(build_directory, "PythonBindingsExample") + help_message = "--help Prints the help text" + # Launch PythonBindingsExample + output = subprocess.run([file_path, "-help"], capture_output=True, timeout=10) + assert ( + len(output.stderr) == 0 and output.returncode == 1 + ), f"Error occurred while launching {file_path}: {output.stderr}" + # Verify help message + assert help_message in str(output.stdout), f"Help Message: {help_message} is not present" diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py new file mode 100644 index 0000000000..e63a00acf1 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_CLITool_SerializeContextTools_Works.py @@ -0,0 +1,32 @@ +""" +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. + + +CLI tool - SerializeContextTools +Launch SerializeContextTools and Verify the help message +""" + +import os +import pytest +import subprocess + + +@pytest.mark.SUITE_smoke +class TestCLIToolSerializeContextToolsWorks(object): + def test_CLITool_SerializeContextTools_Works(self, build_directory): + file_path = os.path.join(build_directory, "SerializeContextTools") + help_message = "Converts a file with an ObjectStream to the new JSON" + # Launch SerializeContextTools + output = subprocess.run([file_path, "-help"], capture_output=True, timeout=10) + assert ( + len(output.stderr) == 0 and output.returncode == 0 + ), f"Error occurred while launching {file_path}: {output.stderr}" + # Verify help message + assert help_message in str(output.stdout), f"Help Message: {help_message} is not present" diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py new file mode 100644 index 0000000000..e6b072ba58 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_Editor_NewExistingLevels_Works.py @@ -0,0 +1,32 @@ +""" +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 os +from automatedtesting_shared.base import TestAutomationBase +import ly_test_tools.environment.file_system as file_system + + +@pytest.mark.SUITE_sandbox +@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("level", ["temp_level"]) +class TestAutomation(TestAutomationBase): + def test_Editor_NewExistingLevels_Works(self, request, workspace, editor, level, project, launcher_platform): + def teardown(): + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) + + request.addfinalizer(teardown) + file_system.delete([os.path.join(workspace.paths.engine_root(), project, "Levels", level)], True, True) + + from . import Editor_NewExistingLevels_Works as test_module + + self._run_test(request, workspace, editor, test_module) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_StaticTools_GenPakShaders_Works.py b/AutomatedTesting/Gem/PythonTests/smoke/test_StaticTools_GenPakShaders_Works.py new file mode 100644 index 0000000000..42cb3afb00 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_StaticTools_GenPakShaders_Works.py @@ -0,0 +1,44 @@ +""" +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. + + +Static tool scripts +Launch Static tool and Verify the help message +""" + +import os +import pytest +import subprocess +import sys + + +def verify_help_message(static_tool): + help_message = ["--help", "show this help message and exit"] + output = subprocess.run([sys.executable, static_tool, "-h"], capture_output=True) + assert ( + len(output.stderr) == 0 and output.returncode == 0 + ), f"Error occurred while launching {static_tool}: {output.stderr}" + # verify help message + for message in help_message: + assert message in str(output.stdout), f"Help Message: {message} is not present" + + +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.SUITE_smoke +class TestStaticToolsGenPakShadersWorks(object): + def test_StaticTools_GenPakShaders_Works(self, editor): + static_tools = [ + os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "gen_shaders.py"), + os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "get_shader_list.py"), + os.path.join(editor.workspace.paths.engine_root(), "scripts", "bundler", "pak_shaders.py"), + ] + + for tool in static_tools: + verify_help_message(tool) diff --git a/AutomatedTesting/Gem/PythonTests/smoke/test_UIApps_AssetProcessor_CheckIdle.py b/AutomatedTesting/Gem/PythonTests/smoke/test_UIApps_AssetProcessor_CheckIdle.py new file mode 100644 index 0000000000..4b039adea8 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/smoke/test_UIApps_AssetProcessor_CheckIdle.py @@ -0,0 +1,39 @@ +""" +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. + + +UI Apps: AssetProcessor +Open AssetProcessor, Wait until AssetProcessor is Idle +Close AssetProcessor. +""" + + +import pytest +from ly_test_tools.o3de.asset_processor import AssetProcessor + + +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.SUITE_smoke +class TestsUIAppsAssetProcessorCheckIdle(object): + @pytest.fixture(autouse=True) + def setup_teardown(self, request): + self.asset_processor = None + + def teardown(): + self.asset_processor.stop() + + request.addfinalizer(teardown) + + def test_UIApps_AssetProcessor_CheckIdle(self, workspace): + """ + Test Launching AssetProcessorBatch and verifies that is shuts down without issue + """ + self.asset_processor = AssetProcessor(workspace) + self.asset_processor.gui_process() diff --git a/AutomatedTesting/Gem/PythonTests/streaming/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/streaming/CMakeLists.txt new file mode 100644 index 0000000000..10b9fabcc0 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/streaming/CMakeLists.txt @@ -0,0 +1,24 @@ +# +# 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. +# + +if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) + # Unstable, SPEC-3838 will restore + #ly_add_pytest( + # NAME AutomatedTesting::asset_load_benchmark_test + # TEST_SERIAL + # TEST_SUITE benchmark + # PATH ${CMAKE_CURRENT_LIST_DIR}/benchmark/asset_load_benchmark_test.py + # RUNTIME_DEPENDENCIES + # AZ::AssetProcessor + # AZ::AssetProcessorBatch + # AutomatedTesting.GameLauncher + #) +endif() diff --git a/AutomatedTesting/Levels/AI/NavigationComponentTest/leveldata/Heightmap.dat b/AutomatedTesting/Levels/AI/NavigationComponentTest/leveldata/Heightmap.dat deleted file mode 100644 index 8c1a4881a8..0000000000 --- a/AutomatedTesting/Levels/AI/NavigationComponentTest/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e1218e785966cba2973af5fcc2adeea81399ef4b9ceee9713e430d14090317bd -size 272849 diff --git a/AutomatedTesting/Levels/AI/NavigationComponentTest/terrain/cover.ctc b/AutomatedTesting/Levels/AI/NavigationComponentTest/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/AI/NavigationComponentTest/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterCollision/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterCollision/leveldata/Heightmap.dat deleted file mode 100644 index c57f97afb8..0000000000 --- a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterCollision/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:259892d63259cdc7b0cbee64c979d917820ea2bb402397ef63a3383ea5146b0a -size 132288 diff --git a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterCollision/terrain/cover.ctc b/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterCollision/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterCollision/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterDamage/LevelData/Heightmap.dat b/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterDamage/LevelData/Heightmap.dat deleted file mode 100644 index c57f97afb8..0000000000 --- a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterDamage/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:259892d63259cdc7b0cbee64c979d917820ea2bb402397ef63a3383ea5146b0a -size 132288 diff --git a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterDamage/terrain/cover.ctc b/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterDamage/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Blast/Blast_ActorSplitsAfterDamage/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly index 17fee158d8..1afbf787db 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly +++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a2a3360287a4711882c4254d64ca2ba70cd743012a7d38ca29aa2a57f151efaa -size 6661 +oid sha256:e15d484113e8151072b410924747a8ad304f6f12457fad577308c0491693ab34 +size 5472 diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/LevelData/Heightmap.dat b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/LevelData/Heightmap.dat deleted file mode 100644 index e3cfc6487c..0000000000 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6f5b950e0dcd47ada8f34dc9f64976ebe156aeedb92d7e6d3467efbeddb3baa2 -size 17407674 diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml index 6c8b361e57..9775a35c53 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml +++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml @@ -1,6 +1,6 @@ - + diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak index e80d5ca1d9..08a775b6c8 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak +++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cd8105f020151e65093988dfb09ab42ff8d33ef5b97c61fbe0011384870aadf8 -size 39238 +oid sha256:64de37c805b0be77cdb7a85b5406af58b7f845e7d97fec1721ac5d789bb641db +size 38856 diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/terrain/cover.ctc b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly index 031989ee11..385027c479 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly +++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f53fb5e096ff562e9f0f12856ce387891596776d086f49c7ed3a59dcd0a0c11a -size 6535 +oid sha256:7b595323d4d51211463dea0338abb6ce2a4a0a8d41efb12ac3c9dccd1f972171 +size 5504 diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/LevelData/Heightmap.dat b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/LevelData/Heightmap.dat deleted file mode 100644 index 80f0296fd4..0000000000 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae30a71535b7283f4b19a0dee09ad98afc2d23e127d3da53c4da76650c0d9698 -size 17407642 diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml index 290a28f223..7ccc1d51eb 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml +++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml @@ -1,6 +1,6 @@ - + diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak index fb91adeba5..12ce03fa87 100644 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak +++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87fbd9fda267daa505f11276b64f47c26115bee9e6d14f2a6f5a1cf1e1234218 -size 39179 +oid sha256:617c455668fc41cb7fd69de690e4aa3c80f2cb36deaa371902b79de18fcd1cb2 +size 39233 diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/terrain/cover.ctc b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/Base/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/Base/leveldata/Heightmap.dat deleted file mode 100644 index 2619d881d2..0000000000 --- a/AutomatedTesting/Levels/Physics/Base/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5080ffd65c2c76fbd5db96f75496dae7d4992dfc2f6a5e9514345e1d74422143 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/Base/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/Base/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/Base/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C12712452_ScriptCanvas_CollisionEvents/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C12712452_ScriptCanvas_CollisionEvents/leveldata/Heightmap.dat deleted file mode 100644 index 43bea299f4..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712452_ScriptCanvas_CollisionEvents/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9018429c312bced4975ab9e4d5cd6420a2fc8605b7d0929334dfd7dff50a79b -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C12712452_ScriptCanvas_CollisionEvents/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C12712452_ScriptCanvas_CollisionEvents/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712452_ScriptCanvas_CollisionEvents/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C12712453_ScriptCanvas_MultipleRaycastNode/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C12712453_ScriptCanvas_MultipleRaycastNode/leveldata/Heightmap.dat deleted file mode 100644 index 8772b96c9f..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712453_ScriptCanvas_MultipleRaycastNode/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2a53b3ffe745f824431028cc36d1990f55e9303bff99542f8ee3b85cd4417636 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C12712453_ScriptCanvas_MultipleRaycastNode/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C12712453_ScriptCanvas_MultipleRaycastNode/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712453_ScriptCanvas_MultipleRaycastNode/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C12712454_ScriptCanvas_OverlapNodeVerification/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C12712454_ScriptCanvas_OverlapNodeVerification/leveldata/Heightmap.dat deleted file mode 100644 index 8dba2c114b..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712454_ScriptCanvas_OverlapNodeVerification/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:35fa1fc96e3092de7200533183d875fe19585ca292e01af24dcc82497c8d400a -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C12712454_ScriptCanvas_OverlapNodeVerification/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C12712454_ScriptCanvas_OverlapNodeVerification/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712454_ScriptCanvas_OverlapNodeVerification/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C12712455_ScriptCanvas_ShapeCastVerification/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C12712455_ScriptCanvas_ShapeCastVerification/leveldata/Heightmap.dat deleted file mode 100644 index b3f394b89e..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712455_ScriptCanvas_ShapeCastVerification/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:93c2de86abea5c70845480f09dd86e9aebf2084c8e26444eee846ad9a3b18fe0 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C12712455_ScriptCanvas_ShapeCastVerification/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C12712455_ScriptCanvas_ShapeCastVerification/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C12712455_ScriptCanvas_ShapeCastVerification/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude/leveldata/Heightmap.dat deleted file mode 100644 index 5f407d9252..0000000000 --- a/AutomatedTesting/Levels/Physics/C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65464a758912e1dc2cdd39606fe86d05315336635a42a659734b3755f6e4ad4c -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C12868580_ForceRegion_SplineModifiedTransform/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C12868580_ForceRegion_SplineModifiedTransform/leveldata/Heightmap.dat deleted file mode 100644 index ea30699f94..0000000000 --- a/AutomatedTesting/Levels/Physics/C12868580_ForceRegion_SplineModifiedTransform/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5517e2cd05060859a9e010f9df1f410a7fc9739a8ec6adbc0e214b894a7eef21 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C12868580_ForceRegion_SplineModifiedTransform/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C12868580_ForceRegion_SplineModifiedTransform/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C12868580_ForceRegion_SplineModifiedTransform/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C12905527_ForceRegion_MagnitudeDeviation/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C12905527_ForceRegion_MagnitudeDeviation/leveldata/Heightmap.dat deleted file mode 100644 index bdce2c873d..0000000000 --- a/AutomatedTesting/Levels/Physics/C12905527_ForceRegion_MagnitudeDeviation/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:55f771fb360a8b7a6d12e9b0e5f8824f9567d1869cb2757b7a3263539d03db1f -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C12905527_ForceRegion_MagnitudeDeviation/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C12905527_ForceRegion_MagnitudeDeviation/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C12905527_ForceRegion_MagnitudeDeviation/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C13351703_COM_NotIncludeTriggerShapes/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C13351703_COM_NotIncludeTriggerShapes/leveldata/Heightmap.dat deleted file mode 100644 index f1d48b1ccd..0000000000 --- a/AutomatedTesting/Levels/Physics/C13351703_COM_NotIncludeTriggerShapes/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7718b09645345926ac1f59513114f64c6e146a49fac69f2835ce20c831953d7 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C13351703_COM_NotIncludeTriggerShapes/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C13351703_COM_NotIncludeTriggerShapes/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C13351703_COM_NotIncludeTriggerShapes/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C13352089_RigidBodies_MaxAngularVelocity/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C13352089_RigidBodies_MaxAngularVelocity/leveldata/Heightmap.dat deleted file mode 100644 index 0c1cfb6e1c..0000000000 --- a/AutomatedTesting/Levels/Physics/C13352089_RigidBodies_MaxAngularVelocity/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3b10f68c7f64dd775e6abc3250c019c1efdf498822b77bd98efb8f8c19513c0e -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C13352089_RigidBodies_MaxAngularVelocity/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C13352089_RigidBodies_MaxAngularVelocity/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C13352089_RigidBodies_MaxAngularVelocity/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C13508019_Terrain_TerrainTexturePainterWorks/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C13508019_Terrain_TerrainTexturePainterWorks/leveldata/Heightmap.dat deleted file mode 100644 index 1f85094c91..0000000000 --- a/AutomatedTesting/Levels/Physics/C13508019_Terrain_TerrainTexturePainterWorks/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:646140ed507ea073e2472196661b204694d686142536e1912b173376324b302a -size 274291 diff --git a/AutomatedTesting/Levels/Physics/C13508019_Terrain_TerrainTexturePainterWorks/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C13508019_Terrain_TerrainTexturePainterWorks/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C13508019_Terrain_TerrainTexturePainterWorks/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_NoRagdoll/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_NoRagdoll/leveldata/Heightmap.dat deleted file mode 100644 index a84b83c152..0000000000 --- a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_NoRagdoll/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:965f0dd885e93c25183390a87675b5aef1d24d374ededc5e073a98e15318858e -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_NoRagdoll/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_NoRagdoll/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_NoRagdoll/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_WithRagdoll/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_WithRagdoll/leveldata/Heightmap.dat deleted file mode 100644 index 54c23454f9..0000000000 --- a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_WithRagdoll/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9487342e768620c77288e3b8019ade03cd12eb1c19067b5d6408a185a62203e -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_WithRagdoll/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_WithRagdoll/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C13895144_Ragdoll_WithRagdoll/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C14195074_ScriptCanvas_PostUpdateEvent/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14195074_ScriptCanvas_PostUpdateEvent/leveldata/Heightmap.dat deleted file mode 100644 index e461c4f629..0000000000 --- a/AutomatedTesting/Levels/Physics/C14195074_ScriptCanvas_PostUpdateEvent/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:54b2dc4c443ea1e9b9aaed9d2aef1227ddeeac7db728b699cacd08811c81db8f -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C14195074_ScriptCanvas_PostUpdateEvent/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14195074_ScriptCanvas_PostUpdateEvent/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C14195074_ScriptCanvas_PostUpdateEvent/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevels/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevels/leveldata/Heightmap.dat deleted file mode 100644 index d290b022fe..0000000000 --- a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevels/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae84e1cb4cc4d54cb4cccb361663f8a4bb214e95ad0023cdd068657ef4705e43 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevels/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevels/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevels/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevelsEmpty/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevelsEmpty/leveldata/Heightmap.dat deleted file mode 100644 index c8eabe5621..0000000000 --- a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevelsEmpty/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a5c76ddb855bd123944e9582f289298091e6dc9089d877e1175079df72a251d9 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevelsEmpty/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevelsEmpty/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C14654881_CharacterController_SwitchLevelsEmpty/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C14654882_Ragdoll_ragdollAPTest/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14654882_Ragdoll_ragdollAPTest/leveldata/Heightmap.dat deleted file mode 100644 index 1ab498d3da..0000000000 --- a/AutomatedTesting/Levels/Physics/C14654882_Ragdoll_ragdollAPTest/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2913bdf321ee6cbe2bf148444554ce0135b41ac5ddac42d62a32d8af4cf7ae1c -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C14654882_Ragdoll_ragdollAPTest/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14654882_Ragdoll_ragdollAPTest/terrain/cover.ctc deleted file mode 100644 index 5df79a372b..0000000000 --- a/AutomatedTesting/Levels/Physics/C14654882_Ragdoll_ragdollAPTest/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:eee27982bfd7ad92814e2287d5fae32f943a470120550e2ac93d2299a4969876 -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C14861498_ConfirmError_NoPxMesh/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14861498_ConfirmError_NoPxMesh/leveldata/Heightmap.dat deleted file mode 100644 index ed4d2f4efc..0000000000 --- a/AutomatedTesting/Levels/Physics/C14861498_ConfirmError_NoPxMesh/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:52834b00e1392b055902d9bc93c52c145e75f758250049e71dc2d6b40a377279 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C14861498_ConfirmError_NoPxMesh/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14861498_ConfirmError_NoPxMesh/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C14861498_ConfirmError_NoPxMesh/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C14902097_ScriptCanvas_PreUpdateEvent/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14902097_ScriptCanvas_PreUpdateEvent/leveldata/Heightmap.dat deleted file mode 100644 index 9fa09123de..0000000000 --- a/AutomatedTesting/Levels/Physics/C14902097_ScriptCanvas_PreUpdateEvent/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb391ba2b3a7631e00b067610f1fa541bfd74d1d64e11aee72741cca5c2b7d90 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C14902097_ScriptCanvas_PreUpdateEvent/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14902097_ScriptCanvas_PreUpdateEvent/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C14902097_ScriptCanvas_PreUpdateEvent/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/leveldata/Heightmap.dat deleted file mode 100644 index 46e1443632..0000000000 --- a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1802389900e2a041717f05ea9f05ae344edd8ce49b5332204a87d2124459561f -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C14902098_ScriptCanvas_PostPhysicsUpdate/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C14976307_Gravity_SetGravityWorks/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14976307_Gravity_SetGravityWorks/leveldata/Heightmap.dat deleted file mode 100644 index 00187ffd24..0000000000 --- a/AutomatedTesting/Levels/Physics/C14976307_Gravity_SetGravityWorks/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3461c62fd0a988d4f3369116f9447d392cac1f4b1f259dc65aabe2fabbfafb37 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C14976307_Gravity_SetGravityWorks/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14976307_Gravity_SetGravityWorks/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C14976307_Gravity_SetGravityWorks/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C14976308_ScriptCanvas_SetKinematicTargetTransform/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C14976308_ScriptCanvas_SetKinematicTargetTransform/leveldata/Heightmap.dat deleted file mode 100644 index b62e36aef5..0000000000 --- a/AutomatedTesting/Levels/Physics/C14976308_ScriptCanvas_SetKinematicTargetTransform/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d7d878cdef5de9038df845b5ef5709cc3afe2a5a3a606f3f5ac4575a733ffc5e -size 273095 diff --git a/AutomatedTesting/Levels/Physics/C14976308_ScriptCanvas_SetKinematicTargetTransform/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C14976308_ScriptCanvas_SetKinematicTargetTransform/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C14976308_ScriptCanvas_SetKinematicTargetTransform/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C15096732_Material_DefaultLibraryUpdatedAcrossLevels/0/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15096732_Material_DefaultLibraryUpdatedAcrossLevels/0/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15096732_Material_DefaultLibraryUpdatedAcrossLevels/0/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15096732_Material_DefaultLibraryUpdatedAcrossLevels/1/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15096732_Material_DefaultLibraryUpdatedAcrossLevels/1/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15096732_Material_DefaultLibraryUpdatedAcrossLevels/1/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15096735_Materials_DefaultLibraryConsistency/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15096735_Materials_DefaultLibraryConsistency/leveldata/Heightmap.dat deleted file mode 100644 index 45e1bc7290..0000000000 --- a/AutomatedTesting/Levels/Physics/C15096735_Materials_DefaultLibraryConsistency/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6931308387c56833dcfa8887cc91cdf3ec2c8dcf47803118892b9734751f86c9 -size 274584 diff --git a/AutomatedTesting/Levels/Physics/C15096735_Materials_DefaultLibraryConsistency/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15096735_Materials_DefaultLibraryConsistency/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C15096735_Materials_DefaultLibraryConsistency/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C15096737_Materials_DefaultMaterialLibraryChanges/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15096737_Materials_DefaultMaterialLibraryChanges/leveldata/Heightmap.dat deleted file mode 100644 index 929371d5ba..0000000000 --- a/AutomatedTesting/Levels/Physics/C15096737_Materials_DefaultMaterialLibraryChanges/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:75c123551336f3ff33d1e7b7a35609e1e5dc70cc360b59a23c11c8650ccf19a6 -size 17409393 diff --git a/AutomatedTesting/Levels/Physics/C15096737_Materials_DefaultMaterialLibraryChanges/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15096737_Materials_DefaultMaterialLibraryChanges/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15096737_Materials_DefaultMaterialLibraryChanges/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithOutTerrain/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithOutTerrain/leveldata/Heightmap.dat deleted file mode 100644 index 2650c4e5cb..0000000000 --- a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithOutTerrain/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5b3d4971af97025075197da8cb357d488ca899e3da8fb1e6f56082d6aace7101 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithOutTerrain/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithOutTerrain/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithOutTerrain/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithTerrain/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithTerrain/leveldata/Heightmap.dat deleted file mode 100644 index e32db0bdff..0000000000 --- a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithTerrain/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b79f9dec3428d224041ff2404c503c9df1a7fc8fb0e84bfec30374a918710b2a -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithTerrain/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithTerrain/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15308217_NoCrash_LevelSwitchWithTerrain/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15308221_Material_ComponentsInSyncWithLibrary/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15308221_Material_ComponentsInSyncWithLibrary/leveldata/Heightmap.dat deleted file mode 100644 index 2521b77547..0000000000 --- a/AutomatedTesting/Levels/Physics/C15308221_Material_ComponentsInSyncWithLibrary/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4adb1fccd94b0bcf444b4a6dc6f387b20bf22f0d83fefe1d938ffa6672e83a13 -size 17408454 diff --git a/AutomatedTesting/Levels/Physics/C15308221_Material_ComponentsInSyncWithLibrary/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15308221_Material_ComponentsInSyncWithLibrary/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15308221_Material_ComponentsInSyncWithLibrary/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15425929_Undo_Redo/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15425929_Undo_Redo/leveldata/Heightmap.dat deleted file mode 100644 index 6798b7f0c0..0000000000 --- a/AutomatedTesting/Levels/Physics/C15425929_Undo_Redo/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fd1588965564e750d4d5d56771d983dbd27cf36a072ad2a4bc00478d3cb4629b -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C15425929_Undo_Redo/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15425929_Undo_Redo/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C15425929_Undo_Redo/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/Heightmap.dat deleted file mode 100644 index 66b1d441b9..0000000000 --- a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:179f70d479b1090b16dfbfc92e5354d69751ee0288b831b51840a936e279b2d1 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_0/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/Heightmap.dat deleted file mode 100644 index 66b1d441b9..0000000000 --- a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:179f70d479b1090b16dfbfc92e5354d69751ee0288b831b51840a936e279b2d1 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15425935_Material_LibraryUpdatedAcrossLevels/C15425935_Material_LibraryUpdatedAcrossLevels_1/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment/leveldata/Heightmap.dat deleted file mode 100644 index e5479ac90e..0000000000 --- a/AutomatedTesting/Levels/Physics/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:709cb703dd55024d7863d8b64ffe74e9e02560e2faefb18e28f23e18a7186f52 -size 17409642 diff --git a/AutomatedTesting/Levels/Physics/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15563573_Material_AddModifyDeleteOnCharacterController/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15563573_Material_AddModifyDeleteOnCharacterController/leveldata/Heightmap.dat deleted file mode 100644 index 6a27041aba..0000000000 --- a/AutomatedTesting/Levels/Physics/C15563573_Material_AddModifyDeleteOnCharacterController/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ac95dd40dd51f41fdbf06528e47f2675d888da0c09fe516a5d78c90ed025f5d -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C15563573_Material_AddModifyDeleteOnCharacterController/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15563573_Material_AddModifyDeleteOnCharacterController/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15563573_Material_AddModifyDeleteOnCharacterController/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C15845879_ForceRegion_HighLinearDampingForce/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C15845879_ForceRegion_HighLinearDampingForce/leveldata/Heightmap.dat deleted file mode 100644 index 95bc38ca3b..0000000000 --- a/AutomatedTesting/Levels/Physics/C15845879_ForceRegion_HighLinearDampingForce/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:336249a60fe83032f9cad84b9e5cfe53e4fbc95d8bbeb27e7376629a6899622e -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C15845879_ForceRegion_HighLinearDampingForce/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C15845879_ForceRegion_HighLinearDampingForce/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C15845879_ForceRegion_HighLinearDampingForce/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243580_Joints_Fixed2BodiesConstrained/LevelData/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243580_Joints_Fixed2BodiesConstrained/LevelData/Heightmap.dat deleted file mode 100644 index 11f4d421fd..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243580_Joints_Fixed2BodiesConstrained/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d831766ab559a54fa77535c1debb710cda545ae2c34e37cf4456b90769abe33a -size 8389548 diff --git a/AutomatedTesting/Levels/Physics/C18243580_Joints_Fixed2BodiesConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243580_Joints_Fixed2BodiesConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243580_Joints_Fixed2BodiesConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243581_Joints_FixedBreakable/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243581_Joints_FixedBreakable/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243581_Joints_FixedBreakable/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243581_Joints_FixedBreakable/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243581_Joints_FixedBreakable/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243581_Joints_FixedBreakable/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243582_Joints_FixedLeadFollowerCollide/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243582_Joints_FixedLeadFollowerCollide/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243582_Joints_FixedLeadFollowerCollide/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243582_Joints_FixedLeadFollowerCollide/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243582_Joints_FixedLeadFollowerCollide/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243582_Joints_FixedLeadFollowerCollide/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243583_Joints_Hinge2BodiesConstrained/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243583_Joints_Hinge2BodiesConstrained/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243583_Joints_Hinge2BodiesConstrained/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243583_Joints_Hinge2BodiesConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243583_Joints_Hinge2BodiesConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243583_Joints_Hinge2BodiesConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243584_Joints_HingeSoftLimitsConstrained/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243584_Joints_HingeSoftLimitsConstrained/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243584_Joints_HingeSoftLimitsConstrained/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243584_Joints_HingeSoftLimitsConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243584_Joints_HingeSoftLimitsConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243584_Joints_HingeSoftLimitsConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243585_Joints_HingeNoLimitsConstrained/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243585_Joints_HingeNoLimitsConstrained/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243585_Joints_HingeNoLimitsConstrained/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243585_Joints_HingeNoLimitsConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243585_Joints_HingeNoLimitsConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243585_Joints_HingeNoLimitsConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243586_Joints_HingeLeadFollowerCollide/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243586_Joints_HingeLeadFollowerCollide/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243586_Joints_HingeLeadFollowerCollide/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243586_Joints_HingeLeadFollowerCollide/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243586_Joints_HingeLeadFollowerCollide/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243586_Joints_HingeLeadFollowerCollide/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243587_Joints_HingeBreakable/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243587_Joints_HingeBreakable/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243587_Joints_HingeBreakable/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243587_Joints_HingeBreakable/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243587_Joints_HingeBreakable/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243587_Joints_HingeBreakable/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243588_Joints_Ball2BodiesConstrained/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243588_Joints_Ball2BodiesConstrained/leveldata/Heightmap.dat deleted file mode 100644 index 5218205cc2..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243588_Joints_Ball2BodiesConstrained/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb33993ffc810014adbb3c2054980e4e6523919a690b6271a218b17b1f537262 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243588_Joints_Ball2BodiesConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243588_Joints_Ball2BodiesConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243588_Joints_Ball2BodiesConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243589_Joints_BallSoftLimitsConstrained/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243589_Joints_BallSoftLimitsConstrained/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243589_Joints_BallSoftLimitsConstrained/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243589_Joints_BallSoftLimitsConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243589_Joints_BallSoftLimitsConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243589_Joints_BallSoftLimitsConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243590_Joints_BallNoLimitsConstrained/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243590_Joints_BallNoLimitsConstrained/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243590_Joints_BallNoLimitsConstrained/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243590_Joints_BallNoLimitsConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243590_Joints_BallNoLimitsConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243590_Joints_BallNoLimitsConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243591_Joints_BallLeadFollowerCollide/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243591_Joints_BallLeadFollowerCollide/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243591_Joints_BallLeadFollowerCollide/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243591_Joints_BallLeadFollowerCollide/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243591_Joints_BallLeadFollowerCollide/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243591_Joints_BallLeadFollowerCollide/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243592_Joints_BallBreakable/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243592_Joints_BallBreakable/leveldata/Heightmap.dat deleted file mode 100644 index 1081404c7a..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243592_Joints_BallBreakable/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44607f0af9f20238fe5405800542230cb9cf374a9f7b94abee43910e177c9195 -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243592_Joints_BallBreakable/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243592_Joints_BallBreakable/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243592_Joints_BallBreakable/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18243593_Joints_GlobalFrameConstrained/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18243593_Joints_GlobalFrameConstrained/leveldata/Heightmap.dat deleted file mode 100644 index 3fbf3cb79d..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243593_Joints_GlobalFrameConstrained/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4e640b0c7396ba078c2d591b84d3e9289f391635e0f2db0d84de824634247cae -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/C18243593_Joints_GlobalFrameConstrained/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18243593_Joints_GlobalFrameConstrained/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18243593_Joints_GlobalFrameConstrained/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18977601_Material_FrictionCombinePriority/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18977601_Material_FrictionCombinePriority/leveldata/Heightmap.dat deleted file mode 100644 index 35dd269a45..0000000000 --- a/AutomatedTesting/Levels/Physics/C18977601_Material_FrictionCombinePriority/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8448b0e7a0a336c44743b3031226572cfbc5d0dd118c7214c2255434d46c070 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C18977601_Material_FrictionCombinePriority/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18977601_Material_FrictionCombinePriority/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18977601_Material_FrictionCombinePriority/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C18981526_Material_RestitutionCombinePriority/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C18981526_Material_RestitutionCombinePriority/leveldata/Heightmap.dat deleted file mode 100644 index 35dd269a45..0000000000 --- a/AutomatedTesting/Levels/Physics/C18981526_Material_RestitutionCombinePriority/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8448b0e7a0a336c44743b3031226572cfbc5d0dd118c7214c2255434d46c070 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C18981526_Material_RestitutionCombinePriority/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C18981526_Material_RestitutionCombinePriority/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C18981526_Material_RestitutionCombinePriority/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain/leveldata/Heightmap.dat deleted file mode 100644 index d0f31986ba..0000000000 --- a/AutomatedTesting/Levels/Physics/C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8faedf8853c5e96edc68089af22243c7cbd0ba27aa76b1b065e72693c9140eb -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C28978033_Ragdoll_WorldBodyBusTests/LevelData/Heightmap.dat b/AutomatedTesting/Levels/Physics/C28978033_Ragdoll_WorldBodyBusTests/LevelData/Heightmap.dat deleted file mode 100644 index c319bfdc1b..0000000000 --- a/AutomatedTesting/Levels/Physics/C28978033_Ragdoll_WorldBodyBusTests/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b0e1bd3cb02be966cfd15ff9c44605c778058a2b06899c1934762f4fe770e73d -size 8389740 diff --git a/AutomatedTesting/Levels/Physics/C28978033_Ragdoll_WorldBodyBusTests/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C28978033_Ragdoll_WorldBodyBusTests/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C28978033_Ragdoll_WorldBodyBusTests/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C29032500_EditorComponents_WorldBodyBusWorks/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C29032500_EditorComponents_WorldBodyBusWorks/leveldata/Heightmap.dat deleted file mode 100644 index 5b841792c2..0000000000 --- a/AutomatedTesting/Levels/Physics/C29032500_EditorComponents_WorldBodyBusWorks/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c2714d5fcf2c87ae5b149ec68e0df1dc66d451e219e050d11609b0e3e41f1c71 -size 8389548 diff --git a/AutomatedTesting/Levels/Physics/C29032500_EditorComponents_WorldBodyBusWorks/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C29032500_EditorComponents_WorldBodyBusWorks/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C29032500_EditorComponents_WorldBodyBusWorks/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C3510642_Terrain_NotCollideWithTerrain/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C3510642_Terrain_NotCollideWithTerrain/leveldata/Heightmap.dat deleted file mode 100644 index 67c08472c3..0000000000 --- a/AutomatedTesting/Levels/Physics/C3510642_Terrain_NotCollideWithTerrain/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e7bcb9526a0f20e01f1f263f4853b6630a93c8eeeca9b65506064fccfeac4e40 -size 273000 diff --git a/AutomatedTesting/Levels/Physics/C3510642_Terrain_NotCollideWithTerrain/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C3510642_Terrain_NotCollideWithTerrain/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C3510642_Terrain_NotCollideWithTerrain/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C3510644_Collider_CollisionGroups/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C3510644_Collider_CollisionGroups/leveldata/Heightmap.dat deleted file mode 100644 index 2bf6b30add..0000000000 --- a/AutomatedTesting/Levels/Physics/C3510644_Collider_CollisionGroups/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57d336a6e26bc0c55b8dbd27fb3e0947d3d2cfc49f18142a8fa88430f4b615b0 -size 272909 diff --git a/AutomatedTesting/Levels/Physics/C3510644_Collider_CollisionGroups/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C3510644_Collider_CollisionGroups/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C3510644_Collider_CollisionGroups/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4044455_Material_LibraryChangesInstantly/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044455_Material_LibraryChangesInstantly/leveldata/Heightmap.dat deleted file mode 100644 index 6f46e7ab93..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044455_Material_LibraryChangesInstantly/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1e90a489a4042a27b564b0edf3ba32258bccf25e6b45a949737da9d7209f30e4 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C4044455_Material_LibraryChangesInstantly/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044455_Material_LibraryChangesInstantly/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044455_Material_LibraryChangesInstantly/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4044456_Material_FrictionCombine/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044456_Material_FrictionCombine/leveldata/Heightmap.dat deleted file mode 100644 index 35dd269a45..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044456_Material_FrictionCombine/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8448b0e7a0a336c44743b3031226572cfbc5d0dd118c7214c2255434d46c070 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C4044456_Material_FrictionCombine/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044456_Material_FrictionCombine/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044456_Material_FrictionCombine/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4044457_Material_RestitutionCombine/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044457_Material_RestitutionCombine/leveldata/Heightmap.dat deleted file mode 100644 index 35dd269a45..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044457_Material_RestitutionCombine/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8448b0e7a0a336c44743b3031226572cfbc5d0dd118c7214c2255434d46c070 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C4044457_Material_RestitutionCombine/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044457_Material_RestitutionCombine/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044457_Material_RestitutionCombine/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4044459_Material_DynamicFriction/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044459_Material_DynamicFriction/leveldata/Heightmap.dat deleted file mode 100644 index 35dd269a45..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044459_Material_DynamicFriction/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8448b0e7a0a336c44743b3031226572cfbc5d0dd118c7214c2255434d46c070 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C4044459_Material_DynamicFriction/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044459_Material_DynamicFriction/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044459_Material_DynamicFriction/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4044460_Material_StaticFriction/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044460_Material_StaticFriction/leveldata/Heightmap.dat deleted file mode 100644 index 35dd269a45..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044460_Material_StaticFriction/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8448b0e7a0a336c44743b3031226572cfbc5d0dd118c7214c2255434d46c070 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C4044460_Material_StaticFriction/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044460_Material_StaticFriction/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044460_Material_StaticFriction/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4044461_Material_Restitution/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044461_Material_Restitution/leveldata/Heightmap.dat deleted file mode 100644 index 35dd269a45..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044461_Material_Restitution/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8448b0e7a0a336c44743b3031226572cfbc5d0dd118c7214c2255434d46c070 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C4044461_Material_Restitution/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044461_Material_Restitution/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044461_Material_Restitution/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4044694_Material_EmptyLibraryUsesDefault/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044694_Material_EmptyLibraryUsesDefault/leveldata/Heightmap.dat deleted file mode 100644 index b7a01eb918..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044694_Material_EmptyLibraryUsesDefault/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3fa70d03516a287419a32ffb59178c302ba10687e5439fe131305d63dd51e0ca -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C4044694_Material_EmptyLibraryUsesDefault/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044694_Material_EmptyLibraryUsesDefault/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044694_Material_EmptyLibraryUsesDefault/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4044697_Material_PerfaceMaterialValidation/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4044697_Material_PerfaceMaterialValidation/leveldata/Heightmap.dat deleted file mode 100644 index f1d0bf3b16..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044697_Material_PerfaceMaterialValidation/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:04ef00ec40ec80a43b39ab898e5ee99810eccf8d3f50278054f52c6e54667f0f -size 17407590 diff --git a/AutomatedTesting/Levels/Physics/C4044697_Material_PerfaceMaterialValidation/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4044697_Material_PerfaceMaterialValidation/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4044697_Material_PerfaceMaterialValidation/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4888315_Material_AddModifyDeleteOnCollider/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4888315_Material_AddModifyDeleteOnCollider/leveldata/Heightmap.dat deleted file mode 100644 index d9ce7a6ec4..0000000000 --- a/AutomatedTesting/Levels/Physics/C4888315_Material_AddModifyDeleteOnCollider/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af292927784263e86581009389f9c9d322e85b3d2208a72286dbe860d8995d2f -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C4888315_Material_AddModifyDeleteOnCollider/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4888315_Material_AddModifyDeleteOnCollider/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4888315_Material_AddModifyDeleteOnCollider/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4925577_PhysXMaterials_MaterialAssignedToTerrain/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4925577_PhysXMaterials_MaterialAssignedToTerrain/leveldata/Heightmap.dat deleted file mode 100644 index 6555bbb47c..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925577_PhysXMaterials_MaterialAssignedToTerrain/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8849aaa3261772f0a4286acb64cf2c5af15f76cbd8e42bd96ce5532df3ed64f4 -size 274401 diff --git a/AutomatedTesting/Levels/Physics/C4925577_PhysXMaterials_MaterialAssignedToTerrain/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4925577_PhysXMaterials_MaterialAssignedToTerrain/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925577_PhysXMaterials_MaterialAssignedToTerrain/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4925579_Material_AddModifyDeleteOnTerrain/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4925579_Material_AddModifyDeleteOnTerrain/leveldata/Heightmap.dat deleted file mode 100644 index 755ba49dc0..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925579_Material_AddModifyDeleteOnTerrain/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4bc0fd79ecccd25461096a9f716f21552d3a0b9650a7d1567060d70f93579afd -size 273771 diff --git a/AutomatedTesting/Levels/Physics/C4925579_Material_AddModifyDeleteOnTerrain/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4925579_Material_AddModifyDeleteOnTerrain/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925579_Material_AddModifyDeleteOnTerrain/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4925580_Material_RagdollBonesMaterial/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4925580_Material_RagdollBonesMaterial/leveldata/Heightmap.dat deleted file mode 100644 index e08359de1c..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925580_Material_RagdollBonesMaterial/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91d4f2760734ec798785956e7873186d2ac45935068011167d4a594f490c0bf4 -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C4925580_Material_RagdollBonesMaterial/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4925580_Material_RagdollBonesMaterial/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925580_Material_RagdollBonesMaterial/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4925582_Material_AddModifyDeleteOnRagdollBones/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4925582_Material_AddModifyDeleteOnRagdollBones/leveldata/Heightmap.dat deleted file mode 100644 index 0b7e8da583..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925582_Material_AddModifyDeleteOnRagdollBones/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b1a9ad65c4a46f5bd1f67ac3350688549b6048620467c7b54cb30102a08c88ad -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C4925582_Material_AddModifyDeleteOnRagdollBones/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4925582_Material_AddModifyDeleteOnRagdollBones/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4925582_Material_AddModifyDeleteOnRagdollBones/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4976194_RigidBody_PhysXComponentIsValid/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976194_RigidBody_PhysXComponentIsValid/leveldata/Heightmap.dat deleted file mode 100644 index b5814e3003..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976194_RigidBody_PhysXComponentIsValid/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5fd1899decf59ab5cf0990a24a7c8f3ab383f8739d1d2b558f081e64787d1e9c -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C4976194_RigidBody_PhysXComponentIsValid/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976194_RigidBody_PhysXComponentIsValid/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976194_RigidBody_PhysXComponentIsValid/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976195_RigidBodies_InitialLinearVelocity/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976195_RigidBodies_InitialLinearVelocity/leveldata/Heightmap.dat deleted file mode 100644 index c7321f0771..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976195_RigidBodies_InitialLinearVelocity/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9ae9eaf24bd5a1348e1a2f867b26408fbcc3275d3d3e45e65ce8fdafc3ceecdb -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C4976195_RigidBodies_InitialLinearVelocity/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976195_RigidBodies_InitialLinearVelocity/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976195_RigidBodies_InitialLinearVelocity/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976197_RigidBodies_InitialAngularVelocity/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976197_RigidBodies_InitialAngularVelocity/leveldata/Heightmap.dat deleted file mode 100644 index fb081369d8..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976197_RigidBodies_InitialAngularVelocity/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4cfdf881e642d5ac20411a85164991d7ca8a4428324ad36224675680633fb64b -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C4976197_RigidBodies_InitialAngularVelocity/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976197_RigidBodies_InitialAngularVelocity/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976197_RigidBodies_InitialAngularVelocity/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976199_RigidBodies_LinearDampingObjectMotion/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976199_RigidBodies_LinearDampingObjectMotion/leveldata/Heightmap.dat deleted file mode 100644 index 1705042d2a..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976199_RigidBodies_LinearDampingObjectMotion/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ebba3e4761448e928c02417fe0732d7af9dde3fa954a74aaa56c7abbdd6c829 -size 17408234 diff --git a/AutomatedTesting/Levels/Physics/C4976199_RigidBodies_LinearDampingObjectMotion/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976199_RigidBodies_LinearDampingObjectMotion/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976199_RigidBodies_LinearDampingObjectMotion/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976200_RigidBody_AngularDampingObjectRotation/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976200_RigidBody_AngularDampingObjectRotation/leveldata/Heightmap.dat deleted file mode 100644 index 6422240323..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976200_RigidBody_AngularDampingObjectRotation/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6476315967452f205596689e576e4b4bb834b3122bb3976e84fc1a42abf8e9cd -size 17408330 diff --git a/AutomatedTesting/Levels/Physics/C4976200_RigidBody_AngularDampingObjectRotation/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976200_RigidBody_AngularDampingObjectRotation/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976200_RigidBody_AngularDampingObjectRotation/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976201_RigidBody_MassIsAssigned/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976201_RigidBody_MassIsAssigned/leveldata/Heightmap.dat deleted file mode 100644 index eb4935beb0..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976201_RigidBody_MassIsAssigned/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fff150891e6035904d35d3821aa2df85af7ed0bc3d9c8780e4bd186dc1ab7216 -size 273031 diff --git a/AutomatedTesting/Levels/Physics/C4976201_RigidBody_MassIsAssigned/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976201_RigidBody_MassIsAssigned/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976201_RigidBody_MassIsAssigned/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4976202_RigidBody_StopsWhenBelowKineticThreshold/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976202_RigidBody_StopsWhenBelowKineticThreshold/leveldata/Heightmap.dat deleted file mode 100644 index 47884d0c4e..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976202_RigidBody_StopsWhenBelowKineticThreshold/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95f16f7ae156afe5d252b95c9b5bfd2ad5f8c0f918888bd1fbc48407708723ab -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C4976202_RigidBody_StopsWhenBelowKineticThreshold/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976202_RigidBody_StopsWhenBelowKineticThreshold/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976202_RigidBody_StopsWhenBelowKineticThreshold/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4976204_Verify_Start_Asleep_Condition/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976204_Verify_Start_Asleep_Condition/leveldata/Heightmap.dat deleted file mode 100644 index 44e7c48c98..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976204_Verify_Start_Asleep_Condition/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3ebda4f2e5bcf223ba1bc6273c49cc641e433c15a343fdbcdb3cab20bbd98c10 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C4976204_Verify_Start_Asleep_Condition/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976204_Verify_Start_Asleep_Condition/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976204_Verify_Start_Asleep_Condition/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976206_RigidBodies_VerifyGravity/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976206_RigidBodies_VerifyGravity/leveldata/Heightmap.dat deleted file mode 100644 index 1853f40c9d..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976206_RigidBodies_VerifyGravity/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f488c4b02efeebb8528a42b2259cb96a40e29d366fa629bae625dff6666621d7 -size 17407721 diff --git a/AutomatedTesting/Levels/Physics/C4976206_RigidBodies_VerifyGravity/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976206_RigidBodies_VerifyGravity/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976206_RigidBodies_VerifyGravity/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976207_PhysXRigidBodies_KinematicBehavior/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976207_PhysXRigidBodies_KinematicBehavior/leveldata/Heightmap.dat deleted file mode 100644 index 536deab727..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976207_PhysXRigidBodies_KinematicBehavior/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:97b22d6b0f426fd22f68f1cd08a2a39bae75644f2f54003a1191f7273e69734a -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C4976207_PhysXRigidBodies_KinematicBehavior/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976207_PhysXRigidBodies_KinematicBehavior/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976207_PhysXRigidBodies_KinematicBehavior/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4976209_RigidBody_ComputesCOM/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976209_RigidBody_ComputesCOM/leveldata/Heightmap.dat deleted file mode 100644 index 4581d9bcb6..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976209_RigidBody_ComputesCOM/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f2a85cc698d064f0701bef963afde2908c31d837e6d25afd3d5d4b08838ad47f -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C4976209_RigidBody_ComputesCOM/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976209_RigidBody_ComputesCOM/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976209_RigidBody_ComputesCOM/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976210_COM_ManualSetting/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976210_COM_ManualSetting/leveldata/Heightmap.dat deleted file mode 100644 index b1bbb93cdb..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976210_COM_ManualSetting/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d7a8b0e93ea230fe46642f392a3836a95651802f1b23ecff4741d5037bba6db -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C4976210_COM_ManualSetting/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976210_COM_ManualSetting/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976210_COM_ManualSetting/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4976218_RigidBodies_InertiaObjectNotComputed/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976218_RigidBodies_InertiaObjectNotComputed/leveldata/Heightmap.dat deleted file mode 100644 index 228cdbb6ec..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976218_RigidBodies_InertiaObjectNotComputed/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0b43531ceeb4f2119b4978b2501038e0106a17694b051de49f829349f8f49eb3 -size 17407561 diff --git a/AutomatedTesting/Levels/Physics/C4976218_RigidBodies_InertiaObjectNotComputed/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976218_RigidBodies_InertiaObjectNotComputed/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976218_RigidBodies_InertiaObjectNotComputed/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976227_Collider_NewGroup/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976227_Collider_NewGroup/leveldata/Heightmap.dat deleted file mode 100644 index 90757c597e..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976227_Collider_NewGroup/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f9ee507c0b37dc5c007afee8524e49ae223727847d075b416a9420c99d7b1c15 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C4976227_Collider_NewGroup/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976227_Collider_NewGroup/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976227_Collider_NewGroup/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976242_Collision_SameCollisionlayerSameCollisiongroup/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976242_Collision_SameCollisionlayerSameCollisiongroup/leveldata/Heightmap.dat deleted file mode 100644 index 77636050c1..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976242_Collision_SameCollisionlayerSameCollisiongroup/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ae5c2fde61764e3f6150ff2b2d15dfaa38c3b0dfe76f0a6ae50f76f85912f781 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C4976242_Collision_SameCollisionlayerSameCollisiongroup/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976242_Collision_SameCollisionlayerSameCollisiongroup/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976242_Collision_SameCollisionlayerSameCollisiongroup/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976243_Collision_SameCollisionGroupDiffCollisionLayers/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976243_Collision_SameCollisionGroupDiffCollisionLayers/leveldata/Heightmap.dat deleted file mode 100644 index 4247db13e0..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976243_Collision_SameCollisionGroupDiffCollisionLayers/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a1886608dca8428ea53e4d2ea0a749072bde8baab935f593657264fd08a7b924 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C4976243_Collision_SameCollisionGroupDiffCollisionLayers/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976243_Collision_SameCollisionGroupDiffCollisionLayers/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976243_Collision_SameCollisionGroupDiffCollisionLayers/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976244_Collider_SameGroupSameLayerCollision/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976244_Collider_SameGroupSameLayerCollision/leveldata/Heightmap.dat deleted file mode 100644 index 2ec404ff7b..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976244_Collider_SameGroupSameLayerCollision/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6dc09aa3d8bcf65faa42043a975b0dce7af7450fe466d297b3b1f803ea8e9a9a -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C4976244_Collider_SameGroupSameLayerCollision/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976244_Collider_SameGroupSameLayerCollision/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976244_Collider_SameGroupSameLayerCollision/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C4976245_PhysxCollider_CollisionLayerTest/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4976245_PhysxCollider_CollisionLayerTest/leveldata/Heightmap.dat deleted file mode 100644 index c4f8a2a863..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976245_PhysxCollider_CollisionLayerTest/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:664ed8be7bd6521f1d98f373087b1f44f18ae5d7cd2da53325e5a3f588b15e43 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C4976245_PhysxCollider_CollisionLayerTest/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4976245_PhysxCollider_CollisionLayerTest/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4976245_PhysxCollider_CollisionLayerTest/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4982593_PhysxCollider_CollisionLayerTest/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4982593_PhysxCollider_CollisionLayerTest/leveldata/Heightmap.dat deleted file mode 100644 index 298e654e19..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982593_PhysxCollider_CollisionLayerTest/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c2430de76e2e824323072e80c7e7194e803e49639facfbf8293d48e832ae3b8 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C4982593_PhysxCollider_CollisionLayerTest/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4982593_PhysxCollider_CollisionLayerTest/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982593_PhysxCollider_CollisionLayerTest/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4982595_Collider_TriggerDisablesCollision/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4982595_Collider_TriggerDisablesCollision/leveldata/Heightmap.dat deleted file mode 100644 index 1bc58fdb62..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982595_Collider_TriggerDisablesCollision/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:885772e6d2bbe859c4de728888970ce003dde3a6b658cf716242a92c0be81f08 -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C4982595_Collider_TriggerDisablesCollision/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4982595_Collider_TriggerDisablesCollision/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982595_Collider_TriggerDisablesCollision/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4982797_Collider_ColliderOffset/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4982797_Collider_ColliderOffset/leveldata/Heightmap.dat deleted file mode 100644 index e238bc5a3d..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982797_Collider_ColliderOffset/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7917bcdcbb3a788e1596b65a47df0efa79d872456775555a478d8d68e104ed5a -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C4982797_Collider_ColliderOffset/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4982797_Collider_ColliderOffset/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982797_Collider_ColliderOffset/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C4982798_Collider_ColliderRotationOffset/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C4982798_Collider_ColliderRotationOffset/leveldata/Heightmap.dat deleted file mode 100644 index 710bb396f3..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982798_Collider_ColliderRotationOffset/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3af891c31ed9b4023548f6aa65fa224a5af379f27432bd11808479ef678ddd25 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C4982798_Collider_ColliderRotationOffset/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C4982798_Collider_ColliderRotationOffset/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C4982798_Collider_ColliderRotationOffset/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5296614_PhysXMaterial_ColliderShape/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5296614_PhysXMaterial_ColliderShape/leveldata/Heightmap.dat deleted file mode 100644 index 47184c77dc..0000000000 --- a/AutomatedTesting/Levels/Physics/C5296614_PhysXMaterial_ColliderShape/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9ad9563ce944d8ce37af3e7300c5647de79331dfb002fe274e3aef0bf0736956 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5296614_PhysXMaterial_ColliderShape/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5296614_PhysXMaterial_ColliderShape/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5296614_PhysXMaterial_ColliderShape/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/leveldata/Heightmap.dat deleted file mode 100644 index 75be3478ff..0000000000 --- a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:243cd3b6a776732db1093147d5482a458d65603e74fc09058ed5b03ee6e04720 -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5689517_Verify_Terrain_Component/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689517_Verify_Terrain_Component/leveldata/Heightmap.dat deleted file mode 100644 index b1d62c11ff..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689517_Verify_Terrain_Component/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7c25f6b8480b95ce5ff101e66d829215fe9efc2fca07b474ef11e8062d95ff50 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C5689517_Verify_Terrain_Component/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689517_Verify_Terrain_Component/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689517_Verify_Terrain_Component/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5689518_PhysXEntity_collides_with_PhysXTerrain/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689518_PhysXEntity_collides_with_PhysXTerrain/leveldata/Heightmap.dat deleted file mode 100644 index 5454b28cd5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689518_PhysXEntity_collides_with_PhysXTerrain/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:185c7b71d452c9d7cfaa28d6c9b782179708b82ab09387919d8ecd1b96df4337 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C5689518_PhysXEntity_collides_with_PhysXTerrain/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689518_PhysXEntity_collides_with_PhysXTerrain/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689518_PhysXEntity_collides_with_PhysXTerrain/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5689521_Terrain_NoCollisionAfterTerrainDeletion/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689521_Terrain_NoCollisionAfterTerrainDeletion/leveldata/Heightmap.dat deleted file mode 100644 index d2da463d29..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689521_Terrain_NoCollisionAfterTerrainDeletion/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f0e21daaaead505664b5cab3e131e7f0e01de76362cc8b304aef908b842b99d -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5689521_Terrain_NoCollisionAfterTerrainDeletion/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689521_Terrain_NoCollisionAfterTerrainDeletion/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689521_Terrain_NoCollisionAfterTerrainDeletion/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5689522_Physxterrain_AddPhysxterrainNoEditorCrash/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689522_Physxterrain_AddPhysxterrainNoEditorCrash/leveldata/Heightmap.dat deleted file mode 100644 index bf01f8b4b9..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689522_Physxterrain_AddPhysxterrainNoEditorCrash/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bf77a5ddfd8ff9a9443e551cebb2eadade3b056db8539a81a38f00c3e448882c -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5689522_Physxterrain_AddPhysxterrainNoEditorCrash/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689522_Physxterrain_AddPhysxterrainNoEditorCrash/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689522_Physxterrain_AddPhysxterrainNoEditorCrash/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5689524_MultipleTerrains_CheckWarningInConsole/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689524_MultipleTerrains_CheckWarningInConsole/leveldata/Heightmap.dat deleted file mode 100644 index 38834c6ffc..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689524_MultipleTerrains_CheckWarningInConsole/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43364efffb1278e1986537f612899e5ed7777d0a2da624827eb478e3290d3e15 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5689524_MultipleTerrains_CheckWarningInConsole/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689524_MultipleTerrains_CheckWarningInConsole/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689524_MultipleTerrains_CheckWarningInConsole/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5689528_Terrain_MultipleTerrainComponents/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689528_Terrain_MultipleTerrainComponents/leveldata/Heightmap.dat deleted file mode 100644 index 2b02b6f32c..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689528_Terrain_MultipleTerrainComponents/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b6ad16faf3d9c08e9fc26cf57f6ccfee4870be0b681302499cfcba1b48ed2450 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5689528_Terrain_MultipleTerrainComponents/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689528_Terrain_MultipleTerrainComponents/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689528_Terrain_MultipleTerrainComponents/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5689529_Verify_Terrain_RigidBody_Collider_Mesh/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689529_Verify_Terrain_RigidBody_Collider_Mesh/leveldata/Heightmap.dat deleted file mode 100644 index e0bb0dca29..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689529_Verify_Terrain_RigidBody_Collider_Mesh/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:957582ad1f2df72a7d8569d15ad5b7d00b711f97a7b85a62af14b45f1e505b83 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C5689529_Verify_Terrain_RigidBody_Collider_Mesh/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689529_Verify_Terrain_RigidBody_Collider_Mesh/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689529_Verify_Terrain_RigidBody_Collider_Mesh/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5689531_Warning_TerrainSliceTerrainComponent/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5689531_Warning_TerrainSliceTerrainComponent/leveldata/Heightmap.dat deleted file mode 100644 index 250572b0e2..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689531_Warning_TerrainSliceTerrainComponent/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f97dab20304bc260b744a92a880f99e78ec720796b99910b566bf59b0a1fc96f -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5689531_Warning_TerrainSliceTerrainComponent/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5689531_Warning_TerrainSliceTerrainComponent/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5689531_Warning_TerrainSliceTerrainComponent/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5932040_ForceRegion_CubeExertsWorldForce/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5932040_ForceRegion_CubeExertsWorldForce/leveldata/Heightmap.dat deleted file mode 100644 index 9c45acebe4..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932040_ForceRegion_CubeExertsWorldForce/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8067bc2add439a73dc9e2f1971e084e7193359b2b1f48883ced366814dccee53 -size 272968 diff --git a/AutomatedTesting/Levels/Physics/C5932040_ForceRegion_CubeExertsWorldForce/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5932040_ForceRegion_CubeExertsWorldForce/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932040_ForceRegion_CubeExertsWorldForce/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies/leveldata/Heightmap.dat deleted file mode 100644 index b01cafea8e..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6401692e054f1c4e98be464da6ba46602a54cffa87dedbe7f93f04e5f4c73b38 -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5932042_PhysxForceRegion_LinearDamping/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5932042_PhysxForceRegion_LinearDamping/leveldata/Heightmap.dat deleted file mode 100644 index fd12b3bcf3..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932042_PhysxForceRegion_LinearDamping/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:505c3eb789d6033663199730a13290bb5e6c8a64997612bedcf468611b1db84c -size 1088935 diff --git a/AutomatedTesting/Levels/Physics/C5932042_PhysxForceRegion_LinearDamping/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5932042_PhysxForceRegion_LinearDamping/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932042_PhysxForceRegion_LinearDamping/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5932043_ForceRegion_SimpleDragOnRigidBody/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5932043_ForceRegion_SimpleDragOnRigidBody/leveldata/Heightmap.dat deleted file mode 100644 index de654e5c66..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932043_ForceRegion_SimpleDragOnRigidBody/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9094ed2eb22b00e83d2b38400295a1b0499a73f7ce69f08c91476aa53f52d55f -size 1088936 diff --git a/AutomatedTesting/Levels/Physics/C5932043_ForceRegion_SimpleDragOnRigidBody/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5932043_ForceRegion_SimpleDragOnRigidBody/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932043_ForceRegion_SimpleDragOnRigidBody/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5932044_PhysX_ForceRegion_PointForceOnRigidBodies/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5932044_PhysX_ForceRegion_PointForceOnRigidBodies/leveldata/Heightmap.dat deleted file mode 100644 index cd96b125c5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932044_PhysX_ForceRegion_PointForceOnRigidBodies/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bdfb853736f89ba7370e1d84d14fbdf2bcd0e7947c8ac1d8ef5c974d174805c5 -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C5932044_PhysX_ForceRegion_PointForceOnRigidBodies/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5932044_PhysX_ForceRegion_PointForceOnRigidBodies/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932044_PhysX_ForceRegion_PointForceOnRigidBodies/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5932045_ForceRegion_Spline/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5932045_ForceRegion_Spline/leveldata/Heightmap.dat deleted file mode 100644 index 88230ecde3..0000000000 --- a/AutomatedTesting/Levels/Physics/C5932045_ForceRegion_Spline/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89c8b97f06c2022d93cd6e8998230dc4e4c984bf915f901c64494c31f43ce361 -size 8389601 diff --git a/AutomatedTesting/Levels/Physics/C5959759_RigidBody_ForceRegionSpherePointForce/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959759_RigidBody_ForceRegionSpherePointForce/leveldata/Heightmap.dat deleted file mode 100644 index f1203cbb38..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959759_RigidBody_ForceRegionSpherePointForce/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b1859b510aefeeef4b56773cb6b9534a8fe9822da42dace360e1275774a4b015 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C5959759_RigidBody_ForceRegionSpherePointForce/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959759_RigidBody_ForceRegionSpherePointForce/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959759_RigidBody_ForceRegionSpherePointForce/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5959760_PhysxForceRegion_PointForceExertion/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959760_PhysxForceRegion_PointForceExertion/leveldata/Heightmap.dat deleted file mode 100644 index c38fc24151..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959760_PhysxForceRegion_PointForceExertion/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fd1933b2146650738286a96252a373272fa193ad584cc3fcef1fb63e563f69d5 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5959760_PhysxForceRegion_PointForceExertion/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959760_PhysxForceRegion_PointForceExertion/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959760_PhysxForceRegion_PointForceExertion/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5959761_ForceRegion_ExertsPointForce_Sedan/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959761_ForceRegion_ExertsPointForce_Sedan/leveldata/Heightmap.dat deleted file mode 100644 index f4d421c60f..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959761_ForceRegion_ExertsPointForce_Sedan/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c1423ef445819bd6fc431636a33c134c6c233cbe0f691590ff51f25a72a4e65 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C5959761_ForceRegion_ExertsPointForce_Sedan/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959761_ForceRegion_ExertsPointForce_Sedan/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959761_ForceRegion_ExertsPointForce_Sedan/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5959763_ForceRegion_ForceRegionImpulsesCube/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959763_ForceRegion_ForceRegionImpulsesCube/leveldata/Heightmap.dat deleted file mode 100644 index 8c77677ddc..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959763_ForceRegion_ForceRegionImpulsesCube/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:41e755a0673feebe74637cb21c48f57cd3f4ddd0bbfe1db56bb0ab425e47e9d7 -size 17407818 diff --git a/AutomatedTesting/Levels/Physics/C5959763_ForceRegion_ForceRegionImpulsesCube/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959763_ForceRegion_ForceRegionImpulsesCube/terrain/cover.ctc deleted file mode 100644 index 3b21b4fd38..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959763_ForceRegion_ForceRegionImpulsesCube/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c312bc0963da8a266a385bc912f0e6549b3cf6e6c7c45b04ae7cd17cdebcbb35 -size 89393864 diff --git a/AutomatedTesting/Levels/Physics/C5959764_ForceRegion_ForceRegionImpulsesCapsule/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959764_ForceRegion_ForceRegionImpulsesCapsule/leveldata/Heightmap.dat deleted file mode 100644 index 8c77677ddc..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959764_ForceRegion_ForceRegionImpulsesCapsule/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:41e755a0673feebe74637cb21c48f57cd3f4ddd0bbfe1db56bb0ab425e47e9d7 -size 17407818 diff --git a/AutomatedTesting/Levels/Physics/C5959764_ForceRegion_ForceRegionImpulsesCapsule/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959764_ForceRegion_ForceRegionImpulsesCapsule/terrain/cover.ctc deleted file mode 100644 index 3b21b4fd38..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959764_ForceRegion_ForceRegionImpulsesCapsule/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c312bc0963da8a266a385bc912f0e6549b3cf6e6c7c45b04ae7cd17cdebcbb35 -size 89393864 diff --git a/AutomatedTesting/Levels/Physics/C5959765_ForceRegion_AssetGetsImpulsed/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959765_ForceRegion_AssetGetsImpulsed/leveldata/Heightmap.dat deleted file mode 100644 index 24e3dc92aa..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959765_ForceRegion_AssetGetsImpulsed/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1e38ef80eb942863c2d7c449da1cb94e5e6c3ccf42efed74f51f5d2bf3927410 -size 1088936 diff --git a/AutomatedTesting/Levels/Physics/C5959765_ForceRegion_AssetGetsImpulsed/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959765_ForceRegion_AssetGetsImpulsed/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959765_ForceRegion_AssetGetsImpulsed/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5959808_ForceRegion_PositionOffset/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959808_ForceRegion_PositionOffset/leveldata/Heightmap.dat deleted file mode 100644 index c93a3463c5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959808_ForceRegion_PositionOffset/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:978fdf9b771a3e0ca49fedeeb8c40efddb65d0f84bdf5cd93dfe07fcf9f5c2ba -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C5959808_ForceRegion_PositionOffset/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959808_ForceRegion_PositionOffset/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959808_ForceRegion_PositionOffset/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5959809_ForceRegion_RotationalOffset/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959809_ForceRegion_RotationalOffset/leveldata/Heightmap.dat deleted file mode 100644 index 7bea75cd29..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959809_ForceRegion_RotationalOffset/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3f82438d7e79d1c519bc46520a138b262358a3b2f930fa85335ba8123cbeac64 -size 272903 diff --git a/AutomatedTesting/Levels/Physics/C5959809_ForceRegion_RotationalOffset/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959809_ForceRegion_RotationalOffset/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959809_ForceRegion_RotationalOffset/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5959810_ForceRegion_ForceRegionCombinesForces/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5959810_ForceRegion_ForceRegionCombinesForces/leveldata/Heightmap.dat deleted file mode 100644 index 8656f8dc82..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959810_ForceRegion_ForceRegionCombinesForces/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:887a277eb6c0394aebf2c1b45bb97c308fdae9b77d5a2d4c435459226ea43315 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C5959810_ForceRegion_ForceRegionCombinesForces/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5959810_ForceRegion_ForceRegionCombinesForces/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5959810_ForceRegion_ForceRegionCombinesForces/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody/leveldata/Heightmap.dat deleted file mode 100644 index a28794f59b..0000000000 --- a/AutomatedTesting/Levels/Physics/C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bd2bb7c49590bdcb95a536e6bb307a6ce4f3290d5575074c71af9929bd815d4b -size 273032 diff --git a/AutomatedTesting/Levels/Physics/C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C5968760_ForceRegion_CheckNetForceChange/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C5968760_ForceRegion_CheckNetForceChange/leveldata/Heightmap.dat deleted file mode 100644 index 4cc409be9e..0000000000 --- a/AutomatedTesting/Levels/Physics/C5968760_ForceRegion_CheckNetForceChange/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0a0ae4b840bc786cde6baaa104b4cd307559ae669191c1193dcc16e1900345f4 -size 17401625 diff --git a/AutomatedTesting/Levels/Physics/C5968760_ForceRegion_CheckNetForceChange/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C5968760_ForceRegion_CheckNetForceChange/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C5968760_ForceRegion_CheckNetForceChange/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_1024x1024_32m/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_1024x1024_32m/leveldata/Heightmap.dat deleted file mode 100644 index f6a994dfc8..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_1024x1024_32m/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8fc79df6e76e7a1b78e868a1b38270a20c4f6f01bf75d8f041ed31b54bcd0f18 -size 17407883 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_1024x1024_32m/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_1024x1024_32m/terrain/cover.ctc deleted file mode 100644 index 3b21b4fd38..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_1024x1024_32m/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c312bc0963da8a266a385bc912f0e6549b3cf6e6c7c45b04ae7cd17cdebcbb35 -size 89393864 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_128x128_1m/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_128x128_1m/leveldata/Heightmap.dat deleted file mode 100644 index bd76461f43..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_128x128_1m/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:82ff0215eec3b56e30c98552229873f9c8171780f064514904fc9c2dc6a06ec5 -size 272968 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_128x128_1m/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_128x128_1m/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_128x128_1m/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_4096x4096_16m/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_4096x4096_16m/leveldata/Heightmap.dat deleted file mode 100644 index fc4176f1d7..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_4096x4096_16m/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1d05be295505fac28ccf838b2693cb8d9728831b7ff755e39f924b3d553c0d33 -size 278507435 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_4096x4096_16m/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_4096x4096_16m/terrain/cover.ctc deleted file mode 100644 index 3b21b4fd38..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_4096x4096_16m/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c312bc0963da8a266a385bc912f0e6549b3cf6e6c7c45b04ae7cd17cdebcbb35 -size 89393864 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_512x512_2m/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_512x512_2m/leveldata/Heightmap.dat deleted file mode 100644 index e300eeda72..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_512x512_2m/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:01b31f5b7a47a98458a8bc41564ca044e1290aaaf03aab45930cbb3665cdcdb2 -size 4352744 diff --git a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_512x512_2m/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_512x512_2m/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C6032082_Terrain_MultipleResolutionsValid_512x512_2m/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C6090546_ForceRegion_SliceFileInstantiates/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090546_ForceRegion_SliceFileInstantiates/leveldata/Heightmap.dat deleted file mode 100644 index 758aa5bc34..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090546_ForceRegion_SliceFileInstantiates/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2e8e198c676660fb0ee41dc26a819a446d22e8191b656c5cf1938c8e84662eb5 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C6090546_ForceRegion_SliceFileInstantiates/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6090546_ForceRegion_SliceFileInstantiates/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090546_ForceRegion_SliceFileInstantiates/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C6090547_ForceRegion_ParentChildForceRegions/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090547_ForceRegion_ParentChildForceRegions/leveldata/Heightmap.dat deleted file mode 100644 index 46362b012e..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090547_ForceRegion_ParentChildForceRegions/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f3e14eb70dd43e5de38f7bf7f6289662a5cec5e3a9b0f4491c9885cf7794b4f -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C6090547_ForceRegion_ParentChildForceRegions/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6090547_ForceRegion_ParentChildForceRegions/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090547_ForceRegion_ParentChildForceRegions/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C6090550_ForceRegion_WorldSpaceForceNegative/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090550_ForceRegion_WorldSpaceForceNegative/leveldata/Heightmap.dat deleted file mode 100644 index bb848da4ed..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090550_ForceRegion_WorldSpaceForceNegative/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:37ea00154e4dcab65e12ee8ca194cb66838bb82529431f4d091cd9c2c79156ed -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C6090550_ForceRegion_WorldSpaceForceNegative/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6090550_ForceRegion_WorldSpaceForceNegative/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090550_ForceRegion_WorldSpaceForceNegative/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C6090551_ForceRegion_LocalSpaceForceNegative/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090551_ForceRegion_LocalSpaceForceNegative/leveldata/Heightmap.dat deleted file mode 100644 index b9ccb9a4d9..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090551_ForceRegion_LocalSpaceForceNegative/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5bd283a1f7d6773603be60d0f68b5dd638ad67af600b77a34ce0c0313c2a9ea -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C6090551_ForceRegion_LocalSpaceForceNegative/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6090551_ForceRegion_LocalSpaceForceNegative/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090551_ForceRegion_LocalSpaceForceNegative/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C6090552_ForceRegion_LinearDampingNegative/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090552_ForceRegion_LinearDampingNegative/leveldata/Heightmap.dat deleted file mode 100644 index adc6d8cd8a..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090552_ForceRegion_LinearDampingNegative/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43ca971f0dc9e3a742df0c9b3823ba91893509d46cd58394a44b0cdb23398a7f -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C6090552_ForceRegion_LinearDampingNegative/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6090552_ForceRegion_LinearDampingNegative/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090552_ForceRegion_LinearDampingNegative/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C6090553_ForceRegion_SimpleDragForceOnRigidBodies/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090553_ForceRegion_SimpleDragForceOnRigidBodies/leveldata/Heightmap.dat deleted file mode 100644 index 2819a15ca8..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090553_ForceRegion_SimpleDragForceOnRigidBodies/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d6da98fed444511cfbf7c816f58644647997ffae6ad95e00fc047be7d2e091aa -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/C6090553_ForceRegion_SimpleDragForceOnRigidBodies/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6090553_ForceRegion_SimpleDragForceOnRigidBodies/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090553_ForceRegion_SimpleDragForceOnRigidBodies/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C6090554_ForceRegion_PointForceNegative/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090554_ForceRegion_PointForceNegative/leveldata/Heightmap.dat deleted file mode 100644 index d4569021f5..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090554_ForceRegion_PointForceNegative/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:111764017407ee2fd7e2be64cd121f8347dc9d706a7964f381f9bcd351a33e30 -size 272967 diff --git a/AutomatedTesting/Levels/Physics/C6090554_ForceRegion_PointForceNegative/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6090554_ForceRegion_PointForceNegative/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090554_ForceRegion_PointForceNegative/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/Physics/C6090555_ForceRegion_SplineFollowOnRigidBodies/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6090555_ForceRegion_SplineFollowOnRigidBodies/leveldata/Heightmap.dat deleted file mode 100644 index 88230ecde3..0000000000 --- a/AutomatedTesting/Levels/Physics/C6090555_ForceRegion_SplineFollowOnRigidBodies/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:89c8b97f06c2022d93cd6e8998230dc4e4c984bf915f901c64494c31f43ce361 -size 8389601 diff --git a/AutomatedTesting/Levels/Physics/C6131473_StaticSlice_OnDynamicSliceSpawn/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6131473_StaticSlice_OnDynamicSliceSpawn/leveldata/Heightmap.dat deleted file mode 100644 index 5b2f135a91..0000000000 --- a/AutomatedTesting/Levels/Physics/C6131473_StaticSlice_OnDynamicSliceSpawn/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c9729210c30daa9177bd8457f2780ed77bae8de6cd15a62bff3a07c52bb603b4 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C6131473_StaticSlice_OnDynamicSliceSpawn/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6131473_StaticSlice_OnDynamicSliceSpawn/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C6131473_StaticSlice_OnDynamicSliceSpawn/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C6224408_ScriptCanvas_EntitySpawn/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6224408_ScriptCanvas_EntitySpawn/leveldata/Heightmap.dat deleted file mode 100644 index f54f95b8d2..0000000000 --- a/AutomatedTesting/Levels/Physics/C6224408_ScriptCanvas_EntitySpawn/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5f28abec553b0e796914564800808ea83c15373b89a72e77c06beb1b79118c3 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C6224408_ScriptCanvas_EntitySpawn/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6224408_ScriptCanvas_EntitySpawn/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C6224408_ScriptCanvas_EntitySpawn/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C6274125_ScriptCanvas_TriggerEvents/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6274125_ScriptCanvas_TriggerEvents/leveldata/Heightmap.dat deleted file mode 100644 index edf807fd0c..0000000000 --- a/AutomatedTesting/Levels/Physics/C6274125_ScriptCanvas_TriggerEvents/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0dba21e478e2062ae68a2309889fa847df1c93306fa92e23989ab99d1a402bee -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/C6274125_ScriptCanvas_TriggerEvents/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6274125_ScriptCanvas_TriggerEvents/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C6274125_ScriptCanvas_TriggerEvents/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/C6321601_Force_HighValuesDirectionAxes/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/C6321601_Force_HighValuesDirectionAxes/leveldata/Heightmap.dat deleted file mode 100644 index 1b7661ff99..0000000000 --- a/AutomatedTesting/Levels/Physics/C6321601_Force_HighValuesDirectionAxes/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a01c0912336c4a1484231d245e4f8d49189e9f6295f1644672bd2443c2504d75 -size 17408042 diff --git a/AutomatedTesting/Levels/Physics/C6321601_Force_HighValuesDirectionAxes/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/C6321601_Force_HighValuesDirectionAxes/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/C6321601_Force_HighValuesDirectionAxes/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/EnablingGravityWorks/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/EnablingGravityWorks/leveldata/Heightmap.dat deleted file mode 100644 index 29cd5e7a62..0000000000 --- a/AutomatedTesting/Levels/Physics/EnablingGravityWorks/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:296d54a50af0194ce6cfc2dbfc20b45f6ca0b22e131fbbc7efb2fa71819e0125 -size 17407722 diff --git a/AutomatedTesting/Levels/Physics/EnablingGravityWorks/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/EnablingGravityWorks/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/EnablingGravityWorks/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Physics/NameNode_Prints/LevelData/Heightmap.dat b/AutomatedTesting/Levels/Physics/NameNode_Prints/LevelData/Heightmap.dat deleted file mode 100644 index f3e0ef3b30..0000000000 --- a/AutomatedTesting/Levels/Physics/NameNode_Prints/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bc68622cb0490202b77ef121e6477cba595563fe48b388e3656e5f83d75326ab -size 17407508 diff --git a/AutomatedTesting/Levels/Physics/Physmaterial_Editor_Test/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Physics/Physmaterial_Editor_Test/leveldata/Heightmap.dat deleted file mode 100644 index d3415a29e8..0000000000 --- a/AutomatedTesting/Levels/Physics/Physmaterial_Editor_Test/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02166a294304ad1b49e0657612066fad67f8c6a534ff29391e096d5f7f02a530 -size 17407562 diff --git a/AutomatedTesting/Levels/Physics/Physmaterial_Editor_Test/terrain/cover.ctc b/AutomatedTesting/Levels/Physics/Physmaterial_Editor_Test/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Physics/Physmaterial_Editor_Test/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab b/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab new file mode 100644 index 0000000000..0776f25935 --- /dev/null +++ b/AutomatedTesting/Levels/Prefab/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab @@ -0,0 +1,171 @@ +{ + "Source": "Levels/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab", + "ContainerEntity": { + "Id": "Entity_[403811863694]", + "Name": "Level", + "Components": { + "Component_[10582285743525614098]": { + "$type": "SelectionComponent", + "Id": 10582285743525614098 + }, + "Component_[12253783095375428046]": { + "$type": "EditorInspectorComponent", + "Id": 12253783095375428046 + }, + "Component_[13764860261821571747]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 13764860261821571747, + "Parent Entity": "" + }, + "Component_[15844324401733835865]": { + "$type": "EditorEntitySortComponent", + "Id": 15844324401733835865 + }, + "Component_[1605854641405361768]": { + "$type": "EditorLockComponent", + "Id": 1605854641405361768 + }, + "Component_[17698173984524983803]": { + "$type": "EditorOnlyEntityComponent", + "Id": 17698173984524983803 + }, + "Component_[3444251662966224826]": { + "$type": "EditorPendingCompositionComponent", + "Id": 3444251662966224826 + }, + "Component_[4231768881195179982]": { + "$type": "EditorVisibilityComponent", + "Id": 4231768881195179982 + }, + "Component_[4722360315410084479]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 4722360315410084479 + }, + "Component_[7614719100624882952]": { + "$type": "EditorPrefabComponent", + "Id": 7614719100624882952 + }, + "Component_[9585901769691795481]": { + "$type": "EditorEntityIconComponent", + "Id": 9585901769691795481 + } + }, + "IsDependencyReady": true + }, + "Entities": { + "Entity_[438171602062]": { + "Id": "Entity_[438171602062]", + "Name": "EntityWithPxCollider", + "Components": { + "Component_[11161653124805884473]": { + "$type": "EditorPendingCompositionComponent", + "Id": 11161653124805884473 + }, + "Component_[13116773315299882093]": { + "$type": "EditorOnlyEntityComponent", + "Id": 13116773315299882093 + }, + "Component_[15820915681461536711]": { + "$type": "EditorVisibilityComponent", + "Id": 15820915681461536711 + }, + "Component_[2222061938345834243]": { + "$type": "SelectionComponent", + "Id": 2222061938345834243 + }, + "Component_[3861913165076405600]": { + "$type": "EditorEntitySortComponent", + "Id": 3861913165076405600 + }, + "Component_[7118587015611303204]": { + "$type": "EditorLockComponent", + "Id": 7118587015611303204 + }, + "Component_[7751174327125555504]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7751174327125555504 + }, + "Component_[8304730147756374057]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 8304730147756374057, + "Parent Entity": "Entity_[403811863694]", + "Transform Data": { + "Translate": [ + 0.0, + 20.0, + 34.0 + ] + } + }, + "Component_[8866353210615920259]": { + "$type": "EditorEntityIconComponent", + "Id": 8866353210615920259 + }, + "Component_[8988181228601932779]": { + "$type": "EditorInspectorComponent", + "Id": 8988181228601932779 + }, + "Component_[7103333782129541775]": { + "$type": "EditorColliderComponent", + "Id": 7103333782129541775 + } + }, + "IsDependencyReady": true + }, + "Entity_[532660882574]": { + "Id": "Entity_[532660882574]", + "Name": "EmptyEntity", + "Components": { + "Component_[16437814751543997955]": { + "$type": "EditorEntitySortComponent", + "Id": 16437814751543997955 + }, + "Component_[16751517102089557119]": { + "$type": "EditorPendingCompositionComponent", + "Id": 16751517102089557119 + }, + "Component_[16773275259304187949]": { + "$type": "EditorInspectorComponent", + "Id": 16773275259304187949 + }, + "Component_[17283539636910567200]": { + "$type": "SelectionComponent", + "Id": 17283539636910567200 + }, + "Component_[250004123617033400]": { + "$type": "EditorLockComponent", + "Id": 250004123617033400 + }, + "Component_[2791138963683667073]": { + "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent", + "Id": 2791138963683667073, + "Parent Entity": "Entity_[403811863694]", + "Transform Data": { + "Translate": [ + 10.0, + 20.0, + 30.0 + ] + } + }, + "Component_[3296942400051129145]": { + "$type": "EditorEntityIconComponent", + "Id": 3296942400051129145 + }, + "Component_[3422076964671342434]": { + "$type": "EditorOnlyEntityComponent", + "Id": 3422076964671342434 + }, + "Component_[3431895414183121731]": { + "$type": "EditorVisibilityComponent", + "Id": 3431895414183121731 + }, + "Component_[7072085777705148766]": { + "$type": "EditorDisabledCompositionComponent", + "Id": 7072085777705148766 + } + }, + "IsDependencyReady": true + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Levels/Simple/Simple.ly b/AutomatedTesting/Levels/Simple/Simple.ly index 0148ee6e34..0a063bf8f8 100644 --- a/AutomatedTesting/Levels/Simple/Simple.ly +++ b/AutomatedTesting/Levels/Simple/Simple.ly @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:804193a2afd68cd1e6bec8155ea11400566f2941fbd6eb0c324839ebcd10192d -size 8492 +oid sha256:302d6172156e8ed665e44e206d81f54f1b0f1008d73327300ea92f8c1159780b +size 11820 diff --git a/AutomatedTesting/Levels/Simple/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Simple/leveldata/Heightmap.dat deleted file mode 100644 index a115a949ea..0000000000 --- a/AutomatedTesting/Levels/Simple/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f5bed6147984ab47380f219627d57d0d81fee47240ee4f9f22eb36ad891cca8 -size 17407722 diff --git a/AutomatedTesting/Levels/Simple/terrain/cover.ctc b/AutomatedTesting/Levels/Simple/terrain/cover.ctc deleted file mode 100644 index 758d8ecc7c..0000000000 --- a/AutomatedTesting/Levels/Simple/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:56ababffe6020616ccd87fff0cc5968fc5b15d6f7812ef1f71457544deda53e5 -size 1310792 diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Heightmap.dat b/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Heightmap.dat deleted file mode 100644 index f4b5b6a7ec..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:33755cbdc3e12d51ebaff02a97ff83632b59d04e15c935e72c819f97a85313ee -size 17407849 diff --git a/AutomatedTesting/Levels/TestDependenciesLevel/terrain/cover.ctc b/AutomatedTesting/Levels/TestDependenciesLevel/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/TestDependenciesLevel/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Utils/Tracer_ErrorEntity/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Utils/Tracer_ErrorEntity/leveldata/Heightmap.dat deleted file mode 100644 index 92979fc15b..0000000000 --- a/AutomatedTesting/Levels/Utils/Tracer_ErrorEntity/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ec97cba81a1332d3ddbf7e792a037b481f98890351ff997eb4c14df608063bf -size 17407612 diff --git a/AutomatedTesting/Levels/Utils/Tracer_ErrorEntity/terrain/cover.ctc b/AutomatedTesting/Levels/Utils/Tracer_ErrorEntity/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Utils/Tracer_ErrorEntity/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/Utils/Tracer_WarningEntity/leveldata/Heightmap.dat b/AutomatedTesting/Levels/Utils/Tracer_WarningEntity/leveldata/Heightmap.dat deleted file mode 100644 index d08880d3f7..0000000000 --- a/AutomatedTesting/Levels/Utils/Tracer_WarningEntity/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4a511fb77ac358234d93b9504d7c4fab728d703599e565c11de82423b6861d7 -size 17407562 diff --git a/AutomatedTesting/Levels/Utils/Tracer_WarningEntity/terrain/cover.ctc b/AutomatedTesting/Levels/Utils/Tracer_WarningEntity/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/Utils/Tracer_WarningEntity/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/WaterSample/WaterSample.ly b/AutomatedTesting/Levels/WaterSample/WaterSample.ly deleted file mode 100644 index b1899f3710..0000000000 --- a/AutomatedTesting/Levels/WaterSample/WaterSample.ly +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d49aceca5ad4e0b9f46c8127afb5c53b68aa30272950b1abd66fba310977ff0c -size 15032 diff --git a/AutomatedTesting/Levels/WaterSample/filelist.xml b/AutomatedTesting/Levels/WaterSample/filelist.xml deleted file mode 100644 index d14b2fdaf2..0000000000 --- a/AutomatedTesting/Levels/WaterSample/filelist.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/AutomatedTesting/Levels/WaterSample/halfsphere.cgf b/AutomatedTesting/Levels/WaterSample/halfsphere.cgf deleted file mode 100644 index 4426d8a232..0000000000 --- a/AutomatedTesting/Levels/WaterSample/halfsphere.cgf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5f221acd847ec8a15e1333a5163d6d0fd886b8eda46fa7b133f76ddbf1d11216 -size 41472 diff --git a/AutomatedTesting/Levels/WaterSample/halfsphere2.cgf b/AutomatedTesting/Levels/WaterSample/halfsphere2.cgf deleted file mode 100644 index c776ff68b8..0000000000 --- a/AutomatedTesting/Levels/WaterSample/halfsphere2.cgf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c8e5dcfbe65fd2fd8ea29a38a96e703683c544fd42b9424857b1df3718c7775a -size 41472 diff --git a/AutomatedTesting/Levels/WaterSample/level.pak b/AutomatedTesting/Levels/WaterSample/level.pak deleted file mode 100644 index 1753ef4b93..0000000000 --- a/AutomatedTesting/Levels/WaterSample/level.pak +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0378911c27933302042550d5a031a5f9104296162edc2b21e44893f1b8cff969 -size 44124 diff --git a/AutomatedTesting/Levels/WaterSample/leveldata/Environment.xml b/AutomatedTesting/Levels/WaterSample/leveldata/Environment.xml deleted file mode 100644 index 6a95c631bb..0000000000 --- a/AutomatedTesting/Levels/WaterSample/leveldata/Environment.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/WaterSample/leveldata/Heightmap.dat b/AutomatedTesting/Levels/WaterSample/leveldata/Heightmap.dat deleted file mode 100644 index faa167e7b9..0000000000 --- a/AutomatedTesting/Levels/WaterSample/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2d279ddb3735d78930a121c8ee861608feadc5d808ec816bf3dc5d577a7f80e6 -size 17409012 diff --git a/AutomatedTesting/Levels/WaterSample/leveldata/TerrainTexture.xml b/AutomatedTesting/Levels/WaterSample/leveldata/TerrainTexture.xml deleted file mode 100644 index 21741afe52..0000000000 --- a/AutomatedTesting/Levels/WaterSample/leveldata/TerrainTexture.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/AutomatedTesting/Levels/WaterSample/leveldata/TimeOfDay.xml b/AutomatedTesting/Levels/WaterSample/leveldata/TimeOfDay.xml deleted file mode 100644 index 60ad405904..0000000000 --- a/AutomatedTesting/Levels/WaterSample/leveldata/TimeOfDay.xml +++ /dev/null @@ -1,356 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/AutomatedTesting/Levels/WaterSample/leveldata/VegetationMap.dat b/AutomatedTesting/Levels/WaterSample/leveldata/VegetationMap.dat deleted file mode 100644 index dce5631cd0..0000000000 --- a/AutomatedTesting/Levels/WaterSample/leveldata/VegetationMap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e6a5435c928079b27796f6b202bbc2623e7e454244ddc099a3cadf33b7cb9e9 -size 63 diff --git a/AutomatedTesting/Levels/WaterSample/pool.cgf b/AutomatedTesting/Levels/WaterSample/pool.cgf deleted file mode 100644 index 04bec52a62..0000000000 --- a/AutomatedTesting/Levels/WaterSample/pool.cgf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:12ca8f1942331abde4d58724aea22609c8d7951cc415afa6e5f1c550a14e67b0 -size 363624 diff --git a/AutomatedTesting/Levels/WaterSample/pool2.cgf b/AutomatedTesting/Levels/WaterSample/pool2.cgf deleted file mode 100644 index 204306f8a8..0000000000 --- a/AutomatedTesting/Levels/WaterSample/pool2.cgf +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5b525a410730d84c0b3e97396d392e1e72f4b894742ddef3de4ede5542b0f8e -size 86148 diff --git a/AutomatedTesting/Levels/WaterSample/tags.txt b/AutomatedTesting/Levels/WaterSample/tags.txt deleted file mode 100644 index 0d6c1880e7..0000000000 --- a/AutomatedTesting/Levels/WaterSample/tags.txt +++ /dev/null @@ -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 diff --git a/AutomatedTesting/Levels/WaterSample/terrain/cover.ctc b/AutomatedTesting/Levels/WaterSample/terrain/cover.ctc deleted file mode 100644 index 0823b8a456..0000000000 --- a/AutomatedTesting/Levels/WaterSample/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:442fe75f06b84d877259b986b69f17f8bb3719f95e87c100ef136a12440706c0 -size 1310792 diff --git a/AutomatedTesting/Levels/WaterSample/terraintexture.pak b/AutomatedTesting/Levels/WaterSample/terraintexture.pak deleted file mode 100644 index fe3604a050..0000000000 --- a/AutomatedTesting/Levels/WaterSample/terraintexture.pak +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8739c76e681f900923b900c9df0ef75cf421d39cabb54650c4b9ad19b6a76d85 -size 22 diff --git a/AutomatedTesting/Levels/WaterSample/woodland_canyon_river.mtl b/AutomatedTesting/Levels/WaterSample/woodland_canyon_river.mtl deleted file mode 100644 index 4548bca421..0000000000 --- a/AutomatedTesting/Levels/WaterSample/woodland_canyon_river.mtl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/AutomatedTesting/Levels/WhiteBox/EmptyLevel/LevelData/Heightmap.dat b/AutomatedTesting/Levels/WhiteBox/EmptyLevel/LevelData/Heightmap.dat deleted file mode 100644 index 29e3419f1f..0000000000 --- a/AutomatedTesting/Levels/WhiteBox/EmptyLevel/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:516a3c2be23cd39ece7cab752845008d2b0940327338667d99f8a9dc934955e7 -size 8389548 diff --git a/AutomatedTesting/Levels/auto_test/LevelData/Heightmap.dat b/AutomatedTesting/Levels/auto_test/LevelData/Heightmap.dat deleted file mode 100644 index c45e9c55d6..0000000000 --- a/AutomatedTesting/Levels/auto_test/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:11035ee2ffa8b8e05694d1e9911bc187ce8d11d44ec21d2e85256348208888cd -size 17407568 diff --git a/AutomatedTesting/Levels/auto_test/terrain/cover.ctc b/AutomatedTesting/Levels/auto_test/terrain/cover.ctc deleted file mode 100644 index 5c869c6533..0000000000 --- a/AutomatedTesting/Levels/auto_test/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdab340ad6c6dc6c1167e31afa061684be083360fc4108fa9f1fa4b15fe95d8c -size 1310792 diff --git a/AutomatedTesting/Levels/ocean_component/LevelData/Heightmap.dat b/AutomatedTesting/Levels/ocean_component/LevelData/Heightmap.dat deleted file mode 100644 index d8cc5b2c0d..0000000000 --- a/AutomatedTesting/Levels/ocean_component/LevelData/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dd639fcd1ed23c191ac037b33dc3b592a5a2350d940851ec2206d391b1988a8c -size 272966 diff --git a/AutomatedTesting/Levels/ocean_component/terrain/cover.ctc b/AutomatedTesting/Levels/ocean_component/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/ocean_component/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Levels/ocean_trackview/leveldata/Heightmap.dat b/AutomatedTesting/Levels/ocean_trackview/leveldata/Heightmap.dat deleted file mode 100644 index 6e54935add..0000000000 --- a/AutomatedTesting/Levels/ocean_trackview/leveldata/Heightmap.dat +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a5a13103dc7a070193a74e362daea1d152b8c50031db93f9a7689a9a5c8137c2 -size 272903 diff --git a/AutomatedTesting/Levels/ocean_trackview/terrain/cover.ctc b/AutomatedTesting/Levels/ocean_trackview/terrain/cover.ctc deleted file mode 100644 index 78c2ab6ed5..0000000000 --- a/AutomatedTesting/Levels/ocean_trackview/terrain/cover.ctc +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bb4e2ab7876994431f3e6e78a004ea5718e057077b37db14ea8a52637338be -size 262184 diff --git a/AutomatedTesting/Objects/LumberTank/ProxyGray_ddna.tif.exportsettings b/AutomatedTesting/Objects/LumberTank/ProxyGray_ddna.tif.exportsettings index 013c774e9e..a4e1a9a3c5 100644 --- a/AutomatedTesting/Objects/LumberTank/ProxyGray_ddna.tif.exportsettings +++ b/AutomatedTesting/Objects/LumberTank/ProxyGray_ddna.tif.exportsettings @@ -1 +1 @@ -/autooptimizefile=0 /M=50,50,0,50,50,50 /preset=NormalsWithSmoothness /reduce="es3:1,ios:1,osx_gl:0,pc:0,provo:0" \ No newline at end of file +/autooptimizefile=0 /M=50,50,0,50,50,50 /preset=NormalsWithSmoothness /reduce="android:1,ios:1,mac:0,pc:0,provo:0" \ No newline at end of file diff --git a/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override b/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override index 9fa5e26768..696a0a74da 100644 --- a/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override +++ b/AutomatedTesting/Registry/C3510644_Collider_CollisionGroups.setreg_override @@ -119,6 +119,9 @@ ] } }, + "DefaultMaterial": { + "SurfaceType": "Default_1" + }, "MaterialLibrary": { "assetId": { "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" diff --git a/AutomatedTesting/Registry/C4044459_Material_DynamicFriction.setreg_override b/AutomatedTesting/Registry/C4044459_Material_DynamicFriction.setreg_override new file mode 100644 index 0000000000..c53b04e5c2 --- /dev/null +++ b/AutomatedTesting/Registry/C4044459_Material_DynamicFriction.setreg_override @@ -0,0 +1,118 @@ +{ + "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 + } + ] + } + }, + "DefaultMaterial": { + "SurfaceType": "Default_1" + }, + "MaterialLibrary": { + "assetId": { + "guid": "{6AA79EE4-7EC3-5717-87AE-EDD7D886FD7F}" + }, + "loadBehavior": "QueueLoad", + "assetHint": "levels/physics/c4044459_material_dynamicfriction/dynamic_friction.physmaterial" + } + } + } + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override b/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override index afbe6a9d38..5e98e08ede 100644 --- a/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override +++ b/AutomatedTesting/Registry/C4976227_Collider_NewGroup.setreg_override @@ -107,6 +107,9 @@ ] } }, + "DefaultMaterial": { + "SurfaceType": "Default_1" + }, "MaterialLibrary": { "assetId": { "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" diff --git a/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override b/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override index 9fa5e26768..696a0a74da 100644 --- a/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override +++ b/AutomatedTesting/Registry/C4976244_Collider_SameGroupSameLayerCollision.setreg_override @@ -119,6 +119,9 @@ ] } }, + "DefaultMaterial": { + "SurfaceType": "Default_1" + }, "MaterialLibrary": { "assetId": { "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" diff --git a/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override b/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override index 9fa5e26768..696a0a74da 100644 --- a/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override +++ b/AutomatedTesting/Registry/C4976245_PhysXCollider_CollisionLayerTest.setreg_override @@ -119,6 +119,9 @@ ] } }, + "DefaultMaterial": { + "SurfaceType": "Default_1" + }, "MaterialLibrary": { "assetId": { "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" diff --git a/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override b/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override index 9fa5e26768..696a0a74da 100644 --- a/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override +++ b/AutomatedTesting/Registry/C4982593_PhysXCollider_CollisionLayer.setreg_override @@ -119,6 +119,9 @@ ] } }, + "DefaultMaterial": { + "SurfaceType": "Default_1" + }, "MaterialLibrary": { "assetId": { "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" diff --git a/AutomatedTesting/Registry/authenticationProvider.setreg b/AutomatedTesting/Registry/authenticationProvider.setreg new file mode 100644 index 0000000000..c90433468c --- /dev/null +++ b/AutomatedTesting/Registry/authenticationProvider.setreg @@ -0,0 +1,5 @@ +{ + "AWS": + { + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/awscoreconfiguration.setreg b/AutomatedTesting/Registry/awscoreconfiguration.setreg new file mode 100644 index 0000000000..b7c60b0fb9 --- /dev/null +++ b/AutomatedTesting/Registry/awscoreconfiguration.setreg @@ -0,0 +1,10 @@ +{ + "Amazon": + { + "AWSCore": + { + "ProfileName": "AWSAutomationTest", + "ResourceMappingConfigFileName": "aws_resource_mappings.json" + } + } +} \ No newline at end of file diff --git a/AutomatedTesting/Registry/physxsystemconfiguration.setreg b/AutomatedTesting/Registry/physxsystemconfiguration.setreg index 02f65b685b..30e9dced44 100644 --- a/AutomatedTesting/Registry/physxsystemconfiguration.setreg +++ b/AutomatedTesting/Registry/physxsystemconfiguration.setreg @@ -101,6 +101,9 @@ ] } }, + "DefaultMaterial": { + "SurfaceType": "Default_1" + }, "MaterialLibrary": { "assetId": { "guid": "{3A055A3F-8CB7-5FEE-B437-EB365FACD0D4}" diff --git a/AutomatedTesting/ScriptCanvas/T92569006_ScriptCanvas.scriptcanvas b/AutomatedTesting/ScriptCanvas/T92569006_ScriptCanvas.scriptcanvas new file mode 100644 index 0000000000..626ee29d96 --- /dev/null +++ b/AutomatedTesting/ScriptCanvas/T92569006_ScriptCanvas.scriptcanvas @@ -0,0 +1,1952 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AutomatedTesting/Slices/1m_Cube.slice b/AutomatedTesting/Slices/1m_Cube.slice index 5ace34bd10..b31869c7fa 100644 --- a/AutomatedTesting/Slices/1m_Cube.slice +++ b/AutomatedTesting/Slices/1m_Cube.slice @@ -39,6 +39,7 @@ + @@ -61,7 +62,7 @@ - + @@ -122,38 +123,26 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + diff --git a/AutomatedTesting/TestAssets/MaxIteration31Deep.txt b/AutomatedTesting/TestAssets/MaxIteration31Deep.txt index e9e8f94715..d0ac57c883 100644 --- a/AutomatedTesting/TestAssets/MaxIteration31Deep.txt +++ b/AutomatedTesting/TestAssets/MaxIteration31Deep.txt @@ -1,3 +1,3 @@ The dependency scanner has a built in limit to how deep it will recurse when multiple results exist on the same line. This file has a single line with 10 invalid UUIDs, and an 11th valid UUID. -1: 00000000-0000-0000-0000-000000000000, 2: 00000000-0000-0000-0000-000000000000, 3: 00000000-0000-0000-0000-000000000000, 4: 00000000-0000-0000-0000-000000000000, 5: 00000000-0000-0000-0000-000000000000, 6: 00000000-0000-0000-0000-000000000000, 7: 00000000-0000-0000-0000-000000000000, 8: 00000000-0000-0000-0000-000000000000, 9: 00000000-0000-0000-0000-000000000000, 10: 00000000-0000-0000-0000-000000000000, 11: 00000000-0000-0000-0000-000000000000, 12: 00000000-0000-0000-0000-000000000000, 13: 00000000-0000-0000-0000-000000000000, 14: 00000000-0000-0000-0000-000000000000, 15: 00000000-0000-0000-0000-000000000000, 16: 00000000-0000-0000-0000-000000000000, 17: 00000000-0000-0000-0000-000000000000, 18: 00000000-0000-0000-0000-000000000000, 19: 00000000-0000-0000-0000-000000000000, 20: 00000000-0000-0000-0000-000000000000, 21: 00000000-0000-0000-0000-000000000000, 22: 00000000-0000-0000-0000-000000000000, 23: 00000000-0000-0000-0000-000000000000, 24: 00000000-0000-0000-0000-000000000000, 25: 00000000-0000-0000-0000-000000000000, 26: 00000000-0000-0000-0000-000000000000, 27: 00000000-0000-0000-0000-000000000000, 28: 00000000-0000-0000-0000-000000000000, 29: 00000000-0000-0000-0000-000000000000, 30: 00000000-0000-0000-0000-000000000000, 31 (valid UUID, game . xml): B92667DC-9F5B-5D72-A29D-99219DD9B691 +1: 00000000-0000-0000-0000-000000000000, 2: 00000000-0000-0000-0000-000000000000, 3: 00000000-0000-0000-0000-000000000000, 4: 00000000-0000-0000-0000-000000000000, 5: 00000000-0000-0000-0000-000000000000, 6: 00000000-0000-0000-0000-000000000000, 7: 00000000-0000-0000-0000-000000000000, 8: 00000000-0000-0000-0000-000000000000, 9: 00000000-0000-0000-0000-000000000000, 10: 00000000-0000-0000-0000-000000000000, 11: 00000000-0000-0000-0000-000000000000, 12: 00000000-0000-0000-0000-000000000000, 13: 00000000-0000-0000-0000-000000000000, 14: 00000000-0000-0000-0000-000000000000, 15: 00000000-0000-0000-0000-000000000000, 16: 00000000-0000-0000-0000-000000000000, 17: 00000000-0000-0000-0000-000000000000, 18: 00000000-0000-0000-0000-000000000000, 19: 00000000-0000-0000-0000-000000000000, 20: 00000000-0000-0000-0000-000000000000, 21: 00000000-0000-0000-0000-000000000000, 22: 00000000-0000-0000-0000-000000000000, 23: 00000000-0000-0000-0000-000000000000, 24: 00000000-0000-0000-0000-000000000000, 25: 00000000-0000-0000-0000-000000000000, 26: 00000000-0000-0000-0000-000000000000, 27: 00000000-0000-0000-0000-000000000000, 28: 00000000-0000-0000-0000-000000000000, 29: 00000000-0000-0000-0000-000000000000, 30: 00000000-0000-0000-0000-000000000000, 31 (valid UUID, libs / particles / milestone2particles . xml): 6BDE282B-49C9-57F7-B071-4B26579BCA9A diff --git a/AutomatedTesting/TestAssets/OnlyMatchesCorrectLengthUUIDs.txt b/AutomatedTesting/TestAssets/OnlyMatchesCorrectLengthUUIDs.txt index d49108072a..10bdaec686 100644 --- a/AutomatedTesting/TestAssets/OnlyMatchesCorrectLengthUUIDs.txt +++ b/AutomatedTesting/TestAssets/OnlyMatchesCorrectLengthUUIDs.txt @@ -1,15 +1,15 @@ The missing dependency scanner was updated to only look for substrings that are the exact length of UUIDs, separated by word boundaries. This avoids problems with very long numbers causing the scan to stall out and take a long time. -This is the UUID for dev / AutomatedTesting / Config / Game . xml with an extra UUID character at the beginning. It should not show up in scan results. -aB92667DC-9F5B-5D72-A29D-99219DD9B691 +This is the UUID for libs / particles / milestone2particles . xml with an extra UUID character at the beginning. It should not show up in scan results. +a6BDE282B49C957F7B0714B26579BCA9A -This is the UUID for dev / AutomatedTesting / Config / Editor . xml. It has an extra non-UUID character at the end. It should not show up in scan results. -06E9D6633C875400A532BCB2C0CA19D6t +This is the UUID for project . json. It has an extra non-UUID character at the end. It should not show up in scan results. +B076CDDC14DF50F4A5E97518ABB3E851t -Two UUIDs, the first invalid a6BDE282B49C957F7B0714B26579BCA9A mixed with a second valid one 58BE9DA51F1753B98CEEEEB10E63454D the same line. The second should show up in scan results. +Two UUIDs, the first invalid a1CB10C43F3245B93A294C602ADEF95F9 mixed with a second valid one D1265251CC14584AB1CECB10746A2BA0 the same line. The second should show up in scan results. -UUID for slices / MuzzleFlash . slice, after an equal sign should show up in scan results=747D31D71E62553592226173C49CF97E +UUID for TestAssets / DependencyScannerAsset . slice, after an equal sign should show up in scan results=837412DFD05F576D81AAACF360463749 -UUID for TestsAssets / WildcardScanTest1 . txt in quotes, should show up in scan results"1CB10C43-F324-5B93-A294-C602ADEF95F9" +UUID for TestAssets / WildcardScanTest2 . txt in quotes, should show up in scan results"D92C4661C8985E19BD3597CB2318CFA6" -UUID for Objects / Lumbertank_turret . cgf in curly braces, should up show in scan results{D92C4661C8985E19BD3597CB2318CFA6} +UUID for TestAssets / SelfReferenceAssetID. txt in curly braces, should up show in scan results{785A05D2483E5B43A2B992ACDAE6E938} diff --git a/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt b/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt index b2f341a15f..d3975ced7c 100644 --- a/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt +++ b/AutomatedTesting/TestAssets/RelativeProductPathsNotDependencies.txt @@ -1,25 +1,25 @@ These tests are mostly done with files that have a different extension between source and product. The source scan is done first, and will catch files in the source path. Product path searching is resolved using "endsWith" logic. -textures/_dev_purple.dds +textures/_dev_purple.tif.streamingimage Back slashes, and project name in the path -automatedtesting\textures\_dev_stucco.dds +pc/textures/_dev_stucco.tif.streamingimage Double back slashes -textures\\_dev_tan.dds +textures\\_dev_tan.tif.streamingimage Casing doesn't match -TEXTURES/_DEV_WHITE.dds +TEXTURES/_DEV_WHITE.tif.streamingimage Some files have multiple extensions, this verifies that won't trip up the scanner. -textures/_dev_yellow_light.dds.2 -Path inline textures/milestone2/ama_grey_02.dds test -Path after=textures/_dev_woodland.dds equal sign +textures/_dev_yellow_light.tif.1002.imagemipchain +Path inline textures/milestone2/ama_grey_02.tif.streamingimage test +Path after=textures/_dev_woodland.tif.streamingimage equal sign Multiple paths on one line Multiple materials/am_grass1.mtl paths materials/am_rockground.mtl on one line Path before a UUID Path materials/floor_tile.mtl before B92667DC-9F5B-5D72-A29D-99219DD9B691 a UUID Path before an asset ID -Path ui/milestone2menu.uicanvas before an 2ef92b8D044E5C278E2BB1AC0374A4E7:131072 asset ID +Path ui/milestone2menu.uicanvas before an 2ef92b8D044E5C278E2BB1AC0374A4E7:1002 asset ID Path after a UUID -Path after CEAA362B4E505BCEB827CB92EF40A50E a ui/fonts/lyshineexamples/vera.ttf UUID +Path after CEAA362B4E505BCEB827CB92EF40A50E a project.json UUID Path after an asset ID -Path after {A2482826-053D-5634-A27B-084B1326AAE5}:[196608] an ui/fonts/lyshineexamples/veramono.ttf asset ID +Path after {A2482826-053D-5634-A27B-084B1326AAE5}:[1002] an libs/particles/milestone2particles.xml asset ID diff --git a/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt b/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt index 27ac8f02dd..a5ae046b11 100644 --- a/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt +++ b/AutomatedTesting/TestAssets/RelativeSourcePathsNotDependencies.txt @@ -3,6 +3,6 @@ TestAssets/RelativeProductPathsNotDependencies.txt Back slashes TestAssets\WildcardScanTest1.txt Casing doesn't match -Config/gAME.XML -Path inline Config/Editor.xml test +libs/particles/milestone2PARTICLES.XML +Path inline project.json test Path after=textures/_dev_Purple.tif equal sign diff --git a/AutomatedTesting/TestAssets/T92569006.scriptevents b/AutomatedTesting/TestAssets/T92569006.scriptevents new file mode 100644 index 0000000000..518b1b5733 --- /dev/null +++ b/AutomatedTesting/TestAssets/T92569006.scriptevents @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt b/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt index 0d677113e0..4cda459232 100644 --- a/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt +++ b/AutomatedTesting/TestAssets/ValidAssetIdNotDependency.txt @@ -1,5 +1,5 @@ -dev/AutomatedTesting/textures/_dev_Purple.tif, the product ID is for one of the mips. -{A2482826-053D-5634-A27B-084B1326AAE5}:[196608] -_dev_Red.tif, another mip, different formatting. -2ef92b8D044E5C278E2BB1AC0374A4E7:131072 -_dev_White.tif, {D83B36F1-61A6-5001-B191-4D0CE282E236}-327680 asset ID inline. + /textures /_dev_Purple . tif, the product ID is for one of the mips. +{A2482826-053D-5634-A27B-084B1326AAE5}:[1002] +_dev_Red . tif, another mip, different formatting. +2ef92b8D044E5C278E2BB1AC0374A4E7:1003 +_dev_White.tif, {D83B36F1-61A6-5001-B191-4D0CE282E236}-1002 asset ID inline. diff --git a/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt b/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt index c6b2cbb0e7..436d6fb628 100644 --- a/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt +++ b/AutomatedTesting/TestAssets/ValidUUIDsNotDependency.txt @@ -1,18 +1,18 @@ Paths are broken up to avoid having them show up as relative path results. -This is the UUID for dev / AutomatedTesting / Config / Game . xml -B92667DC-9F5B-5D72-A29D-99219DD9B691 -This is the UUID for dev / AutomatedTesting / Config / Editor . xml. This tests UUIDs without separators. -06E9D6633C875400A532BCB2C0CA19D6 +This is the UUID for Materials / Default / AM_UV_v1_1K_source . png +C67BEA9F-09FF-59AA-A7F0-A52B8F987508 +This is the UUID for libs / particles / milestone2particles . xml. This tests UUIDs without separators. +6BDE282B49C957F7B0714B26579BCA9A This is the UUID for SelfReferenceUUID.txt. This tests UUIDs with mixed casing. 33bcee02F3225688ABEE534F6058593F -This is a UUID mid-line 9886E132-572D-5746-9377-E629AB6C1981, for gems . json +This is a UUID mid-line B076CDDC-14DF-50F4-A5E9-7518ABB3E851, for project . json Two UUIDs on the same line -Two UUIDs 6BDE282B49C957F7B0714B26579BCA9A mixed on 58BE9DA51F1753B98CEEEEB10E63454D the same line +Two UUIDs 345E5C660D6254FF8D0F7C8EE66A2249 mixed on A26C73D1837E5AE59E68F916FA7C3699 the same line Test UUIDs and Asset IDs mixed on the same line. Relative paths are handled in the relative path tests. UUID: slices / MuzzleFlash . slice, AssetID: TestsAssets / WildcardScanTest1 . txt This 747D31D71E62553592226173C49CF97E uuid is on the line with 1CB10C43F3245B93A294C602ADEF95F9:[0] a valid asset ID UUID: Objects / Lumbertank_turret . cgf, AssetID: TestsAssets / WildcardScanTest2 . txt -This D92C4661C8985E19BD3597CB2318CFA6:[0] uuid is on the line with 7364AB2B092F5B0B80601BBC6E53087C a valid asset ID +This D92C4661C8985E19BD3597CB2318CFA6:[0] uuid is on the line with 37108522F50459499CD6C8D47A960CF1 a valid asset ID diff --git a/AutomatedTesting/preview.png b/AutomatedTesting/preview.png index 2191a0ebc2..c6928d31fc 100644 --- a/AutomatedTesting/preview.png +++ b/AutomatedTesting/preview.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a18fae4040a22d2bb359a8ca642b97bb8f6468eeb52e2826b3b029bd8f1350b6 -size 5466 +oid sha256:b9cd9d6f67440c193a85969ec5c082c6343e6d1fff3b6f209a0a6931eb22dd47 +size 2949 diff --git a/AutomatedTesting/sounds/.gitignore b/AutomatedTesting/sounds/.gitignore new file mode 100644 index 0000000000..80c66daa1c --- /dev/null +++ b/AutomatedTesting/sounds/.gitignore @@ -0,0 +1,8 @@ +.backup/ +.cache/ +*.log +*.akd +*.dat +*.prof +*.validationcache +*.wsettings \ No newline at end of file diff --git a/AutomatedTesting/sounds/wwise/Init.bnk b/AutomatedTesting/sounds/wwise/Init.bnk index 530a7e007f..292288ff26 100644 --- a/AutomatedTesting/sounds/wwise/Init.bnk +++ b/AutomatedTesting/sounds/wwise/Init.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:803ddb37eb27cba666f9320c2f5905219193e1a069d1144a64df92fab0e31878 -size 1243 +oid sha256:c9e6a4ef3d2f33f31827ce2bba2ed8bad87324f3fe86f79389ef2956b304a924 +size 1180 diff --git a/AutomatedTesting/sounds/wwise/Init.txt b/AutomatedTesting/sounds/wwise/Init.txt index 038359ac1a..4b989c4017 100644 --- a/AutomatedTesting/sounds/wwise/Init.txt +++ b/AutomatedTesting/sounds/wwise/Init.txt @@ -21,5 +21,4 @@ Audio Bus ID Name Wwise Object Path Notes Audio Devices ID Name Type Notes 2317455096 No_Output No Output 3859886410 System System - 4230635974 Default_Motion_Device Wwise Motion diff --git a/AutomatedTesting/sounds/wwise/PluginInfo.xml b/AutomatedTesting/sounds/wwise/PluginInfo.xml index 61e689f373..19f3fe9c1b 100644 --- a/AutomatedTesting/sounds/wwise/PluginInfo.xml +++ b/AutomatedTesting/sounds/wwise/PluginInfo.xml @@ -1,9 +1,8 @@ - + - - - - + + + diff --git a/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml b/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml index 22ae71f4dc..d7bfecaa53 100644 --- a/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml +++ b/AutomatedTesting/sounds/wwise/SoundbanksInfo.xml @@ -1,11 +1,11 @@ - + - Q:\audio\dev\AutomatedTesting\sounds\wwise_project\ - Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\ - Q:\audio\dev\AutomatedTesting\sounds\wwise\ + D:\code\o3de\AutomatedTesting\sounds\wwise_project\ + D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\ + D:\code\o3de\AutomatedTesting\sounds\wwise\ - Q:\audio\dev\AutomatedTesting\sounds\wwise_project\GeneratedSoundBanks\Windows + D:\code\o3de\AutomatedTesting\sounds\wwise_project\GeneratedSoundBanks\Windows @@ -28,7 +28,7 @@ - + \SoundBanks\Default Work Unit\test_bank2 test_bank2 test_bank2.bnk @@ -37,7 +37,7 @@ - + \SoundBanks\Default Work Unit\test_bank3 test_bank3 test_bank3.bnk @@ -60,7 +60,7 @@ - + \SoundBanks\Default Work Unit\test_bank1 test_bank1 test_bank1.bnk @@ -83,7 +83,7 @@ - + \SoundBanks\Default Work Unit\test_bank6 test_bank6 test_bank6.bnk @@ -102,7 +102,7 @@ - + \SoundBanks\Default Work Unit\test_bank7 test_bank7 test_bank7.bnk @@ -125,7 +125,7 @@ - + \SoundBanks\Default Work Unit\test_bank4 test_bank4 test_bank4.bnk @@ -136,7 +136,7 @@ - + \SoundBanks\Default Work Unit\test_bank5 test_bank5 test_bank5.bnk @@ -169,7 +169,7 @@ - + Init Init Init.bnk diff --git a/AutomatedTesting/sounds/wwise/test_bank1.bnk b/AutomatedTesting/sounds/wwise/test_bank1.bnk index 9e8f50a98a..bd0e1e66cb 100644 --- a/AutomatedTesting/sounds/wwise/test_bank1.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank1.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:94ea13931c13592deba669bd4920328ff96f17e6f8fce280d03f00251a96327a -size 94122 +oid sha256:3db299d7d823b649ff20a7ffc986dccfce1fa3189f178491e2712d6c00b317af +size 94126 diff --git a/AutomatedTesting/sounds/wwise/test_bank1.txt b/AutomatedTesting/sounds/wwise/test_bank1.txt index a0c6e13621..5ec2e4b96b 100644 --- a/AutomatedTesting/sounds/wwise/test_bank1.txt +++ b/AutomatedTesting/sounds/wwise/test_bank1.txt @@ -3,8 +3,8 @@ Event ID Name Wwise Object Path Notes 865645077 test_event_1_bank1_embedded_target \Default Work Unit\test_event_1_bank1_embedded_target In Memory Audio ID Name Audio source file Wwise Object Path Notes Data Size - 23965881 test_sfx_1_bank1_embedded Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire_impact004_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_1_bank1_embedded 93864 + 23965881 test_sfx_1_bank1_embedded D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire_impact004_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_1_bank1_embedded 93864 Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 499820003 test_sfx_2_bank1_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed + 499820003 test_sfx_2_bank1_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed diff --git a/AutomatedTesting/sounds/wwise/test_bank2.bnk b/AutomatedTesting/sounds/wwise/test_bank2.bnk index 2e31c359bf..ee96554646 100644 --- a/AutomatedTesting/sounds/wwise/test_bank2.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank2.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad73fd0981e47fe3313eff51d2841ea5fd522a99103684d696849e7353277ea9 -size 430 +oid sha256:1bdaed4dc5cc514a8a3ddfaf990f59061514af7962a7a112eb677ad5c45fcb85 +size 434 diff --git a/AutomatedTesting/sounds/wwise/test_bank3.bankdeps b/AutomatedTesting/sounds/wwise/test_bank3.bankdeps index 606dbdbac8..51a952d463 100644 --- a/AutomatedTesting/sounds/wwise/test_bank3.bankdeps +++ b/AutomatedTesting/sounds/wwise/test_bank3.bankdeps @@ -2,9 +2,9 @@ "version": "1.0", "bankName": "test_bank3.bnk", "dependencies": [ - "196049145.wem", + "test_bank4.bnk", "Init.bnk", - "test_bank4.bnk" + "196049145.wem" ], "includedEvents": [ "test_event_5_bank3_embedded_target_bank4", diff --git a/AutomatedTesting/sounds/wwise/test_bank3.bnk b/AutomatedTesting/sounds/wwise/test_bank3.bnk index 32e6161e6c..6b83836c18 100644 --- a/AutomatedTesting/sounds/wwise/test_bank3.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank3.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:33eabaa646e9567017946bee05b1b5a835e91862f63145ebe5a2fbdd9c9f5a49 -size 226 +oid sha256:57c75cf8745b31071a788a20d8de5a60cedbfb8a6155eae1a461b8c6501e5479 +size 230 diff --git a/AutomatedTesting/sounds/wwise/test_bank3.txt b/AutomatedTesting/sounds/wwise/test_bank3.txt index ca6efc6e02..9a843afad7 100644 --- a/AutomatedTesting/sounds/wwise/test_bank3.txt +++ b/AutomatedTesting/sounds/wwise/test_bank3.txt @@ -3,5 +3,5 @@ Event ID Name Wwise Object Path Notes 645979556 test_event_6_bank3_streamed_target_bank4 \Default Work Unit\test_event_6_bank3_streamed_target_bank4 Event that lives in test_bank3. This event targets only one media, which is streamed from test_bank4. Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 196049145 test_sfx_6_bank4_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire003_56D34C19.wem 196049145.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_6_bank4_streamed + 196049145 test_sfx_6_bank4_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZ_sfx_NME_wpn_plasma_pistol_fire003_56D34C19.wem 196049145.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_6_bank4_streamed diff --git a/AutomatedTesting/sounds/wwise/test_bank4.bnk b/AutomatedTesting/sounds/wwise/test_bank4.bnk index e169744d84..5f5883d559 100644 --- a/AutomatedTesting/sounds/wwise/test_bank4.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank4.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79d308f3c50fece383fd82fd0060e26558e6a2e78a4ecd5d8afe24907489a88f +oid sha256:3a635f7d1ccb256caed90d18ca566cd0fa56d49b491af7c88c0b5da55a3ef4fe size 142234 diff --git a/AutomatedTesting/sounds/wwise/test_bank4.txt b/AutomatedTesting/sounds/wwise/test_bank4.txt index 770cb7f171..7649b0eed5 100644 --- a/AutomatedTesting/sounds/wwise/test_bank4.txt +++ b/AutomatedTesting/sounds/wwise/test_bank4.txt @@ -1,3 +1,3 @@ In Memory Audio ID Name Audio source file Wwise Object Path Notes Data Size - 666825490 test_sfx_5_bank4_embedded Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZN_sfx_env_commsarray_apllyupdate_end_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_5_bank4_embedded 142170 + 666825490 test_sfx_5_bank4_embedded D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\AMZN_sfx_env_commsarray_apllyupdate_end_56D34C19.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_5_bank4_embedded 142170 diff --git a/AutomatedTesting/sounds/wwise/test_bank5.bnk b/AutomatedTesting/sounds/wwise/test_bank5.bnk index b4e629d9a7..168c7c1a4d 100644 --- a/AutomatedTesting/sounds/wwise/test_bank5.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank5.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:80c02f30d439ffcfb479e4a82b0269fe4f479c50019028e51f0fa6e3fea0bfdd -size 290 +oid sha256:fa329eeb83184e88b7ab26fbff2479a98232210bcd130801041b20ccb3bcf16e +size 294 diff --git a/AutomatedTesting/sounds/wwise/test_bank5.txt b/AutomatedTesting/sounds/wwise/test_bank5.txt index 0f66c57f8e..3d560cf9f5 100644 --- a/AutomatedTesting/sounds/wwise/test_bank5.txt +++ b/AutomatedTesting/sounds/wwise/test_bank5.txt @@ -5,5 +5,5 @@ Event ID Name Wwise Object Path Notes 3546419658 test_event_7_bank5_referenced_event_bank1_embedded \Default Work Unit\test_event_7_bank5_referenced_event_bank1_embedded Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 499820003 test_sfx_2_bank1_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed + 499820003 test_sfx_2_bank1_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\env_door_scanner_scan_success_56D34C19.wem 499820003.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_2_bank1_streamed diff --git a/AutomatedTesting/sounds/wwise/test_bank6.bnk b/AutomatedTesting/sounds/wwise/test_bank6.bnk index 18ee92b51d..4c942037f0 100644 --- a/AutomatedTesting/sounds/wwise/test_bank6.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank6.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:07d132d54b2c747e2409a56c05a4adca0dfa4407b791ffaa6bb14531f92f89aa -size 494 +oid sha256:80d3014fcfd3a8ff37219515f0c9d67a2a674094002538ac6741702dca07c14d +size 498 diff --git a/AutomatedTesting/sounds/wwise/test_bank7.bankdeps b/AutomatedTesting/sounds/wwise/test_bank7.bankdeps index 02be60a544..56cf29c619 100644 --- a/AutomatedTesting/sounds/wwise/test_bank7.bankdeps +++ b/AutomatedTesting/sounds/wwise/test_bank7.bankdeps @@ -2,9 +2,9 @@ "version": "1.0", "bankName": "test_bank7.bnk", "dependencies": [ + "656567798.wem", "601903616.wem", - "Init.bnk", - "656567798.wem" + "Init.bnk" ], "includedEvents": [ "test_event_11_bank7_streamed_target", diff --git a/AutomatedTesting/sounds/wwise/test_bank7.bnk b/AutomatedTesting/sounds/wwise/test_bank7.bnk index abc398d1f1..c01346fd58 100644 --- a/AutomatedTesting/sounds/wwise/test_bank7.bnk +++ b/AutomatedTesting/sounds/wwise/test_bank7.bnk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:990538a33c72e79d63cab0c191b4e0f199688b923bb6bdcc8888aab375e7d11d -size 226 +oid sha256:0de33094b9792d7f9ff8042e16b153dd76729e9010d6713e1824d2229c653042 +size 230 diff --git a/AutomatedTesting/sounds/wwise/test_bank7.txt b/AutomatedTesting/sounds/wwise/test_bank7.txt index 033c2ea5b9..3bf2da686b 100644 --- a/AutomatedTesting/sounds/wwise/test_bank7.txt +++ b/AutomatedTesting/sounds/wwise/test_bank7.txt @@ -3,6 +3,6 @@ Event ID Name Wwise Object Path Notes 2110064689 test_event_11_bank7_streamed_target \Default Work Unit\test_event_11_bank7_streamed_target Streamed Audio ID Name Audio source file Generated audio file Wwise Object Path Notes - 601903616 test_sfx_8_bank7_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\gun_blaster_no_trigger_shot_1_56D34C19.wem 601903616.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_8_bank7_streamed - 656567798 test_sfx_7_bank7_streamed Q:\audio\dev\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\impact_bot_hits_metalelement_56D34C19.wem 656567798.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_7_bank7_streamed + 601903616 test_sfx_8_bank7_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\gun_blaster_no_trigger_shot_1_56D34C19.wem 601903616.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_8_bank7_streamed + 656567798 test_sfx_7_bank7_streamed D:\code\o3de\AutomatedTesting\sounds\wwise_project\.cache\Windows\SFX\impact_bot_hits_metalelement_56D34C19.wem 656567798.wem \Actor-Mixer Hierarchy\Default Work Unit\test_sfx_7_bank7_streamed diff --git a/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu index 8cc6eeecc2..33ac513281 100644 --- a/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Actor-Mixer Hierarchy/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + @@ -21,6 +21,7 @@ + @@ -50,6 +51,7 @@ + @@ -72,6 +74,7 @@ + @@ -101,6 +104,7 @@ + @@ -130,6 +134,7 @@ + @@ -159,6 +164,7 @@ + @@ -187,6 +193,7 @@ SFX + @@ -215,6 +222,7 @@ SFX + diff --git a/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu index 9034f07366..955c7d9e4a 100644 --- a/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Attenuations/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu index 472e9b12d1..f56682b0bf 100644 --- a/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Audio Devices/Default Work Unit.wwu @@ -1,11 +1,10 @@ - + - diff --git a/AutomatedTesting/sounds/wwise_project/AutomatedTesting.wproj b/AutomatedTesting/sounds/wwise_project/AutomatedTesting.wproj new file mode 100644 index 0000000000..1aead159ad --- /dev/null +++ b/AutomatedTesting/sounds/wwise_project/AutomatedTesting.wproj @@ -0,0 +1,13491 @@ + + + + + + + + + + + + + + + + + + + + + + GeneratedSoundBanks\Windows + + + + + 256 + + + + + + ..\wwise\ + + + + + Copy Streamed Files and Generate Dependency Info + + + + + "$(CopyStreamedFilesExePath)" -info "$(InfoFilePath)" -outputpath "$(SoundBankPath)" -banks "$(SoundBankListAsTextFile)" -languages "$(LanguageList)" +"$(WwiseProjectPath)\..\..\..\python\python.cmd" "$(WwiseProjectPath)\..\..\..\Gems\AudioEngineWwise\Tools\WwiseAuthoringScripts\bank_info_parser.py" "$(InfoFilePath)" "$(SoundBankPath)" + + + + + + + + + + + + + + + -80 + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 8 + + + + + 0 + + + + + -1 + + + + + -1 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + -1 + + + + + -1 + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 2 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + 1 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + 10000 + + + + + 1 + + + + + 400 + + + + + 1 + + + + + 1 + + + + + 0.5 + + + + + 0 + + + + + -96 + + + + + 0 + + + + + True + + + + + False + + + + + 0 + + + + + 0 + + + + + 16 + + + + + -96 + + + + + 0 + + + + + 48000 + + + + + 0 + + + + + + + + + 16 + + + + + False + + + + + 1 + + + + + 75 + + + + + + + + + False + + + + + 512 + + + + + -50 + + + + + -30 + + + + + -40 + + + + + 0 + + + + + 24024 + + + + + 0 + + + + + 8 + + + + + English(US) + + + + + 0 + + + + + 0 + + + + + False + + + + + + + + + + + + + + + 1 + + + + + True + + + + + False + + + + + False + + + + + True + + + + + 256 + + + + + + + + + + 50 + + + + + 100 + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + True + + + + + True + + + + + True + + + + + True + + + + + -80 + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 64 + + + + + 1.5 + + + + + 2 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + 64 + + + + + 64 + + + + + 4 + + + + + 0 + + + + + 0.1 + + + + + 4 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 20 + + + + + 10000 + + + + + 0.2 + + + + + True + + + + + 80 + + + + + 0.2 + + + + + False + + + + + 200 + + + + + 0.25 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 4 + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 0 + + + + + 100 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 10 + + + + + 1 + + + + + 200 + + + + + 0 + + + + + 0 + + + + + 10 + + + + + 1 + + + + + 200 + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 40 + + + + + 0 + + + + + 1000 + + + + + 160 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0.2 + + + + + 0 + + + + + 0.2 + + + + + 0.2 + + + + + 3000 + + + + + 0.2 + + + + + 0 + + + + + 6 + + + + + 15000 + + + + + 0 + + + + + 1000 + + + + + 20000 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 0.5 + + + + + 0.2 + + + + + 0 + + + + + 1 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + 1 + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + True + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + False + + + + + 3 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 1 + + + + + False + + + + + 2 + + + + + True + + + + + False + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + True + + + + + 1 + + + + + 1 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 5 + + + + + 0.5 + + + + + 0 + + + + + True + + + + + 5000 + + + + + 10000 + + + + + False + + + + + + + + + False + + + + + 0 + + + + + 3 + + + + + 9 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + 1000 + + + + + 5000 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 96 + + + + + -100 + + + + + -100 + + + + + -100 + + + + + False + + + + + False + + + + + + + + + False + + + + + 0 + + + + + 35 + + + + + 0 + + + + + True + + + + + 0 + + + + + 1 + + + + + 1 + + + + + True + + + + + + + + + 0 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 3 + + + + + 9 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + False + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + False + + + + + False + + + + + + + + + 64 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + 0 + + + + + True + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 100 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + -96 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 100 + + + + + 0 + + + + + False + + + + + 0 + + + + + 50 + + + + + 50 + + + + + 50 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + 4000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 120 + + + + + 4 + + + + + 4 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 100 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + False + + + + + 65535 + + + + + 127 + + + + + 0 + + + + + 1 + + + + + 60 + + + + + 0 + + + + + 127 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 1 + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + True + + + + + False + + + + + False + + + + + True + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + + -1 + + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 120 + + + + + 4 + + + + + 4 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 12 + + + + + False + + + + + 20 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 1 + + + + + 50 + + + + + False + + + + + -10 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 100 + + + + + 120 + + + + + 4 + + + + + 4 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 1 + + + + + 1 + + + + + False + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 50 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 7 + + + + + + + + + + False + + + + + 1 + + + + + + + + + + False + + + + + True + + + + + True + + + + + True + + + + + True + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + -6 + + + + + 0 + + + + + 90 + + + + + 0 + + + + + 245 + + + + + False + + + + + True + + + + + False + + + + + 100 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + False + + + + + 100 + + + + + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + False + + + + + + + + + + + + + + + False + + + + + False + + + + + True + + + + + False + + + + + False + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + + + + + + True + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + True + + + + + + + + + 0 + + + + + False + + + + + + + + + + + + + + + + + + True + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 8 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + 0 + + + + + True + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 100 + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 100 + + + + + 1 + + + + + 0 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + False + + + + + + + + + 0 + + + + + 50 + + + + + 0.2 + + + + + False + + + + + 0.2 + + + + + 0.5 + + + + + True + + + + + 100 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + False + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + + + + + + 1 + + + + + False + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + + + + + + 1 + + + + + False + + + + + 0 + + + + + + + + + + 0 + + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + + + + + 0 + + + + + True + + + + + 1 + + + + + 1 + + + + + False + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 4 + + + + + 1 + + + + + 440 + + + + + -12 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 4 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + -12 + + + + + 1 + + + + + False + + + + + 0 + + + + + -12 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + 10 + + + + + 0 + + + + + + + + + 0 + + + + + 4 + + + + + 6 + + + + + 5 + + + + + 100 + + + + + 1000 + + + + + 12000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + True + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 1 + + + + + 1 + + + + + 1 + + + + + + + + + 0 + + + + + 0.5 + + + + + 15 + + + + + True + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 25 + + + + + + + + + 0.1 + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 1.5 + + + + + 0.1 + + + + + 0 + + + + + + + + + 0.1 + + + + + True + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + True + + + + + 3 + + + + + 0.01 + + + + + -40 + + + + + + + + + True + + + + + 0 + + + + + True + + + + + 0.01 + + + + + 0 + + + + + False + + + + + True + + + + + 10 + + + + + 0.1 + + + + + 0 + + + + + + + + + 100 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 1 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + True + + + + + 40 + + + + + 0 + + + + + 0 + + + + + 18000 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + True + + + + + 10 + + + + + 0 + + + + + 100 + + + + + -40 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + True + + + + + 40 + + + + + 18000 + + + + + -96 + + + + + -20 + + + + + 20 + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + 100 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 13.62 + + + + + 26.09 + + + + + 26.55 + + + + + 26.91 + + + + + 28.04 + + + + + 29.09 + + + + + 29.9 + + + + + 30.86 + + + + + 15.66 + + + + + 17.52 + + + + + 19.02 + + + + + 20.83 + + + + + 22.6 + + + + + 24.05 + + + + + 24.78 + + + + + 25.6 + + + + + -96.3 + + + + + 2 + + + + + True + + + + + 8 + + + + + False + + + + + 0 + + + + + True + + + + + 4 + + + + + -35 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + 0 + + + + + True + + + + + 100 + + + + + 0 + + + + + False + + + + + -96.3 + + + + + + + + + 0 + + + + + 0 + + + + + 40 + + + + + 1.2 + + + + + 80 + + + + + 50 + + + + + 8 + + + + + 2 + + + + + 100 + + + + + 15 + + + + + 5 + + + + + 66 + + + + + -96.3 + + + + + 0 + + + + + -20 + + + + + 23 + + + + + True + + + + + False + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + 1 + + + + + 1000 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + 2 + + + + + 10000 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + 0 + + + + + 2.25 + + + + + True + + + + + 0 + + + + + -96.3 + + + + + -96.3 + + + + + False + + + + + 25 + + + + + 8 + + + + + 0 + + + + + -20 + + + + + 100 + + + + + 50 + + + + + 100 + + + + + 0.8 + + + + + 0.1 + + + + + 0 + + + + + 180 + + + + + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 10 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0.5 + + + + + False + + + + + 0 + + + + + 10 + + + + + 5 + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0.25 + + + + + False + + + + + 0 + + + + + 0.5 + + + + + + + + + 1 + + + + + 1 + + + + + True + + + + + 0.5 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 0 + + + + + 10 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + False + + + + + 10 + + + + + 0.5 + + + + + 0 + + + + + 1 + + + + + + + + + 440 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 10 + + + + + + + + + False + + + + + 440 + + + + + 0 + + + + + 10 + + + + + 1 + + + + + + + + + 0 + + + + + 5 + + + + + 1 + + + + + True + + + + + 0 + + + + + 1 + + + + + True + + + + + 50 + + + + + 1 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + False + + + + + 100 + + + + + + + + + 0 + + + + + 50 + + + + + 50 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 100 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + -96.3 + + + + + 0 + + + + + 0 + + + + + False + + + + + 4 + + + + + 0 + + + + + 100 + + + + + 0 + + + + + 0 + + + + + -75 + + + + + False + + + + + False + + + + + 6 + + + + + 0 + + + + + 0 + + + + + True + + + + + 100 + + + + + True + + + + + 0 + + + + + -96.3 + + + + + 0 + + + + + -60 + + + + + -96.3 + + + + + False + + + + + 0 + + + + + 0 + + + + + 1024 + + + + + 48000 + + + + + 48000 + + + + + 48000 + + + + + 180 + + + + + 0 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 0 + + + + + -48 + + + + + False + + + + + 0.1 + + + + + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + 100 + + + + + 0 + + + + + 2048 + + + + + + + + + 0 + + + + + True + + + + + 100 + + + + + 1 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + True + + + + + + + + + 1 + + + + + False + + + + + Recorder.wav + + + + + -3 + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + + + + + + True + + + + + -96.3 + + + + + False + + + + + -3 + + + + + -3 + + + + + + + + + 0 + + + + + 0 + + + + + False + + + + + False + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + -100 + + + + + True + + + + + -12 + + + + + 0.1 + + + + + -12 + + + + + 0 + + + + + False + + + + + -12 + + + + + 0.1 + + + + + -12 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + 50 + + + + + -96 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + 0 + + + + + False + + + + + False + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + False + + + + + True + + + + + True + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1024 + + + + + + + + + 0 + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + -96 + + + + + 0 + + + + + 0 + + + + + False + + + + + -6 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + False + + + + + -6 + + + + + 50 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + + + + + False + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 250 + + + + + 100 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + -96 + + + + + 3 + + + + + True + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + False + + + + + 0.5 + + + + + 0 + + + + + 2400 + + + + + 345 + + + + + 0 + + + + + 0 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 1 + + + + + + + + + False + + + + + True + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + 0 + + + + + 0 + + + + + 32 + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + False + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + False + + + + + False + + + + + False + + + + + False + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 100 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 10 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 20000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0.707 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1000 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 256 + + + + + False + + + + + 100 + + + + + 100 + + + + + 100 + + + + + 100 + + + + + 1000 + + + + + 1000 + + + + + 1000 + + + + + 1000 + + + + + 20000 + + + + + 20000 + + + + + 20000 + + + + + 20000 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 5 + + + + + 5 + + + + + 9 + + + + + 9 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 16641 + + + + + 0 + + + + + 0 + + + + + False + + + + + 10 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 60 + + + + + 1 + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + 0 + + + + + True + + + + + False + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 0.01 + + + + + True + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0.1 + + + + + 0 + + + + + 150 + + + + + 1000 + + + + + 6000 + + + + + 0 + + + + + False + + + + + 0 + + + + + 4 + + + + + 0 + + + + + False + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + True + + + + + True + + + + + True + + + + + True + + + + + True + + + + + 5 + + + + + 100 + + + + + 0 + + + + + 1 + + + + + True + + + + + 3 + + + + + 200 + + + + + 0 + + + + + 1 + + + + + True + + + + + 3 + + + + + 500 + + + + + 0 + + + + + 1 + + + + + True + + + + + 4 + + + + + 1000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 3 + + + + + 3000 + + + + + 0 + + + + + 1 + + + + + False + + + + + 3 + + + + + 6000 + + + + + 0 + + + + + 1 + + + + + 4 + + + + + + + + + -12 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + False + + + + + + + + + 1 + + + + + 0 + + + + + + + + + 0 + + + + + 0 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + -12 + + + + + 1 + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 6 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + + + + + 1 + + + + + 1 + + + + + 1 + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + + + + + 0.6 + + + + + 0.6 + + + + + 0.5 + + + + + 0.3 + + + + + 0.05 + + + + + 0.25 + + + + + 0.02 + + + + + 1.5 + + + + + 0.2 + + + + + 0.3 + + + + + True + + + + + 0.2 + + + + + 8 + + + + + 0.2 + + + + + 12 + + + + + + + + + 20 + + + + + 0.7 + + + + + 100 + + + + + 0.1 + + + + + 1 + + + + + 1 + + + + + True + + + + + 1 + + + + + 0 + + + + + 3 + + + + + 1 + + + + + + + + + 2 + + + + + 0.7 + + + + + 1 + + + + + 0 + + + + + 1 + + + + + 0.9 + + + + + 0.1 + + + + + 3 + + + + + + + + + 0 + + + + + True + + + + + False + + + + + + + + + 0 + + + + + True + + + + + 0 + + + + + False + + + + + + + + + 0 + + + + + False + + + + + False + + + + + True + + + + + 0 + + + + + 0 + + + + + + + + + + 0 + + + + + 0 + + + + + 0 + + + + + 0 + + + + + False + + + + + 2 + + + + + False + + + + + + + + + + + + + + + 1 + + + + + + + + + + + + + + 0 + + + + + + + + + False + + + + + 0 + + + + + 0 + + + + + 1.4 + + + + + -6 + + + + + True + + + + + 0 + + + + + 0 + + + + + False + + + + + True + + + + + 0.5 + + + + + 10000 + + + + + -6 + + + + + 7 + + + + + 1 + + + + + 1 + + + + + 7.25 + + + + + 2.75 + + + + + 3.25 + + + + + 4.25 + + + + + 4.75 + + + + + 3.75 + + + + + + + + + 100 + + + + + 50 + + + + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + -200 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + -200 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + 0 + 0 + 5 + + + 100 + 100 + 37 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu index 1f7d254b46..4e13dee554 100644 --- a/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Control Surface Sessions/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu index ac7c83d1db..236f5765db 100644 --- a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu index 9a94d81c32..7873f5135a 100644 --- a/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu +++ b/AutomatedTesting/sounds/wwise_project/Conversion Settings/Factory Conversion Settings.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu index e6e033e251..5411c7d503 100644 --- a/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Dynamic Dialogue/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu index f938135d6b..ca63005f4b 100644 --- a/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Effects/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu b/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu index ac716afb97..5a545f5e61 100644 --- a/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu +++ b/AutomatedTesting/sounds/wwise_project/Effects/Factory Effects.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu b/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu index f2269dd2dc..2c0ebb6b67 100644 --- a/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu +++ b/AutomatedTesting/sounds/wwise_project/Effects/Factory Reflect.wwu @@ -1,10 +1,9 @@ - + - - + @@ -185,8 +184,7 @@ - - + diff --git a/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu index c65c8adca1..73c2e8f028 100644 --- a/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Events/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu index e373885f46..a939ebe124 100644 --- a/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Game Parameters/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu index b06d283012..3989d74308 100644 --- a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu +++ b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory Motion.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu index 049dacb51e..efe69cb1a8 100644 --- a/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu +++ b/AutomatedTesting/sounds/wwise_project/Game Parameters/Factory SoundSeed Air Game Syncs.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu index 1086c4511f..e8f4d23bb6 100644 --- a/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Interactive Music Hierarchy/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu index a627ce106e..b6c14df7af 100644 --- a/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Master-Mixer Hierarchy/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + @@ -9,13 +9,15 @@ + - + + diff --git a/AutomatedTesting/sounds/wwise_project/Metadata/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Metadata/Default Work Unit.wwu new file mode 100644 index 0000000000..0317c70b7c --- /dev/null +++ b/AutomatedTesting/sounds/wwise_project/Metadata/Default Work Unit.wwu @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu index 8c62ef9009..c24440febd 100644 --- a/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Mixing Sessions/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu index 062f9f80df..dc16200be3 100644 --- a/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Modulators/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu index 2bed1c6613..07f7565980 100644 --- a/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Presets/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu b/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu index 53f828f459..8138f5bcdd 100644 --- a/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu +++ b/AutomatedTesting/sounds/wwise_project/Presets/Factory Reflect.wwu @@ -1,5 +1,5 @@ - + @@ -19,6 +19,7 @@ + diff --git a/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu b/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu index 5b96bd3b29..d73cf8d8c3 100644 --- a/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu +++ b/AutomatedTesting/sounds/wwise_project/Presets/Factory Spatial Audio.wwu @@ -1,5 +1,5 @@ - + @@ -17,6 +17,7 @@ + diff --git a/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu index f4e9f99aa4..ff80573330 100644 --- a/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Queries/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu b/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu index 527315de63..813983d789 100644 --- a/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu +++ b/AutomatedTesting/sounds/wwise_project/Queries/Factory Queries.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu index da8fa90010..c12261ab5b 100644 --- a/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/SoundBanks/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu index d6b8329537..379bf37da9 100644 --- a/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Soundcaster Sessions/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu index f27a0d0310..b06937baa9 100644 --- a/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/States/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu index 49c00bc378..37fb0b424c 100644 --- a/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Switches/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu index 3b2e2634df..bb2a827d79 100644 --- a/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Triggers/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu index 29c26cbbab..d10d9475dc 100644 --- a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu +++ b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Default Work Unit.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu index 864f6ba959..ca4a1ae8f2 100644 --- a/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu +++ b/AutomatedTesting/sounds/wwise_project/Virtual Acoustics/Factory Reflect Acoustic Textures.wwu @@ -1,5 +1,5 @@ - + diff --git a/AutomatedTesting/surfacetypemateriallibrary.physmaterial b/AutomatedTesting/surfacetypemateriallibrary.physmaterial index 3c39d5521e..481cd2fbfa 100644 --- a/AutomatedTesting/surfacetypemateriallibrary.physmaterial +++ b/AutomatedTesting/surfacetypemateriallibrary.physmaterial @@ -1,19 +1,155 @@ - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CMakeLists.txt b/CMakeLists.txt index ae8a7a05f8..387f536966 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,10 +32,14 @@ if(NOT PROJECT_NAME) ) endif() +################################################################################ +# Initialize +################################################################################ include(cmake/GeneralSettings.cmake) include(cmake/FileUtil.cmake) include(cmake/PAL.cmake) include(cmake/PALTools.cmake) +include(cmake/RuntimeDependencies.cmake) include(cmake/Install.cmake) include(cmake/Configurations.cmake) # Requires to be after PAL so we get platform variable definitions include(cmake/Dependencies.cmake) @@ -43,89 +47,106 @@ include(cmake/Deployment.cmake) include(cmake/3rdParty.cmake) include(cmake/LYPython.cmake) include(cmake/LYWrappers.cmake) +include(cmake/Gems.cmake) include(cmake/UnitTest.cmake) include(cmake/LYTestWrappers.cmake) include(cmake/Monolithic.cmake) include(cmake/SettingsRegistry.cmake) include(cmake/TestImpactFramework/LYTestImpactFramework.cmake) include(cmake/CMakeFiles.cmake) +include(cmake/O3DEJson.cmake) ################################################################################ # Subdirectory processing ################################################################################ +function(add_engine_json_external_subdirectories) + read_json_external_subdirs(external_subdis ${LY_ROOT_FOLDER}/engine.json) + foreach(external_subdir ${external_subdis}) + file(REAL_PATH ${external_subdir} real_external_subdir BASE_DIRECTORY ${LY_ROOT_FOLDER}) + list(APPEND engine_external_subdirs ${real_external_subdir}) + endforeach() + + set_property(GLOBAL APPEND PROPERTY LY_EXTERNAL_SUBDIRS ${engine_external_subdirs}) +endfunction() + # Add the projects first so the Launcher can find them include(cmake/Projects.cmake) if(NOT INSTALLED_ENGINE) + # Add the rest of the targets add_subdirectory(Code) - add_subdirectory(Gems) + add_subdirectory(scripts) + + # SPEC-1417 will investigate and fix this + if(NOT PAL_PLATFORM_NAME STREQUAL "Mac") + add_subdirectory(Tools/LyTestTools/tests/) + add_subdirectory(Tools/RemoteConsole/ly_remote_console/tests/) + endif() + + # Add external subdirectories listed in the engine.json. LY_EXTERNAL_SUBDIRS is a cache variable so the user can add extra + # external subdirectories + add_engine_json_external_subdirectories() + get_property(external_subdirs GLOBAL PROPERTY LY_EXTERNAL_SUBDIRS) + list(APPEND LY_EXTERNAL_SUBDIRS ${external_subdirs}) + + # Loop over the additional external subdirectories and invoke add_subdirectory on them + foreach(external_directory ${LY_EXTERNAL_SUBDIRS}) + # Hash the extenal_directory name and append it to the Binary Directory section of add_subdirectory + # This is to deal with potential situations where multiple external directories has the same last directory name + # For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory + file(REAL_PATH ${external_directory} full_directory_path) + string(SHA256 full_directory_hash ${full_directory_path}) + # Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit + # when the external subdirectory contains relative paths of significant length + string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash) + # Use the last directory as the suffix path to use for the Binary Directory + get_filename_component(directory_name ${external_directory} NAME) + add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/External/${directory_name}-${full_directory_hash}) + endforeach() + else() ly_find_o3de_packages() endif() -set(enabled_platforms - ${PAL_PLATFORM_NAME} - ${LY_PAL_TOOLS_ENABLED}) - -foreach(restricted_platform ${PAL_RESTRICTED_PLATFORMS}) - if(restricted_platform IN_LIST enabled_platforms) - add_subdirectory(restricted/${restricted_platform}) - endif() -endforeach() - -if(NOT INSTALLED_ENGINE) - add_subdirectory(scripts) -endif() - -# SPEC-1417 will investigate and fix this -if(NOT PAL_PLATFORM_NAME STREQUAL "Mac") - add_subdirectory(Tools/LyTestTools/tests/) - add_subdirectory(Tools/RemoteConsole/ly_remote_console/tests/) -endif() - ################################################################################ # Post-processing ################################################################################ - -# Loop over the additional external subdirectories and invoke add_subdirectory on them -foreach(external_directory ${LY_EXTERNAL_SUBDIRS}) - # Hash the extenal_directory name and append it to the Binary Directory section of add_subdirectory - # This is to deal with potential situations where multiple external directories has the same last directory name - # For example if D:/Company1/RayTracingGem and F:/Company2/Path/RayTracingGem were both added as a subdirectory - file(REAL_PATH ${external_directory} full_directory_path) - string(SHA256 full_directory_hash ${full_directory_path}) - # Truncate the full_directory_hash down to 8 characters to avoid hitting the Windows 260 character path limit - # when the external subdirectory contains relative paths of significant length - string(SUBSTRING ${full_directory_hash} 0 8 full_directory_hash) - # Use the last directory as the suffix path to use for the Binary Directory - get_filename_component(directory_name ${external_directory} NAME) - add_subdirectory(${external_directory} ${CMAKE_BINARY_DIR}/${directory_name}-${full_directory_hash}) -endforeach() - # The following steps have to be done after all targets are registered: -# 1. generate a settings registry .setreg file for all ly_add_project_dependencies() and ly_add_target_dependencies() calls +# Defer generation of the StaticModules.inl file which is needed to create the AZ::Module derived class in monolithic +# builds until after all the targets are known +ly_delayed_generate_static_modules_inl() + +# 1. Add any dependencies registered via ly_enable_gems +ly_enable_gems_delayed() + +# 2. generate a settings registry .setreg file for all ly_add_project_dependencies() and ly_add_target_dependencies() calls # to provide applications with the filenames of gem modules to load -# This must be done before ly_delayed_target_link_libraries() as that inserts BUILD_DEPENDENCIE as MANUALLY_ADDED_DEPENDENCIES +# This must be done before ly_delayed_target_link_libraries() as that inserts BUILD_DEPENDENCIES as MANUALLY_ADDED_DEPENDENCIES # if the build dependency is a MODULE_LIBRARY. That would cause a false load dependency to be generated ly_delayed_generate_settings_registry() -# 2. link targets where the dependency was yet not declared, we need to have the declaration so we do different + +# 3. link targets where the dependency was yet not declared, we need to have the declaration so we do different # linking logic depending on the type of target ly_delayed_target_link_libraries() -# 3. generate a registry file for unit testing for platforms that support unit testing + +# 4. generate a registry file for unit testing for platforms that support unit testing if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_delayed_generate_unit_test_module_registry() endif() -# 4. inject runtime dependencies to the targets. We need to do this after (1) since we are going to walk through -# the dependencies -include(cmake/RuntimeDependencies.cmake) -# 5. Perform test impact framework post steps once all of the targets have been enumerated -ly_test_impact_post_step() -# 6. Generate the O3DE find file and setup install locations for scripts, tools, assets etc., required by the engine -if(NOT INSTALLED_ENGINE) - ly_setup_o3de_install() - # IMPORTANT: must be included last +# 5. inject runtime dependencies to the targets. We need to do this after (1) since we are going to walk through +# the dependencies +ly_delayed_generate_runtime_dependencies() + +# 6. Perform test impact framework post steps once all of the targets have been enumerated +ly_test_impact_post_step() + +# 7. Generate the O3DE find file and setup install locations for scripts, tools, assets etc., required by the engine +if(NOT INSTALLED_ENGINE) + # 8. Generate the O3DE find file and setup install locations for scripts, tools, assets etc., required by the engine + ly_setup_o3de_install() + # 9. CPack information (to be included after install) include(cmake/Packaging.cmake) endif() diff --git a/Code/.p4ignore b/Code/.p4ignore deleted file mode 100644 index f0b9f1ea6b..0000000000 --- a/Code/.p4ignore +++ /dev/null @@ -1,6 +0,0 @@ -#Ignore these directories -SDKs - -#ColinB (8/26)- I know there are depot files that this will ignore... But these files should not be -#here, they should all be in 3rdParty... so we will ignore them until I can move them, it should -#be OK for now because they shouldn't change at all anyway. diff --git a/Code/CryEngine/CryCommon/AABBSV.h b/Code/CryEngine/CryCommon/AABBSV.h deleted file mode 100644 index 4c1c277e35..0000000000 --- a/Code/CryEngine/CryCommon/AABBSV.h +++ /dev/null @@ -1,525 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : shadow volume AABB functionality for overlap testings - - -#ifndef CRYINCLUDE_CRYCOMMON_AABBSV_H -#define CRYINCLUDE_CRYCOMMON_AABBSV_H -#pragma once - -#include "Cry_Geo.h" - -struct Shadowvolume -{ - uint32 sideamount; - uint32 nplanes; - - Plane oplanes[10]; -}; - -namespace NAABB_SV -{ - //*************************************************************************************** - //*************************************************************************************** - //*** Calculate a ShadowVolume using an AABB and a point-light *** - //*************************************************************************************** - //*** The planes of the AABB facing away from the point-light are the far-planes *** - //*** of the ShadowVolume. There can be 3-6 far-planes. *** - //*************************************************************************************** - void AABB_ReceiverShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv); - - //*************************************************************************************** - //*************************************************************************************** - //*** Calculate a ShadowVolume using an AABB and a point-light *** - //*************************************************************************************** - //*** The planes of the AABB facing the point-light are the near-planes of the *** - //*** the ShadowVolume. There can be 1-3 near-planes. *** - //*** The far-plane is defined by lightrange. *** - //*************************************************************************************** - void AABB_ShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv, f32 lightrange); - - //*************************************************************************************** - //*** this is the "fast" version to check if an AABB is overlapping a shadowvolume *** - //*************************************************************************************** - bool Is_AABB_In_ShadowVolume(const Shadowvolume& sv, const AABB& Receiver); - - //*************************************************************************************** - //*** this is the "hierarchical" check *** - //*************************************************************************************** - char Is_AABB_In_ShadowVolume_hierarchical(const Shadowvolume& sv, const AABB& Receiver); -} - - - - - -inline void NAABB_SV::AABB_ReceiverShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv) -{ - sv.sideamount = 0; - sv.nplanes = 0; - - //------------------------------------------------------------------------------ - //-- check if PointLight is in front of any occluder plane or inside occluder -- - //------------------------------------------------------------------------------ - uint32 front = 0; - if (PointLight.x < Occluder.min.x) - { - front |= 0x01; - } - if (PointLight.x > Occluder.max.x) - { - front |= 0x02; - } - if (PointLight.y < Occluder.min.y) - { - front |= 0x04; - } - if (PointLight.y > Occluder.max.y) - { - front |= 0x08; - } - if (PointLight.z < Occluder.min.z) - { - front |= 0x10; - } - if (PointLight.z > Occluder.max.z) - { - front |= 0x20; - } - - sv.sideamount = BoxSides[(front << 3) + 7]; - - uint32 back = front ^ 0x3f; - if (back & 0x01) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(-1, +0, +0), Occluder.min); - sv.nplanes++; - } - if (back & 0x02) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+1, +0, +0), Occluder.max); - sv.nplanes++; - } - if (back & 0x04) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, -1, +0), Occluder.min); - sv.nplanes++; - } - if (back & 0x08) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +1, +0), Occluder.max); - sv.nplanes++; - } - if (back & 0x10) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, -1), Occluder.min); - sv.nplanes++; - } - if (back & 0x20) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, +1), Occluder.max); - sv.nplanes++; - } - - if (front == 0) - { - return; //light is inside occluder - } - //all 8 vertices of a AABB - Vec3 o[8] = - { - Vec3(Occluder.min.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.max.z) - }; - - //--------------------------------------------------------------------- - //--- find the silhouette-vertices of the occluder-AABB --- - //--------------------------------------------------------------------- - uint32 p0 = BoxSides[(front << 3) + 0]; - uint32 p1 = BoxSides[(front << 3) + 1]; - uint32 p2 = BoxSides[(front << 3) + 2]; - uint32 p3 = BoxSides[(front << 3) + 3]; - uint32 p4 = BoxSides[(front << 3) + 4]; - uint32 p5 = BoxSides[(front << 3) + 5]; - - float a; - if (sv.sideamount == 4) - { - //sv.oplanes[sv.nplanes+0] = Plane::CreatePlane( o[p0],o[p1], PointLight ); - //sv.oplanes[sv.nplanes+1] = Plane::CreatePlane( o[p1],o[p2], PointLight ); - //sv.oplanes[sv.nplanes+2] = Plane::CreatePlane( o[p2],o[p3], PointLight ); - //sv.oplanes[sv.nplanes+3] = Plane::CreatePlane( o[p3],o[p0], PointLight ); - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p3]) | (o[p3] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p0], PointLight); - sv.sideamount++; - } - } - - if (sv.sideamount == 6) - { - //sv.oplanes[sv.nplanes+0] = Plane::CreatePlane( o[p0],o[p1], PointLight ); - //sv.oplanes[sv.nplanes+1] = Plane::CreatePlane( o[p1],o[p2], PointLight ); - //sv.oplanes[sv.nplanes+2] = Plane::CreatePlane( o[p2],o[p3], PointLight ); - //sv.oplanes[sv.nplanes+3] = Plane::CreatePlane( o[p3],o[p4], PointLight ); - //sv.oplanes[sv.nplanes+4] = Plane::CreatePlane( o[p4],o[p5], PointLight ); - //sv.oplanes[sv.nplanes+5] = Plane::CreatePlane( o[p5],o[p0], PointLight ); - - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p4] - o[p3]) | (o[p3] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p4], PointLight); - sv.sideamount++; - } - a = (o[p5] - o[p4]) | (o[p4] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p4], o[p5], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p5]) | (o[p5] - PointLight); - assert(sv.nplanes + sv.sideamount < 10); - PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p5], o[p0], PointLight); - sv.sideamount++; - } - } -} - -inline void NAABB_SV::AABB_ShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv, f32 lightrange) -{ - sv.sideamount = 0; - sv.nplanes = 0; - - //------------------------------------------------------------------------------ - //-- check if PointLight is in front of any occluder plane or inside occluder -- - //------------------------------------------------------------------------------ - uint32 front = 0; - if (PointLight.x < Occluder.min.x) - { - front |= 0x01; - } - if (PointLight.x > Occluder.max.x) - { - front |= 0x02; - } - if (PointLight.y < Occluder.min.y) - { - front |= 0x04; - } - if (PointLight.y > Occluder.max.y) - { - front |= 0x08; - } - if (PointLight.z < Occluder.min.z) - { - front |= 0x10; - } - if (PointLight.z > Occluder.max.z) - { - front |= 0x20; - } - if (front == 0) - { - return; //light is inside occluder - } - sv.sideamount = BoxSides[(front << 3) + 7]; - - if (front & 0x01) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(-1, +0, +0), Occluder.min); - sv.nplanes++; - } - if (front & 0x02) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+1, +0, +0), Occluder.max); - sv.nplanes++; - } - if (front & 0x04) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, -1, +0), Occluder.min); - sv.nplanes++; - } - if (front & 0x08) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +1, +0), Occluder.max); - sv.nplanes++; - } - if (front & 0x10) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, -1), Occluder.min); - sv.nplanes++; - } - if (front & 0x20) - { - sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, +1), Occluder.max); - sv.nplanes++; - } - - //all 8 vertices of a AABB - Vec3 o[8] = - { - Vec3(Occluder.min.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.min.z), - Vec3(Occluder.min.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.min.y, Occluder.max.z), - Vec3(Occluder.min.x, Occluder.max.y, Occluder.max.z), - Vec3(Occluder.max.x, Occluder.max.y, Occluder.max.z) - }; - - //--------------------------------------------------------------------- - //--- find the silhouette-vertices of the occluder-AABB --- - //--------------------------------------------------------------------- - uint32 p0 = BoxSides[(front << 3) + 0]; - uint32 p1 = BoxSides[(front << 3) + 1]; - uint32 p2 = BoxSides[(front << 3) + 2]; - uint32 p3 = BoxSides[(front << 3) + 3]; - uint32 p4 = BoxSides[(front << 3) + 4]; - uint32 p5 = BoxSides[(front << 3) + 5]; - - //the new center-position in world-space - Vec3 MiddleOfOccluder = (Occluder.max + Occluder.min) * 0.5f; - sv.oplanes[sv.nplanes] = Plane::CreatePlane((MiddleOfOccluder - PointLight).GetNormalized(), (MiddleOfOccluder - PointLight).GetNormalized() * lightrange + PointLight); - sv.nplanes++; - - float a; - if (sv.sideamount == 4) - { - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p3]) | (o[p3] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p0], PointLight); - sv.sideamount++; - } - } - - if (sv.sideamount == 6) - { - sv.sideamount = 0; - a = (o[p1] - o[p0]) | (o[p0] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight); - sv.sideamount++; - } - a = (o[p2] - o[p1]) | (o[p1] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight); - sv.sideamount++; - } - a = (o[p3] - o[p2]) | (o[p2] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight); - sv.sideamount++; - } - a = (o[p4] - o[p3]) | (o[p3] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p4], PointLight); - sv.sideamount++; - } - a = (o[p5] - o[p4]) | (o[p4] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p4], o[p5], PointLight); - sv.sideamount++; - } - a = (o[p0] - o[p5]) | (o[p5] - PointLight); - if (a) - { - sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p5], o[p0], PointLight); - sv.sideamount++; - } - } -} - -inline bool NAABB_SV::Is_AABB_In_ShadowVolume(const Shadowvolume& sv, const AABB& Receiver) -{ - uint32 pa = sv.sideamount + sv.nplanes; - - f32 d; - const Vec3* pAABB = &Receiver.min; - - union f32_u - { - float floatVal; - uint32 uintVal; - }; - - //------------------------------------------------------------------------------ - //---- check if receiver-AABB is in front of any of these planes ------ - //------------------------------------------------------------------------------ - for (uint32 x = 0; x < pa; x++) - { - d = sv.oplanes[x].d; - - //avoid breaking strict aliasing rules - f32_u ux; - ux.floatVal = sv.oplanes[x].n.x; - f32_u uy; - uy.floatVal = sv.oplanes[x].n.y; - f32_u uz; - uz.floatVal = sv.oplanes[x].n.z; - const uint32 bitX = ux.uintVal >> 31; - const uint32 bitY = uy.uintVal >> 31; - const uint32 bitZ = uz.uintVal >> 31; - - d += sv.oplanes[x].n.x * pAABB[bitX].x; - d += sv.oplanes[x].n.y * pAABB[bitY].y; - d += sv.oplanes[x].n.z * pAABB[bitZ].z; - if (d > 0) - { - return CULL_EXCLUSION; - } - } - return CULL_OVERLAP; -} - -inline char NAABB_SV::Is_AABB_In_ShadowVolume_hierarchical(const Shadowvolume& sv, const AABB& Receiver) -{ - uint32 pa = sv.sideamount + sv.nplanes; - const Vec3* pAABB = &Receiver.min; - - f32 dot1, dot2; - uint32 notOverlap = 0x80000000; // will be reset to 0 if there's at least one overlapping - - union f32_u - { - float floatVal; - uint32 uintVal; - }; - - //------------------------------------------------------------------------------ - //---- check if receiver-AABB is in front of any of these planes ------ - //------------------------------------------------------------------------------ - for (uint32 x = 0; x < pa; x++) - { - dot1 = dot2 = sv.oplanes[x].d; - - //avoid breaking strict aliasing rules - f32_u ux; - ux.floatVal = sv.oplanes[x].n.x; - f32_u uy; - uy.floatVal = sv.oplanes[x].n.y; - f32_u uz; - uz.floatVal = sv.oplanes[x].n.z; - const uint32 bitX = ux.uintVal >> 31; - const uint32 bitY = uy.uintVal >> 31; - const uint32 bitZ = uz.uintVal >> 31; - - dot1 += sv.oplanes[x].n.x * pAABB[0 + bitX].x; - dot2 += sv.oplanes[x].n.x * pAABB[1 - bitX].x; - dot1 += sv.oplanes[x].n.y * pAABB[0 + bitY].y; - dot2 += sv.oplanes[x].n.y * pAABB[1 - bitY].y; - dot1 += sv.oplanes[x].n.z * pAABB[0 + bitZ].z; - dot2 += sv.oplanes[x].n.z * pAABB[1 - bitZ].z; - PREFAST_SUPPRESS_WARNING(6001) f32_u d; - d.floatVal = dot1; - if (!(d.uintVal & 0x80000000)) - { - return CULL_EXCLUSION; - } - PREFAST_SUPPRESS_WARNING(6001) f32_u d2; - d2.floatVal = dot2; - notOverlap &= d2.uintVal; - } - if (notOverlap) - { - return CULL_INCLUSION; - } - return CULL_OVERLAP; -} - -#endif // CRYINCLUDE_CRYCOMMON_AABBSV_H - diff --git a/Code/CryEngine/CryCommon/Algorithm.h b/Code/CryEngine/CryCommon/Algorithm.h deleted file mode 100644 index 554fe7f507..0000000000 --- a/Code/CryEngine/CryCommon/Algorithm.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_ALGORITHM_H -#define CRYINCLUDE_CRYCOMMON_ALGORITHM_H -#pragma once -//short hand for using stl algorithms. same syntax (from users perspective) of c++17 range library. Only the shorthand algorithms from range library(N4128) though. -//Not all algorithms are covered. Add any as you need them. It would be a fair amount of work to add them all, so I'm just adding them as needed. -//Note Android doesn't have non member cbegin and cend yet. - -#include -#include -#include - -namespace std17 -{ - template - void for_each(const Container& con, Callable callable) - { - std::for_each(begin(con), end(con), callable); - } - - template - bool any_of(const Container& con, UnaryPredicate pred) - { - return std::any_of(begin(con), end(con), pred); - } - - template - bool all_of(const Container& con, UnaryPredicate pred) - { - return std::all_of(begin(con), end(con), pred); - } - - template - bool none_of(const Container& con, UnaryPredicate pred) - { - return std::none_of(begin(con), end(con), pred); - } - - template - typename Container::iterator find_if(Container& con, UnaryPredicate pred) - { - return std::find_if(begin(con), end(con), pred); - } - - template - T accumulate(const Container& con, T init) - { - return std::accumulate(begin(con), end(con), init); - } - - template - T accumulate(const Container& con, T init, BinaryOperation binary_op) - { - return std::accumulate(begin(con), end(con), init, binary_op); - } - - template - auto count_if(const Container&con, UnaryPredicate pred)->decltype(std::count_if(begin(con), end(con), pred)) - { - return std::count_if(begin(con), end(con), pred); - } -} - -#endif // CRYINCLUDE_CRYCOMMON_ALGORITHM_H diff --git a/Code/CryEngine/CryCommon/Allocator.h b/Code/CryEngine/CryCommon/Allocator.h deleted file mode 100644 index 682de1e862..0000000000 --- a/Code/CryEngine/CryCommon/Allocator.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_ALLOCATOR_H -#pragma once - -#include "CryMemoryAllocator.h" - -//////////////////////////////////////////////////////////////////////// -// Allocator default implementation - -struct StdAllocator -{ - // Class-specific alloc/free/size functions. Use aligned versions only when necessary. - template - static void* Allocate(T*& p) - { - return p = NeedAlign() ? - (T*)CryModuleMemalign(sizeof(T), alignof(T)) : - (T*)CryModuleMalloc(sizeof(T)); - } - - template - static void Deallocate(T* p) - { - if (NeedAlign()) - { - CryModuleMemalignFree(p); - } - else - { - CryModuleFree(p); - } - } - - template - static size_t GetMemSize(const T* p) - { - return NeedAlign() ? - sizeof(T) + alignof(T) : - sizeof(T); - } - - template - void GetMemoryUsage(ICrySizer* pSizer) const { /*nothing*/} -protected: - - template - static bool NeedAlign() - { PREFAST_SUPPRESS_WARNING(6326); return alignof(T) > _ALIGNMENT; } -}; - -// Handy delete template function, for any allocator. -template -void Delete(TAlloc& alloc, T* ptr) -{ - if (ptr) - { - ptr->~T(); - alloc.Deallocate(ptr); - } -} - -#endif // CRYINCLUDE_CRYCOMMON_ALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/AnimTime.h b/Code/CryEngine/CryCommon/AnimTime.h deleted file mode 100644 index 8bd0b9d442..0000000000 --- a/Code/CryEngine/CryCommon/AnimTime.h +++ /dev/null @@ -1,173 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __animtime_h__ -#define __animtime_h__ - -#include -#include -#include - -struct SAnimTime -{ - static const uint numTicksPerSecond = 6000; - - // List of possible frame rates (dividers of 6000). Most commonly used ones first. - enum EFrameRate - { - // Common - eFrameRate_30fps, eFrameRate_60fps, eFrameRate_120fps, - - // Possible - eFrameRate_10fps, eFrameRate_12fps, eFrameRate_15fps, eFrameRate_24fps, - eFrameRate_25fps, eFrameRate_40fps, eFrameRate_48fps, eFrameRate_50fps, - eFrameRate_75fps, eFrameRate_80fps, eFrameRate_100fps, eFrameRate_125fps, - eFrameRate_150fps, eFrameRate_200fps, eFrameRate_240fps, eFrameRate_250fps, - eFrameRate_300fps, eFrameRate_375fps, eFrameRate_400fps, eFrameRate_500fps, - eFrameRate_600fps, eFrameRate_750fps, eFrameRate_1000fps, eFrameRate_1200fps, - eFrameRate_1500fps, eFrameRate_2000fps, eFrameRate_3000fps, eFrameRate_6000fps, - - eFrameRate_Num - }; - - SAnimTime() - : m_ticks(0) {} - explicit SAnimTime(int32 ticks) - : m_ticks(ticks) {} - explicit SAnimTime(float time) - : m_ticks(aznumeric_caster(std::lround(static_cast(time) * numTicksPerSecond))) {} - - static uint GetFrameRateValue(EFrameRate frameRate) - { - const uint frameRateValues[eFrameRate_Num] = - { - // Common - 30, 60, 120, - - // Possible - 10, 12, 15, 24, 25, 40, 48, 50, 75, 80, 100, 125, - 150, 200, 240, 250, 300, 375, 400, 500, 600, 750, - 1000, 1200, 1500, 2000, 3000, 6000 - }; - - return frameRateValues[frameRate]; - } - - static const char* GetFrameRateName(EFrameRate frameRate) - { - const char* frameRateNames[eFrameRate_Num] = - { - // Common - "30 fps", "60 fps", "120 fps", - - // Possible - "10 fps", "12 fps", "15 fps", "24 fps", - "25 fps", "40 fps", "48 fps", "50 fps", - "75 fps", "80 fps", "100 fps", "125 fps", - "150 fps", "200 fps", "240 fps", "250 fps", - "300 fps", "375 fps", "400 fps", "500 fps", - "600 fps", "750 fps", "1000 fps", "1200 fps", - "1500 fps", "2000 fps", "3000 fps", "6000 fps" - }; - - return frameRateNames[frameRate]; - } - - float ToFloat() const { return static_cast(m_ticks) / numTicksPerSecond; } - - void Serialize(Serialization::IArchive& ar) - { - ar(m_ticks, "ticks", "Ticks"); - } - - // Helper to serialize from ticks or old float time - void Serialize(XmlNodeRef keyNode, bool bLoading, const char* pName, const char* pLegacyName) - { - if (bLoading) - { - int32 ticks; - if (!keyNode->getAttr(pName, ticks)) - { - // Backwards compatibility - float time = 0.0f; - keyNode->getAttr(pLegacyName, time); - *this = SAnimTime(time); - } - else - { - m_ticks = ticks; - } - } - else if (m_ticks > 0) - { - keyNode->setAttr(pName, m_ticks); - } - } - - int32 GetTicks() const { return m_ticks; } - - static SAnimTime Min() { SAnimTime minTime; minTime.m_ticks = std::numeric_limits::lowest(); return minTime; } - static SAnimTime Max() { SAnimTime maxTime; maxTime.m_ticks = (std::numeric_limits::max)(); return maxTime; } - - SAnimTime operator-() const { return SAnimTime(-m_ticks); } - SAnimTime operator-(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks -= r.m_ticks; return temp; } - SAnimTime operator+(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks += r.m_ticks; return temp; } - SAnimTime operator*(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks *= r.m_ticks; return temp; } - SAnimTime operator/(SAnimTime r) const { SAnimTime temp; temp.m_ticks = static_cast((static_cast(m_ticks) * numTicksPerSecond) / r.m_ticks); return temp; } - SAnimTime operator%(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks %= r.m_ticks; return temp; } - SAnimTime operator*(float r) const { SAnimTime temp; temp.m_ticks = aznumeric_caster(std::lround(static_cast(m_ticks) * r)); return temp; } - SAnimTime operator/(float r) const { SAnimTime temp; temp.m_ticks = aznumeric_caster(std::lround(static_cast(m_ticks) / r)); return temp; } - SAnimTime& operator+=(SAnimTime r) { *this = *this + r; return *this; } - SAnimTime& operator-=(SAnimTime r) { *this = *this - r; return *this; } - SAnimTime& operator*=(SAnimTime r) { *this = *this * r; return *this; } - SAnimTime& operator/=(SAnimTime r) { *this = *this / r; return *this; } - SAnimTime& operator%=(SAnimTime r) { *this = *this % r; return *this; } - SAnimTime& operator*=(float r) { *this = *this * r; return *this; } - SAnimTime& operator/=(float r) { *this = *this / r; return *this; } - - bool operator<(SAnimTime r) const { return m_ticks < r.m_ticks; } - bool operator<=(SAnimTime r) const { return m_ticks <= r.m_ticks; } - bool operator>(SAnimTime r) const { return m_ticks > r.m_ticks; } - bool operator>=(SAnimTime r) const { return m_ticks >= r.m_ticks; } - bool operator==(SAnimTime r) const { return m_ticks == r.m_ticks; } - bool operator!=(SAnimTime r) const { return m_ticks != r.m_ticks; } - - // Snap to nearest multiple of given frame rate - SAnimTime SnapToNearest(const EFrameRate frameRate) - { - const int sign = sgn(m_ticks); - const int32 absTicks = abs(m_ticks); - - const int framesMod = numTicksPerSecond / GetFrameRateValue(frameRate); - const int32 remainder = absTicks % framesMod; - const bool bNextMultiple = remainder >= (framesMod / 2); - return SAnimTime(sign * ((absTicks - remainder) + (bNextMultiple ? framesMod : 0))); - } - -private: - int32 m_ticks; - - friend bool Serialize(Serialization::IArchive& ar, SAnimTime& animTime, const char* name, const char* label); -}; - -inline bool Serialize(Serialization::IArchive& ar, SAnimTime& animTime, const char* name, const char* label) -{ - return ar(animTime.m_ticks, name, label); -} - -inline SAnimTime abs(SAnimTime time) -{ - return (time >= SAnimTime(0)) ? time : -time; -} - -#endif diff --git a/Code/CryEngine/CryCommon/Bezier.h b/Code/CryEngine/CryCommon/Bezier.h deleted file mode 100644 index fa1cf60d49..0000000000 --- a/Code/CryEngine/CryCommon/Bezier.h +++ /dev/null @@ -1,321 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __BEZIER_H__ -#define __BEZIER_H__ - -#include -#include -#include - -struct SBezierControlPoint -{ - SBezierControlPoint() - : m_value(0.0f) - , m_inTangent(ZERO) - , m_outTangent(ZERO) - , m_inTangentType(eTangentType_Auto) - , m_outTangentType(eTangentType_Auto) - , m_bBreakTangents(false) - { - } - - enum ETangentType - { - eTangentType_Custom, - eTangentType_Auto, - eTangentType_Zero, - eTangentType_Step, - eTangentType_Linear, - }; - - void Serialize(Serialization::IArchive& ar) - { - ar(m_value, "value", "Value"); - - if (ar.IsOutput()) - { - bool breakTangents = m_bBreakTangents; - ar(breakTangents, "breakTangents", "Break Tangents"); - } - else - { - bool breakTangents = false; - ar(breakTangents, "breakTangents", "Break Tangents"); - m_bBreakTangents = breakTangents; - } - - if (ar.IsOutput()) - { - ETangentType inTangentType = m_inTangentType; - ar(inTangentType, "inTangentType", "Incoming tangent type"); - } - else - { - ETangentType inTangentType = eTangentType_Auto; - ar(inTangentType, "inTangentType", "Incoming tangent type"); - m_inTangentType = inTangentType; - } - - ar(m_inTangent, "inTangent", (m_inTangentType == eTangentType_Custom) ? "Incoming Tangent" : NULL); - - if (ar.IsOutput()) - { - ETangentType outTangentType = m_outTangentType; - ar(outTangentType, "outTangentType", "Outgoing tangent type"); - } - else - { - ETangentType outTangentType = eTangentType_Auto; - ar(outTangentType, "outTangentType", "Outgoing tangent type"); - m_outTangentType = outTangentType; - } - - ar(m_outTangent, "outTangent", (m_outTangentType == eTangentType_Custom) ? "Outgoing Tangent" : NULL); - } - - float m_value; - - // For 1D Bezier only the Y component is used - Vec2 m_inTangent; - Vec2 m_outTangent; - - ETangentType m_inTangentType : 4; - ETangentType m_outTangentType : 4; - bool m_bBreakTangents : 1; -}; - -struct SBezierKey -{ - SBezierKey() - : m_time(0) {} - - void Serialize(Serialization::IArchive& ar) - { - ar(m_time, "time", "Time"); - ar(m_controlPoint, "controlPoint", "Control Point"); - } - - SAnimTime m_time; - SBezierControlPoint m_controlPoint; -}; - -namespace Bezier -{ - inline float Evaluate(float t, float p0, float p1, float p2, float p3) - { - const float a = 1 - t; - const float aSq = a * a; - const float tSq = t * t; - return (aSq * a * p0) + (3.0f * aSq * t * p1) + (3.0f * a * tSq * p2) + (tSq * t * p3); - } - - inline float EvaluateDeriv(float t, float p0, float p1, float p2, float p3) - { - const float a = 1 - t; - const float ta = t * a; - const float aSq = a * a; - const float tSq = t * t; - return 3.0f * ((-p2 * tSq) + (p3 * tSq) - (p0 * aSq) + (p1 * aSq) + 2.0f * ((-p1 * ta) + (p2 * ta))); - } - - inline float EvaluateX(const float t, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = 0.0f; - const float p1 = p0 + start.m_outTangent.x; - const float p3 = duration; - const float p2 = p3 + end.m_inTangent.x; - return Evaluate(t, p0, p1, p2, p3); - } - - inline float EvaluateY(const float t, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = start.m_value; - const float p1 = p0 + start.m_outTangent.y; - const float p3 = end.m_value; - const float p2 = p3 + end.m_inTangent.y; - return Evaluate(t, p0, p1, p2, p3); - } - - // Duration = (time at end key) - (time at start key) - inline float EvaluateDerivX(const float t, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = 0.0f; - const float p1 = p0 + start.m_outTangent.x; - const float p3 = duration; - const float p2 = p3 + end.m_inTangent.x; - return EvaluateDeriv(t, p0, p1, p2, p3); - } - - inline float EvaluateDerivY(const float t, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - const float p0 = start.m_value; - const float p1 = p0 + start.m_outTangent.y; - const float p3 = end.m_value; - const float p2 = p3 + end.m_inTangent.y; - return EvaluateDeriv(t, p0, p1, p2, p3); - } - - // Find interpolation factor where 2D bezier curve has the given x value. Works only for curves where x is monotonically increasing. - // The passed x must be in range [0, duration]. Uses the Newton-Raphson root finding method. Usually takes 2 or 3 iterations. - // - // Note: This is for "1D" 2D bezier curves as used in TrackView. The curves are restricted by the curve editor to be monotonically increasing. - // - inline float InterpolationFactorFromX(const float x, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end) - { - float t = (x / duration); - - const float epsilon = 0.00001f; - const uint maxSteps = 10; - - for (uint i = 0; i < maxSteps; ++i) - { - const float currentX = EvaluateX(t, duration, start, end) - x; - if (fabs(currentX) <= epsilon) - { - break; - } - - const float currentXDeriv = EvaluateDerivX(t, duration, start, end); - t -= currentX / currentXDeriv; - } - - return t; - } - - inline SBezierControlPoint CalculateInTangent( - float time, const SBezierControlPoint& point, - float leftTime, const SBezierControlPoint* pLeftPoint, - float rightTime, const SBezierControlPoint* pRightPoint) - { - SBezierControlPoint newPoint = point; - - // In tangent X can never be positive - newPoint.m_inTangent.x = std::min(point.m_inTangent.x, 0.0f); - - if (pLeftPoint) - { - switch (point.m_inTangentType) - { - case SBezierControlPoint::eTangentType_Custom: - { - // Need to clamp tangent if it is reaching over last point - const float deltaTime = time - leftTime; - if (deltaTime < -newPoint.m_inTangent.x) - { - if (newPoint.m_inTangent.x == 0) - { - newPoint.m_inTangent = Vec2(ZERO); - } - else - { - float scaleFactor = deltaTime / -newPoint.m_inTangent.x; - newPoint.m_inTangent.x = -deltaTime; - newPoint.m_inTangent.y *= scaleFactor; - } - } - } - break; - case SBezierControlPoint::eTangentType_Zero: - // Fall through. Zero for y is same as Auto, x is set to 0.0f - case SBezierControlPoint::eTangentType_Auto: - { - const SBezierControlPoint& rightPoint = pRightPoint ? *pRightPoint : point; - const float deltaTime = (pRightPoint ? rightTime : time) - leftTime; - if (deltaTime > 0.0f) - { - const float ratio = (time - leftTime) / deltaTime; - const float deltaValue = rightPoint.m_value - pLeftPoint->m_value; - const bool bIsZeroTangent = (point.m_inTangentType == SBezierControlPoint::eTangentType_Zero); - newPoint.m_inTangent = Vec2(-(deltaTime * ratio) / 3.0f, bIsZeroTangent ? 0.0f : -(deltaValue * ratio) / 3.0f); - } - else - { - newPoint.m_inTangent = Vec2(ZERO); - } - } - break; - case SBezierControlPoint::eTangentType_Linear: - newPoint.m_inTangent = Vec2((leftTime - time) / 3.0f, - (pLeftPoint->m_value - point.m_value) / 3.0f); - break; - } - } - - return newPoint; - } - - inline SBezierControlPoint CalculateOutTangent( - float time, const SBezierControlPoint& point, - float leftTime, const SBezierControlPoint* pLeftPoint, - float rightTime, const SBezierControlPoint* pRightPoint) - { - SBezierControlPoint newPoint = point; - - // Out tangent X can never be negative - newPoint.m_outTangent.x = std::max(point.m_outTangent.x, 0.0f); - - if (pRightPoint) - { - switch (point.m_outTangentType) - { - case SBezierControlPoint::eTangentType_Custom: - { - // Need to clamp tangent if it is reaching over next point - const float deltaTime = rightTime - time; - if (deltaTime < newPoint.m_outTangent.x) - { - if (newPoint.m_outTangent.x == 0) - { - newPoint.m_outTangent = Vec2(ZERO); - } - else - { - float scaleFactor = deltaTime / newPoint.m_outTangent.x; - newPoint.m_outTangent.x = deltaTime; - newPoint.m_outTangent.y *= scaleFactor; - } - } - } - break; - case SBezierControlPoint::eTangentType_Zero: - // Fall through. Zero for y is same as Auto, x is set to 0.0f - case SBezierControlPoint::eTangentType_Auto: - { - const SBezierControlPoint& leftPoint = pLeftPoint ? *pLeftPoint : point; - const float deltaTime = rightTime - (pLeftPoint ? leftTime : time); - if (deltaTime > 0.0f) - { - const float ratio = (rightTime - time) / deltaTime; - const float deltaValue = pRightPoint->m_value - leftPoint.m_value; - const bool bIsZeroTangent = (point.m_outTangentType == SBezierControlPoint::eTangentType_Zero); - newPoint.m_outTangent = Vec2((deltaTime * ratio) / 3.0f, bIsZeroTangent ? 0.0f : (deltaValue * ratio) / 3.0f); - } - else - { - newPoint.m_outTangent = Vec2(ZERO); - } - } - break; - case SBezierControlPoint::eTangentType_Linear: - newPoint.m_outTangent = Vec2((rightTime - time) / 3.0f, - (pRightPoint->m_value - point.m_value) / 3.0f); - break; - } - } - - return newPoint; - } -} - -#endif diff --git a/Code/CryEngine/CryCommon/CGFContent.h b/Code/CryEngine/CryCommon/CGFContent.h deleted file mode 100644 index 9c6ff391ef..0000000000 --- a/Code/CryEngine/CryCommon/CGFContent.h +++ /dev/null @@ -1,903 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Describe contents on CGF file. - - -#ifndef CRYINCLUDE_CRYCOMMON_CGFCONTENT_H -#define CRYINCLUDE_CRYCOMMON_CGFCONTENT_H -#pragma once - -#include // <> required for Interfuscator -#include // <> required for Interfuscator -#include -#include -#include -#include -#include - -#include //Required for LOD support for touch bending vegetation -#include //Required for LOD support for touch bending vegetation - -const int CGF_NODE_NAME_LENGTH = 64; -//END: Add LOD support for touch bending vegetation - -struct CMaterialCGF; -struct IConvertContext; - -#define CGF_NODE_NAME_LOD_PREFIX "$lod" - -////////////////////////////////////////////////////////////////////////// -// This structure represents CGF node. -////////////////////////////////////////////////////////////////////////// -struct CNodeCGF - : public _cfg_reference_target -{ - enum ENodeType - { - NODE_MESH, - NODE_LIGHT, - NODE_HELPER, - }; - enum EPhysicalizeFlags - { - ePhysicsalizeFlag_MeshNotNeeded = BIT(2), // When set physics data doesn't need additional Mesh indices or vertices. - ePhysicsalizeFlag_NoBreaking = BIT(3), // node is unsuitable for procedural 3d breaking - }; - - ENodeType type; - //START: Add LOD support for touch bending vegetation - char name[CGF_NODE_NAME_LENGTH]; - //END: Add LOD support for touch bending vegetation - string properties; - Matrix34 localTM; // Local space transformation matrix. - Matrix34 worldTM; // World space transformation matrix. - CNodeCGF* pParent; // Pointer to parent node. - CNodeCGF* pSharedMesh; // Not NULL if this node is sharing mesh and physics from referenced Node. - CMesh* pMesh; // Pointer to mesh loaded for this node. (Only when type == NODE_MESH) - - HelperTypes helperType; // Only relevant if type==NODE_HELPER - Vec3 helperSize; // Only relevant if type==NODE_HELPER - - CMaterialCGF* pMaterial; // Material node. - - // Physical data of the node with mesh. - int nPhysicalizeFlags; // Saved into the nFlags2 chunk member. - AZStd::vector physicalGeomData[4]; - int nPhysTriCount; // Not saved! only used for statistics in RC - - ////////////////////////////////////////////////////////////////////////// - // Used internally. - int nChunkId; // Chunk id as loaded from CGF. - int nParentChunkId; // Chunk id of parent Node. - int nObjectChunkId; // Chunk id of the corresponding mesh. - int pos_cont_id; // position controller chunk id - int rot_cont_id; // rotation controller chunk id - int scl_cont_id; // scale controller chunk id - ////////////////////////////////////////////////////////////////////////// - - // True if worldTM is identity. - bool bIdentityMatrix; - // True when this node is invisible physics proxy. - bool bPhysicsProxy; - - // These values are not saved, but are only used for loading empty mesh chunks. - struct MeshInfo - { - int nVerts; - int nIndices; - int nSubsets; - Vec3 bboxMin; - Vec3 bboxMax; - float fGeometricMean; - }; - MeshInfo meshInfo; - - CrySkinVtx* pSkinInfo; // for skinning with skeleton meshes (deformable objects) - - ////////////////////////////////////////////////////////////////////////// - // Constructor. - ////////////////////////////////////////////////////////////////////////// - void Init() - { - type = NODE_MESH; - localTM.SetIdentity(); - worldTM.SetIdentity(); - pParent = 0; - pSharedMesh = 0; - pMesh = 0; - pMaterial = 0; - helperType = HP_POINT; - helperSize.Set(0, 0, 0); - nPhysicalizeFlags = 0; - nChunkId = 0; - nParentChunkId = 0; - nObjectChunkId = 0; - pos_cont_id = rot_cont_id = scl_cont_id = 0; - bIdentityMatrix = true; - bPhysicsProxy = false; - pSkinInfo = 0; - nPhysTriCount = 0; - - ZeroStruct(meshInfo); - } - - CNodeCGF() - { - Init(); - } - - explicit CNodeCGF(_cfg_reference_target::DeleteFncPtr pDeleteFnc) - : _cfg_reference_target(pDeleteFnc) - { - Init(); - } - - ~CNodeCGF() - { - if (!pSharedMesh) - { - delete pMesh; - } - if (pSkinInfo) - { - delete[] pSkinInfo; - } - } -}; - - -////////////////////////////////////////////////////////////////////////// -// structures for skinning -////////////////////////////////////////////////////////////////////////// - -struct TFace -{ - uint16 i0, i1, i2; - TFace() {} - TFace(uint16 v0, uint16 v1, uint16 v2) { i0 = v0; i1 = v1; i2 = v2; } - TFace(const CryFace& face) { i0 = aznumeric_caster(face[0]); i1 = aznumeric_caster(face[1]); i2 = aznumeric_caster(face[2]); } - void operator = (const TFace& f) { i0 = f.i0; i1 = f.i1; i2 = f.i2; } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} - AUTO_STRUCT_INFO -}; - -struct PhysicalProxy -{ - uint32 ChunkID; - DynArray m_arrPoints; - DynArray m_arrIndices; - DynArray m_arrMaterials; -}; - -struct MorphTargets -{ - uint32 MeshID; - string m_strName; - DynArray m_arrIntMorph; - DynArray m_arrExtMorph; -}; - -typedef MorphTargets* MorphTargetsPtr; - -struct IntSkinVertex -{ - Vec3 __obsolete0; // thin/fat vertex position. must be removed in the next RC refactoring - Vec3 pos; // vertex-position of model.2 - Vec3 __obsolete2; // thin/fat vertex position. must be removed in the next RC refactoring - uint16 boneIDs[4]; - f32 weights[4]; - ColorB color; //index for blend-array - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} - AUTO_STRUCT_INFO -}; - - - -////////////////////////////////////////////////////////////////////////// -// TCB Controller implementation. -////////////////////////////////////////////////////////////////////////// - - -// retrieves the position and orientation (in the logarithmic space, i.e. instead of quaternion, its logarithm is returned) -// may be optimal for motion interpolation -struct PQLog -{ - Vec3 vPos; - Vec3 vRotLog; // logarithm of the rotation - void blendPQ (const PQLog& pqFrom, const PQLog& pqTo, f32 fBlend); - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -struct CControllerType -{ - uint16 m_controllertype; - uint16 m_index; - CControllerType() - { - m_controllertype = 0xffff; - m_index = 0xffff; - } -}; - -struct TCBFlags -{ - uint8 f0, f1; - TCBFlags() { f0 = f1 = 0; } -}; - -struct CStoredSkinningInfo -{ - int32 m_nTicksPerFrame; - f32 m_secsPerTick; - int32 m_nStart; - int32 m_nEnd; - f32 m_Speed; - f32 m_Distance; - f32 m_Slope; - int m_nAssetFlags; - f32 m_LHeelStart, m_LHeelEnd; - f32 m_LToe0Start, m_LToe0End; - f32 m_RHeelStart, m_RHeelEnd; - f32 m_RToe0Start, m_RToe0End; - Vec3 m_MoveDirection; // raw storage - - CStoredSkinningInfo() - : m_Speed(-1.0f) - , m_Distance(-1.0f) - , m_nAssetFlags(0) - , m_LHeelStart(-10000.0f) - , m_LHeelEnd(-10000.0f) - , m_LToe0Start(-10000.0f) - , m_LToe0End(-10000.0f) - , m_RHeelStart(-10000.0f) - , m_RHeelEnd(-10000.0f) - , m_RToe0Start(-10000.0f) - , m_RToe0End(-10000.0f) - , m_Slope(-1.0f) - { - } - AUTO_STRUCT_INFO -}; - - - -// structure for recreating controllers -struct CControllerInfo -{ - uint32 m_nControllerID; - uint32 m_nPosKeyTimeTrack; - uint32 m_nPosTrack; - uint32 m_nRotKeyTimeTrack; - uint32 m_nRotTrack; - - CControllerInfo() - : m_nControllerID(~0) - , m_nPosKeyTimeTrack(~0) - , m_nPosTrack(~0) - , m_nRotKeyTimeTrack(~0) - , m_nRotTrack(~0) {} - - AUTO_STRUCT_INFO -}; - -struct MeshCollisionInfo -{ - AABB m_aABB; - OBB m_OBB; - Vec3 m_Pos; - DynArray m_arrIndexes; - int32 m_iBoneId; - - MeshCollisionInfo() - { - // This didn't help much. - // The BBs are reset to opposite infinites, - // but never clamped/grown by any member points. - m_aABB.min.zero(); - m_aABB.max.zero(); - m_OBB.m33.SetIdentity(); - m_OBB.h.zero(); - m_OBB.c.zero(); - m_Pos.zero(); - } - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_arrIndexes); - } -}; - - - -struct SJointsAimIK_Rot -{ - const char* m_strJointName; - int16 m_nJointIdx; - int16 m_nPosIndex; - uint8 m_nPreEvaluate; - uint8 m_nAdditive; - int16 m_nRotJointParentIdx; - SJointsAimIK_Rot() - { - m_strJointName = 0; - m_nJointIdx = -1; - m_nPosIndex = -1; - m_nPreEvaluate = 0; - m_nAdditive = 0; - m_nRotJointParentIdx = -1; - }; - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -struct SJointsAimIK_Pos -{ - const char* m_strJointName; - int16 m_nJointIdx; - uint8 m_nAdditive; - uint8 m_nEmpty; - SJointsAimIK_Pos() - { - m_strJointName = 0; - m_nJointIdx = -1; - m_nAdditive = 0; - m_nEmpty = 0; - }; - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - - -struct DirectionalBlends -{ - string m_AnimToken; - uint32 m_AnimTokenCRC32; - const char* m_strParaJointName; - int16 m_nParaJointIdx; - int16 m_nRotParaJointIdx; - const char* m_strStartJointName; - int16 m_nStartJointIdx; - int16 m_nRotStartJointIdx; - const char* m_strReferenceJointName; - int32 m_nReferenceJointIdx; - DirectionalBlends() - { - m_AnimTokenCRC32 = 0; - m_strParaJointName = 0; - m_nParaJointIdx = -1; - m_nRotParaJointIdx = -1; - m_strStartJointName = 0; - m_nStartJointIdx = -1; - m_nRotStartJointIdx = -1; - m_strReferenceJointName = 0; - m_nReferenceJointIdx = 1; //by default we use the Pelvis - }; - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} -}; - - -struct CSkinningInfo - : public _reference_target_t -{ - DynArray m_arrBonesDesc; //animation-bones - - DynArray m_LookIK_Rot; //rotational joints used for Look-IK - DynArray m_LookIK_Pos; //positional joints used for Look-IK - DynArray m_LookDirBlends; //positional joints used for Look-IK - - DynArray m_AimIK_Rot; //rotational joints used for Aim-IK - DynArray m_AimIK_Pos; //positional joints used for Aim-IK - DynArray m_AimDirBlends; //positional joints used for Aim-IK - - - DynArray m_arrPhyBoneMeshes; //collision proxi - DynArray m_arrMorphTargets; - DynArray m_arrIntFaces; - DynArray m_arrIntVertices; - DynArray m_arrExt2IntMap; - DynArray m_arrBoneEntities; //physical-bones - DynArray m_arrCollisions; - - uint32 m_numChunks{ 0 }; - bool m_bRotatedMorphTargets; - bool m_bProperBBoxes; - - CSkinningInfo() - : m_bRotatedMorphTargets(false) - , m_bProperBBoxes(false) {} - - ~CSkinningInfo() - { - for (DynArray::iterator it = m_arrMorphTargets.begin(), end = m_arrMorphTargets.end(); it != end; ++it) - { - delete *it; - } - } - - int32 GetJointIDByName(const char* strJointName) const - { - uint32 numJoints = m_arrBonesDesc.size(); - for (uint32 i = 0; i < numJoints; i++) - { - if (_stricmp(m_arrBonesDesc[i].m_arrBoneName, strJointName) == 0) - { - return i; - } - } - return -1; - } - - // Return name of bone from bone table, return zero id nId is out of range - const char* GetJointNameByID(int32 nJointID) const - { - int32 numJoints = m_arrBonesDesc.size(); - if (nJointID >= 0 && nJointID < numJoints) - { - return m_arrBonesDesc[nJointID].m_arrBoneName; - } - return ""; // invalid bone id - } -}; - -////////////////////////////////////////////////////////////////////////// -// This structure represents Material inside CGF. -////////////////////////////////////////////////////////////////////////// -struct CMaterialCGF - : public _cfg_reference_target -{ - char name[128]; // Material name; - int nFlags; // Material flags. - int nPhysicalizeType; - bool bOldMaterial; - float shOpacity; - - // Array of sub materials. - DynArray subMaterials; - - ////////////////////////////////////////////////////////////////////////// - // Used internally. - int nChunkId; - ////////////////////////////////////////////////////////////////////////// - - void Init() - { - nFlags = 0; - nChunkId = 0; - bOldMaterial = false; - nPhysicalizeType = PHYS_GEOM_TYPE_DEFAULT; - shOpacity = 1.f; - } - - CMaterialCGF() { Init(); } - - explicit CMaterialCGF(_cfg_reference_target::DeleteFncPtr pDeleteFnc) - : _cfg_reference_target(pDeleteFnc) - { Init(); } -}; - -////////////////////////////////////////////////////////////////////////// -// Info about physicalization of the CGF. -////////////////////////////////////////////////////////////////////////// -struct CPhysicalizeInfoCGF -{ - bool bWeldVertices; - float fWeldTolerance; // Min Distance between vertices when they collapse to single vertex if bWeldVertices enabled. - - // breakable physics - int nGranularity; - int nMode; - - Vec3* pRetVtx; - int nRetVtx; - int* pRetTets; - int nRetTets; - - CPhysicalizeInfoCGF() - : bWeldVertices(true) - , fWeldTolerance(0.01f) - , nMode(-1) - , nGranularity(-1) - , pRetVtx(0) - , nRetVtx(0) - , pRetTets(0) - , nRetTets(0){} - - ~CPhysicalizeInfoCGF() - { - if (pRetVtx) - { - delete []pRetVtx; - pRetVtx = 0; - } - if (pRetTets) - { - delete []pRetTets; - pRetTets = 0; - } - } -}; - - -////////////////////////////////////////////////////////////////////////// -// Serialized skinnable foliage data -////////////////////////////////////////////////////////////////////////// - -#define NODE_PROPERTY_STIFFNESS "stiffness" -#define NODE_PROPERTY_DAMPING "damping" -#define NODE_PROPERTY_THICKNESS "thickness" - -struct SSpineRC -{ - SSpineRC() - : pVtx(nullptr) - , pSegDim(nullptr) - , nVtx(0) - , len(0) - , pBoneIDs(nullptr) - , parentBoneID(-1) - , pStiffness(nullptr) - , pDamping(nullptr) - , pThickness(nullptr) {} - - ~SSpineRC() - { - if (pVtx) - { - delete[] pVtx; - } - if (pSegDim) - { - delete[] pSegDim; - } - if (pBoneIDs) - { - delete[] pBoneIDs; - } - if (pStiffness) - { - delete[] pStiffness; - } - if (pDamping) - { - delete[] pDamping; - } - if (pThickness) - { - delete[] pThickness; - } - } - - /// Add Skinned Geometry (.CGF) export type (for touch bending vegetation) - static float GetDefaultStiffness() { return 0.5f; } - static float GetDefaultDamping() { return 0.5f; } - static float GetDefaultThickness() { return 0.03f; } - - Vec3* pVtx; - Vec4* pSegDim; - int nVtx; - float len; - Vec3 navg; - - int parentBoneID; - int* pBoneIDs; - - //Per Bone parameters. - float* pStiffness; - float* pDamping; - float* pThickness; - - int iAttachSpine; - int iAttachSeg; -}; - -struct SFoliageInfoCGF -{ - SFoliageInfoCGF() { nSpines = 0; pSpines = 0; pBoneMapping = 0; } - ~SFoliageInfoCGF() - { - if (pSpines) - { - for (int i = 1; i < nSpines; i++) // spines 1..n-1 use the same buffer, so make sure they don't delete it - { - pSpines[i].pVtx = nullptr; - pSpines[i].pSegDim = nullptr; - pSpines[i].pBoneIDs = nullptr; - pSpines[i].pStiffness = nullptr; - pSpines[i].pDamping = nullptr; - pSpines[i].pThickness = nullptr; - } - delete[] pSpines; - } - - SAFE_DELETE_ARRAY(pBoneMapping); - - AZStd::unordered_map::iterator iter = boneMappings.begin(); - while (iter != boneMappings.end()) - { - if (iter->second != nullptr) - { - SAFE_DELETE_ARRAY(iter->second->pBoneMapping); - } - iter++; - } - - } - - SSpineRC* pSpines; - int nSpines; - - ///Bone mappings for each LOD level - AZStd::unordered_map boneMappings; - - ///Bone mapping for legacy format - struct SMeshBoneMapping_uint8* pBoneMapping; - int nSkinnedVtx; - - DynArray chunkBoneIds; -}; - - -////////////////////////////////////////////////////////////////////////// -struct CExportInfoCGF -{ - bool bMergeAllNodes; - bool bUseCustomNormals; - bool bCompiledCGF; - bool bHavePhysicsProxy; - bool bHaveAutoLods; - bool bNoMesh; - bool bWantF32Vertices; - bool b8WeightsPerVertex; - - /// Prevent reprocessing skinning data for skinned CGF - bool bSkinnedCGF; - - bool bFromColladaXSI; - bool bFromColladaMAX; - bool bFromColladaMAYA; - - unsigned int rc_version[4]; // Resource compiler version. - char rc_version_string[16]; // Version as a string. - - unsigned int authorToolVersion; -}; - -////////////////////////////////////////////////////////////////////////// -// This class contain all info loaded from the CGF file. -////////////////////////////////////////////////////////////////////////// -class CContentCGF -{ -public: - ////////////////////////////////////////////////////////////////////////// - CContentCGF(const char* filename) - { - azstrcpy(m_filename, AZ_ARRAY_SIZE(m_filename), filename); - memset(&m_exportInfo, 0, sizeof(m_exportInfo)); - m_exportInfo.bMergeAllNodes = true; - m_exportInfo.bUseCustomNormals = false; - m_exportInfo.bWantF32Vertices = false; - m_exportInfo.b8WeightsPerVertex = false; - m_exportInfo.bSkinnedCGF = false; - m_pCommonMaterial = 0; - m_bConsoleFormat = false; - m_pOwnChunkFile = 0; - } - - ////////////////////////////////////////////////////////////////////////// - virtual ~CContentCGF() - { - // Free nodes. - m_nodes.clear(); - if (m_pOwnChunkFile) - { - m_pOwnChunkFile->Release(); - } - } - - ////////////////////////////////////////////////////////////////////////// - const char* GetFilename() const - { - return m_filename; - } - - void SetFilename(const char* filename) - { - azstrcpy(m_filename, AZ_ARRAY_SIZE(m_filename), filename); - } - - ////////////////////////////////////////////////////////////////////////// - // Access to CGF nodes. - void AddNode(CNodeCGF* pNode) - { - m_nodes.push_back(pNode); - } - - int GetNodeCount() const - { - return m_nodes.size(); - } - - CNodeCGF* GetNode(int i) - { - return m_nodes[i]; - } - - const CNodeCGF* GetNode(int i) const - { - return m_nodes[i]; - } - - void ClearNodes() - { - m_nodes.clear(); - } - - void RemoveNode(CNodeCGF* pNode) - { - assert(pNode); - for (int i = 0; i < m_nodes.size(); ++i) - { - if (m_nodes[i] == pNode) - { - pNode->pParent = 0; - m_nodes.erase(i); - break; - } - } - } - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Access to CGF materials. - void AddMaterial(CMaterialCGF* pNode) - { - m_materials.push_back(pNode); - } - - int GetMaterialCount() const - { - return m_materials.size(); - } - - CMaterialCGF* GetMaterial(int i) - { - return m_materials[i]; - } - - void ClearMaterials() - { - m_materials.clear(); - } - - CMaterialCGF* GetCommonMaterial() const - { - return m_pCommonMaterial; - } - - void SetCommonMaterial(CMaterialCGF* pMtl) - { - m_pCommonMaterial = pMtl; - } - - DynArray& GetUsedMaterialIDs() - { - return m_usedMaterialIds; - } - - const DynArray& GetUsedMaterialIDs() const - { - return m_usedMaterialIds; - } - - ////////////////////////////////////////////////////////////////////////// - - CPhysicalizeInfoCGF* GetPhysicalizeInfo() - { - return &m_physicsInfo; - } - - const CPhysicalizeInfoCGF* GetPhysicalizeInfo() const - { - return &m_physicsInfo; - } - - CExportInfoCGF* GetExportInfo() - { - return &m_exportInfo; - } - - const CExportInfoCGF* GetExportInfo() const - { - return &m_exportInfo; - } - - CSkinningInfo* GetSkinningInfo() - { - return &m_SkinningInfo; - } - - const CSkinningInfo* GetSkinningInfo() const - { - return &m_SkinningInfo; - } - - SFoliageInfoCGF* GetFoliageInfo() - { - return &m_foliageInfo; - } - - bool GetConsoleFormat() - { - return m_bConsoleFormat; - } - - bool ValidateMeshes(const char** const ppErrorDescription) const - { - for (int i = 0; i < m_nodes.size(); ++i) - { - const CNodeCGF* const pNode = m_nodes[i]; - if (pNode && pNode->pMesh && (!pNode->pMesh->Validate(ppErrorDescription))) - { - return false; - } - } - return true; - } - - // Set chunk file that this CGF owns. - void SetChunkFile(IChunkFile* pChunkFile) - { - m_pOwnChunkFile = pChunkFile; - } - -public: - bool m_bConsoleFormat; - -private: - char m_filename[260]; - CSkinningInfo m_SkinningInfo; - DynArray<_smart_ptr > m_nodes; - DynArray<_smart_ptr > m_materials; - DynArray m_usedMaterialIds; - _smart_ptr m_pCommonMaterial; - - CPhysicalizeInfoCGF m_physicsInfo; - CExportInfoCGF m_exportInfo; - SFoliageInfoCGF m_foliageInfo; - - IChunkFile* m_pOwnChunkFile; -}; - -namespace AZ -{ - namespace SceneAPI - { - namespace DataTypes - { - class IAnimationGroup; - } - } -} - -// Asset Writer interface for writing CContentCGF content to asset file -struct IAssetWriter -{ - virtual ~IAssetWriter() - { - } - - virtual bool WriteCGF(CContentCGF* content) = 0; - virtual bool WriteCHR(CContentCGF* content, IConvertContext* convertContext) = 0; - virtual bool WriteSKIN(CContentCGF* content, IConvertContext* convertContext, bool exportMorphTargets) = 0; -}; - - -#endif // CRYINCLUDE_CRYCOMMON_CGFCONTENT_H diff --git a/Code/CryEngine/CryCommon/CGFContent_info.cpp b/Code/CryEngine/CryCommon/CGFContent_info.cpp deleted file mode 100644 index 27d61c2f62..0000000000 --- a/Code/CryEngine/CryCommon/CGFContent_info.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "TypeInfo_impl.h" -#include "CGFContent.h" - -STRUCT_INFO_BEGIN(TFace) -STRUCT_VAR_INFO(i0, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(i1, TYPE_INFO(uint16)) -STRUCT_VAR_INFO(i2, TYPE_INFO(uint16)) -STRUCT_INFO_END(TFace) - -STRUCT_INFO_BEGIN(IntSkinVertex) -STRUCT_VAR_INFO(__obsolete0, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(pos, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(__obsolete2, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(boneIDs, TYPE_ARRAY(4, TYPE_INFO(uint16))) -STRUCT_VAR_INFO(weights, TYPE_ARRAY(4, TYPE_INFO(f32))) -STRUCT_VAR_INFO(color, TYPE_INFO(ColorB)) -STRUCT_INFO_END(IntSkinVertex) - -STRUCT_INFO_BEGIN(CStoredSkinningInfo) -STRUCT_VAR_INFO(m_nTicksPerFrame, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_secsPerTick, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_nStart, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_nEnd, TYPE_INFO(int32)) -STRUCT_VAR_INFO(m_Speed, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_Distance, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_Slope, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_nAssetFlags, TYPE_INFO(int)) -STRUCT_VAR_INFO(m_LHeelStart, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_LHeelEnd, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_LToe0Start, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_LToe0End, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RHeelStart, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RHeelEnd, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RToe0Start, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_RToe0End, TYPE_INFO(f32)) -STRUCT_VAR_INFO(m_MoveDirection, TYPE_INFO(Vec3)) -STRUCT_INFO_END(CStoredSkinningInfo) - -STRUCT_INFO_BEGIN(CControllerInfo) -STRUCT_VAR_INFO(m_nControllerID, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nPosKeyTimeTrack, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nPosTrack, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nRotKeyTimeTrack, TYPE_INFO(uint32)) -STRUCT_VAR_INFO(m_nRotTrack, TYPE_INFO(uint32)) -STRUCT_INFO_END(CControllerInfo) - -STRUCT_INFO_BEGIN(UCol) -STRUCT_VAR_INFO(dcolor, TYPE_INFO(uint32)) -STRUCT_INFO_END(UCol) - -STRUCT_INFO_BEGIN(SVF_P3S_C4B_T2S) -STRUCT_VAR_INFO(xyz, TYPE_INFO(Vec3f16)) -STRUCT_VAR_INFO(color, TYPE_INFO(UCol)) -STRUCT_VAR_INFO(st, TYPE_INFO(Vec2f16)) -STRUCT_INFO_END(SVF_P3S_C4B_T2S) diff --git a/Code/CryEngine/CryCommon/CMakeLists.txt b/Code/CryEngine/CryCommon/CMakeLists.txt index 4725489358..3a1eb90d9d 100644 --- a/Code/CryEngine/CryCommon/CMakeLists.txt +++ b/Code/CryEngine/CryCommon/CMakeLists.txt @@ -9,58 +9,15 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_pal_tool_dirs(pal_tool_dirs ${CMAKE_CURRENT_LIST_DIR}/Platform) - ly_add_target( NAME CryCommon STATIC NAMESPACE Legacy FILES_CMAKE crycommon_files.cmake - ${pal_dir}/crycommon_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/crycommon_${PAL_PLATFORM_NAME_LOWERCASE}.cmake INCLUDE_DIRECTORIES PUBLIC . # Lots of code without CryCommon/ .. # Dangerous since exports CryEngine's path (client code can do CrySystem/ without depending on that target) - ${pal_dir} - ${pal_tool_dirs} - BUILD_DEPENDENCIES - PUBLIC - AZ::AzCore - AZ::AzFramework -) - -ly_add_target( - NAME CryCommon.EngineSettings.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - crycommon_enginesettings_files.cmake - ${pal_dir}/crycommon_enginesettings_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - ${pal_dir} - BUILD_DEPENDENCIES - PUBLIC - AZ::AzCore - AZ::AzFramework -) - -ly_add_target( - NAME CryCommon.EngineSettings.RC.Static STATIC - NAMESPACE Legacy - FILES_CMAKE - crycommon_enginesettings_files.cmake - ${pal_dir}/crycommon_enginesettings_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - ${pal_dir} - COMPILE_DEFINITIONS - PRIVATE - RESOURCE_COMPILER BUILD_DEPENDENCIES PUBLIC AZ::AzCore diff --git a/Code/CryEngine/CryCommon/CREBaseCloud.h b/Code/CryEngine/CryCommon/CREBaseCloud.h deleted file mode 100644 index b7a95d88d4..0000000000 --- a/Code/CryEngine/CryCommon/CREBaseCloud.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CREBASECLOUD_H__ -#define __CREBASECLOUD_H__ - -//================================================================================ - -class SCloudParticle -{ -public: - inline SCloudParticle(); - inline SCloudParticle(const Vec3& vPos, float fRadius, const ColorF& baseColor, float fTransparency = 0); - inline SCloudParticle(const Vec3& vPos, float fRadiusX, float fRadiusY, float fRotMin, float fRotMax, Vec2 vUV[]); - inline ~SCloudParticle(); - - float GetRadiusX() const { return m_fSize[0]; } - float GetRadiusY() const { return m_fSize[1]; } - float GetTransparency() const { return m_fTransparency; } - const Vec3& GetPosition() const { return m_vPosition; } - const ColorF& GetBaseColor() const { return m_vBaseColor; } - uint32 GetNumLitColors() const { return m_vLitColors.size(); } - inline const ColorF GetLitColor(unsigned int index) const; - float GetSquareSortDistance() const { return m_fSquareSortDistance; } - - //! Sets the radius of the particle. - void SetRadiusX(float rad) { m_fSize[0] = rad; } - void SetRadiusY(float rad) { m_fSize[1] = rad; } - void SetTransparency(float trans) { m_fTransparency = trans; } - void SetPosition(const Vec3& pos) { m_vPosition = pos; } - void SetBaseColor(const ColorF& col) { m_vBaseColor = col; } - void AddLitColor(const ColorF& col) { m_vLitColors.push_back(col); } - void ClearLitColors() { m_vLitColors.clear(); } - void SetSquareSortDistance(float fSquareDistance) { m_fSquareSortDistance = fSquareDistance; } - - bool operator<(const SCloudParticle& p) const - { - return (m_fSquareSortDistance < p.m_fSquareSortDistance); - } - - bool operator>(const SCloudParticle& p) const - { - return (m_fSquareSortDistance > p.m_fSquareSortDistance); - } - -protected: - float m_fTransparency; - Vec3 m_vPosition; - float m_fSize[2]; - float m_fRotMin; - float m_fRotMax; - ColorF m_vBaseColor; - TArray m_vLitColors; - Vec3 m_vEye; - - // for sorting particles during shading - float m_fSquareSortDistance; -public: - Vec2 m_vUV[2]; -}; - -inline SCloudParticle::SCloudParticle() -{ - m_fSize[0] = 0; - m_fTransparency = 0; - m_vPosition = Vec3(0, 0, 0); - m_vBaseColor = Col_Black; - m_vEye = Vec3(0, 0, 0); - m_fSquareSortDistance = 0; - - m_vLitColors.clear(); -} - -inline SCloudParticle::SCloudParticle(const Vec3& pos, float fRadius, const ColorF& baseColor, float fTransparency) -{ - m_fSize[0] = fRadius; - m_fSize[1] = fRadius; - m_fTransparency = fTransparency; - m_vPosition = pos; - m_vBaseColor = baseColor; - m_vUV[0] = Vec2(0, 0); - m_vUV[1] = Vec2(1, 1); - - m_fRotMin = 0; - m_fRotMax = 0; - m_vEye = Vec3(0, 0, 0); - m_fSquareSortDistance = 0; - - m_vLitColors.clear(); -} - -inline SCloudParticle::SCloudParticle(const Vec3& vPos, float fRadiusX, float fRadiusY, float fRotMin, float fRotMax, Vec2 vUV[2]) -{ - m_fSize[0] = fRadiusX; - m_fSize[1] = fRadiusY; - m_vPosition = vPos; - m_vBaseColor = Col_White; - m_vUV[0] = vUV[0]; - m_vUV[1] = vUV[1]; - m_fRotMin = fRotMin; - m_fRotMax = fRotMax; - - m_fTransparency = 1.0f; - m_vEye = Vec3(0, 0, 0); - m_fSquareSortDistance = 0; - - m_vLitColors.clear(); -} - -inline SCloudParticle::~SCloudParticle() -{ - m_vLitColors.clear(); -} - -inline const ColorF SCloudParticle::GetLitColor(unsigned int index) const -{ - if (index <= m_vLitColors.size()) - { - return m_vLitColors[index]; - } - else - { - return Col_Black; - } -} - -//=========================================================================== -class CREBaseCloud - : public CRendElementBase -{ - friend class CRECloud; - -public: - CREBaseCloud() - : CRendElementBase() - { - mfSetType(eDATA_Cloud); - mfUpdateFlags(FCEF_TRANSFORM); - } - virtual void SetParticles(SCloudParticle* pParticles, int nNumParticles) = 0; - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -#endif // __CREBASECLOUD_H__ diff --git a/Code/CryEngine/CryCommon/CREFogVolume.h b/Code/CryEngine/CryCommon/CREFogVolume.h deleted file mode 100644 index 83a024d15e..0000000000 --- a/Code/CryEngine/CryCommon/CREFogVolume.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#ifndef _CREFOGVOLUME_ -#define _CREFOGVOLUME_ - -#pragma once - -#include "VertexFormats.h" - - -struct IFogVolumeRenderNode; - - -class CREFogVolume - : public CRendElementBase -{ -public: - CREFogVolume(); - - virtual ~CREFogVolume(); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - - Vec3 m_center; - uint32 m_viewerInsideVolume : 1; - uint32 m_affectsThisAreaOnly : 1; - uint32 m_stencilRef : 8; - uint32 m_volumeType : 1; - uint32 m_reserved : 21; - AABB m_localAABB; - Matrix34 m_matWSInv; - float m_globalDensity; - float m_densityOffset; - float m_nearCutoff; - Vec2 m_softEdgesLerp; - ColorF m_fogColor; // color already combined with fHDRDynamic - Vec3 m_heightFallOffDirScaled; - Vec3 m_heightFallOffBasePoint; - Vec3 m_eyePosInWS; - Vec3 m_eyePosInOS; - Vec3 m_rampParams; - Vec3 m_windOffset; - float m_noiseScale; - Vec3 m_noiseFreq; - float m_noiseOffset; - float m_noiseElapsedTime; - Vec3 m_scale; -}; - - -#endif // #ifndef _CREFOGVOLUME_ diff --git a/Code/CryEngine/CryCommon/CREGameEffect.h b/Code/CryEngine/CryCommon/CREGameEffect.h deleted file mode 100644 index 17e68813ed..0000000000 --- a/Code/CryEngine/CryCommon/CREGameEffect.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#ifndef _CREGameEffect_ -#define _CREGameEffect_ - -#pragma once - -//================================================================================================== -// Name: IREGameEffect -// Desc: Interface for game effect render elements, designed to be instantiated in game code, and -// called from the CREGameEffect within the engine. This then allows render elements -// to be created in game code as well as in the engine. -// Author: James Chilvers -//================================================================================================== -struct IREGameEffect -{ - virtual ~IREGameEffect(){} - - virtual void mfPrepare(bool bCheckOverflow) = 0; - virtual bool mfDraw(CShader* ef, SShaderPass* sfm, CRenderObject* renderObj) = 0; -};//------------------------------------------------------------------------------------------------ - -//================================================================================================== -// Name: CREGameEffect -// Desc: Render element that uses the IREGameEffect interface for its functionality -// Author: James Chilvers -//================================================================================================== -class CREGameEffect - : public CRendElementBase -{ -public: - - CREGameEffect(); - ~CREGameEffect(); - - // CRendElementBase interface - void mfPrepare(bool bCheckOverflow); - bool mfDraw(CShader* ef, SShaderPass* sfm); - - // CREGameEffect interface - inline void SetPrivateImplementation(IREGameEffect* pImpl) { m_pImpl = pImpl; } - inline IREGameEffect* GetPrivateImplementation() const { return m_pImpl; } - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -private: - - IREGameEffect* m_pImpl; // Implementation of of render element -};//------------------------------------------------------------------------------------------------ - -#endif // #ifndef _CREGameEffect_ diff --git a/Code/CryEngine/CryCommon/CREGeomCache.h b/Code/CryEngine/CryCommon/CREGeomCache.h deleted file mode 100644 index 6911b8486e..0000000000 --- a/Code/CryEngine/CryCommon/CREGeomCache.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Backend part of geometry cache rendering - -#ifndef CRYINCLUDE_CRYCOMMON_CREGEOMCACHE_H -#define CRYINCLUDE_CRYCOMMON_CREGEOMCACHE_H -#pragma once - -#if defined(USE_GEOM_CACHES) - -#include -#include - -class CREGeomCache - : public CRendElementBase -{ -public: - struct SMeshInstance - { - AABB m_aabb; - Matrix34 m_matrix; - Matrix34 m_prevMatrix; - }; - - struct SMeshRenderData - { - DynArray m_instances; - _smart_ptr m_pRenderMesh; - }; - - struct UpdateList - { - CryCriticalSection m_mutex; - AZStd::vector> m_geoms; - }; - -public: - CREGeomCache(); - ~CREGeomCache(); - - bool Update(const int flags, const bool bTesselation); - static void UpdateModified(); - - // CRendElementBase interface - virtual bool mfUpdate(int Flags, bool bTessellation); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - // CREGeomCache interface - virtual void InitializeRenderElement(const uint numMeshes, _smart_ptr* pMeshes, uint16 materialId); - virtual void SetupMotionBlur(CRenderObject* pRenderObject, const SRenderingPassInfo& passInfo); - - virtual volatile int* SetAsyncUpdateState(int& threadId); - virtual DynArray* GetMeshFillDataPtr(); - virtual DynArray* GetRenderDataPtr(); - virtual void DisplayFilledBuffer(const int threadId); - - - AZ::Vertex::Format GetVertexFormat() const override; - bool GetGeometryInfo(SGeometryInfo &streams) override; - -private: - uint16 m_materialId; - volatile bool m_bUpdateFrame[2]; - volatile int m_transformUpdateState[2]; - - // We use a double buffered m_meshFillData array for input from the main thread. When data - // was successfully sent from the main thread it gets copied to m_meshRenderData - // This simplifies the cases where frame data is missing, e.g. meshFillData is not updated for a frame - // Note that meshFillData really needs to be double buffered because the copy occurs in render thread - // so the next main thread could already be touching the data again - // - // Note: m_meshRenderData is directly accessed for ray intersections via GetRenderDataPtr. - // This is safe, because it's only used in editor. - DynArray m_meshFillData[2]; - DynArray m_meshRenderData; - - static StaticInstance sm_updateList[2]; // double buffered update lists - - AZ::Vertex::Format m_geomCacheVertexFormat; -}; - -#endif -#endif // CRYINCLUDE_CRYCOMMON_CREGEOMCACHE_H diff --git a/Code/CryEngine/CryCommon/CREImposter.h b/Code/CryEngine/CryCommon/CREImposter.h deleted file mode 100644 index 1150212b7d..0000000000 --- a/Code/CryEngine/CryCommon/CREImposter.h +++ /dev/null @@ -1,194 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "Cry_Camera.h" - -//================================================================================ - -struct SDynTexture2; -struct SDynTexture; -class IDynTexture; -class CameraViewParameters; - -struct IImposterRenderElement -{ - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - virtual void mfPrepare(bool bCheckOverflow) = 0; - virtual bool mfDraw(CShader* ef, SShaderPass* sl) = 0; - virtual const SMinMaxBox& mfGetWorldSpaceBounds() = 0; - - virtual bool IsSplit() = 0; - virtual bool IsScreenImposter() = 0; - - virtual float GetRadiusX() = 0; - virtual float GetRadiusY() = 0; - virtual Vec3* GetQuadCorners() = 0; - virtual Vec3 GetNearPoint() = 0; - virtual Vec3 GetFarPoint() = 0; - virtual float GetErrorToleranceCosAngle() = 0; - virtual uint32 GetState() = 0; - virtual int GetAlphaRef() = 0; - virtual ColorF GetColorHelper() = 0; - virtual Vec3 GetLastSunDirection() = 0; - virtual uint8 GetLastBestEdge() = 0; - virtual float GetNear() = 0; - virtual float GetFar() = 0; - virtual float GetTransparency() = 0; - virtual Vec3 GetPosition(); - virtual int GetLogResolutionX() = 0; - virtual int GetLogResolutionY() = 0; - virtual CameraViewParameters& GetLastViewParameters() = 0; - virtual IDynTexture* GetTexture() = 0; - virtual IDynTexture* GetScreenTexture() = 0; - virtual IDynTexture* GetFrontTexture() = 0; - virtual IDynTexture* GetDepthTexture() = 0; - virtual const SMinMaxBox& GetWorldSpaceBounds() = 0; - - virtual void SetBBox(const Vec3& min, const Vec3& max) = 0; - virtual void SetScreenImposterState(bool state) = 0; - virtual void SetState(uint32 state) = 0; - virtual void SetAlphaRef(uint32 ref) = 0; - virtual void SetPosition(Vec3 pos) = 0; - virtual void SetFrameResetValue(int frameResetValue) = 0; - virtual void SetTexture(IDynTexture* texture) = 0; - virtual void SetScreenTexture(IDynTexture* texture) = 0; - virtual void SetFrontTexture(IDynTexture* texture) = 0; - virtual void SetDepthTexture(IDynTexture* texture) = 0; -}; - -class CREImposter - : public CRendElementBase -{ - friend class CRECloud; - static IDynTexture* m_pScreenTexture; - - CameraViewParameters m_LastViewParameters; - bool m_bScreenImposter; - bool m_bSplit; - float m_fRadiusX; - float m_fRadiusY; - Vec3 m_vQuadCorners[4]; // in world space, relative to m_vPos, in clockwise order, can be rotated - Vec3 m_vNearPoint; - Vec3 m_vFarPoint; - int m_nLogResolutionX; - int m_nLogResolutionY; - IDynTexture* m_pTexture; - IDynTexture* m_pFrontTexture; - IDynTexture* m_pTextureDepth; - float m_fErrorToleranceCosAngle; // cosine of m_fErrorToleranceAngle used to check if IsImposterValid - SMinMaxBox m_WorldSpaceBV; - uint32 m_State; - int m_AlphaRef; - float m_fCurTransparency; - ColorF m_ColorHelper; - Vec3 m_vPos; - Vec3 m_vLastSunDir; - uint8 m_nLastBestEdge; // 0..11 this edge is favored to not jitter between different edges - float m_fNear; - float m_fFar; - - bool IsImposterValid(const CameraViewParameters& viewParameters, float fRadiusX, float fRadiusY, float fCamRadiusX, float fCamRadiusY, - const int iRequiredLogResX, const int iRequiredLogResY, const uint32 dwBestEdge); - - bool Display(bool bDisplayFrontOfSplit); - -public: - int m_nFrameReset; - int m_FrameUpdate; - float m_fTimeUpdate; - - static int m_MemUpdated; - static int m_MemPostponed; - static int m_PrevMemUpdated; - static int m_PrevMemPostponed; - - CREImposter() - : CRendElementBase() - , m_pTexture(NULL) - , m_pFrontTexture(NULL) - , m_pTextureDepth(NULL) - , m_bSplit(false) - , m_fRadiusX(0) - , m_fRadiusY(0) - , m_fErrorToleranceCosAngle(cos(DEG2RAD(0.25f))) - , m_bScreenImposter(false) - , m_State(GS_DEPTHWRITE) - , m_AlphaRef(-1) - , m_fCurTransparency(1.0f) - , m_FrameUpdate(0) - , m_nFrameReset(0) - , m_fTimeUpdate(0) - , m_vLastSunDir(0, 0, 0) - , m_nLogResolutionX(0) - , m_nLogResolutionY(0) - , m_nLastBestEdge(0) - { - mfSetType(eDATA_Imposter); - mfUpdateFlags(FCEF_TRANSFORM); - m_ColorHelper = Col_White; - } - virtual ~CREImposter() - { - ReleaseResources(); - } - - bool UpdateImposter(); - void ReleaseResources(); - - bool PrepareForUpdate(); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sl); - const SMinMaxBox& mfGetWorldSpaceBounds() { return m_WorldSpaceBV; } - - virtual bool IsSplit() { return m_bSplit; } - virtual bool IsScreenImposter() { return m_bScreenImposter; } - - virtual float GetRadiusX() { return m_fRadiusX; } - virtual float GetRadiusY() { return m_fRadiusY; } - virtual Vec3* GetQuadCorners() { return &m_vQuadCorners[0]; } - virtual Vec3 GetNearPoint() { return m_vNearPoint; } - virtual Vec3 GetFarPoint() { return m_vFarPoint; } - virtual float GetErrorToleranceCosAngle() { return m_fErrorToleranceCosAngle; } - virtual uint32 GetState() { return m_State; } - virtual int GetAlphaRef() { return m_AlphaRef; } - virtual ColorF GetColorHelper() { return m_ColorHelper; } - virtual Vec3 GetLastSunDirection() { return m_vLastSunDir; } - virtual uint8 GetLastBestEdge() { return m_nLastBestEdge; } - virtual float GetNear() { return m_fNear; } - virtual float GetFar() { return m_fFar; } - virtual float GetTransparency() { return m_fCurTransparency; } - virtual Vec3 GetPosition(); - virtual int GetLogResolutionX() { return m_nLogResolutionX; } - virtual int GetLogResolutionY() { return m_nLogResolutionY; } - virtual CameraViewParameters& GetLastViewParameters() { return m_LastViewParameters; } - virtual IDynTexture** GetTexture() { return &m_pTexture; } - virtual IDynTexture** GetScreenTexture() { return &m_pScreenTexture; } - virtual IDynTexture** GetFrontTexture() { return &m_pFrontTexture; } - virtual IDynTexture** GetDepthTexture() { return &m_pTextureDepth; } - virtual const SMinMaxBox& GetWorldSpaceBounds() { return m_WorldSpaceBV; } - virtual int GetFrameReset() { return m_nFrameReset; } - virtual void SetBBox(const Vec3& min, const Vec3& max) { m_WorldSpaceBV.SetMin(min); m_WorldSpaceBV.SetMax(max); } - virtual void SetScreenImposterState(bool state) { m_bScreenImposter = state; } - virtual void SetState(uint32 state) { m_State = state; } - virtual void SetAlphaRef(uint32 ref) { m_AlphaRef = ref; } - virtual void SetPosition(Vec3 pos) { m_vPos = pos; } - virtual void SetFrameResetValue(int frameResetValue) { m_nFrameReset = frameResetValue; } -}; diff --git a/Code/CryEngine/CryCommon/CREMesh.h b/Code/CryEngine/CryCommon/CREMesh.h deleted file mode 100644 index 40df816808..0000000000 --- a/Code/CryEngine/CryCommon/CREMesh.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CREMESH_H__ -#define __CREMESH_H__ - -class CREMesh - : public CRendElementBase -{ -public: - - struct CRenderChunk* m_pChunk; - class CRenderMesh* m_pRenderMesh; - - // Copy of Chunk to avoid indirections - int32 m_nFirstIndexId; - int32 m_nNumIndices; - - uint32 m_nFirstVertId; - uint32 m_nNumVerts; - -protected: - CREMesh() - { - mfSetType(eDATA_Mesh); - mfUpdateFlags(FCEF_TRANSFORM); - - m_pChunk = NULL; - m_pRenderMesh = NULL; - m_nFirstIndexId = -1; - m_nNumIndices = -1; - m_nFirstVertId = 0; - m_nNumVerts = 0; - } - - virtual ~CREMesh() - { - } - - // Ideally should be declared and left unimplemented to prevent slicing at compile time - // but this would prevent auto code gen in renderer later on. - // To track potential slicing, uncomment the following (and their equivalent in CREMeshImpl) - //CREMesh(CREMesh&); - //CREMesh& operator=(CREMesh& rhs); -}; - -#endif // __CREMESH_H__ diff --git a/Code/CryEngine/CryCommon/CREOcclusionQuery.h b/Code/CryEngine/CryCommon/CREOcclusionQuery.h deleted file mode 100644 index 9350a74104..0000000000 --- a/Code/CryEngine/CryCommon/CREOcclusionQuery.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CREOCCLUSIONQUERY_H__ -#define __CREOCCLUSIONQUERY_H__ - -#define SUPP_HMAP_OCCL -#define SUPP_HWOBJ_OCCL - -//============================================================= - -class CRenderMesh; - -class CREOcclusionQuery - : public CRendElementBase -{ - friend class CRender3D; - bool m_bSucceeded; -public: - - int m_nVisSamples; - int m_nCheckFrame; - int m_nDrawFrame; - Vec3 m_vBoxMin; - Vec3 m_vBoxMax; - - UINT_PTR m_nOcclusionID; // this will carry a pointer LPDIRECT3DQUERY9, so it needs to be 64-bit on Windows 64 - - CRenderMesh* m_pRMBox; - static uint32 m_nQueriesPerFrameCounter; - static uint32 m_nReadResultNowCounter; - static uint32 m_nReadResultTryCounter; - - CREOcclusionQuery() - { - m_nOcclusionID = 0; - - m_nVisSamples = 800 * 600; - m_nCheckFrame = 0; - m_nDrawFrame = 0; - m_vBoxMin = Vec3(0, 0, 0); - m_vBoxMax = Vec3(0, 0, 0); - m_pRMBox = NULL; - - mfSetType(eDATA_OcclusionQuery); - mfUpdateFlags(FCEF_TRANSFORM); - } - - bool RT_ReadResult_Try(uint32 nDefaultNumSamples); - - ILINE bool HasSucceeded() const { return m_bSucceeded; } - - virtual ~CREOcclusionQuery(); - - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void mfReset(); - virtual bool mfReadResult_Try(uint32 nDefaultNumSamples = 1); - virtual bool mfReadResult_Now(); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -struct OcclusionTestClient -{ - OcclusionTestClient() - : nLastOccludedMainFrameID(0) - , nLastVisibleMainFrameID(0) - { -#ifdef SUPP_HMAP_OCCL - vLastVisPoint.Set(0, 0, 0); - nTerrainOccLastFrame = 0; -#endif -#ifdef SUPP_HWOBJ_OCCL - bOccluded = true; - pREOcclusionQuery = 0; -#endif - //nInstantTestRequested=0; - } -#ifdef SUPP_HWOBJ_OCCL - ~OcclusionTestClient() - { - if (pREOcclusionQuery) - { - pREOcclusionQuery->Release(false); - } - } -#endif - uint32 nLastVisibleMainFrameID, nLastOccludedMainFrameID; - uint32 nLastShadowCastMainFrameID, nLastNoShadowCastMainFrameID; -#ifdef SUPP_HMAP_OCCL - Vec3 vLastVisPoint; - int nTerrainOccLastFrame; -#endif -#ifdef SUPP_HWOBJ_OCCL - CREOcclusionQuery* pREOcclusionQuery; - uint8 bOccluded; -#endif - //uint8 nInstantTestRequested; -}; - - -#endif // CRYINCLUDE_CRYCOMMON_CREOCCLUSIONQUERY_H diff --git a/Code/CryEngine/CryCommon/CREPostProcess.h b/Code/CryEngine/CryCommon/CREPostProcess.h deleted file mode 100644 index 4803ae2166..0000000000 --- a/Code/CryEngine/CryCommon/CREPostProcess.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_CREPOSTPROCESS_H -#define CRYINCLUDE_CRYCOMMON_CREPOSTPROCESS_H -#pragma once - - -class CREPostProcess - : public CRendElementBase -{ - friend class CD3D9Renderer; - -public: - - CREPostProcess(); - virtual ~CREPostProcess(); - - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - // Use for setting numeric values, vec4 (colors, position, vectors, wtv), strings - virtual int mfSetParameter(const char* pszParam, float fValue, bool bForceValue = false) const; - virtual int mfSetParameterVec4(const char* pszParam, const Vec4& pValue, bool bForceValue = false) const; - virtual int mfSetParameterString(const char* pszParam, const char* pszArg) const; - - virtual void mfGetParameter(const char* pszParam, float& fValue) const; - virtual void mfGetParameterVec4(const char* pszParam, Vec4& pValue) const; - virtual void mfGetParameterString(const char* pszParam, const char*& pszArg) const; - - virtual int32 mfGetPostEffectID(const char* pPostEffectName) const; - - // Reset all post processing effects - virtual void Reset(bool bOnSpecChange = false); - virtual void mfReset() - { - Reset(); - } - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_CREPOSTPROCESS_H diff --git a/Code/CryEngine/CryCommon/CREPrismObject.h b/Code/CryEngine/CryCommon/CREPrismObject.h deleted file mode 100644 index 4ec290f1b9..0000000000 --- a/Code/CryEngine/CryCommon/CREPrismObject.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#ifndef _CREPRISMOBJECT_ -#define _CREPRISMOBJECT_ - -#pragma once - -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) - -class CREPrismObject - : public CRendElementBase -{ -public: - CREPrismObject(); - - virtual ~CREPrismObject() {} - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - - Vec3 m_center; -}; - -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - -#endif // _CREPRISMOBJECT_ diff --git a/Code/CryEngine/CryCommon/CRESky.h b/Code/CryEngine/CryCommon/CRESky.h deleted file mode 100644 index 3dfc7d184f..0000000000 --- a/Code/CryEngine/CryCommon/CRESky.h +++ /dev/null @@ -1,92 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CRESKY_H__ -#define __CRESKY_H__ - -//============================================================= - -#include "VertexFormats.h" -#include - -struct SSkyLightRenderParams; - -class CRESky - : public CRendElementBase -{ - friend class CRender3D; - -public: - - float m_fTerrainWaterLevel; - float m_fSkyBoxStretching; - float m_fAlpha; - int m_nSphereListId; - -public: - CRESky(); - virtual ~CRESky(); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - - AZ::Vertex::Format GetVertexFormat() const override; - bool GetGeometryInfo(SGeometryInfo& streams) override; - -private: - AZ::Vertex::Format m_skyVertexFormat; -}; - -class CREHDRSky - : public CRendElementBase -{ -public: - CREHDRSky(); - virtual ~CREHDRSky(); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - - void GenerateSkyDomeTextures(int32 width, int32 height); - - virtual AZ::Vertex::Format GetVertexFormat() const override; - virtual bool GetGeometryInfo(SGeometryInfo& streams) override; - -public: - const SSkyLightRenderParams* m_pRenderParams; - int m_moonTexId; - class CTexture* m_pSkyDomeTextureMie; - class CTexture* m_pSkyDomeTextureRayleigh; - - static void SetCommonMoonParams(CShader* ef, bool bUseMoon = false); - -private: - void Init(); - -private: - int m_skyDomeTextureLastTimeStamp; - int m_frameReset; - class CStars* m_pStars; - AZ::Vertex::Format m_hdrSkyVertexFormat; -}; - - -#endif // __CRESKY_H__ diff --git a/Code/CryEngine/CryCommon/CREVolumeObject.h b/Code/CryEngine/CryCommon/CREVolumeObject.h deleted file mode 100644 index 2137053a8e..0000000000 --- a/Code/CryEngine/CryCommon/CREVolumeObject.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#ifndef _CREVOLUMEOBJECT_ -#define _CREVOLUMEOBJECT_ - -#pragma once - -#include "VertexFormats.h" - - -struct IVolumeObjectRenderNode; - -struct IVolumeTexture -{ -public: - virtual ~IVolumeTexture() {} - virtual void Release() = 0; - virtual bool Create(unsigned int width, unsigned int height, unsigned int depth, unsigned char* pData) = 0; - virtual bool Update(unsigned int width, unsigned int height, unsigned int depth, const unsigned char* pData) = 0; - virtual int GetTexID() const = 0; - virtual uint32 GetWidth() const = 0; - virtual uint32 GetHeight() const = 0; - virtual uint32 GetDepth() const = 0; - virtual ITexture* GetTexture() const = 0; -}; - -class CREVolumeObject - : public CRendElementBase -{ -public: - CREVolumeObject(); - - virtual ~CREVolumeObject(); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - - virtual IVolumeTexture* CreateVolumeTexture() const; - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - - Vec3 m_center; - Matrix34 m_matInv; - Vec3 m_eyePosInWS; - Vec3 m_eyePosInOS; - Plane_tpl m_volumeTraceStartPlane; - AABB m_renderBoundsOS; - bool m_viewerInsideVolume; - bool m_nearPlaneIntersectsVolume; - float m_alpha; - float m_scale; - - IVolumeTexture* m_pDensVol; - IVolumeTexture* m_pShadVol; - _smart_ptr m_pHullMesh; -}; - -#endif // #ifndef _CREVOLUMEOBJECT_ diff --git a/Code/CryEngine/CryCommon/CREWaterOcean.h b/Code/CryEngine/CryCommon/CREWaterOcean.h deleted file mode 100644 index e8ca310d41..0000000000 --- a/Code/CryEngine/CryCommon/CREWaterOcean.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _CREWATEROCEAN_ -#define _CREWATEROCEAN_ - -class CWater; - -class CREWaterOcean - : public CRendElementBase -{ -public: - CREWaterOcean(); - virtual ~CREWaterOcean(); - - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void mfGetPlane(Plane_tpl& pl); - - virtual void Create(uint32 nVerticesCount, SVF_P3F_C4B_T2F* pVertices, uint32 nIndicesCount, const void* pIndices, uint32 nIndexSizeof); - void ReleaseOcean(); - - virtual Vec3 GetPositionAt(float x, float y) const; - virtual Vec4* GetDisplaceGrid() const; - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } -private: - - uint32 m_nVerticesCount; - uint32 m_nIndicesCount; - uint32 m_nIndexSizeof; - - void* m_pVertDecl; - void* m_pVertices; - void* m_pIndices; - -private: - - void UpdateFFT(); - void FrameUpdate(); -}; - - -#endif diff --git a/Code/CryEngine/CryCommon/CREWaterVolume.h b/Code/CryEngine/CryCommon/CREWaterVolume.h deleted file mode 100644 index 89102e3097..0000000000 --- a/Code/CryEngine/CryCommon/CREWaterVolume.h +++ /dev/null @@ -1,110 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -#ifndef _CREWATERVOLUME_ -#define _CREWATERVOLUME_ - -#pragma once - - -#include "VertexFormats.h" - -class CREWaterVolume - : public CRendElementBase -{ -public: - CREWaterVolume(); - - virtual ~CREWaterVolume(); - virtual void mfPrepare(bool bCheckOverflow); - virtual bool mfDraw(CShader* ef, SShaderPass* sfm); - virtual void mfGetPlane(Plane_tpl& pl); - virtual void mfCenter(Vec3& vCenter, CRenderObject* pObj); - - virtual void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this, sizeof(*this)); - } - -public: - struct SParams - { - SParams() - : m_pVertices(0) - , m_pIndices(0) - , m_numVertices(0) - , m_numIndices(0) - , m_center(0, 0, 0) - , m_WSBBox(Vec3(-1, -1, -1), Vec3(1, 1, 1)) - , m_fogPlane(Vec3(0, 0, 1), 0) - , m_fogDensity(0.1f) - , m_fogColor(0.2f, 0.5f, 0.7f) - , m_fogColorAffectedBySun(true) - , m_fogShadowing(0.5f) - , m_caustics(true) - , m_causticIntensity(1.0f) - , m_causticTiling(1.0f) - , m_causticHeight(0.9f) - , m_viewerInsideVolume(false) - , m_viewerCloseToWaterPlane(false) - , m_viewerCloseToWaterVolume(false) - { - } - - const SVF_P3F_C4B_T2F* m_pVertices; - const uint16* m_pIndices; - - size_t m_numVertices; - size_t m_numIndices; - - Vec3 m_center; - AABB m_WSBBox; - - Plane_tpl m_fogPlane; - float m_fogDensity; - Vec3 m_fogColor; - bool m_fogColorAffectedBySun; - float m_fogShadowing; - - bool m_caustics; - float m_causticIntensity; - float m_causticTiling; - float m_causticHeight; - - bool m_viewerInsideVolume; - bool m_viewerCloseToWaterPlane; - bool m_viewerCloseToWaterVolume; - }; - - struct SOceanParams - { - SOceanParams() - : m_fogColor(0.2f, 0.5f, 0.7f) - , m_fogColorShallow(0.2f, 0.5f, 0.7f) - , m_fogDensity(0.2f) - { - } - - Vec3 m_fogColor; - Vec3 m_fogColorShallow; - float m_fogDensity; - }; - -public: - const SParams* m_pParams; - const SOceanParams* m_pOceanParams; - bool m_drawWaterSurface; - bool m_drawFastPath; -}; - - -#endif // #ifndef _CREWATERVOLUME_ diff --git a/Code/CryEngine/CryCommon/Console_std.h b/Code/CryEngine/CryCommon/Console_std.h deleted file mode 100644 index 55944a2960..0000000000 --- a/Code/CryEngine/CryCommon/Console_std.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include - -#include - -namespace std -{ -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(Console_std_h) -#endif -} diff --git a/Code/CryEngine/CryCommon/CountedValue.h b/Code/CryEngine/CryCommon/CountedValue.h deleted file mode 100644 index 8ff3c5639c..0000000000 --- a/Code/CryEngine/CryCommon/CountedValue.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : A wrapper that counts the number of times the wrapped object -// has been set This is useful for netserializing an object -// that might be given a new value that s the same as the old value - - -#ifndef CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H -#define CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H -#pragma once - - -template -struct CountedValue -{ -public: - CountedValue() - : m_lastProducedId(0) - , m_lastConsumedId(0) {} - - typedef uint32 TCountedID; - - void SetAndDirty(const T& value) - { - m_value = value; - ++m_lastProducedId; - CRY_ASSERT(m_lastProducedId > 0); - } - - const T* GetLatestValue() - { - bool bHasNewValue = IsDirty(); // check for dirtiness before updating ids - m_lastConsumedId = m_lastProducedId; - - return bHasNewValue ? &m_value : NULL; - } - - inline bool IsDirty() const - { - return m_lastProducedId != m_lastConsumedId; - } - - const T& Peek() const - { - return m_value; - } - - TCountedID GetLatestID() const - { - return m_lastProducedId; - } - - // This method should only be used to update the object during serialization! - void UpdateDuringSerializationOnly(const T& value, TCountedID lastProducedId) - { - m_value = value; - m_lastProducedId = lastProducedId; - } - -private: - TCountedID m_lastProducedId; - TCountedID m_lastConsumedId; - T m_value; -}; - -#endif // CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H diff --git a/Code/CryEngine/CryCommon/CrtDebugStats.h b/Code/CryEngine/CryCommon/CrtDebugStats.h deleted file mode 100644 index 6f03d33c18..0000000000 --- a/Code/CryEngine/CryCommon/CrtDebugStats.h +++ /dev/null @@ -1,160 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// support for leak dumping and statistics gathering using vs Crt Debug -// should be included in every DLL below DllMain() -#ifndef CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H -#define CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H -#pragma once - -#ifdef WIN32 -#ifdef _DEBUG - - -#include -#include // CryLogAlways -#include - -// copied from DBGINT.H (not a public header!) - -#define nNoMansLandSize 4 - -typedef struct _CrtMemBlockHeader -{ - struct _CrtMemBlockHeader* pBlockHeaderNext; - struct _CrtMemBlockHeader* pBlockHeaderPrev; - char* szFileName; - int nLine; - size_t nDataSize; - int nBlockUse; - long lRequest; - unsigned char gap[nNoMansLandSize]; - /* followed by: - * unsigned char data[nDataSize]; - * unsigned char anotherGap[nNoMansLandSize]; - */ -} _CrtMemBlockHeader; - -struct SFileInfo -{ - int blocks; - INT_PTR bytes; //AMD Port - SFileInfo(INT_PTR b) { blocks = 1; bytes = b; }; //AMD Port -}; - -_CrtMemState lastcheckpoint; -bool checkpointset = false; - -extern "C" void __declspec(dllexport) CheckPoint() -{ - _CrtMemCheckpoint(&lastcheckpoint); - checkpointset = true; -}; - -bool pairgreater(const std::pair& elem1, const std::pair& elem2) -{ - return elem1.second.bytes > elem2.second.bytes; -} - -extern "C" void __declspec(dllexport) UsageSummary([[maybe_unused]] ILog * log, char* modulename, int* extras) -{ - _CrtMemState state; - - if (checkpointset) - { - _CrtMemState recent; - _CrtMemCheckpoint(&recent); - _CrtMemDifference(&state, &lastcheckpoint, &recent); - } - else - { - _CrtMemCheckpoint(&state); - }; - - INT_PTR numblocks = state.lCounts[_NORMAL_BLOCK]; //AMD Port - INT_PTR totalalloc = state.lSizes[_NORMAL_BLOCK]; //AMD Port - - check_convert(extras[0]) = totalalloc; - check_convert(extras[1]) = numblocks; - - CryLogAlways("$5---------------------------------------------------------------------------------------------------"); - - if (!numblocks) - { - CryLogAlways("$3Module %s has no memory in use", modulename); - return; - } - ; - - CryLogAlways("$5Usage summary for module %s", modulename); - CryLogAlways("%d kbytes (peak %d) in %d objects of %d average bytes\n", - totalalloc / 1024, state.lHighWaterCount / 1024, numblocks, numblocks ? totalalloc / numblocks : 0); - CryLogAlways("%d kbytes allocated over time\n", state.lTotalCount / 1024); - - typedef std::map FileMap; - FileMap fm; - - for (_CrtMemBlockHeader* h = state.pBlockHeader; h; h = h->pBlockHeaderNext) - { - if (_BLOCK_TYPE(h->nBlockUse) != _NORMAL_BLOCK) - { - continue; - } - string s = h->szFileName ? h->szFileName : "NO_SOURCE"; - if (h->nLine > 0) - { - char buf[16]; - sprintf_s(buf, "_%d", h->nLine); - s += buf; - } - FileMap::iterator it = fm.find(s); - if (it != fm.end()) - { - (*it).second.blocks++; - (*it).second.bytes += h->nDataSize; - } - else - { - fm.insert(FileMap::value_type(s, SFileInfo(h->nDataSize))); - }; - } - ; - - typedef std::vector< std::pair > FileVector; - FileVector fv; - for (FileMap::iterator it = fm.begin(); it != fm.end(); ++it) - { - fv.push_back((*it)); - } - std::sort(fv.begin(), fv.end(), pairgreater); - - for (FileVector::iterator it = fv.begin(); it != fv.end(); ++it) - { - CryLogAlways("%6d kbytes / %6d blocks allocated from %s\n", - (*it).second.bytes / 1024, (*it).second.blocks, (*it).first.c_str()); - } - ; -}; - -#endif // _DEBUG - -#if !defined(_RELEASE) && !defined(_DLL) && defined(HANDLE) -extern "C" HANDLE _crtheap; -extern "C" HANDLE __declspec(dllexport) GetDLLHeap() { - return _crtheap; -}; -#endif - -#endif // WIN32 - -#endif // CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H diff --git a/Code/CryEngine/CryCommon/CryArray.h b/Code/CryEngine/CryCommon/CryArray.h index 793201cf40..73a9a9ec38 100644 --- a/Code/CryEngine/CryCommon/CryArray.h +++ b/Code/CryEngine/CryCommon/CryArray.h @@ -15,7 +15,7 @@ #define CRYINCLUDE_CRYCOMMON_CRYARRAY_H #pragma once -#include // <> required for Interfuscator +#include "CryLegacyAllocator.h" //--------------------------------------------------------------------------- // Convenient iteration macros @@ -91,8 +91,6 @@ Public classes: Array StaticArray DynArray - FastDynArray - FixedDynArray StaticDynArray Support classes are placed in namespaces NArray and NAlloc to reduce global name usage. @@ -612,13 +610,6 @@ namespace NAlloc //--------------------------------------------------------------------------- // Allocators for DynArray. - // No reallocation, for use in FixedDynArray - struct NullAlloc - { - static void* alloc(void* pMem, [[maybe_unused]] size_t& nSize, [[maybe_unused]] size_t nAlign, [[maybe_unused]] bool bSlack = false) - { return pMem; } - }; - // Standard CryModule memory allocation, using aligned versions struct ModuleAlloc { @@ -655,128 +646,15 @@ namespace NAlloc // Standard allocator for DynArray stores a compatibility pointer in the memory typedef AllocCompatible StandardAlloc; - - // Allocator using specific heaps - struct GeneralHeapAlloc - : ModuleAlloc - { - IGeneralMemoryHeap* m_pHeap; - - GeneralHeapAlloc() - : m_pHeap(0) {} - - explicit GeneralHeapAlloc(IGeneralMemoryHeap* pHeap) - : m_pHeap(pHeap) {} - - void* alloc(void* pMem, size_t& nSize, size_t nAlign, bool bSlack = false) const - { - if (m_pHeap) - { - if (pMem) - { - if (!nSize) - { - // Dealloc - m_pHeap->Free(pMem); - return 0; - } - } - else if (nSize) - { - // Alloc - if (bSlack) - { - nSize = realloc_size(nSize); - } - return m_pHeap->Memalign(nAlign, nSize, ""); - } - } - - return ModuleAlloc::alloc(pMem, nSize, nAlign, bSlack); - } - }; }; //--------------------------------------------------------------------------- // Storage schemes for dynamic arrays namespace NArray { - /*--------------------------------------------------------------------------- - // STORAGE prototype for DynArray - // Extends ArrayStorage with resizing functionality. - - struct DynStorage - { - struct Store: ArrayStorage::Store - { - I capacity() const; - size_t get_alloc_size() const; - void resize_raw( I new_size, bool allow_slack ); - }; - }; - ---------------------------------------------------------------------------*/ - - //--------------------------------------------------------------------------- - // FastDynStorage: STORAGE scheme for DynArray. - // Simple extension to ArrayStorage: size & capacity fields are inline, 3 words storage, fast access. - - template - struct FastDynStorage - { - template - struct Store - : private A - , public ArrayStorage::Store - { - typedef ArrayStorage::Store super_type; - - using super_type::m_aElems; - using super_type::m_nCount; - - // Construction. - Store() - : m_nCapacity(0) - { - } - - Store(const A& a) - : A(a) - , m_nCapacity(0) - { - } - - I capacity() const - { return m_nCapacity; } - - size_t get_alloc_size() const - { return NAlloc::get_alloc_size(*this, m_aElems, capacity() * sizeof(T), alignof(T)); } - - void resize_raw(I new_size, bool allow_slack = false) - { - if (allow_slack ? new_size > capacity() : new_size != capacity()) - { - m_nCapacity = new_size; - m_aElems = NAlloc::reallocate(static_cast(*this), m_aElems, m_nCount, m_nCapacity, alignof(T), allow_slack); - } - set_size(new_size); - } - - protected: - - I m_nCapacity; - - void set_size(I new_size) - { - assert(new_size >= 0 && new_size <= capacity()); - m_nCount = new_size; - } - }; - }; - //--------------------------------------------------------------------------- // SmallDynStorage: STORAGE scheme for DynArray. // Array is just a single pointer, size and capacity information stored before the array data. - // Slightly slower than FastDynStorage, optimal for saving space, especially when array likely to be empty. template struct SmallDynStorage @@ -1459,35 +1337,6 @@ struct LegacyDynArray } }; - -//--------------------------------------------------------------------------- - -template -struct FastDynArray - : DynArray< T, I, NArray::FastDynStorage > -{ -}; - -template -struct FixedDynArray - : LegacyDynArray< T, I, NArray::FastDynStorage > -{ - typedef NArray::ArrayStorage::Store S; - - void set(void* elems, I mem_size) - { - this->m_aElems = (T*)elems; - this->m_nCapacity = mem_size / sizeof(T); - this->m_nCount = 0; - } - void set(Array array) - { - this->m_aElems = array.begin(); - this->m_nCapacity = array.size(); - this->m_nCount = 0; - } -}; - template struct StaticDynArray : LegacyDynArray< T, I, NArray::StaticDynStorage > diff --git a/Code/CryEngine/CryCommon/CryArray2d.h b/Code/CryEngine/CryCommon/CryArray2d.h deleted file mode 100644 index 531b23c7f6..0000000000 --- a/Code/CryEngine/CryCommon/CryArray2d.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ARRAY2D_H -#define CRYINCLUDE_CRYCOMMON_ARRAY2D_H -#pragma once - -// Dynamic replacement for static 2d array -template -struct Array2d -{ - Array2d() - { - m_nSize = 0; - m_pData = 0; - } - - int GetSize() const { return m_nSize; } - int GetDataSize() const { return m_nSize * m_nSize * sizeof(T); } - - T* GetData() { return m_pData; } - - T* GetDataEnd() { return &m_pData[m_nSize * m_nSize]; } - - void SetData(T* pData, int nSize) - { - Allocate(nSize); - memcpy(m_pData, pData, nSize * nSize * sizeof(T)); - } - - void Allocate(int nSize) - { - if (m_nSize == nSize) - { - return; - } - - delete [] m_pData; - - m_nSize = nSize; - m_pData = new T [nSize * nSize]; - memset(m_pData, 0, nSize * nSize * sizeof(T)); - } - - ~Array2d() - { - delete [] m_pData; - } - - void Reset() - { - delete [] m_pData; - m_pData = 0; - m_nSize = 0; - } - - T* m_pData; - int m_nSize; - - T* operator [] (const int& nPos) const - { - assert(nPos >= 0 && nPos < m_nSize); - return &m_pData[nPos * m_nSize]; - } - - Array2d& operator = (const Array2d& other) - { - Allocate(other.m_nSize); - memcpy(m_pData, other.m_pData, m_nSize * m_nSize * sizeof(T)); - return *this; - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_ARRAY2D_H diff --git a/Code/CryEngine/CryCommon/CryAssert_Android.h b/Code/CryEngine/CryCommon/CryAssert_Android.h index 68f716ec28..6e60df1bb1 100644 --- a/Code/CryEngine/CryCommon/CryAssert_Android.h +++ b/Code/CryEngine/CryCommon/CryAssert_Android.h @@ -31,7 +31,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { diff --git a/Code/CryEngine/CryCommon/CryAssert_Linux.h b/Code/CryEngine/CryCommon/CryAssert_Linux.h index 7c52f78366..f0acdd79db 100644 --- a/Code/CryEngine/CryCommon/CryAssert_Linux.h +++ b/Code/CryEngine/CryCommon/CryAssert_Linux.h @@ -34,7 +34,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { diff --git a/Code/CryEngine/CryCommon/CryAssert_Mac.h b/Code/CryEngine/CryCommon/CryAssert_Mac.h index 8cf49e1a5d..f7f74c3b58 100644 --- a/Code/CryEngine/CryCommon/CryAssert_Mac.h +++ b/Code/CryEngine/CryCommon/CryAssert_Mac.h @@ -30,7 +30,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { @@ -45,43 +45,6 @@ void CryAssertTrace(const char* szFormat, ...) } } } -/* -bool CryAssert(const char* szCondition, const char* szFile,unsigned int line, bool *pIgnore) -{ - if (!gEnv) return false; - - gEnv->pSystem->OnAssert(szCondition, gs_szMessage, szFile, line); - - if (!gEnv->bNoAssertDialog && !gEnv->bIgnoreAllAsserts) - { - EDialogAction action = MacOSXHandleAssert(szCondition, szFile, line, gs_szMessage, gEnv->pRenderer != NULL); - - switch (action) { - case eDAStop: - raise(SIGABRT); - exit(-1); - case eDABreak: - return true; - case eDAIgnoreAll: - gEnv->bIgnoreAllAsserts = true; - break; - case eDAIgnore: - *pIgnore = true; - break; - case eDAReportAsBug: - if ( gEnv && gEnv->pSystem) - { - gEnv->pSystem->ReportBug("Assert: %s - %s", szCondition,gs_szMessage); - } - - case eDAContinue: - default: - break; - } - } - - return false; -}*/ bool CryAssert(const char* szCondition, const char* szFile, unsigned int line, bool* pIgnore) { diff --git a/Code/CryEngine/CryCommon/CryAssert_iOS.h b/Code/CryEngine/CryCommon/CryAssert_iOS.h index ad668fb131..2cb08befff 100644 --- a/Code/CryEngine/CryCommon/CryAssert_iOS.h +++ b/Code/CryEngine/CryCommon/CryAssert_iOS.h @@ -31,7 +31,7 @@ void CryAssertTrace(const char* szFormat, ...) return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (szFormat == NULL) { diff --git a/Code/CryEngine/CryCommon/CryAssert_impl.h b/Code/CryEngine/CryCommon/CryAssert_impl.h index ed55162f1a..edbbb2f0c4 100644 --- a/Code/CryEngine/CryCommon/CryAssert_impl.h +++ b/Code/CryEngine/CryCommon/CryAssert_impl.h @@ -305,7 +305,7 @@ void CryAssertTrace(const char* _pszFormat, ...) { return; } - if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting) + if (!gEnv->bIgnoreAllAsserts) { if (NULL == _pszFormat) { diff --git a/Code/CryEngine/CryCommon/CryCustomTypes.h b/Code/CryEngine/CryCommon/CryCustomTypes.h index e8f83145eb..25578ce9cc 100644 --- a/Code/CryEngine/CryCommon/CryCustomTypes.h +++ b/Code/CryEngine/CryCommon/CryCustomTypes.h @@ -1207,23 +1207,4 @@ protected: uint nPrefixLength; }; - -// Define an irregular enum with TypeInfo - -#define DEFINE_ENUM_VALS(EType, TInt, ...) \ - struct EType \ - { \ - enum E { __VA_ARGS__ }; \ - DEFINE_ENUM_VALUE(EType, E, TInt) \ - ILINE static uint Count() { return TypeInfo().Count(); } \ - static const CEnumInfo& TypeInfo() { \ - static char enum_str[] = #__VA_ARGS__; \ - static LegacyDynArray Elems; \ - CEnumDef::SInit::Init(Elems); \ - CEnumDef::SInit __VA_ARGS__; \ - static CEnumInfo info( #EType, Elems, enum_str); \ - return info; \ - } \ - }; - #endif // CRYINCLUDE_CRYCOMMON_CRYCUSTOMTYPES_H diff --git a/Code/CryEngine/CryCommon/CryExtension/CryCreateClassInstance.h b/Code/CryEngine/CryCommon/CryExtension/CryCreateClassInstance.h deleted file mode 100644 index 1d1a4805d4..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/CryCreateClassInstance.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H -#define CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H -#pragma once - - -#include "ICryUnknown.h" -#include "ICryFactory.h" -#include "ICryFactoryRegistry.h" -#include // <> required for Interfuscator - - -template -bool CryCreateClassInstance(const CryClassID& cid, AZStd::shared_ptr& p) -{ - p = AZStd::shared_ptr(); - ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry(); - if (pFactoryReg) - { - ICryFactory* pFactory = pFactoryReg->GetFactory(cid); - if (pFactory && pFactory->ClassSupports(cryiidof())) - { - ICryUnknownPtr pUnk = pFactory->CreateClassInstance(); - AZStd::shared_ptr pT = cryinterface_cast(pUnk); - if (pT) - { - p = pT; - } - } - } - return p.get() != NULL; -} - - -template -bool CryCreateClassInstance(const char* cname, AZStd::shared_ptr& p) -{ - p = AZStd::shared_ptr(); - ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry(); - if (pFactoryReg) - { - ICryFactory* pFactory = pFactoryReg->GetFactory(cname); - if (pFactory != NULL && pFactory->ClassSupports(cryiidof())) - { - ICryUnknownPtr pUnk = pFactory->CreateClassInstance(); - AZStd::shared_ptr pT = cryinterface_cast(pUnk); - if (pT) - { - p = pT; - } - } - } - return p.get() != NULL; -} - - -template -bool CryCreateClassInstanceForInterface(const CryInterfaceID& iid, AZStd::shared_ptr& p) -{ - p = AZStd::shared_ptr(); - ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry(); - if (pFactoryReg) - { - size_t numFactories = 1; - ICryFactory* pFactory = 0; - pFactoryReg->IterateFactories(iid, &pFactory, numFactories); - if (numFactories == 1 && pFactory) - { - ICryUnknownPtr pUnk = pFactory->CreateClassInstance(); - AZStd::shared_ptr pT = cryinterface_cast(pUnk); - if (pT) - { - p = pT; - } - } - } - return p.get() != NULL; -} - - -#endif // CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H diff --git a/Code/CryEngine/CryCommon/CryExtension/CryGUID.h b/Code/CryEngine/CryCommon/CryExtension/CryGUID.h deleted file mode 100644 index a779e91bd2..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/CryGUID.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_CRYGUID_H -#define CRYINCLUDE_CRYEXTENSION_CRYGUID_H -#pragma once - -#include "Serialization/IArchive.h" -#include "Random.h" - -#include - -struct CryGUID -{ - uint64 hipart; - uint64 lopart; - - // !!! Do NOT turn CryGUID into a non-aggregate !!! - // It will prevent inlining and type list unrolling opportunities within - // cryinterface_cast() and cryiidof(). As such prevent constructors, - // non-public members, base classes and virtual functions! - - //CryGUID() : hipart(0), lopart(0) {} - //CryGUID(uint64 h, uint64 l) : hipart(h), lopart(l) {} - - static CryGUID Construct(const uint64& hipart, const uint64& lopart) - { - CryGUID guid = {hipart, lopart}; - return guid; - } - - static CryGUID Create() - { - uint64 lopart = 0; - uint64 hipart = 0; - while (lopart == 0 || hipart == 0) - { - const uint32 a = cry_random_uint32(); - const uint32 b = cry_random_uint32(); - const uint32 c = cry_random_uint32(); - const uint32 d = cry_random_uint32(); - lopart = (uint64)a | ((uint64)b << 32); - hipart = (uint64)c | ((uint64)d << 32); - } - - return Construct(lopart, hipart); - } - - static CryGUID Null() - { - return Construct(0, 0); - } - - bool operator ==(const CryGUID& rhs) const {return hipart == rhs.hipart && lopart == rhs.lopart; } - bool operator !=(const CryGUID& rhs) const {return hipart != rhs.hipart || lopart != rhs.lopart; } - bool operator <(const CryGUID& rhs) const {return hipart == rhs.hipart ? lopart < rhs.lopart : hipart < rhs.hipart; } - - void Serialize(Serialization::IArchive& ar) - { - if (ar.IsInput()) - { - uint32 dwords[4]; - ar(dwords, "guid"); - lopart = (((uint64)dwords[1]) << 32) | (uint64)dwords[0]; - hipart = (((uint64)dwords[3]) << 32) | (uint64)dwords[2]; - } - else - { - uint32 guid[4] = { - (uint32)(lopart & 0xFFFFFFFF), (uint32)((lopart >> 32) & 0xFFFFFFFF), - (uint32)(hipart & 0xFFFFFFFF), (uint32)((hipart >> 32) & 0xFFFFFFFF) - }; - ar(guid, "guid"); - } - } -}; - -// This is only used by the editor where we use C++ 11. -namespace std -{ - template<> - struct hash - { - public: - size_t operator()(const CryGUID& guid) const - { - std::hash hasher; - return hasher(guid.lopart) ^ hasher(guid.hipart); - } - }; -} - -namespace AZStd -{ - template<> - struct hash - { - public: - size_t operator()(const CryGUID& guid) const - { - std::hash hasher; - return hasher(guid); - } - }; -} - -#define MAKE_CRYGUID(high, low) CryGUID::Construct((uint64) high##LL, (uint64) low##LL) - - -#endif // CRYINCLUDE_CRYEXTENSION_CRYGUID_H diff --git a/Code/CryEngine/CryCommon/CryExtension/CryTypeID.h b/Code/CryEngine/CryCommon/CryExtension/CryTypeID.h deleted file mode 100644 index 16ae05b448..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/CryTypeID.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H -#define CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H -#pragma once - - -#include "CryGUID.h" - - -typedef CryGUID CryInterfaceID; -typedef CryGUID CryClassID; - - -#endif // CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H diff --git a/Code/CryEngine/CryCommon/CryExtension/ICryFactory.h b/Code/CryEngine/CryCommon/CryExtension/ICryFactory.h deleted file mode 100644 index a1a7344198..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/ICryFactory.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H -#define CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H -#pragma once - - -#include "CryTypeID.h" -#include - -struct ICryUnknown; -DECLARE_SMART_POINTERS(ICryUnknown); - -struct ICryFactory -{ - virtual const char* GetName() const = 0; - virtual const CryClassID& GetClassID() const = 0; - virtual bool ClassSupports(const CryInterfaceID& iid) const = 0; - virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const = 0; - virtual ICryUnknownPtr CreateClassInstance() const = 0; - -protected: - // prevent explicit destruction from client side (delete, shared_ptr, etc) - virtual ~ICryFactory() {} -}; - -#endif // CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H diff --git a/Code/CryEngine/CryCommon/CryExtension/ICryFactoryRegistry.h b/Code/CryEngine/CryCommon/CryExtension/ICryFactoryRegistry.h deleted file mode 100644 index f97c0780a1..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/ICryFactoryRegistry.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H -#define CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H -#pragma once - - -#include "CryTypeID.h" - - -struct ICryFactory; - - -struct ICryFactoryRegistry -{ - virtual ICryFactory* GetFactory(const char* cname) const = 0; - virtual ICryFactory* GetFactory(const CryClassID& cid) const = 0; - /** - * Iterates all factories implementing the interface specified by \p iid. - * \param[in] iid ID of the interface to iterate. Often procured using cryiidof<...>(). - * \param[out] pFactories A pointer of the array of factories to fill in. May be nullptr (see below). - * \param[in] Size (in elements) of the pFactories array [out] Number of elements actually written to pFactories or, when pFactories is null, the number of elements that would be written if sufficient storage was available. - * - * Example: - * \code{.cpp} - * size_t factoryCount = 0; - * // Assigns the number of found factories to factoryCount - * factoryRegistry->IterateFactories(cryiidof(), 0, factoryCount); - * // Allocate an array of the proper length on the stack - * ICryFactory** factories = static_cast(alloca(sizeof(ICryFactory*) * factoryCount); - * // Fill in factories with factoryCount results. - * factoryRegistry->IterateFactories(cryiidof(), factories, factoryCount); - * \endcode - */ - virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const = 0; - -protected: - // prevent explicit destruction from client side (delete, shared_ptr, etc) - virtual ~ICryFactoryRegistry() {} -}; - -#endif // CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H diff --git a/Code/CryEngine/CryCommon/CryExtension/ICryUnknown.h b/Code/CryEngine/CryCommon/CryExtension/ICryUnknown.h deleted file mode 100644 index 0de018305b..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/ICryUnknown.h +++ /dev/null @@ -1,224 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H -#define CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H -#pragma once - - -#include "CryTypeID.h" -#include - - -struct ICryFactory; -struct ICryUnknown; - -namespace InterfaceCastSemantics -{ - template - const CryInterfaceID& cryiidof() - { - return T::IID(); - } - -#define _BEFRIEND_CRYIIDOF() \ - template \ - friend const CryInterfaceID&InterfaceCastSemantics::cryiidof(); - - - template - Dst* cryinterface_cast(Src* p) - { - return static_cast(p ? p->QueryInterface(cryiidof()) : 0); - } - - template - Dst* cryinterface_cast(const Src* p) - { - return static_cast(p ? p->QueryInterface(cryiidof()) : 0); - } - - namespace Internal - { - template - struct cryinterface_cast_shared_ptr_helper; - - template - struct cryinterface_cast_shared_ptr_helper - { - static AZStd::shared_ptr Op(const AZStd::shared_ptr& p) - { - Dst* dp = cryinterface_cast(p.get()); - return dp ? AZStd::shared_ptr(p, dp) : AZStd::shared_ptr(); - } - }; - - template - struct cryinterface_cast_shared_ptr_helper - { - static AZStd::shared_ptr Op(const AZStd::shared_ptr& p) - { - ICryUnknown* dp = cryinterface_cast(p.get()); - return dp ? AZStd::shared_ptr(*((const AZStd::shared_ptr*) & p), dp) : AZStd::shared_ptr(); - } - }; - - template - struct cryinterface_cast_shared_ptr_helper - { - static AZStd::shared_ptr Op(const AZStd::shared_ptr& p) - { - const ICryUnknown* dp = cryinterface_cast(p.get()); - return dp ? AZStd::shared_ptr(*((const AZStd::shared_ptr*) & p), dp) : AZStd::shared_ptr(); - } - }; - } // namespace Internal - - template - AZStd::shared_ptr cryinterface_cast(const AZStd::shared_ptr& p) - { - return Internal::cryinterface_cast_shared_ptr_helper::Op(p); - } - -#define _BEFRIEND_CRYINTERFACE_CAST() \ - template \ - friend Dst * InterfaceCastSemantics::cryinterface_cast(Src*); \ - template \ - friend Dst * InterfaceCastSemantics::cryinterface_cast(const Src*); \ - template \ - friend AZStd::shared_ptr InterfaceCastSemantics::cryinterface_cast(const AZStd::shared_ptr&); -} // namespace InterfaceCastSemantics - -using InterfaceCastSemantics::cryiidof; -using InterfaceCastSemantics::cryinterface_cast; - - -template -bool CryIsSameClassInstance(S* p0, T* p1) -{ - return static_cast(p0) == static_cast(p1) || cryinterface_cast(p0) == cryinterface_cast(p1); -} - -template -bool CryIsSameClassInstance(const AZStd::shared_ptr& p0, T* p1) -{ - return CryIsSameClassInstance(p0.get(), p1); -} - -template -bool CryIsSameClassInstance(S* p0, const AZStd::shared_ptr& p1) -{ - return CryIsSameClassInstance(p0, p1.get()); -} - -template -bool CryIsSameClassInstance(const AZStd::shared_ptr& p0, const AZStd::shared_ptr& p1) -{ - return CryIsSameClassInstance(p0.get(), p1.get()); -} - - -namespace CompositeQuerySemantics -{ - template - AZStd::shared_ptr crycomposite_query(Src* p, const char* name, bool* pExposed = 0) - { - void* pComposite = p ? p->QueryComposite(name) : 0; - pExposed ? *pExposed = pComposite != 0 : 0; - return pComposite ? *static_cast*>(pComposite) : AZStd::shared_ptr(); - } - - template - AZStd::shared_ptr crycomposite_query(const Src* p, const char* name, bool* pExposed = 0) - { - void* pComposite = p ? p->QueryComposite(name) : 0; - pExposed ? *pExposed = pComposite != 0 : 0; - return pComposite ? *static_cast*>(pComposite) : AZStd::shared_ptr(); - } - - template - AZStd::shared_ptr crycomposite_query(const AZStd::shared_ptr& p, const char* name, bool* pExposed = 0) - { - return crycomposite_query(p.get(), name, pExposed); - } - - template - AZStd::shared_ptr crycomposite_query(const AZStd::shared_ptr& p, const char* name, bool* pExposed = 0) - { - return crycomposite_query(p.get(), name, pExposed); - } - -#define _BEFRIEND_CRYCOMPOSITE_QUERY() \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(Src*, const char*, bool*); \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(const Src*, const char*, bool*); \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(const AZStd::shared_ptr&, const char*, bool*); \ - template \ - friend AZStd::shared_ptr CompositeQuerySemantics::crycomposite_query(const AZStd::shared_ptr&, const char*, bool*); -} // namespace CompositeQuerySemantics - -using CompositeQuerySemantics::crycomposite_query; - - -#define _BEFRIEND_MAKE_SHARED() \ - template \ - friend class AZStd::Internal::sp_ms_deleter; \ - template \ - friend AZStd::shared_ptr AZStd::make_shared(); \ - template \ - friend AZStd::shared_ptr AZStd::allocate_shared(A const& a); - -// prevent explicit destruction from client side -#define _PROTECTED_DTOR(iname) \ -protected: \ - virtual ~iname() {} - - -// Befriending cryinterface_cast() and crycomposite_query() via CRYINTERFACE_DECLARE is actually only needed for ICryUnknown -// since QueryInterface() and QueryComposite() are usually not redeclared in derived interfaces but it doesn't hurt either -#define CRYINTERFACE_DECLARE(iname, iidHigh, iidLow) \ - _BEFRIEND_CRYIIDOF() \ - _BEFRIEND_CRYINTERFACE_CAST() \ - _BEFRIEND_CRYCOMPOSITE_QUERY() \ - _BEFRIEND_MAKE_SHARED() \ - _PROTECTED_DTOR(iname) \ - \ -private: \ - static const CryInterfaceID& IID() \ - { \ - static const CryInterfaceID iid = {(uint64) iidHigh##LL, (uint64) iidLow##LL}; \ - return iid; \ - } \ -public: - - -struct ICryUnknown -{ - CRYINTERFACE_DECLARE(ICryUnknown, 0x1000000010001000, 0x1000100000000000) - - virtual ICryFactory * GetFactory() const = 0; - -protected: - virtual void* QueryInterface(const CryInterfaceID& iid) const = 0; - virtual void* QueryComposite(const char* name) const = 0; -}; - -DECLARE_SMART_POINTERS(ICryUnknown); - - -#endif // CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/ClassWeaver.h b/Code/CryEngine/CryCommon/CryExtension/Impl/ClassWeaver.h deleted file mode 100644 index c3b5bb340c..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/ClassWeaver.h +++ /dev/null @@ -1,461 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H -#pragma once - -#include "TypeList.h" -#include "Conversion.h" -#include "RegFactoryNode.h" -#include "../ICryUnknown.h" -#include "../ICryFactory.h" -#include - -namespace CW -{ - namespace Internal - { - template - struct InterfaceCast; - - template - struct InterfaceCast - { - template - static void* Op(T* p) - { - return (Dst*) p; - } - }; - - template <> - struct InterfaceCast - { - template - static void* Op(T* p) - { - return const_cast(static_cast(static_cast(p))); - } - }; - } - - template - struct InterfaceCast; - - template <> - struct InterfaceCast - { - template - static void* Op(T*, const CryInterfaceID&) - { - return 0; - } - }; - - template - struct InterfaceCast > - { - template - static void* Op(T* p, const CryInterfaceID& iid) - { - if (cryiidof() == iid) - { - return Internal::InterfaceCast::Op(p); - } - return InterfaceCast::Op(p, iid); - } - }; - - template - struct FillIIDs; - - template <> - struct FillIIDs - { - static void Op(CryInterfaceID*) - { - } - }; - - template - struct FillIIDs > - { - static void Op(CryInterfaceID* p) - { - *p++ = cryiidof(); - FillIIDs::Op(p); - } - }; - - namespace Internal - { - template - struct PickList; - - template - struct PickList - { - typedef TL::BuildTypelist<>::Result Result; - }; - - template - struct PickList - { - typedef typename S::FullCompositeList Result; - }; - } - - template - struct ProbeFullCompositeList - { - private: - typedef char y[1]; - typedef char n[2]; - - template - static y& test(typename S::FullCompositeList*); - - template - static n& test(...); - - public: - enum - { - listFound = sizeof(test(0)) == sizeof(y) - }; - - typedef typename Internal::PickList::Result ListType; - }; - - namespace Internal - { - template - struct CompositeQuery; - - template <> - struct CompositeQuery - { - template - static void* Op(const T&, const char*) - { - return 0; - } - }; - - template - struct CompositeQuery > - { - template - static void* Op(const T& ref, const char* name) - { - void* p = ref.Head::CompositeQueryImpl(name); - return p ? p : CompositeQuery::Op(ref, name); - } - }; - } - - struct CompositeQuery - { - template - static void* Op(const T& ref, const char* name) - { - return Internal::CompositeQuery::ListType>::Op(ref, name); - } - }; - - inline bool NameMatch(const char* name, const char* compositeName) - { - if (!name || !compositeName) - { - return false; - } - size_t i = 0; - for (; name[i] && name[i] == compositeName[i]; ++i) - { - } - return name[i] == compositeName[i]; - } - - template - void* CheckCompositeMatch(const char* name, const AZStd::shared_ptr& composite, const char* compositeName) - { - typedef TC::SuperSubClass Rel; - COMPILE_TIME_ASSERT(Rel::exists); - return NameMatch(name, compositeName) ? const_cast(static_cast(&composite)) : 0; - } -} // namespace CW - - -#define CRYINTERFACE_BEGIN() \ -private: \ - typedef TL::BuildTypelist < ICryUnknown - -#define CRYINTERFACE_ADD(iname) , iname - -#define CRYINTERFACE_END() > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_UserDefinedPartialInterfaceList>::Result FullInterfaceList; - -#define _CRY_TPL_APPEND0(base) TL::Append::Result -#define _CRY_TPL_APPEND(base, intermediate) TL::Append::Result - -#define CRYINTERFACE_ENDWITHBASE(base) > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_CRY_TPL_APPEND0(base)>::Result FullInterfaceList; - -#define CRYINTERFACE_ENDWITHBASE2(base0, base1) > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_CRY_TPL_APPEND(base0, _CRY_TPL_APPEND0(base1))>::Result FullInterfaceList; - -#define CRYINTERFACE_ENDWITHBASE3(base0, base1, base2) > ::Result _UserDefinedPartialInterfaceList; \ -protected: \ - typedef TL::NoDuplicates<_CRY_TPL_APPEND(base0, _CRY_TPL_APPEND(base1, _CRY_TPL_APPEND0(base2)))>::Result FullInterfaceList; - -#define CRYINTERFACE_SIMPLE(iname) \ - CRYINTERFACE_BEGIN() \ - CRYINTERFACE_ADD(iname) \ - CRYINTERFACE_END() - -#define CRYCOMPOSITE_BEGIN() \ -private: \ - void* CompositeQueryImpl(const char* name) const \ - { \ - (void)(name); \ - void* res = 0; (void)(res); \ - -#define CRYCOMPOSITE_ADD(member, membername) \ - COMPILE_TIME_ASSERT((sizeof(membername) / sizeof(membername[0])) > 1); \ - if ((res = CW::CheckCompositeMatch(name, member, membername)) != 0) { \ - return res; } - -#define _CRYCOMPOSITE_END(implclassname) \ - return 0; \ - }; \ -protected: \ - typedef TL::BuildTypelist::Result _PartialCompositeList; \ - \ - template \ - friend struct CW::Internal::PickList; - -#define CRYCOMPOSITE_END(implclassname) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef _PartialCompositeList FullCompositeList; - -#define _CRYCOMPOSITE_APPEND0(base) TL::Append<_PartialCompositeList, CW::ProbeFullCompositeList::ListType>::Result -#define _CRYCOMPOSITE_APPEND(base, intermediate) TL::Append::ListType>::Result - -#define CRYCOMPOSITE_ENDWITHBASE(implclassname, base) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef _CRYCOMPOSITE_APPEND0 (base) FullCompositeList; - -#define CRYCOMPOSITE_ENDWITHBASE2(implclassname, base0, base1) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef TL::NoDuplicates<_CRYCOMPOSITE_APPEND(base1, _CRYCOMPOSITE_APPEND0(base0))>::Result FullCompositeList; - -#define CRYCOMPOSITE_ENDWITHBASE3(implclassname, base0, base1, base2) \ - _CRYCOMPOSITE_END(implclassname) \ -protected: \ - typedef TL::NoDuplicates<_CRYCOMPOSITE_APPEND(base2, _CRYCOMPOSITE_APPEND(base1, _CRYCOMPOSITE_APPEND0(base0)))>::Result FullCompositeList; - -template -class CFactory - : public ICryFactory -{ -public: - virtual const char* GetName() const - { - return T::GetCName(); - } - - virtual const CryClassID& GetClassID() const - { - return T::GetCID(); - } - - virtual bool ClassSupports(const CryInterfaceID& iid) const - { - for (size_t i = 0; i < m_numIIDs; ++i) - { - if (iid == m_pIIDs[i]) - { - return true; - } - } - return false; - } - - virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const - { - pIIDs = m_pIIDs; - numIIDs = m_numIIDs; - } -public: - virtual ICryUnknownPtr CreateClassInstance() const - { - AZStd::shared_ptr p = AZStd::make_shared(); - return cryinterface_cast (p); - } - - CFactory() - : m_numIIDs(0) - , m_pIIDs(0) - , m_regFactory() - { - static CryInterfaceID supportedIIDs[TL::Length < typename T::FullInterfaceList > ::value]; - CW::FillIIDs::Op(supportedIIDs); - m_pIIDs = &supportedIIDs[0]; - m_numIIDs = TL::Length::value; - new(&m_regFactory)SRegFactoryNode(this); - } - -protected: - CFactory(const CFactory&); - CFactory& operator =(const CFactory&); - - - size_t m_numIIDs; - CryInterfaceID* m_pIIDs; - SRegFactoryNode m_regFactory; -}; - -template -class CSingletonFactory - : public CFactory -{ -public: - CSingletonFactory() - : CFactory() - , m_csCreateClassInstance() - { - } - - virtual ICryUnknownPtr CreateClassInstance() const - { - CryAutoLock lock(m_csCreateClassInstance); - // override the allocator. These function static instances are being destroyed after the AZ alloctor has been deleted. - // On win, TerminateProcess() prevents these destructors from being called, but that is not the case on OSX. - static typename AZStd::aligned_storage,SingletonAllocator>), AZStd::alignment_of::value>::type m_storage; - static ICryUnknownPtr p = AZStd::allocate_shared(SingletonAllocator(AZStd::addressof(m_storage))); - return p; - } - - mutable CryCriticalSection m_csCreateClassInstance; - - struct SingletonAllocator - { - SingletonAllocator(void* ptr) : - m_data(ptr) - {} - void* allocate(size_t /*byteSize*/, size_t /*alignment*/, int /*flags*/ = 0) - { - return m_data; - } - void deallocate(void* /*ptr*/, size_t /*byteSize*/, size_t /*alignment*/) - { - // nothing to see here - } - void* m_data; - }; -}; - -#define _CRYFACTORY_DECLARE(implclassname) \ -private: \ - friend class CFactory; \ - static CFactory s_factory; - -#define _CRYFACTORY_DECLARE_SINGLETON(implclassname) \ -private: \ - friend class CFactory; \ - friend void* Get##implclassname##Factory(); \ - static CSingletonFactory s_factory; - -#define _IMPLEMENT_ICRYUNKNOWN() \ -public: \ - virtual ICryFactory* GetFactory() const \ - { \ - return &s_factory; \ - } \ - \ -protected: \ - virtual void* QueryInterface(const CryInterfaceID&iid) const \ - { \ - return CW::InterfaceCast::Op(this, iid); \ - } \ - \ - template \ - friend struct CW::Internal::CompositeQuery; \ - \ - virtual void* QueryComposite(const char* name) const \ - { \ - return CW::CompositeQuery::Op(*this, name); \ - } - -#define _ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow) \ -public: \ - static const char* GetCName() \ - { \ - return cname; \ - } \ - static const CryClassID& GetCID() \ - { \ - static const CryClassID cid = {(uint64) cidHigh##LL, (uint64) cidLow##LL}; \ - return cid; \ - } \ - static AZStd::shared_ptr CreateClassInstance() \ - { \ - ICryUnknownPtr p = s_factory.CreateClassInstance(); \ - return AZStd::shared_ptr(*static_cast*>(static_cast(&p))); \ - } \ - \ -protected: \ - implclassname(); \ - virtual ~implclassname(); - -#define _BEFRIEND_OPS() \ - _BEFRIEND_CRYINTERFACE_CAST() \ - _BEFRIEND_CRYCOMPOSITE_QUERY() \ - _BEFRIEND_MAKE_SHARED() - -#define CRYGENERATE_CLASS(implclassname, cname, cidHigh, cidLow) \ - _CRYFACTORY_DECLARE(implclassname) \ - _BEFRIEND_OPS() \ - _IMPLEMENT_ICRYUNKNOWN() \ - _ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow) - -#define CRYGENERATE_SINGLETONCLASS(implclassname, cname, cidHigh, cidLow) \ - _CRYFACTORY_DECLARE_SINGLETON(implclassname) \ - _BEFRIEND_OPS() \ - _IMPLEMENT_ICRYUNKNOWN() \ - _ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow) - - -#define CRYREGISTER_CLASS(implclassname) \ - CFactory implclassname::s_factory; - -#define DECLARE_CRYREGISTER_SINGLETON_CLASS(implclassname) \ - void* Get##implclassname##Factory(); - -#define CRYREGISTER_SINGLETON_CLASS(implclassname) \ - CSingletonFactory implclassname::s_factory; \ - void* Get##implclassname##Factory() { \ - return &implclassname::s_factory; \ - } - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/Conversion.h b/Code/CryEngine/CryCommon/CryExtension/Impl/Conversion.h deleted file mode 100644 index bd729f259e..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/Conversion.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H -#pragma once - - -namespace TC -{ - //template - //struct Conversion - //{ - //private: - // typedef char y[1]; - // typedef char n[2]; - // static y& Test(U); - // static n& Test(...); - // static T MakeT(); - - //public: - // enum - // { - // exists = sizeof(Test(MakeT())) == sizeof(y), - // sameType = false - // }; - //}; - - //template - //struct Conversion - //{ - //public: - // enum - // { - // exists = true, - // sameType = true - // }; - //}; - - //template - //struct CheckInheritance - //{ - // enum - // { - // exists = Conversion::exists && !Conversion::sameType - // }; - //}; - - //template - //struct CheckStrictInheritance - //{ - // enum - // { - // exists = CheckInheritance::exists && !Conversion::sameType - // }; - //}; - - - template - struct SuperSubClass - { - private: - typedef char y[1]; - typedef char n[2]; - - template - static y& check(const volatile Derived&, T); - static n& check(const volatile Base&, int); - - struct C - { - operator const volatile Base&() const; - operator const volatile Derived&(); - }; - - static C getC(); - - public: - enum - { - exists = sizeof(check(getC(), 0)) == sizeof(y), - sameType = false - }; - }; - - template - struct SuperSubClass - { - enum - { - exists = true - }; - }; -} // namespace TC - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/CryGUIDHelper.h b/Code/CryEngine/CryCommon/CryExtension/Impl/CryGUIDHelper.h deleted file mode 100644 index 53ee4352fc..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/CryGUIDHelper.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H -#pragma once - - -#include "../CryGUID.h" -#include "../../CryString.h" - - -namespace CryGUIDHelper -{ - string Print(const CryGUID& val) - { - char buf[39]; // sizeof("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}") - - static const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - char* p = buf; - *p++ = '{'; - for (int i = 15; i >= 8; --i) - { - *p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 7; i >= 4; --i) - { - *p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 3; i >= 0; --i) - { - *p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 15; i >= 12; --i) - { - *p++ = hex[(unsigned char) ((val.lopart >> (i << 2)) & 0xF)]; - } - *p++ = '-'; - for (int i = 11; i >= 0; --i) - { - *p++ = hex[(unsigned char) ((val.lopart >> (i << 2)) & 0xF)]; - } - *p++ = '}'; - *p++ = '\0'; - - return string(buf); - } -} - - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/ICryFactoryRegistryImpl.h b/Code/CryEngine/CryCommon/CryExtension/Impl/ICryFactoryRegistryImpl.h deleted file mode 100644 index 051c33fc33..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/ICryFactoryRegistryImpl.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H -#pragma once - - -#include "../ICryFactoryRegistry.h" - - -struct SRegFactoryNode; - - -struct ICryFactoryRegistryCallback -{ - virtual void OnNotifyFactoryRegistered(ICryFactory* pFactory) = 0; - virtual void OnNotifyFactoryUnregistered(ICryFactory* pFactory) = 0; - -protected: - virtual ~ICryFactoryRegistryCallback() {} -}; - - -struct ICryFactoryRegistryImpl - : public ICryFactoryRegistry -{ - virtual ICryFactory* GetFactory(const char* cname) const = 0; - virtual ICryFactory* GetFactory(const CryClassID& cid) const = 0; - virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const = 0; - - virtual void RegisterCallback(ICryFactoryRegistryCallback* pCallback) = 0; - virtual void UnregisterCallback(ICryFactoryRegistryCallback* pCallback) = 0; - - virtual void RegisterFactories(const SRegFactoryNode* pFactories) = 0; - virtual void UnregisterFactories(const SRegFactoryNode* pFactories) = 0; - - virtual void UnregisterFactory(ICryFactory* const pFactory) = 0; - -protected: - // prevent explicit destruction from client side (delete, shared_ptr, etc) - virtual ~ICryFactoryRegistryImpl() {} -}; - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/RegFactoryNode.h b/Code/CryEngine/CryCommon/CryExtension/Impl/RegFactoryNode.h deleted file mode 100644 index 8209ae9728..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/RegFactoryNode.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H -#define CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H -#pragma once - -struct ICryFactory; -struct SRegFactoryNode; - -extern SRegFactoryNode* g_pHeadToRegFactories; - -struct SRegFactoryNode -{ - SRegFactoryNode() - { - } - - SRegFactoryNode(ICryFactory* pFactory) - : m_pFactory(pFactory) - , m_pNext(g_pHeadToRegFactories) - { - g_pHeadToRegFactories = this; - } - - static void* operator new(size_t, void* p) - { - return p; - } - - static void operator delete(void*, void*) - { - } - - ICryFactory* m_pFactory; - SRegFactoryNode* m_pNext; -}; - -#endif // CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H diff --git a/Code/CryEngine/CryCommon/CryExtension/Impl/TypeList.h b/Code/CryEngine/CryCommon/CryExtension/Impl/TypeList.h deleted file mode 100644 index 231283fc19..0000000000 --- a/Code/CryEngine/CryCommon/CryExtension/Impl/TypeList.h +++ /dev/null @@ -1,236 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYEXTENSION_TYPELIST_H -#define CRYINCLUDE_CRYEXTENSION_TYPELIST_H -#pragma once - - -namespace TL -{ - // typelist terminator - class NullType - { - }; - - - // structure for typelist generation - template - struct Typelist - { - typedef T Head; - typedef U Tail; - }; - - - // helper structure to automatically build typelists containing n types - template - < - typename T0 = NullType, typename T1 = NullType, typename T2 = NullType, typename T3 = NullType, typename T4 = NullType, - typename T5 = NullType, typename T6 = NullType, typename T7 = NullType, typename T8 = NullType, typename T9 = NullType, - typename T10 = NullType, typename T11 = NullType, typename T12 = NullType, typename T13 = NullType, typename T14 = NullType, - typename T15 = NullType, typename T16 = NullType, typename T17 = NullType, typename T18 = NullType, typename T19 = NullType - > - struct BuildTypelist - { - private: - typedef typename BuildTypelist::Result TailResult; - - public: - typedef Typelist Result; - }; - - template <> - struct BuildTypelist<> - { - typedef NullType Result; - }; - - // typelist operation : Length - template - struct Length; - - template <> - struct Length - { - enum - { - value = 0 - }; - }; - - template - struct Length > - { - enum - { - value = 1 + Length::value - }; - }; - - - // typelist operation : TypeAt - template - struct TypeAt; - - template - struct TypeAt, 0> - { - typedef Head Result; - }; - - template - struct TypeAt, index> - { - typedef typename TypeAt::Result Result; - }; - - - // typelist operation : IndexOf - template - struct IndexOf; - - template - struct IndexOf - { - enum - { - value = -1 - }; - }; - - template - struct IndexOf, T> - { - enum - { - value = 0 - }; - }; - - template - struct IndexOf, T> - { - private: - enum - { - temp = IndexOf::value - }; - public: - enum - { - value = temp == -1 ? -1 : 1 + temp - }; - }; - - - // typelist operation : Append - template - struct Append; - - template <> - struct Append - { - typedef NullType Result; - }; - - template - struct Append - { - typedef Typelist Result; - }; - - template - struct Append > - { - typedef Typelist Result; - }; - - template - struct Append, T> - { - typedef Typelist::Result> Result; - }; - - - // typelist operation : Erase - template - struct Erase; - - template - struct Erase - { - typedef NullType Result; - }; - - template - struct Erase, T> - { - typedef Tail Result; - }; - - template - struct Erase, T> - { - typedef Typelist::Result> Result; - }; - - - // typelist operation : Erase All - template - struct EraseAll; - - template - struct EraseAll - { - typedef NullType Result; - }; - - template - struct EraseAll, T> - { - typedef typename EraseAll::Result Result; - }; - - template - struct EraseAll, T> - { - typedef Typelist::Result> Result; - }; - - - // typelist operation : NoDuplicates - template - struct NoDuplicates; - - template <> - struct NoDuplicates - { - typedef NullType Result; - }; - - template - struct NoDuplicates > - { - private: - typedef typename NoDuplicates::Result L1; - typedef typename Erase::Result L2; - public: - typedef Typelist Result; - }; -} // namespace TL - -#endif // CRYINCLUDE_CRYEXTENSION_TYPELIST_H diff --git a/Code/CryEngine/CryCommon/CryFixedArray.h b/Code/CryEngine/CryCommon/CryFixedArray.h deleted file mode 100644 index 58bdd2b14f..0000000000 --- a/Code/CryEngine/CryCommon/CryFixedArray.h +++ /dev/null @@ -1,309 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -/* -CryFixedArray.h - - no longer support being created on the stack (since the alignment code was changed to support adding CryFixedArrays into stl::vectors) - - performs construction or destruction only on elements as they become live/dead or are moved around during the RemoveAt() reshuffle - - just a range checked equivelant of a standard array - - for now only allows push_back() population of array - - if using as a class member variable ensure to put the CryFixedArrays after all other member variables at the bottom of your class - to ensure all members stay on the same cacheline -*/ - -#ifndef CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H -#define CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H -#pragma once - -#define DEBUG_CRYFIXED_ARRAY _DEBUG - -template< - unsigned int align > -struct CryFixedArrayDatum -{ -}; - -template<> -struct CryFixedArrayDatum< 4 > -{ - typedef uint32 TDatum; -}; - -template<> -struct CryFixedArrayDatum< 8 > -{ - typedef uint64 TDatum; -}; - -template -class CryFixedArray -{ -protected: - enum - { - ALIGN = MAX(alignof(T), sizeof(unsigned int)) - }; // ALIGN at least sizeof(unsigned int) - - typedef typename CryFixedArrayDatum< ALIGN >::TDatum TDatum; - - uint32 m_curSize[ sizeof (TDatum) / sizeof (uint32) ]; // Padded for alignment - - TDatum m_data[(N * sizeof(T) + (sizeof(TDatum) - 1)) / sizeof(TDatum)]; // simple debugging - in VS: just add to a watch as "(T*)m_data, " to see the array. ie. "(int*)m_data, 5" - the size of the array has to be a literal int - -public: - typedef T* iterator; - typedef const T* const_iterator; - - CryFixedArray() - { -#if DEBUG_CRYFIXED_ARRAY - if (((uintptr_t)m_data & (ALIGN - 1)) != 0) - { - CryLogAlways("CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported."); - } -#endif - CRY_ASSERT_MESSAGE(((uintptr_t)m_data & (ALIGN - 1)) == 0, "CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported."); - m_curSize[0] = 0; - } - - CryFixedArray(const CryFixedArray& other) - { - // doesn't require clear() this is newly constructed - m_curSize[0] = other.m_curSize[0]; - - int size = m_curSize[0]; - for (int i = 0; i < size; i++) - { - T& ele = operator[](i); - const T& otherEle = other.operator[](i); - new (&ele)T(otherEle); // placement new - } - } - - CryFixedArray& operator=(const CryFixedArray& other) - { - if (this != &other) - { - clear(); // necessary to avoid potentially leaking within existing elements - - m_curSize[0] = other.m_curSize[0]; - - int size = m_curSize[0]; - for (int i = 0; i < size; i++) - { - T& ele = operator[](i); - const T& otherEle = other.operator[](i); - //ele = otherEle; // assignment instead of placement new to keep type of operation consistent - this cannot be done until this is rewritten to assign over existing elements and deconstruct any left overs, and placement new any new elements - new (&ele)T(otherEle); // placement new - } - } - - return *this; - } - - virtual ~CryFixedArray() - { - clear(); - } - - ILINE T& at(unsigned int i) - { -#if DEBUG_CRYFIXED_ARRAY - if (i < size()) - { - return alias_cast(m_data)[i]; - } - else - { - // Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!! - CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N)); - abort(); // better option than dereferncing a nullptr? - } -#else - return alias_cast(m_data)[i]; -#endif - } - - ILINE const T& at(unsigned int i) const - { -#if DEBUG_CRYFIXED_ARRAY - if (i < size()) - { - return alias_cast(m_data)[i]; - } - else - { - // Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!! - CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N)); - abort(); // better option than dereferncing a nullptr? - } -#else - return alias_cast(m_data)[i]; -#endif - } - - ILINE const T& operator[](unsigned int i) const - { - return at(i); - } - - ILINE T& operator[](unsigned int i) - { - return at(i); - } - - ILINE void clear() - { - for (uint32 i = 0; i < m_curSize[0]; i++) - { - T& ele = operator[](i); - ele.~T(); - } - m_curSize[0] = 0; -#if DEBUG_CRYFIXED_ARRAY - memset(m_data, 0, N * sizeof(T)); -#endif - } - - ILINE iterator begin() - { - return alias_cast(m_data); - } - ILINE const_iterator begin() const - { - return alias_cast(m_data); - } - ILINE iterator end() - { - return &(alias_cast(m_data))[m_curSize[0]]; - } - ILINE const_iterator end() const - { - return &(alias_cast(m_data))[m_curSize[0]]; - } - - ILINE unsigned int max_size() const { return N; } - ILINE unsigned int size() const { return m_curSize[0]; } - ILINE bool empty() const { return size() == 0; } - ILINE unsigned int isfull() const { return (size() == max_size()); } - - // allows you to push back default constructed elements - ILINE void push_back () - { - unsigned int curSize = size(); - if (curSize < N) - { - T* newT = &(alias_cast(m_data))[curSize]; - new (newT) T(); - - m_curSize[0]++; - } - else - { - CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N); - CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N)); - } - } - - ILINE void push_back (const T& ele) - { - unsigned int curSize = size(); - if (curSize < N) - { - T* newT = &(alias_cast(m_data))[curSize]; - new (newT) T(ele); // placement new copy constructor - setup vtable etc - - m_curSize[0]++; - } - else - { - CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N); - CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N)); - } - } - - ILINE void pop_back() - { - if (size() > 0) - { - back().~T(); // destruct back - m_curSize[0]--; - } - else - { - CryLogAlways("CryFixedArray::pop_back() failed as array is empty"); - CRY_ASSERT_MESSAGE(0, "CryFixedArray::pop_back() failed as array is empty"); - } - } - -protected: - ILINE const T& backEx() const - { -#if DEBUG_CRYFIXED_ARRAY - if (m_curSize[0] > 0) - { - return (alias_cast(m_data))[m_curSize[0] - 1]; - } - else - { - CryLogAlways("CryFixedArray::back() failed as array is empty"); - CRY_ASSERT_MESSAGE(0, "CryFixedArray::back() failed as array is empty"); - abort(); // better option than dereferncing a nullptr? - } -#else - return (alias_cast(m_data))[m_curSize[0] - 1]; -#endif - } - -public: - ILINE const T& back() const - { - return backEx(); - } - - ILINE T& back() - { - return (T&)(backEx()); - } - - // if returns true then an element has been swapped into the new element[i] and as such may need updating to reflect its new location in memory - ILINE bool removeAt(uint32 i) - { - bool swappedElement = false; - - if (i < m_curSize[0]) - { - if (i != m_curSize[0] - 1) - { - operator[](i).~T(); // destruct element being removed - - // copy back() into element i - T* newT = &(alias_cast(m_data))[i]; - new (newT) T(back()); // placement new copy constructor - setup vtable etc - - swappedElement = true; - } - pop_back(); // will destruct back() - } - else - { - CryLog("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0]); - CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0])); - } - return swappedElement; - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H diff --git a/Code/CryEngine/CryCommon/CryFixedString.h b/Code/CryEngine/CryCommon/CryFixedString.h index 9c522ad078..cabcc7d06f 100644 --- a/Code/CryEngine/CryCommon/CryFixedString.h +++ b/Code/CryEngine/CryCommon/CryFixedString.h @@ -2019,21 +2019,6 @@ inline CryStackStringT CryStackStringT::Tokenize(const_str charSet, return CryStackStringT(); } -////////////////////////////////////////////////////////////////////////// -// Specialization providing efficient move semantics for array classes. -template -bool raw_movable(const CryStackStringT& str) -{ - return false; -} - -template -void move_init(CryStackStringT& dest, CryStackStringT& source) -{ - dest.move(source); -} - - #if defined(_RELEASE) #define ASSERT_LEN (void)(0) #define ASSERT_WLEN (void)(0) diff --git a/Code/CryEngine/CryCommon/CryMemoryAllocator.h b/Code/CryEngine/CryCommon/CryMemoryAllocator.h deleted file mode 100644 index b9003fc6fa..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryAllocator.h +++ /dev/null @@ -1,274 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. -/* - * Part of this code coming from STLPort alloc - * - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Copyright (c) 1997 - * Moscow Center for SPARC Technology - * - * Copyright (c) 1999 - * Boris Fomitchev - * - * - */ - -#ifndef CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H -#pragma once - -#include - -#define CRY_STL_ALLOC - -#if defined(LINUX64) || defined(APPLE) -#include -#endif - -#include // memset - -// DON't USE _MAX_BYTES as identifier for Max Bytes, STLPORT defines the same enum -// this leads to situation where the wrong enum is choosen in different compilation units -// which in case leads to errors(The stlport one is defined as 128) -#if defined (__OS400__) || defined (_WIN64) || defined(MAC) || defined(LINUX64) -enum {_ALIGNMENT = 16, _ALIGN_SHIFT = 4, __MAX_BYTES = 512, NFREELISTS=32, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 40}; -#else -enum {_ALIGNMENT = 8, _ALIGN_SHIFT = 3, __MAX_BYTES = 512, NFREELISTS = 64, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 20}; -#endif /* __OS400__ */ - -#define CRY_MEMORY_ALLOCATOR - -#define S_FREELIST_INDEX(__bytes) ((__bytes - size_t(1)) >> (int)_ALIGN_SHIFT) - -class _Node_alloc_obj { -public: - _Node_alloc_obj * _M_next; -}; - -#if defined (_WIN64) || defined(APPLE) || defined(LINUX64) -#define MASK_COUNT 0x000000FFFFFFFFFF -#define MASK_VALUE 0xFFFFFF -#define MASK_NEXT 0xFFFFFFFFFF000000 -#define MASK_SHIFT 24 -#else -#define MASK_COUNT 0x000FFFFF -#define MASK_VALUE 0xFFF -#define MASK_NEXT 0xFFFFF000 -#define MASK_SHIFT 12 -#endif - -#define NUM_OBJ 64 - -struct _Obj_Address { - // short int * _M_next; - // short int - size_t GetNext(size_t pBase) { - return pBase +(size_t)(_M_value >> MASK_SHIFT); - } - - //size_t GetNext() { - // return (size_t)(_M_value >> 20); - //} - - size_t GetCount() { - return _M_value & MASK_VALUE; - } - - void SetNext(/*void **/size_t pNext) { - _M_value &= MASK_COUNT; - _M_value |= (size_t)pNext << MASK_SHIFT; - } - - void SetCount(size_t count) { - _M_value &= MASK_NEXT; - _M_value |= count & MASK_VALUE; - } -private: - size_t _M_value; - // short int * _M_end; -}; - -//struct _Node_Allocations_Tree { -// enum { eListSize = _Size / (sizeof(void *) * _Num_obj); }; -// _Obj_Address * _M_allocations_list[eListSize]; -// int _M_Count; -// _Node_Allocations_Tree * _M_next; -//}; - -template -struct _Node_Allocations_Tree { - //Pointer to the end of the memory block - char *_M_end; - - enum { eListSize = _Size / (sizeof(void *) * NUM_OBJ) }; - // List of allocations - _Obj_Address _M_allocations_list[eListSize]; - int _M_allocations_count; - //Pointer to the next memory block - _Node_Allocations_Tree *_M_Block_next; -}; - - -struct _Node_alloc_Mem_block_Huge { - //Pointer to the end of the memory block - char *_M_end; - // number - int _M_count; - _Node_alloc_Mem_block_Huge *_M_next; -}; - -template -struct _Node_alloc_Mem_block { - //Pointer to the end of the memory block - char *_M_end; - //Pointer to the next memory block - _Node_alloc_Mem_block_Huge *_M_huge_block; - _Node_alloc_Mem_block *_M_next; -}; - - -// Allocators! -enum EAllocFreeType -{ - eCryDefaultMalloc, - eCryMallocCryFreeCRTCleanup, -}; - -template -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryModuleMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - CryModuleFree(ptr); - return 0; - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } -}; - -// partial -template <> -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - size_t n = CryCrtSize(ptr); - CryCrtFree(ptr); - return n; - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } - -}; - -// partial -template <> -struct Node_Allocator -{ - inline void * pool_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline void * cleanup_alloc(size_t size) - { - return CryCrtMalloc(size); - }; - inline size_t pool_free(void * ptr) - { - return CryCrtFree(ptr); - }; - inline void cleanup_free(void * ptr) - { - CryCrtFree(ptr); - }; - inline size_t getSize(void * ptr) - { - return CryCrtSize(ptr); - } - -}; - -#include "MultiThread.h" - -struct InternalCriticalSectionDummy { - char padding[128]; -} ; - -inline void CryInternalCreateCriticalSection(void * pCS) -{ - CryCreateCriticalSectionInplace(pCS); -} - -// A class that forward node allocator calls directly to CRT -struct cry_crt_node_allocator -{ - static const size_t MaxSize = ~0; - - static void *alloc(size_t __n) - { - return CryCrtMalloc(__n); - } - static size_t dealloc( void *p ) - { - return CryCrtFree(p); - } - static void *allocate(size_t __n) - { - return alloc(__n); - } - static void *allocate(size_t __n, [[maybe_unused]] size_t nAlignment) - { - return alloc(__n); - } - static size_t deallocate(void *__p) - { - return dealloc(__p); - } - void cleanup() {} -}; - - -//#endif // WIN32|DEBUG - -#endif // CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/CryMemoryManager.h b/Code/CryEngine/CryCommon/CryMemoryManager.h deleted file mode 100644 index 4547ae70bc..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryManager.h +++ /dev/null @@ -1,298 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Defines functions for CryEngine custom memory manager. - -#pragma once - -// Section dictionary -#if defined(AZ_RESTRICTED_PLATFORM) -#define CRYMEMORYMANAGER_H_SECTION_TRAITS 1 -#define CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY 2 -#endif - -#include -// Traits -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_TRAITS - #include AZ_RESTRICTED_FILE(CryMemoryManager_h) -#else -#if !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H 1 -#endif -#if defined(LINUX) || defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H 1 -#endif -#if !defined(LINUX) && !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H 1 -#endif -#if !defined(APPLE) -#define CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY 1 -#endif -#endif - -#include "platform.h" - -#include -#include - -#if defined(APPLE) || defined(ANDROID) - #include // memalign -#endif // defined(APPLE) - -#ifndef STLALLOCATOR_CLEANUP -#define STLALLOCATOR_CLEANUP -#endif - -#define _CRY_DEFAULT_MALLOC_ALIGNMENT 4 - -#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H - #include -#endif - -#if defined(__cplusplus) -#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H - #include -#else - #include -#endif -#endif - - #ifdef CRYSYSTEM_EXPORTS - #define CRYMEMORYMANAGER_API DLL_EXPORT - #else - #define CRYMEMORYMANAGER_API DLL_IMPORT - #endif - -#ifdef __cplusplus - -#if defined(_DEBUG) && CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H - #include -#endif //_DEBUG - -#include "LegacyAllocator.h" - -namespace CryMemory -{ - // checks if the heap is valid in debug; in release, this function shouldn't be called - // returns non-0 if it's valid and 0 if not valid - ILINE int IsHeapValid() - { - #if (defined(_DEBUG) && !defined(RELEASE_RUNTIME) && CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY) || (defined(DEBUG_MEMORY_MANAGER)) - return _CrtCheckMemory(); - #else - return true; - #endif - } - - inline void* AllocPages(size_t size) - { - const size_t alignment = AZ_PAGE_SIZE; - void* ret = AZ::AllocatorInstance::Get().Allocate(size, alignment, 0, "AllocPages", __FILE__, __LINE__); - return ret; - } - - inline void FreePages(void* p, size_t size) - { - const size_t alignment = AZ_PAGE_SIZE; - AZ::AllocatorInstance::Get().DeAllocate(p, size, alignment); - } -} - -////////////////////////////////////////////////////////////////////////// - -#endif //__cplusplus - -struct ICustomMemoryHeap; -class IGeneralMemoryHeap; -class IPageMappingHeap; -class IDefragAllocator; -class IMemoryAddressRange; - -// Description: -// Interfaces that allow access to the CryEngine memory manager. -struct IMemoryManager -{ - typedef unsigned char HeapHandle; - enum - { - BAD_HEAP_HANDLE = 0xFF - }; - - struct SProcessMemInfo - { - uint64 PageFaultCount; - uint64 PeakWorkingSetSize; - uint64 WorkingSetSize; - uint64 QuotaPeakPagedPoolUsage; - uint64 QuotaPagedPoolUsage; - uint64 QuotaPeakNonPagedPoolUsage; - uint64 QuotaNonPagedPoolUsage; - uint64 PagefileUsage; - uint64 PeakPagefileUsage; - - uint64 TotalPhysicalMemory; - int64 FreePhysicalMemory; - - uint64 TotalVideoMemory; - int64 FreeVideoMemory; - }; - - enum EAllocPolicy - { - eapDefaultAllocator, - eapPageMapped, - eapCustomAlignment, -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY - #include AZ_RESTRICTED_FILE(CryMemoryManager_h) -#endif - }; - - virtual ~IMemoryManager(){} - - virtual bool GetProcessMemInfo(SProcessMemInfo& minfo) = 0; - - ////////////////////////////////////////////////////////////////////////// - // Heap Tracing API - virtual HeapHandle TraceDefineHeap(const char* heapName, size_t size, const void* pBase) = 0; - virtual void TraceHeapAlloc(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint = 0) = 0; - virtual void TraceHeapFree(HeapHandle heap, void* mem, size_t blockSize) = 0; - virtual void TraceHeapSetColor(uint32 color) = 0; - virtual uint32 TraceHeapGetColor() = 0; - virtual void TraceHeapSetLabel(const char* sLabel) = 0; - ////////////////////////////////////////////////////////////////////////// - - // Create an instance of ICustomMemoryHeap - virtual ICustomMemoryHeap* const CreateCustomMemoryHeapInstance(EAllocPolicy const eAllocPolicy) = 0; - virtual IGeneralMemoryHeap* CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage) = 0; - virtual IGeneralMemoryHeap* CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage) = 0; - - virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName) = 0; - virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName) = 0; - - virtual IDefragAllocator* CreateDefragAllocator() = 0; -}; - -// Global function implemented in CryMemoryManager_impl.h -IMemoryManager* CryGetIMemoryManager(); - -// Summary: -// Structure filled by call to CryModuleGetMemoryInfo(). -struct CryModuleMemoryInfo -{ - uint64 requested; - // Total Ammount of memory allocated. - uint64 allocated; - // Total Ammount of memory freed. - uint64 freed; - // Total number of memory allocations. - int num_allocations; - // Allocated in CryString. - uint64 CryString_allocated; - // Allocated in STL. - uint64 STL_allocated; - // Amount of memory wasted in pools in stl (not usefull allocations). - uint64 STL_wasted; -}; - -struct CryReplayInfo -{ - uint64 uncompressedLength; - uint64 writtenLength; - uint32 trackingSize; - const char* filename; -}; - -////////////////////////////////////////////////////////////////////////// -// Extern declarations of globals inside CrySystem. -////////////////////////////////////////////////////////////////////////// -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -void* CryMalloc(size_t size, size_t& allocated, size_t alignment); -void* CryRealloc(void* memblock, size_t size, size_t& allocated, size_t& oldsize, size_t alignment); -size_t CryFree(void* p, size_t alignment); -size_t CryGetMemSize(void* p, size_t size); -int CryStats(char* buf); -void CryFlushAll(); -void CryCleanup(); -int CryGetUsedHeapSize(); -int CryGetWastedHeapSize(); -size_t CrySystemCrtGetUsedSpace(); -CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager); - -#ifdef __cplusplus -} -#endif //__cplusplus - -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -// Cry Memory Manager accessible in all build modes. -////////////////////////////////////////////////////////////////////////// -#if !defined(USING_CRY_MEMORY_MANAGER) -#define USING_CRY_MEMORY_MANAGER -#endif - -#include "CryLegacyAllocator.h" - - -template -inline T* CryAlignedNew(Args&& ... args) -{ - void* pAlignedMemory = CryModuleMemalign(sizeof(T), std::alignment_of::value); - return new(pAlignedMemory) T(std::forward(args) ...); -} - -// This utility function should be used for allocating arrays of objects with specific alignment requirements on the heap. -// Note: The caller must remember the number of items in the array, since CryAlignedDeleteArray needs this information. -template -inline T* CryAlignedNewArray(size_t count) -{ - T* const pAlignedMemory = reinterpret_cast(CryModuleMemalign(sizeof(T) * count, std::alignment_of::value)); - T* pCurrentItem = pAlignedMemory; - for (size_t i = 0; i < count; ++i, ++pCurrentItem) - { - new(static_cast(pCurrentItem))T(); - } - return pAlignedMemory; -} - -// Utility function that frees an object previously allocated with CryAlignedNew. -template -inline void CryAlignedDelete(T* pObject) -{ - if (pObject) - { - pObject->~T(); - CryModuleMemalignFree(pObject); - } -} - -// Utility function that frees an array of objects previously allocated with CryAlignedNewArray. -// The same count used to allocate the array must be passed to this function. -template -inline void CryAlignedDeleteArray(T* pObject, size_t count) -{ - if (pObject) - { - for (size_t i = 0; i < count; ++i) - { - (pObject + i)->~T(); - } - CryModuleMemalignFree(pObject); - } -} diff --git a/Code/CryEngine/CryCommon/CryMemoryManager_impl.h b/Code/CryEngine/CryCommon/CryMemoryManager_impl.h deleted file mode 100644 index fdb4f5665e..0000000000 --- a/Code/CryEngine/CryCommon/CryMemoryManager_impl.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Provides implementation for CryMemoryManager globally defined functions. -// This file included only by platform_impl.cpp, do not include it directly in code! - - -#pragma once - -#ifdef AZ_MONOLITHIC_BUILD - #include // <> required for Interfuscator -#endif // AZ_MONOLITHIC_BUILD - -#include "CryLibrary.h" - -#include - -#define DLL_ENTRY_GETMEMMANAGER "CryGetIMemoryManagerInterface" - -// Resolve IMemoryManager by looking in this DLL, then loading and rummaging through -// CrySystem. Cache the result per DLL, because this is not quick. -IMemoryManager* CryGetIMemoryManager() -{ - static AZ::EnvironmentVariable memMan = nullptr; - if (!memMan) - { - memMan = AZ::Environment::FindVariable("CryIMemoryManagerInterface"); - AZ_Assert(memMan, "Unable to find CryIMemoryManagerInterface via AZ::Environment"); - } - return *memMan; -} diff --git a/Code/CryEngine/CryCommon/CryName.h b/Code/CryEngine/CryCommon/CryName.h index 699525f958..0fb34c9532 100644 --- a/Code/CryEngine/CryCommon/CryName.h +++ b/Code/CryEngine/CryCommon/CryName.h @@ -19,7 +19,6 @@ #include #include #include -#include #include class CNameTable; diff --git a/Code/CryEngine/CryCommon/CryPhysicsDeprecation.h b/Code/CryEngine/CryCommon/CryPhysicsDeprecation.h deleted file mode 100644 index d2523f2a5c..0000000000 --- a/Code/CryEngine/CryCommon/CryPhysicsDeprecation.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* 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. -* -*/ - -// Description: Utilities and functions used when cryphysics is disabled - -#pragma once - -// Assert if CryPhysics is disabled and no functionality replacement has been implemented -// 1: Runtime AZ_Error -// 2: Runtime Assertion -// 3: Compilation error -// Other: Do nothing -#define ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT 0 - -#if (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 1) -#define CRY_PHYSICS_REPLACEMENT_ASSERT() AZ_Error("CryPhysics", false, __FUNCTION__ " - CRYPHYSICS REPLACEMENT NOT IMPLEMENTED") -#elif (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 2) -#define CRY_PHYSICS_REPLACEMENT_ASSERT() AZ_Assert(false, "CRYPHYSICS REPLACEMENT NOT IMPLEMENTED") -#elif (ENABLE_CRY_PHYSICS_REPLACEMENT_ASSERT == 3) -#define CRY_PHYSICS_REPLACEMENT_ASSERT() static_assert(false, __FUNCTION__ " - CRYPHYSICS REPLACEMENT NOT IMPLEMENTED") -#else -#define CRY_PHYSICS_REPLACEMENT_ASSERT() -#endif diff --git a/Code/CryEngine/CryCommon/CryPool/Allocator.h b/Code/CryEngine/CryCommon/CryPool/Allocator.h deleted file mode 100644 index cc751e68f1..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Allocator.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_ALLOCATOR_H -#define CRYINCLUDE_CRYPOOL_ALLOCATOR_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CFirstFit - : public TPool - { - public: - ILINE CFirstFit() - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - //fastpath? - if (TPool::m_pEmpty && TPool::m_pEmpty->Available(Size, Align)) - { - TItem* pItem = TPool::Split(TPool::m_pEmpty, Size, Align); - if (!pItem) - { - return 0; - } - pItem->InUse(Align); - TPool::AllocatedMemory(pItem->MemSize()); - - //not fully occupied empty space? - TPool::m_pEmpty = pItem != TPool::m_pEmpty ? TPool::m_pEmpty : 0; - return TPool::Handle(pItem); - } - - TItem* pBestItem; - for (pBestItem = TPool::m_Items.First(); pBestItem; pBestItem = pBestItem->Next()) - { - if (pBestItem->Available(Size, Align)) // && (!pBestItem || pItem->MemSize()MemSize())) - { - break; - } - } - if (!pBestItem) - { - return 0; //out of mem - } - TItem* pItem = TPool::Split(pBestItem, Size, Align); - if (!pItem) //no free node - { - return 0; - } - pItem->InUse(Align); - TPool::AllocatedMemory(pItem->MemSize()); - - //not fully occupied empty space? - TPool::m_pEmpty = pItem != pBestItem ? pBestItem : 0; - return TPool::Handle(pItem); - } - template - ILINE bool Free(T Handle, bool ForceBoundsCheck = false) - { - return Handle ? TPool::Free(Handle, ForceBoundsCheck) : false; - } - }; - - template - class CWorstFit - : public TPool - { - public: - ILINE CWorstFit() - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - TItem* pBestItem = 0; - for (TItem* pItem = TPool::m_Items.First(); pItem; pItem = pItem->Next()) - { - if (pItem->IsFree() && (!pBestItem || pItem->MemSize() > pBestItem->MemSize())) - { - pBestItem = pItem; - } - } - if (!pBestItem || !pBestItem->Available(Size, Align)) - { - return 0; //out of mem - } - TItem* pItem = Split(pBestItem, Size, Align); - if (!pItem) //no free node - { - return 0; - } - pItem->InUse(Align); - AllocatedMemory(pItem->MemSize()); - return Handle(pItem); - } - }; - - template - class CBestFit - : public TPool - { - public: - ILINE CBestFit() - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - TItem* pBestItem = 0; - for (TItem* pItem = TPool::m_Items.First(); pItem; pItem = pItem->Next()) - { - if ((!pBestItem || pItem->MemSize() < pBestItem->MemSize()) && pItem->Available(Size, Align)) - { - if (pItem->MemSize() == Size) - { - pItem->InUse(Align); - AllocatedMemory(pItem->MemSize()); - return (T)Handle(pItem); - } - pBestItem = pItem; - } - } - if (!pBestItem) - { - return 0; //out of mem - } - TItem* pItem = Split(pBestItem, Size, Align); - if (!pItem) //no free node - { - return 0; - } - pItem->InUse(Align); - AllocatedMemory(pItem->MemSize()); - return (T)Handle(pItem); - } - }; - - - template - class CReallocator - : public TAllocator - { - public: - - template - ILINE bool Reallocate(T* pData, size_t Size, size_t Alignment) - { - //special cases - if (!Size) //just free? - { - TAllocator::Free(*pData); - *pData = 0; - return true; - } - - if (!*pData) //just alloc? - { - *pData = TAllocator::template Allocate(Size, Alignment); - return *pData != 0; - } - - //same size, nothing to do at all? - if (TAllocator::Item(*pData)->MemSize() == Size) - { - return true; - } - - if (TAllocator::ReSize(pData, Size)) - { - return true; - } - - T pNewData = TAllocator::template Allocate(Size, Alignment); - if (!pNewData) - { - return false; - } - memcpy(TAllocator::template Resolve(pNewData), - TAllocator::template Resolve(*pData), min(TAllocator::Item(*pData)->MemSize(), Size)); - TAllocator::template Free(*pData); - *pData = pNewData; - return true; - } - }; -} - - -#endif // CRYINCLUDE_CRYPOOL_ALLOCATOR_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Container.h b/Code/CryEngine/CryCommon/CryPool/Container.h deleted file mode 100644 index 82ea2735bc..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Container.h +++ /dev/null @@ -1,655 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_CONTAINER_H -#define CRYINCLUDE_CRYPOOL_CONTAINER_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CPool - : public CMemoryStatic - { - class CPoolNode; - class CPoolNode - : public CListItem - { - }; - CList m_List; - public: - ILINE CPool() - { - CPoolNode* pPrev = 0; - CPoolNode* pNode = 0; - for (size_t a = 1; a < TElementCount; a++) //skip first element as it would be counted as zero ptr - { - uint8* pData = &CMemoryStatic::Data()[a * sizeof(TElement)]; - pNode = reinterpret_cast(pData); - pNode->Prev(pPrev); - if (pPrev) - { - pPrev->Next(pNode); - } - else - { - m_List.First(pNode); - } - pPrev = pNode; - // m_List.AddLast(pNode); - } - if (pPrev) - { - pPrev->Next(0); - m_List.Last(pPrev); - } - } - ILINE uint8* Allocate([[maybe_unused]] size_t Size, [[maybe_unused]] size_t Align = 1) - { - CPoolNode* pNode = m_List.PopFirst(); - return reinterpret_cast(pNode); - } - - template - ILINE void Free(T* pData) - { - if (pData) - { - CPoolNode* pNode = reinterpret_cast(pData); - m_List.AddLast(pNode); - } - } - - ILINE TElement& operator[](uint32 Idx) - { - uint8* pData = &CMemoryStatic::Data()[Idx * sizeof(TElement)]; - return *reinterpret_cast(pData); - } - - ILINE const TElement& operator[](uint32 Idx) const - { - const uint8* pData = &CMemoryStatic::Data()[Idx * sizeof(TElement)]; - return *reinterpret_cast(pData); - } - }; - - template - class CInPlace - : public TMemory - { - protected: - CList m_Items; - size_t m_Allocated; - CListItemInPlace* m_pEmpty; - - - ILINE void AllocatedMemory(size_t S) - { - m_Allocated += S + sizeof(CListItemInPlace); - } - ILINE void FreedMemory(size_t S) - { - m_Allocated -= S + sizeof(CListItemInPlace); - } - ILINE void Stack(CListItemInPlace* pItem) - { - } - public: - ILINE CInPlace() - : m_Allocated(0) - { - } - - ILINE void InitMem(const size_t S = 0, uint8* pData = 0) - { - TMemory::InitMem(S, pData); - if (!TMemory::MemSize()) - { - return; - } - pData = TMemory::Data(); - CListItemInPlace* pFirst = reinterpret_cast(pData); - CListItemInPlace* pFree = pFirst + 1; - CListItemInPlace* pLast = reinterpret_cast(pData + TMemory::MemSize()) - 1; - m_Items.~CList(); - new (&m_Items)CList(); - m_Items.AddLast(pFirst); - m_Items.AddLast(pFree); - m_Items.AddLast(pLast); - - pFirst->InUse(0); //static first item - pFree->Free(); - pLast->InUse(0); //static last item - m_pEmpty = pFree; - m_Allocated = 0; - } - - ILINE size_t FragmentCount() const - { - return m_Items.Count(); - } - - ILINE CListItemInPlace* Split(CListItemInPlace* pItem, size_t Size, size_t Align) - { - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += pItem->MemSize(); //ptr to end - Offset -= Size; //minus size - Size += Offset & (Align - 1); //adjust size to fit required alignment - Offset -= Offset & (Align - 1); - size_t TSize = sizeof(CListItemInPlace); - Offset -= TSize; //header - - if (Offset <= reinterpret_cast(pItem + 1)) //not enough space for splitting? - { - return pItem; - } - - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - - const size_t Offset2 = reinterpret_cast(pItemNext->Data()); - CPA_ASSERT(!(Offset2 & (Align - 1))); - m_Items.AddBehind(pItemNext, pItem); - //pItemNext->Prev(pItem); - //pItemNext->Next(pItem->Next()); - - // if(pItem->Next()) - // pItem->Next()->Prev(pItemNext); - - // pItem->Next(pItemNext); - pItemNext->Free(); - return pItemNext; - } - - ILINE void Merge(CListItemInPlace* pItem) - { - //merge with next if possible - CListItemInPlace* pItemNext = pItem->Next(); - if (pItemNext->IsFree()) - { - if (m_pEmpty == pItemNext) - { - m_pEmpty = pItem; - } - m_Items.Remove(pItemNext); - //pItem->Next(pItemNext->Next()); - //pItem->Next()->Prev(pItem); - } - //merge with prev if possible - CListItemInPlace* pItemPrev = pItem->Prev(); - if (pItemPrev->IsFree()) - { - if (m_pEmpty == pItem) - { - m_pEmpty = pItemPrev; - } - m_Items.Remove(pItem); - //pItemPrev->Next(pItem->Next()); - //pItem->Next()->Prev(pItemPrev); - pItem = pItemPrev; - } - } - template - ILINE T Resolve(void* rItem) const - { - return reinterpret_cast(rItem); - } - - template - ILINE size_t Size(const T* pData) const - { - const CListItemInPlace* pItem = Item(pData); - return pItem->MemSize(); - } - - bool InBounds(const void* pData, const bool Check) const - { - return !Check || ( - reinterpret_cast(pData) >= reinterpret_cast(TMemory::Data()) && - reinterpret_cast(pData) < reinterpret_cast(TMemory::Data()) + TMemory::MemSize()); - } - - template - ILINE bool Free(T* pData, bool ForceBoundsCheck = false) - { - if (pData && InBounds(pData, BoundsCheck | ForceBoundsCheck)) - { - CListItemInPlace* pItem = Item(pData); - FreedMemory(pItem->MemSize()); - pItem->Free(); - Merge(pItem); - return true; - } - return false; - } - - ILINE bool Beat(){return false; }//dummy beat in case no defragmentator is wraping - ILINE size_t MemFree() const{return TMemory::MemSize() - m_Allocated; } - ILINE size_t MemSize() const{return TMemory::MemSize(); } - - ILINE uint8* Handle(CListItemInPlace* pItem) const - { - return pItem->Data(); - } - template - ILINE CListItemInPlace* Item(T* pData) - { - return reinterpret_cast(pData) - 1; - } - template - ILINE const CListItemInPlace* Item(const T* pData) const - { - return reinterpret_cast(pData) - 1; - } - ILINE static bool Defragmentable(){return false; } - - template - ILINE bool ReSize(T* pData, size_t SizeNew) - { - //special cases - CListItemInPlace* pItem = Item(*pData); - const size_t SizeOld = pItem->MemSize(); - - //reduction - if (SizeOld > SizeNew) - { - if (pItem->Next()->IsFree()) - { - CListItemInPlace* pNextNext = pItem->Next()->Next(); - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += SizeNew; //Offset to next - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - pItem->Next(pItemNext); - pNextNext->Prev(pItemNext); - pItemNext->Prev(pItem); - pItemNext->Next(pNextNext); - pItemNext->Free(); - return true; - } - - if (SizeOld - SizeNew <= sizeof(CListItemInPlace)) - { - return true; //header is bigger than the amount of freed memory - } - //split - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += SizeNew; //Offset to next - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - m_Items.AddBehind(pItemNext, pItem); - pItemNext->Free(); - return true; - } - - //SizeOldNext(); - CListItemInPlace* pNextNext = pNext->Next(); - const size_t SizeNext = pNext->IsFree() ? pNext->MemSize() + sizeof(CListItemInPlace) : 0; - if (SizeNew <= SizeNext + SizeOld) - { - if (SizeNew + sizeof(CListItemInPlace) + 1 < SizeNext + SizeOld) - { - size_t Offset = reinterpret_cast(pItem->Data()); - Offset += SizeNew; //Offset to next - CListItemInPlace* pItemNext = reinterpret_cast(Offset); - pItem->Next(pItemNext); - pNextNext->Prev(pItemNext); - pItemNext->Prev(pItem); - pItemNext->Next(pNextNext); - pItemNext->Free(); - } - else - { - pItem->Next(pNextNext); - pNextNext->Prev(pItem); - } - return true; - } - return false; //no further in-place realloc possible - } - }; - - template - class CReferenced - : public TMemory - { - typedef CPool tdNodePool; - - protected: - tdNodePool m_NodePool; - CList m_Items; - size_t m_Allocated; - CListItemReference* m_pEmpty; - - ILINE void AllocatedMemory(size_t S) - { - m_Allocated += S; - } - ILINE void FreedMemory(size_t S) - { - m_Allocated -= S; - } - ILINE void Stack(CListItemReference* pItem) - { - m_Items.Validate(pItem); - CListItemReference* pItem2 = 0; - CListItemReference* pNext = pItem->Next(); - uint8* pData = pItem->Data(pNext->Align()); - if (pData != pItem->Data()) //needs splitting 'cause of alignment? - { - pItem2 = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItem2) //no free node found for splitting? - { - return; //failed to stack -> return - } - } - - memmove(pData, pNext->Data(), pNext->MemSize()); - - if (pItem2) //was not aligned? - { - //then keep the current ITem - const size_t SizeItem = pItem->MemSize(); - const size_t SizeNext = pNext->MemSize(); - m_Items.AddBehind(pItem2, pNext); - pItem2->Data(pData + SizeNext); - pNext->Data(pData); - pItem2->MemSize(pItem2->Next()->Data() - pItem2->Data()); - pNext->MemSize(SizeNext); - pItem->MemSize(pNext->Data() - pItem->Data()); - m_Items.Validate(pItem); - m_Items.Validate(pItem2); - m_Items.Validate(pNext); - } - else - { - const size_t SizeItem = pItem->MemSize(); - const size_t SizeNext = pNext->MemSize(); - m_Items.Remove(pItem); - m_Items.AddBehind(pItem, pNext); - pItem->Data(pNext->Data()); - pNext->Data(pData); - pNext->MemSize(SizeItem); - pItem->MemSize(SizeNext); - m_Items.Validate(pItem); - m_Items.Validate(pNext); - } - } - public: - ILINE CReferenced() - : m_Allocated(0) - { - } - - ILINE void InitMem(const size_t S = 0, uint8* pData = 0) - { - TMemory::InitMem(S, pData); - if (!TMemory::MemSize()) - { - return; - } - pData = TMemory::Data(); - CListItemReference* pItem = reinterpret_cast(m_NodePool.Allocate(1, 1)); - CListItemReference* pLast = reinterpret_cast(m_NodePool.Allocate(1, 1)); - m_Items.AddFirst(pItem); - m_Items.AddLast(pLast); - pLast->Init(pData + TMemory::MemSize(), 0, pItem, 0); - pLast->InUse(0); - pItem->Init(pData, TMemory::MemSize(), 0, pLast); - pItem->Free(); - m_pEmpty = pItem; - m_Allocated = 0; - } - - ILINE size_t FragmentCount() const - { - return m_Items.Count(); - } - - ILINE CListItemReference* Split(CListItemReference* pItem, size_t Size, size_t Align) - { - size_t Offset = reinterpret_cast(pItem->Data()); - if (!(Offset & (Align - 1))) //perfectly aligned? - { - if (pItem->MemSize() != Size) //not perfectly fitting? - { //then split - CListItemReference* pItemPrev = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItemPrev) - { - return 0; - } - const size_t OrgSize = pItem->MemSize(); - m_Items.AddBefore(pItemPrev, pItem); - pItemPrev->Data(pItem->Data()); - pItem->Data(pItem->Data() + Size); - pItem->MemSize(OrgSize - Size); - pItemPrev->MemSize(Size); - pItem = pItemPrev; - } - return pItem; - } - - //not aligned to block start - //then lets try to align to block end - Offset += pItem->MemSize(); //ptr to end - Offset -= Size; //minus size - if (!(Offset & (Align - 1))) //perfectly aligned? - { - CListItemReference* pItemPrev = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItemPrev) - { - return 0; - } - const size_t OrgSize = pItem->MemSize(); - m_Items.AddBefore(pItemPrev, pItem); - pItemPrev->Data(pItem->Data()); - pItem->Data(reinterpret_cast(Offset)); - pItemPrev->MemSize(OrgSize - Size); - pItem->MemSize(Size); - pItemPrev->Free(); - return pItem; - } - //last resort, fragment it into 3 parts - - //Size +=Offset&(Align-1); //adjust size to fit required alignment - Offset -= Offset & (Align - 1); - - CListItemReference* pItemPrev = reinterpret_cast(m_NodePool.Allocate(1, 1)); - CListItemReference* pItemNext = reinterpret_cast(m_NodePool.Allocate(1, 1)); - if (!pItemPrev || !pItemNext) - { - return 0; - } - const size_t OrgSize = pItem->MemSize(); - - m_Items.AddBefore(pItemPrev, pItem); - m_Items.AddBehind(pItemNext, pItem); - - pItemPrev->Data(pItem->Data()); - pItem->Data(reinterpret_cast(Offset)); - pItemNext->Data(pItem->Data() + Size); - pItemPrev->MemSize(pItem->Data() - pItemPrev->Data()); - pItemNext->MemSize(OrgSize - pItemPrev->MemSize() - Size); - pItem->MemSize(Size); - - pItemPrev->Free(); - pItemNext->Free(); - return pItem; - } - - ILINE void Merge(CListItemReference* pItem) - { - m_Items.Validate(pItem); - - //merge with next if possible - CListItemReference* pItemNext = pItem->Next(); - if (pItemNext && pItemNext->IsFree()) - { - if (m_pEmpty == pItemNext) - { - m_pEmpty = pItem; - } - const size_t OrgSize = pItem->MemSize(); - const size_t NextSize = pItemNext->MemSize(); - m_Items.Remove(pItemNext); - pItem->MemSize(OrgSize + NextSize); - m_NodePool.Free(pItemNext); - } - //merge with prev if possible - CListItemReference* pItemPrev = pItem->Prev(); - if (pItemPrev && pItemPrev->IsFree()) - { - if (m_pEmpty == pItem) - { - m_pEmpty = pItemPrev; - } - const size_t OrgSize = pItem->MemSize(); - const size_t PrevSize = pItemPrev->MemSize(); - m_Items.Remove(pItem); - pItemPrev->MemSize(PrevSize + OrgSize); - m_NodePool.Free(pItem); - } - } - - template - ILINE T Resolve(const uint32 ID) - { - CPA_ASSERT(ID); //0 is invalid - return reinterpret_cast(Item(ID)->Data()); - } - - ILINE uint32 AddressToHandle(void* pData) - { - for (CListItemReference* pItem = m_Items.First(); pItem; pItem = pItem->Next()) - { - if (pItem->Data() == pData) - { - return Handle(pItem); - } - } - return 0; - } - - template - ILINE size_t Size(T ID) const - { - CPA_ASSERT(ID); //0 is invalid - return Item(ID)->MemSize(); - } - template - bool InBounds([[maybe_unused]] T ID, [[maybe_unused]] const bool Check) const - { - //boundscheck doesn't work for Referenced containers - return true; - } - - template - ILINE bool Free(T ID, bool ForceBoundsCheck = false) - { - IF (!ID, false) - { - return true; - } - IF (!InBounds(ID, BoundsCheck | ForceBoundsCheck), false) - { - return false; - } - - CListItemReference* pItem = Item(ID); - FreedMemory(pItem->MemSize()); - pItem->Free(); - Merge(pItem); - return true; - } - - ILINE bool Beat(){return false; }//dummy beat in case no defragmentator is wraping - - ILINE size_t MemFree() const{return TMemory::MemSize() - m_Allocated; } - - ILINE size_t MemSize() const{return TMemory::MemSize(); } - - ILINE uint32 Handle(CListItemReference* pItem) const - { - return static_cast(pItem - &m_NodePool[0]); - } - ILINE CListItemReference* Item(uint32 ID) - { - return &m_NodePool[ID]; - } - ILINE const CListItemReference* Item(uint32 ID) const - { - return &m_NodePool[ID]; - } - ILINE static bool Defragmentable(){return true; } - - - - template - ILINE bool ReSize(T* pData, size_t SizeNew) - { - CListItemReference* pItem = Item(*pData); - const size_t SizeOld = pItem->MemSize(); - - //reduction - if (SizeOld > SizeNew) - { - if (pItem->Next()->IsFree()) - { - CListItemReference* pNext = pItem->Next(); - const size_t NextSize = pNext->MemSize(); - pNext->Data(pNext->Data() + SizeNew - SizeOld); - pNext->MemSize(NextSize - SizeNew + SizeOld); - pItem->MemSize(SizeNew); - return true; - } - - //split - CListItemReference* pItemNext = reinterpret_cast(m_NodePool.Allocate(1, 1)); - m_Items.AddBehind(pItemNext, pItem); - pItemNext->Data(pItem->Data() + SizeNew); - pItem->MemSize(SizeNew); - pItemNext->MemSize(SizeOld - SizeNew); - pItemNext->Free(); - return true; - } - - //SizeOldNext(); - const size_t SizeNext = pNext->IsFree() ? pNext->MemSize() : 0; - if (SizeNew <= SizeNext + SizeOld) - { - if (SizeNew == SizeNext + SizeOld) - { - m_Items.Remove(pNext); - m_NodePool.Free(pNext); - } - else - { - pNext->Data(pNext->Data() + SizeNew - SizeOld); - pNext->MemSize(SizeNext - SizeNew + SizeOld); - } - pItem->MemSize(SizeNew); - return true; - } - return false; //no further in-place realloc possible - } - }; -} - - - - - - - -#endif // CRYINCLUDE_CRYPOOL_CONTAINER_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Defrag.h b/Code/CryEngine/CryCommon/CryPool/Defrag.h deleted file mode 100644 index 51fe6fabfb..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Defrag.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_DEFRAG_H -#define CRYINCLUDE_CRYPOOL_DEFRAG_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CDefragStacked - : public T - { - template - ILINE bool DefragElement(TItem* pItem) - { - T::m_Items.Validate(); - if (pItem) - { - for (; pItem->Next(); pItem = pItem->Next()) - { - if (!pItem->IsFree()) - { - continue; - } - if (pItem->Next()->Locked()) - { - continue; - } - if (!pItem->Available(pItem->Next()->Align(), pItem->Next()->Align())) - { - continue; - } - T::m_Items.Validate(pItem); - Stack(pItem); - T::m_Items.Validate(pItem); - Merge(pItem); - T::m_Items.Validate(); - return true; - } - } - return false; - } - public: - ILINE bool Beat() - { - return T::Defragmentable() && DefragElement(T::m_Items.First()); - }; - }; -} - - -#endif // CRYINCLUDE_CRYPOOL_DEFRAG_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Fallback.h b/Code/CryEngine/CryCommon/CryPool/Fallback.h deleted file mode 100644 index 4a2babce1a..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Fallback.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_FALLBACK_H -#define CRYINCLUDE_CRYPOOL_FALLBACK_H -#pragma once - - -namespace NCryPoolAlloc -{ - enum EFallbackMode - { - EFM_DISABLED, - EFM_ENABLED, - EFM_ALWAYS - }; - template - class CFallback - : public TAllocator - { - EFallbackMode m_Fallback; - public: - ILINE CFallback() - : m_Fallback(EFM_DISABLED) - { - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - if (EFM_ALWAYS == m_Fallback) - { - return reinterpret_cast(CPA_ALLOC(Align, Size)); - } - T pRet = TAllocator::template Allocate(Size, Align); - if (!pRet && EFM_ENABLED == m_Fallback) - { - return reinterpret_cast(CPA_ALLOC(Align, Size)); - } - return pRet; - } - - template - ILINE bool Free(T Handle) - { - if (!Handle) - { - return true; - } - if (EFM_ALWAYS == m_Fallback) - { - CPA_FREE(Handle); - return true; - } - - if (EFM_ENABLED == m_Fallback && TAllocator::InBounds(Handle, true)) - { - CPA_FREE(Handle); - return true; - } - return TAllocator::template Free(Handle); - } - - void FallbackMode(EFallbackMode M){m_Fallback = M; } - EFallbackMode FallbaclMode() const{return m_Fallback; } - }; -} - - -#endif // CRYINCLUDE_CRYPOOL_FALLBACK_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Inspector.h b/Code/CryEngine/CryCommon/CryPool/Inspector.h deleted file mode 100644 index 1d16095828..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Inspector.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_INSPECTOR_H -#define CRYINCLUDE_CRYPOOL_INSPECTOR_H -#pragma once - - -namespace NCryPoolAlloc -{ - template - class CInspector - : public TAllocator - { - enum - { - EITableSize = 30 - }; - size_t m_Allocations[EITableSize]; - size_t m_Alignment[EITableSize]; - char m_LogFileName[1024]; - size_t m_AllocCount; - size_t m_FreeCount; - size_t m_ResizeCount; - size_t m_FailAllocCount; - size_t m_FailFreeCount; - size_t m_FailResizeCount; - - void WriteOut(const char* pFileName, uint32 Stack, const char* pFormat, ...) const - { - /* - if(!pFileName) - { - if(!*m_LogFileName) - return; - pFileName = m_LogFileName; - } - FILE* File = fopen(pFileName,"a"); - if(File) - { - - char Buffer[1024]; - for(uint32 a=0;a>= 1; - while (C) - { - Count++; - C >>= 1; - } - return Count >= EITableSize ? EITableSize - 1 : Count; - } - public: - CInspector() - { - for (size_t a = 0; a < EITableSize; a++) - { - m_Allocations[a] = m_Alignment[a] = 0; - } - - m_LogFileName[0] = 0; - m_AllocCount = 0; - m_FreeCount = 0; - m_ResizeCount = 0; - m_FailAllocCount = 0; - m_FailFreeCount = 0; - m_FailResizeCount = 0; - } - - bool LogFileName(const char* pFileName) - { - const size_t Size = strlen(pFileName) + 1; - if (Size > sizeof(m_LogFileName)) - { - m_LogFileName[0] = 0; - return false; - } - memcpy(m_LogFileName, pFileName, Size); - WriteOut(0, "[log start]\n"); - return true; - } - void SaveStats(const char* pFileName) const - { - WriteOut(pFileName, 0, "stats:\n"); - - WriteOut(pFileName, 1, "Counter calls|fails\n"); - WriteOut(pFileName, 2, "Alloc: %6d|%6d\n", m_AllocCount, m_FailAllocCount); - WriteOut(pFileName, 2, "Free: %6d|%6d\n", m_FreeCount, m_FailFreeCount); - WriteOut(pFileName, 2, "Resize:%6d|%6d\n", m_ResizeCount, m_FailResizeCount); - - WriteOut(pFileName, 1, "Allocations:\n"); - for (size_t a = 0; a < EITableSize; a++) - { - WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Allocations[a]); - } - - WriteOut(pFileName, 1, "Alignment:\n"); - for (size_t a = 0; a < EITableSize; a++) - { - WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Alignment[a]); - } - } - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - m_AllocCount++; - m_Allocations[Bit(Size)]++; - m_Alignment[Bit(Align)]++; - T pData = TAllocator::template Allocate(Size, Align); - WriteOut(0, 0, "[A|%d|%d|%d]", (int)pData, Size, Align); - if (!pData) - { - m_FailAllocCount++; - WriteOut(0, 0, "[failed]", Size, Align); - } - return pData; - } - - - template - ILINE bool Free(T pData, bool ForceBoundsCheck = false) - { - m_FreeCount++; - const bool Ret = TAllocator::Free(pData, ForceBoundsCheck); - WriteOut(0, 0, "[F|%d|%d|%d]", (int)pData, (int)ForceBoundsCheck, (int)Ret); - m_FailFreeCount += !Ret; - return Ret; - } - //template - //ILINE bool Free(T pData) - // { - // m_FreeCount++; - // const bool Ret = TAllocator::Free(pData); - // WriteOut(0,0,"[F|%d|%d|%d]",(int)pData,(int)-1,(int)Ret); - // m_FailFreeCount+=!Ret; - // return Ret; - // } - - template - ILINE bool Resize(T** pData, size_t Size, size_t Alignment) - { - m_ResizeCount++; - const bool Ret = TAllocator::Resize(pData, Size, Alignment); - WriteOut(0, 0, "[R|%d|%d|%d]", (int)*pData, (int)-1, (int)Ret); - m_FailResizeCount += !Ret; - return Ret; - } - - template - ILINE size_t FindBiggest(const T* pItem) - { - size_t Biggest = 0; - while (pItem) - { - if (pItem->IsFree() && pItem->MemSize() > Biggest) - { - Biggest = pItem->MemSize(); - } - pItem = pItem->Next(); - } - return Biggest; - } - - ILINE size_t BiggestFreeBlock() - { - return FindBiggest(TAllocator::m_Items.First()); - } - - ILINE uint8* FirstItem() - { - return TAllocator::m_Items.First()->Data(); - } - }; -} - - - - -#endif // CRYINCLUDE_CRYPOOL_INSPECTOR_H - diff --git a/Code/CryEngine/CryCommon/CryPool/List.h b/Code/CryEngine/CryCommon/CryPool/List.h deleted file mode 100644 index 5c4588d40c..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/List.h +++ /dev/null @@ -1,366 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_LIST_H -#define CRYINCLUDE_CRYPOOL_LIST_H -#pragma once - -namespace NCryPoolAlloc -{ - class CListItemInPlace; - class CListItemReference; - - template - class CListItem - { - TItem* m_pPrev; - TItem* m_pNext; - public: - - ILINE TItem* Prev(){return m_pPrev; } - ILINE TItem* Next(){return m_pNext; } - ILINE const TItem* Prev() const{return m_pPrev; } - ILINE const TItem* Next() const{return m_pNext; } - ILINE void Prev(TItem* pPrev){ m_pPrev = pPrev; } - ILINE void Next(TItem* pNext){ m_pNext = pNext; } - - //debugging - void Validate(); - }; - - template - class CListItemFlagged - : public CListItem - { - enum - { - ELIF_INUSE = (1 << 0), - ELIF_LOCKED = (1 << 1), - }; - uint32 m_Flags : 8; - uint32 m_Align : 24; - public: - ILINE CListItemFlagged() - : m_Flags(0) - { - } - ILINE bool IsFree() const{return (m_Flags & ELIF_INUSE) != ELIF_INUSE; } - ILINE void Free(){m_Flags &= ~ELIF_INUSE; } - ILINE void InUse(uint32 A){m_Flags |= ELIF_INUSE; m_Align = A; } - ILINE bool Locked() const{return ELIF_LOCKED == (m_Flags & ELIF_LOCKED); } - ILINE void Lock(){m_Flags |= ELIF_LOCKED; } - ILINE void Unlock(){m_Flags &= ~ELIF_LOCKED; } - ILINE uint32 Align() const{return m_Align; } - }; - - class CListItemInPlace - : public CListItemFlagged - { - public: - ILINE void Init([[maybe_unused]] uint8* pData, [[maybe_unused]] size_t Size, CListItemInPlace* pPrev, CListItemInPlace* pNext) - { - Prev(pPrev); - Next(pNext); - CPA_ASSERT(Size == MemSize()); - } - - ILINE bool Available(size_t Size, size_t Align) const - { - size_t Offset = reinterpret_cast(Data()); - if (Offset & (Align - 1)) //not aligned? - { - Size += sizeof(CListItemInPlace) + Align - 1; //then an intermedian node needs to fit - } - return Size <= MemSize() && IsFree(); - } - ILINE uint8* Data(){return reinterpret_cast(this) + sizeof(CListItemInPlace); } - ILINE const uint8* Data() const{return reinterpret_cast(this) + sizeof(CListItemInPlace); } - ILINE size_t MemSize() const - { - const uint8* pNext = reinterpret_cast(Next()); - const uint8* pThis = reinterpret_cast(this); - const size_t ESize = sizeof(CListItemInPlace); - size_t Delta = pNext - pThis; - Delta -= ESize; - return Delta; - } - }; - - class CListItemReference - : public CListItemFlagged - { - uint8* m_pData; - // size_t m_Size; - public: - ILINE void Init(uint8* pData, size_t Size, CListItemReference* pPrev, CListItemReference* pNext) - { - Data(pData); - Prev(pPrev); - Next(pNext); - MemSize(Size); - } - ILINE bool Available(size_t Size, size_t Align) const - { - size_t Offset = reinterpret_cast(Data()); - if ((Offset & (Align - 1))) - { - Size += Align - (Offset & (Align - 1)); - } - return Size <= MemSize() && IsFree(); - } - ILINE void Data(uint8* pData){m_pData = pData; } - ILINE uint8* Data(size_t Align) - { - Align--; - size_t Offset = reinterpret_cast(m_pData); - Offset = (Offset + Align) & ~Align; - return reinterpret_cast(Offset); - } - ILINE uint8* Data(){return m_pData; } - ILINE const uint8* Data() const{return m_pData; } - ILINE void MemSize([[maybe_unused]] size_t Size) { } - ILINE size_t MemSize() const - { - const size_t T = reinterpret_cast(Data()); - const size_t N = Next() ? reinterpret_cast(Next()->Data()) : T; - return N - T; - } - //ILINE void MemSize(size_t Size){m_Size=Size;} - //ILINE size_t MemSize()const{return m_Size;} - }; - - template - class CList - { - TItem* m_pFirst; - TItem* m_pLast; - size_t m_Count; - public: - ILINE CList() - : m_pFirst(0) - , m_pLast(0) - , m_Count(0) - { - } - - ILINE void First(TItem* pItem){m_pFirst = pItem; } - ILINE TItem* First(){return m_pFirst; } - ILINE void Last(TItem* pItem){m_pLast = pItem; } - ILINE TItem* Last(){return m_pLast; } - ILINE bool Empty() const{return m_pFirst == 0; } - - ILINE TItem* PopFirst() - { - Validate(); - - if (!m_pFirst) - { - return 0; - } - - TItem* pRet = m_pFirst; - - m_pFirst = m_pFirst->Next(); - - if (m_pFirst) //if any element exists - { - m_pFirst->Prev(0); //set prev ptr of this element to 0 - } - else - { - m_pLast = 0; //set ptr to last element to 0 if ptr to first is zero as well - } - Validate(); - m_Count--; - return pRet; - } - - ILINE TItem* PopLast() - { - Validate(); - - if (!m_pLast) - { - return 0; - } - - TItem* pRet = m_pLast; - - m_pLast = m_pLast->Prev(); - - if (m_pLast) //if any element exists - { - m_pLast->Next(0); //set prev ptr of this element to 0 - } - else - { - m_pFirst = 0; //set ptr to last element to 0 if ptr to first is zero as well - } - Validate(); - m_Count--; - return pRet; - } - - ILINE void AddFirst(TItem* pItem) - { - CPA_ASSERT(pItem); //ERROR AddFirst got 0 pointer - - Validate(); - - pItem->Prev(0); - pItem->Next(m_pFirst); - if (!m_pFirst) - { - m_pLast = pItem; - } - else - { - m_pFirst->Prev(pItem); - } - m_pFirst = pItem; - - m_Count++; - Validate(); - } - - ILINE void AddLast(TItem* pItem) - { - CPA_ASSERT(pItem); //ERROR AddLast got 0 pointer - - Validate(); - - pItem->Prev(m_pLast); - pItem->Next(0); - if (!m_pLast) - { - m_pFirst = pItem; - } - else - { - m_pLast->Next(pItem); - } - m_pLast = pItem; - - m_Count++; - Validate(); - } - ILINE void AddBefore(TItem* pItem, TItem* pItemSuccessor) - { - CPA_ASSERT(pItem); - CPA_ASSERT(pItemSuccessor); - - Validate(); - - pItem->Next(pItemSuccessor); - pItem->Prev(pItemSuccessor->Prev()); - pItemSuccessor->Prev(pItem); - - if (pItemSuccessor == m_pFirst) - { - m_pFirst = pItem; - } - else - { - pItem->Prev()->Next(pItem); - } - - m_Count++; - Validate(); - } - ILINE void AddBehind(TItem* pItem, TItem* pItemPredecessor) - { - CPA_ASSERT(pItem); - CPA_ASSERT(pItemPredecessor); - - Validate(); - - pItem->Next(pItemPredecessor->Next()); - pItem->Prev(pItemPredecessor); - pItemPredecessor->Next(pItem); - - if (pItemPredecessor == m_pLast) - { - m_pLast = pItem; - } - else - { - pItem->Next()->Prev(pItem); - } - - m_Count++; - Validate(); - } - - ILINE void Remove(TItem* pItem) - { - CPA_ASSERT(pItem); //ERROR releasing empty item - - if (pItem == m_pFirst) - { - PopFirst(); - return; - } - if (pItem == m_pLast) - { - PopLast(); - return; - } - - Validate(pItem); - - pItem->Prev()->Next(pItem->Next()); - pItem->Next()->Prev(pItem->Prev()); - - m_Count--; - Validate(); - } - - //debug - ILINE void Validate(TItem* pReferenceItem = 0) - { - if (!VALIDATE) - { - return; - } - - //one-sided empty? - CPA_ASSERT((!First() && !Last()) || (First() && Last())); //ERROR validating item-list, just one end is 0 - - // endles linking? - TItem* pPrev = 0; - TItem* pItem = First(); - while (pItem) - { - if (pReferenceItem == pItem) - { - pReferenceItem = 0; - } - CPA_ASSERT(pPrev == pItem->Prev()); //ERROR validating item-list, endless linking NULL - pPrev = pItem; - pItem = pItem->Next(); - } - - CPA_ASSERT(pPrev == Last()); //ERROR validating item-list, broken list, does not end at specified Last item - CPA_ASSERT(!pReferenceItem); //ERROR reference item not found in the item-list - } - ILINE size_t Count() const{return m_Count; } - }; -} - - - - - - -#endif // CRYINCLUDE_CRYPOOL_LIST_H - diff --git a/Code/CryEngine/CryCommon/CryPool/Memory.h b/Code/CryEngine/CryCommon/CryPool/Memory.h deleted file mode 100644 index 43daaaeada..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/Memory.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_MEMORY_H -#define CRYINCLUDE_CRYPOOL_MEMORY_H -#pragma once - -namespace NCryPoolAlloc -{ - class CMemoryDynamic - { - size_t m_Size; - uint8* m_pData; - - protected: - ILINE CMemoryDynamic() - : m_Size(0) - , m_pData(0){} - - public: - ILINE void InitMem(const size_t S, uint8* pData) - { - m_Size = S; - m_pData = pData; - CPA_ASSERT(S); - CPA_ASSERT(pData); - } - - ILINE size_t MemSize() const{return m_Size; } - ILINE uint8* Data(){return m_pData; } - ILINE const uint8* Data() const{return m_pData; } - }; - - template - class CMemoryStatic - { - uint8 m_Data[TSize]; - - protected: - ILINE CMemoryStatic() - { - } - public: - ILINE void InitMem(const size_t S, uint8* pData) - { - } - ILINE size_t MemSize() const{return TSize; } - ILINE uint8* Data(){return m_Data; } - ILINE const uint8* Data() const{return m_Data; } - }; -} - - - - - - - -#endif // CRYINCLUDE_CRYPOOL_MEMORY_H - diff --git a/Code/CryEngine/CryCommon/CryPool/PoolAlloc.h b/Code/CryEngine/CryCommon/CryPool/PoolAlloc.h deleted file mode 100644 index 23eda51a2a..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/PoolAlloc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#if defined(POOLALLOCTESTSUIT) -//cheat just for unit testing on windows -#include "BaseTypes.h" -#define ILINE inline -#endif - -// Traits -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(CryPool/PoolAlloc_h) -#elif defined(APPLE) || defined(LINUX) -#define POOLALLOC_H_TRAIT_USE_MEMALIGN 1 -#endif - - -#if POOLALLOC_H_TRAIT_USE_MEMALIGN -#define CPA_ALLOC memalign -#define CPA_FREE free -#else -#define CPA_ALLOC _aligned_malloc -#define CPA_FREE _aligned_free -#endif -#define CPA_ASSERT assert -#define CPA_ASSERT_STATIC(X) {uint8 assertdata[(X) ? 0 : 1]; } -#define CPA_BREAK __debugbreak() - -#include "List.h" -#include "Memory.h" -#include "Container.h" -#include "Allocator.h" -#include "Defrag.h" -#include "STLWrapper.h" -#include "Inspector.h" -#include "Fallback.h" -#if !defined(POOLALLOCTESTSUIT) -#include "ThreadSafe.h" -#endif - -#undef CPA_ASSERT -#undef CPA_ASSERT_STATIC -#undef CPA_BREAK diff --git a/Code/CryEngine/CryCommon/CryPool/STLWrapper.h b/Code/CryEngine/CryCommon/CryPool/STLWrapper.h deleted file mode 100644 index cb06ced1a4..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/STLWrapper.h +++ /dev/null @@ -1,148 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_STLWRAPPER_H -#define CRYINCLUDE_CRYPOOL_STLWRAPPER_H -#pragma once - -namespace NCryPoolAlloc -{ - //namespace CSTLPoolAllocWrapperHelper - //{ - // inline void destruct(char *) {} - // inline void destruct(wchar_t*) {} - // template - // inline void destruct(T *t) {t->~T();} - //} - - //template - //struct CSTLPoolAllocWrapperStatic - //{ - // static PoolAllocator * allocator; - //}; - - //template - //struct CSTLPoolAllocWrapperKungFu : public CSTLPoolAllocWrapperStatic - //{ - //}; - - template - class CSTLPoolAllocWrapper - { - private: - static TCont* m_pContainer; - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - static TCont* Container(){return m_pContainer; } - static void Container(TCont* pContainer){m_pContainer = pContainer; } - - - template - struct rebind - { - typedef CSTLPoolAllocWrapper other; - }; - - CSTLPoolAllocWrapper() throw() - { - } - - CSTLPoolAllocWrapper(const CSTLPoolAllocWrapper&) throw() - { - } - - template - CSTLPoolAllocWrapper(const CSTLPoolAllocWrapper&) throw() - { - } - - ~CSTLPoolAllocWrapper() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate(size_type n = 1, const_pointer hint = 0) - { - TCont* pContainer = Container(); - uint8* pData = pContainer->TCont::template Allocate(n * sizeof(T), sizeof(T)); - return pContainer->TCont::template Resolve(pData); - // return Container()?Container()->Allocate(n*sizeof(T),sizeof(T)):0 - } - - void deallocate(pointer p, size_type n = 1) - { - if (Container()) - { - Container()->Free(p); - } - } - - size_type max_size() const throw() - { - return Container() ? Container()->MemSize() : 0; - } - - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } - - void destroy(pointer p) - { - p->~T(); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const CSTLPoolAllocWrapper&) {return true; } - bool operator!=(const CSTLPoolAllocWrapper&) {return false; } - }; -} - -#endif // CRYINCLUDE_CRYPOOL_STLWRAPPER_H - diff --git a/Code/CryEngine/CryCommon/CryPool/ThreadSafe.h b/Code/CryEngine/CryCommon/CryPool/ThreadSafe.h deleted file mode 100644 index 5ae7dbd4bc..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/ThreadSafe.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_THREADSAFE_H -#define CRYINCLUDE_CRYPOOL_THREADSAFE_H -#pragma once - - -#include - -namespace NCryPoolAlloc -{ - template - class CThreadSafe - : public TAllocator - { - CryCriticalSection m_Mutex; - public: - - template - ILINE T Allocate(size_t Size, size_t Align = 1) - { - CryAutoLock lock(m_Mutex); - return TAllocator::template Allocate(Size, Align); - } - - - template - ILINE bool Free(T pData, bool ForceBoundsCheck = false) - { - CryAutoLock lock(m_Mutex); - return TAllocator::Free(pData, ForceBoundsCheck); - } - - template - ILINE bool Resize(T** pData, size_t Size, size_t Alignment) - { - CryAutoLock lock(m_Mutex); - return TAllocator::Resize(pData, Size, Alignment); - } - }; -} - - - - -#endif // CRYINCLUDE_CRYPOOL_THREADSAFE_H - diff --git a/Code/CryEngine/CryCommon/CryPool/example.h b/Code/CryEngine/CryCommon/CryPool/example.h deleted file mode 100644 index e17d5abee2..0000000000 --- a/Code/CryEngine/CryCommon/CryPool/example.h +++ /dev/null @@ -1,287 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYPOOL_EXAMPLE_H -#define CRYINCLUDE_CRYPOOL_EXAMPLE_H -#pragma once - - -//The documentation is split up into 3 main parts, so strg+f for -// -Theory -// -Building blocks -// -Usage -// -FAQ -// -Realloc/Resize - -///////////////////////////////////////////////////////////////////////// -// -Theory -///////////////////////////////////////////////////////////////////////// - - -//this includes the 3 major parts of the allocate suite -//1. the memory location templates -//2. container types -//3. some allocator version -//addtional you get -//4. a simple stack based defragmentation template -//5. helper - -//1. memory location templates -// There are two types of them, static and dynamic -//1.1 CMemoryStatic allows you do define on compile time what size -// it should have, suitable for pool you know that they won't grow or -// shrink -//1.2 CMemoryDynamic, this one has no template parameter, it has just one -// indirection via ptr to the memory location and size, that you will -// set during initialization. - -//2. Container types -// We have also two container types, one so called "In Place" -// and one "Referenced". -//2.1 "In Place" means that a header is placed above every allocation, -// this is the usual way most allocators work. -//2.2 "Referenced", has an extra pool of headers that point to the actual -// memory. This is suitable for -// - external memory locations that are not directly accessable by the -// cpu. E.g. pools on disk, networks, rsx memory.. -// - defragmentation, because you don't save a ptr to the real memory -// location, just a "handle" of the referencing item. -// - big alignments, having 4kb of alignment would waste also -// - 4kb for ever "In Place" header, you might not want that. - -//3. Allocators -// This time we have 3 of them, "BestFit", "WorstFit" and "FirstFit" -//3.1 FirstFit just seeks for any location big enought to fit your -// requested size of memory. Internally it also saves the last used -// free memory area to speed up allocations. -// Use this also if you have just one particular allocation size. -//3.2 WorstFit, although it might sound illogical, WorstFit can reduce -// memory fragmentation in a cases with very random allocation sizes, -// because it gives smaller free blocks the chance to concatenate to -// bigger free blocks again while filling up those previously -// generated big blocks. The bad side is that it takes quite some time -// to find the biggest block as this needs to be done every time you -// allocate, so use this just when having a low amount of allocations -// or you're really desperately looking for mem. -//3.3 BestFit, it's best used if you don't have just one allocation size, -// but still very few varying sizes. Previously released blocks of -// the currently allocating sizes will be seeked and reused, this -// strongly helps to reduce fragmentation. While this might be slow -// in some cases, it can save you from doing any defragmentation. - -//4. Defragmentation -// At the moment just one defragmentation algorithm is implemented: -// "Stack defragmentator" -// If you don't want some block to be moved, "Lock" it using your -// memory handle. -//4.1 Stack based -// To reduce fragmentation, holes are filled up with the next used, -// memory area. This defragmentation sheme is useful when you have -// some long living locations as well as very short living ones. -// At some point all long live memory will end up at the bottom of -// the stack, while leaving empty memory areas at the top for short -// living allocations. - -//5. Helper -// this should be filled up with some handy helper tools for this -// pool suite. -// The first tool is a wrapper for the usage with stl -//5.1 Wrapper for STL -// As you know, you can pass your own allocator as the last -// parameter of stl containers, with this helper you can use a pool -// created with this suite and wrap it for the stl. - - -///////////////////////////////////////////////////////////////////////// -// -Building blocks -///////////////////////////////////////////////////////////////////////// - -//That's the theory, so how does it work? -//It's pretty simple, you compose the pool of your dreams by cascading -//templates. -//Lets start with an exmaple -//Per level you want to allocate a fixed amount of memory for your -//textures. -CMemoryDynamic -//- They are placed in some memory you can access directly with the cpu: -CInPlace -//- and you don't want to defragmentate, so you prefer an allocation -// sheme that reduces fragmentation. - CBestFit -//now you combine them -typedef CBestFit, CListItemInPlace> TMyOwnPool; - -//Yes, it's that simple. -//ok, ok, texture memory is usually nothing you want to access directly -//with your cpu, so let's create a referencing pool. Therefor you need -//to also specify how many nodes that can reference your pool will have. -//We won't have more than 4000 textures, so let's start with -{ - enum TEXTURE_NODE_COUNT = 4096 -}; -//and now our referencing pool -typedef CBestFit < CReferenced TMyOwnPool; - -//But yeah, you're right, texture memory has also a fixed size, lets -//assume it's 128MB. -{ - enum TEXTURE_MEMORY_SIZE = 128 * 1024 * 1024 -}; -//and our fixed sized memory pool -typedef CBestFit < CReferenced, TEXTURE_NODE_COUNT> TMyOwnPool; - -//ok, but you don't trust the best fit allocator in all cases, you prefer -//a fast one and you accept the slow down for defragmentation incase the -//allocation fails. -//So lets created a straight First Fit allocator with defragmentation: -typedef CDefragStacked < CFirstFit, TEXTURE_NODE_COUNT> > TMyOwnPool; - -//here you see how simple you can add defragmentation, but be careful, it -//works of course just on Reference based memory containers, if you have -//Direct pointers to In Place allocation, we cannot shuffle them around. - - -///////////////////////////////////////////////////////////////////////// -// -Usage -///////////////////////////////////////////////////////////////////////// - - -//it all starts by including the meain header -#include "PoolAlloc.h" - -//Define your dream allocator, preferably using a typedef (or macro) -typedef CBestFit, CListItemInPlace> TMyOwnPool; -//also typedef (or macro) your handle -typedef uint8* TMyHandle; //in case of "In Place" allocations -typedef uint32 TMyHandle; //in case of "Referenced" - -//Instantiate it -TMyOwnPool g_MyMemory; - -//now you need to initialize it, -g_MyMemory.InitMem(pMemoryArea, MemorySize); //in case you use "CMemoryDynamic" -g_MyMemory.InitMem(); //in case you use "CmemoryStatic, -//altough you could pass the same -//parameters, they'd be ignored. -//Use this also to flush the pool -//quickly - - -//now allocate -TMyHandle MemID = g_MyMemory.Allocate(Size); -//optionally alignment can be passed as 2nd parameter -TMyHandle MemID = g_MyMemory.Allocate(Size, Align); - -//free it simply by calling -g_Memory.Free(MemID); - -//you might want to call the beat function to defragment the memory -//on regular base -g_Memory.Beat(); -//you might also want to call it just when an allocation failed to -//defragmentate the memory as good as possible -if (!(MemID = g_Memoery.Allocate(Size))) -{ - while (g_Memory.Beat()) - { - ; - } - MemID = g_Memoery.Allocate(Size); -} - -//To acquire the pointer to your data, you need to resolve the handle -MyObject* pObject = g_Memory.Resolve(MemID); - -///////////////////////////////////////////////////////////////////////// -// -Realloc/Resize -///////////////////////////////////////////////////////////////////////// - -// The Containers provide a "resize" function. This one does nothing else -// than the name suggest, it is freeing some memory at the end of your -// allocation or, if free memory is available, allocates some memory to -// the end of your buffer. But it may also fail, if not enough memory -// available to allocate. -// "Realloc" on the other side requires an extra template that you wrap -// around your existing one like: -typedef CReallocator TMyOwnPoolWithReallocation; -// This one will first try to use resize, but in case it fails, it will -// allocate a seperate memory area, copy the data and free the old one. -// -// But this may fail as well, therefor the result is not a pointer to the -// allocation, but true/false. -// There for you need to pass a pointer to your pointer to the memory area -// or handle you deal with. -Handle = rMemory.Allocate(10, 1); -if (!rMemory.Reallocate(&Handles, 11, 1)) -{ - //handle realloc failure -} - - -///////////////////////////////////////////////////////////////////////// -// -FAQ -///////////////////////////////////////////////////////////////////////// - -//"DO I HAVE TO ALWAYS RESOLVE?" -//if you use "In Place" memory, not at all, all resolve does is to -//cast your handle to your object ptr and returns it. -//if you use "Referenced" memory and you don't defragmentate, you -//can do it once and keep the ptr, but you also need to keep the -//handle to free the memory later on. - -//"any reason I should resolve?" -//Yes, first of all, it makes it very easy to switch between various -//pool configuration for testing, you simply change some params of -//your typedef (or macro) and it should work out of the box. -//second, for defragmentation it's the only way to go and for future -//things it might be needed as well - -//"but isn't resolving just overhead?" -//in case of "In Place": no, the resolve function just returns the -//pointer, casting to your wanted type -//in case of "Referenced": it cost you one indirection. - - -//"How do I flush the whole pool without freeing all items?" -g_Memory.InitMem() -//yes, you can call "InitMem" once again, you need to pass the mem -//ptr and size if using CMemoryDynamic e.g. -g_Memory.Init(g_Memory.Size(), g_Memory.Data()); - -//"How do I lock the allocated memory to avoid any reallocation" -g_Memory.Item(ptr)->Lock(); - - -//"How do I get the size of a memory block?" -g_Memory.Item(ptr)->MemSize(); - - - - -//"Is there any example?" -//for a real life example check PAUnitTest.cpp used to validate all -//functions of this pool. - - -//bug reports? questions? support? -//just ask me :) (michael kopietz) - - - - - - - - -#endif // CRYINCLUDE_CRYPOOL_EXAMPLE_H - diff --git a/Code/CryEngine/CryCommon/CryPtrArray.h b/Code/CryEngine/CryCommon/CryPtrArray.h deleted file mode 100644 index 55fd0bcec6..0000000000 --- a/Code/CryEngine/CryCommon/CryPtrArray.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H -#define CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H -#pragma once - -#include "CryArray.h" -#include "CrySizer.h" - -//--------------------------------------------------------------------------- -template -struct PtrArray - : DynArray

-{ - typedef DynArray

super; - - // Overrides. - typedef T value_type; - - ILINE ~PtrArray(){} - - inline T& operator [](int i) const - { return *super::operator[](i); } - - // Iterators. - struct iterator - { - iterator(P* p) - : _ptr(p) - {} - - operator P* () const - { - return _ptr; - } - void operator++() - { _ptr++; } - void operator--() - { _ptr--; } - T& operator*() const - { assert(_ptr); return **_ptr; } - T* operator->() const - { assert(_ptr); return *_ptr; } - - protected: - P* _ptr; - }; - - struct const_iterator - { - const_iterator(const P* p) - : _ptr(p) - {} - - operator const P* () const - { - return _ptr; - } - void operator++() - { _ptr++; } - void operator--() - { _ptr--; } - T& operator*() const - { assert(_ptr); return **_ptr; } - T* operator->() const - { assert(_ptr); return *_ptr; } - - protected: - const P* _ptr; - }; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(this->begin(), this->get_alloc_size()); - for (int i = 0; i < this->size(); ++i) - { - pSizer->AddObject(this->super::operator [](i)); - } - } -}; - -//--------------------------------------------------------------------------- -template -struct SmartPtrArray - : PtrArray< T, _smart_ptr > -{ -}; - -#endif // CRYINCLUDE_CRYCOMMON_CRYPTRARRAY_H diff --git a/Code/CryEngine/CryCommon/CrySizer.h b/Code/CryEngine/CryCommon/CrySizer.h index fc45438209..7a6f6cf962 100644 --- a/Code/CryEngine/CryCommon/CrySizer.h +++ b/Code/CryEngine/CryCommon/CrySizer.h @@ -33,7 +33,6 @@ #include #include #include -#include #include // forward declarations for overloads @@ -48,8 +47,6 @@ struct SPipTangents; #include // workaround for Amd64 compiler #endif -#include // <> required for Interfuscator. IResourceCollector - namespace AZ { class Vector3; @@ -251,12 +248,6 @@ public: void AddObject([[maybe_unused]] const AZ::Vector3& rObj) {} void AddObject(void*) {} - template - void AddObject(const Array2d& array2d) - { - this->AddObject(array2d.m_pData, array2d.GetDataSize()); - } - // overloads for container, will automaticly traverse the content template void AddObject(const std::list& rList) @@ -335,20 +326,6 @@ public: } } - template - void AddObject(const TArray& rVector) - { - if (!this->AddObject(rVector.begin(), rVector.capacity() * sizeof(T))) - { - return; - } - - for (int i = 0, end = rVector.size(); i < end; ++i) - { - this->AddObject(rVector[i]); - } - } - template void AddObject(const PodArray& rVector) { @@ -427,11 +404,6 @@ public: return AddObject (&rObject, sizeof(T)); } - // used to collect the assets needed for streaming and to gather statistics - // always returns a valid reference - virtual IResourceCollector* GetResourceCollector() = 0; - virtual void SetResourceCollector(IResourceCollector* pColl) = 0; - bool Add (const char* szText) { return AddObject(szText, strlen(szText) + 1); diff --git a/Code/CryEngine/CryCommon/CrySystemBus.h b/Code/CryEngine/CryCommon/CrySystemBus.h index f183de0fa9..def1ce4688 100644 --- a/Code/CryEngine/CryCommon/CrySystemBus.h +++ b/Code/CryEngine/CryCommon/CrySystemBus.h @@ -49,12 +49,6 @@ public: //! ISystem has shut down. virtual void OnCrySystemPostShutdown() {} - //! Engine pre physics update. - virtual void OnCrySystemPrePhysicsUpdate() {} - - //! Engine post physics update. - virtual void OnCrySystemPostPhysicsUpdate() {} - //! Sent when a new level is being created. virtual void OnCryEditorBeginCreate() {} diff --git a/Code/CryEngine/CryCommon/CryThread.h b/Code/CryEngine/CryCommon/CryThread.h index f1e97b2199..9aa7bce128 100644 --- a/Code/CryEngine/CryCommon/CryThread.h +++ b/Code/CryEngine/CryCommon/CryThread.h @@ -37,9 +37,6 @@ enum CryLockType #define CRYLOCK_HAVE_FASTLOCK 1 -void CryThreadSetName(threadID nThreadId, const char* sThreadName); -const char* CryThreadGetName(threadID nThreadId); - ///////////////////////////////////////////////////////////////////////////// // // Primitive locks and conditions. diff --git a/Code/CryEngine/CryCommon/CryThreadImpl.h b/Code/CryEngine/CryCommon/CryThreadImpl.h index b151b3da8a..da9be86dd5 100644 --- a/Code/CryEngine/CryCommon/CryThreadImpl.h +++ b/Code/CryEngine/CryCommon/CryThreadImpl.h @@ -31,22 +31,3 @@ #else // Put other platform specific includes here! #endif - -#include - -void CryThreadSetName(threadID dwThreadId, const char* sThreadName) -{ - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager()) - { - gEnv->pSystem->GetIThreadTaskManager()->SetThreadName(dwThreadId, sThreadName); - } -} - -const char* CryThreadGetName(threadID dwThreadId) -{ - if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager()) - { - return gEnv->pSystem->GetIThreadTaskManager()->GetThreadName(dwThreadId); - } - return ""; -} diff --git a/Code/CryEngine/CryCommon/CryThreadImpl_windows.h b/Code/CryEngine/CryCommon/CryThreadImpl_windows.h index 6f37edeea1..3ff28a81be 100644 --- a/Code/CryEngine/CryCommon/CryThreadImpl_windows.h +++ b/Code/CryEngine/CryCommon/CryThreadImpl_windows.h @@ -13,8 +13,6 @@ #pragma once -//#include - #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif diff --git a/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h b/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h deleted file mode 100644 index aaf5a0889f..0000000000 --- a/Code/CryEngine/CryCommon/CryThreadSafeRendererContainer.h +++ /dev/null @@ -1,634 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Specialized Container for Renderer data with the following proberties: -// - Created during the 3DEngine Update, comsumed in the renderer in the following frame -// - This Container is very restricted and likely not optimal for other situations - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H -#pragma once - - -// This container is specialized for data which is generated in the 3DEngine and consumed by the renderer -// in the following frame due to multithreaded rendering. To be useable by Jobs as well as other Threads -// some very specific desing choices were taken: -// First of the underlying continous memory block is only resized during a call to 'CoalesceMemory' -// to prevent freeing a memory block which could be used by another thread. -// If new memory is requiered, a page of 4 KB is allocated and used as a temp storage till the next -// call to 'CoalesceMemory' which then copies all page memory into one continous block. -// Also all threading relevant functions are implemented LockLess to prevent lock contention and make -// this container useable from Jobs -// -// Right now, the main usage pattern of this container is by the RenderThread, who calls at the beginning -// of its frame 'CoalesceMemory', since then we can be sure that the 3DEngine has finished creating it's elements. -// -// Since the main purpose of this container is multi-threading adding of elements, a slight change was done to the -// push_back interface compared to std::vector: -// All implemented push_back variants can return a pointer into the storage (safe since no memory is freed during adding) -// and a index for this elements. This is done since calling operator[] could be expensive when called before 'CoalesceMemory' -// -// For ease of implementation (and a little bit of speed), this container only supports POD types (which can be copied with memcpy) -// also note that this container only supports push_back (and resize back to 0) and no pop back due cost (performance and code complexity) of supporting lock-free in parallel pop_back -#define TSRC_ALIGN _MS_ALIGN(128) - -template -class TSRC_ALIGN CThreadSafeRendererContainer -{ -public: - CThreadSafeRendererContainer(); - ~CThreadSafeRendererContainer(); - - //NOTE: be aware that these valus can potentially change if some objects are added in parallel - size_t size() const; - size_t empty() const; - size_t capacity() const; - - //NOTE: be aware that this operator can be more expensive if the memory was not coalesced before - T& operator[](size_t n); - const T& operator[](size_t n) const; - - T* push_back_new(); - T* push_back_new(size_t& nIndex); - - void push_back(const T&); - void push_back(const T&, size_t& nIndex); - - // NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe - void clear(); - void resize(size_t n); - void reserve(size_t n); - - void CoalesceMemory(); - - void GetMemoryUsage(ICrySizer*) const; - - // disable copy/assignment - CThreadSafeRendererContainer(const CThreadSafeRendererContainer& rOther) = delete; - CThreadSafeRendererContainer& operator=(const CThreadSafeRendererContainer& rOther) = delete; - -private: - - ///////////////////////////////////// - // Struct to represent a memory chunk - // used in fallback allocations during 'Fill' phase - class CMemoryPage - { - public: - // size of a page to allocate, the CMemoryPage is just the header, - // the actual object data is stored in the 4KB chunk right - // after the header (while keeping the requiered alignment and so on) - enum - { - nMemoryPageSize = 4096 - }; - - CMemoryPage(); - - // allocation functions - static CMemoryPage* AllocateNewPage(); - bool TryAllocateElement(size_t& nIndex, T*& pObj); - - // access to the elements - T& GetElement(size_t n); - T* GetData() const; - - // information about the page (NOTE: not thread-safe in all combinations) - size_t Size() const; - size_t Capacity() const; - size_t GetDataSize() const; - - CMemoryPage* m_pNext; // Pointer to next entry in single-linked list of CMemoryPages - - private: - LONG m_nSize; // Number of elements currently in the page - LONG m_nCapacity; // Number of elements which could fit into the page - T* m_arrData; // Element memory, from the same memory chunk right after the CMemoryPage class - }; - - - ///////////////////////////////////// - // Private functions which do the lock-less updating - T* push_back_impl(size_t& nIndex); - bool try_append_to_continous_memory(size_t& nIndex, T*& pObj); - - T& GetMemoryPageElement(size_t n); - - - ///////////////////////////////////// - // Private Member Variables - T* m_arrData; // Storage for the continous memory part, during coalescing resized to hold all page memory - LONG m_nCapacity; // Avaible Memory in continous memory part, if exhausted during 'Fill' phase, pages as temp memory chunks are allocated - - CMemoryPage* m_pMemoryPages; // Single linked list of memory chunks, used for fallback allocations during 'Fill' phase (to prevent changing the continous memory block during 'Fill' - - LONG m_nSize; // Number of elements currently in the container, can be larger than m_nCapacity due the nonContinousPages - - bool m_bElementAccessSafe; // bool to indicate if we are currently doing a 'CoalasceMemory' step, during which some operations are now allowed -} _ALIGN(128); - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::CThreadSafeRendererContainer() - : m_arrData(NULL) - , m_nCapacity(0) - , m_pMemoryPages(NULL) - , m_nSize(0) - , m_bElementAccessSafe(true) -{ -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::~CThreadSafeRendererContainer() -{ - clear(); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::size() const -{ - return *const_cast(&m_nSize); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::empty() const -{ - return *const_cast(&m_nSize) == 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::capacity() const -{ - // capacity of continous memory block - LONG nCapacity = m_nCapacity; - - // add capacity of all memory pages - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - nCapacity += pCurrentMemoryPage->Capacity(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - - return nCapacity; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeRendererContainer::operator[](size_t n) -{ - assert(m_bElementAccessSafe); - T* pRet = NULL; - -#if !defined(NULL_RENDERER) - assert((LONG)n < m_nSize); -#endif - if ((LONG)n < m_nCapacity) - { - pRet = &m_arrData[n]; - } - else - { - pRet = &GetMemoryPageElement(n); - } - return *pRet; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline const T& CThreadSafeRendererContainer::operator[](size_t n) const -{ - return const_cast(const_cast*>(this)->operator[](n)); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_new() -{ - assert(m_bElementAccessSafe); - size_t nUnused = ~0; - return push_back_impl(nUnused); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_new(size_t& nIndex) -{ - assert(m_bElementAccessSafe); - return push_back_impl(nIndex); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::push_back(const T& rObj) -{ - assert(m_bElementAccessSafe); - size_t nUnused = ~0; - T* pObj = push_back_impl(nUnused); - *pObj = rObj; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::push_back(const T& rObj, size_t& nIndex) -{ - assert(m_bElementAccessSafe); - T* pObj = push_back_impl(nIndex); - *pObj = rObj; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::clear() -{ - assert(m_bElementAccessSafe); - // free continous part - CryModuleMemalignFree(m_arrData); - m_arrData = NULL; - - // free non-continous pages if we have some - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - CMemoryPage* pOldPage = pCurrentMemoryPage; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - CryModuleFree(pOldPage); - } - m_pMemoryPages = NULL; - - m_nSize = 0; - m_nCapacity = 0; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::resize(size_t n) -{ - assert(m_bElementAccessSafe); - CoalesceMemory(); - size_t nOldSize = m_nSize; - m_nSize = n; - - if ((LONG)n <= m_nCapacity) - { - return; - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, nOldSize * sizeof(T)); - memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - m_nCapacity = n; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeRendererContainer::reserve(size_t n) -{ - assert(m_bElementAccessSafe); - CoalesceMemory(); - if ((LONG)n <= m_nCapacity) - { - return; - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, m_nSize * sizeof(T)); - memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - m_nCapacity = n; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline bool CThreadSafeRendererContainer::try_append_to_continous_memory(size_t& nIndex, T*& pObj) -{ - assert(m_bElementAccessSafe); - LONG nSize = ~0; - LONG nCapacity = ~0; - do - { - // read volatile the new size - nSize = *const_cast(&m_nSize); - nCapacity = *const_cast(&m_nCapacity); - - if (nSize >= nCapacity) - { - return false; - } - } while (CryInterlockedCompareExchange(alias_cast(&m_nSize), nSize + 1, nSize) != nSize); - nIndex = nSize; - pObj = &m_arrData[nSize]; - - return true; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeRendererContainer::push_back_impl(size_t& nIndex) -{ - assert(m_bElementAccessSafe); - T* pObj = NULL; - - // non atomic check to see if there is space in the continous array - if (try_append_to_continous_memory(nIndex, pObj)) - { - return pObj; - } - - // exhausted continous memory, falling back to page allocation - for (;; ) - { - assert(m_bElementAccessSafe); - size_t nPageBaseIndex = 0; - - // traverse the page list till the first page with free memory - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - size_t nAvaibleElements = pCurrentMemoryPage->Capacity() - pCurrentMemoryPage->Size(); - if (nAvaibleElements) - { - break; - } - - // no memory in this page, go to the next one - nPageBaseIndex += pCurrentMemoryPage->Capacity(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - - // try to allocate a element on this page - if (pCurrentMemoryPage && pCurrentMemoryPage->TryAllocateElement(nIndex, pObj)) - { - // update global elements counter - CryInterlockedIncrement(alias_cast(&m_nSize)); - - // adjust in-page-index to global index - nIndex += nPageBaseIndex + m_nCapacity; - return pObj; - } - else - { - // all pages are empty, allocate and link a new one - CMemoryPage* pNewPage = CMemoryPage::AllocateNewPage(); - - void* volatile* ppLastMemoryPageAddress = NULL; - do - { - // find place to link in page - CMemoryPage* pLastMemoryPage = m_pMemoryPages; - ppLastMemoryPageAddress = alias_cast(&m_pMemoryPages); - - while (pLastMemoryPage) - { - ppLastMemoryPageAddress = alias_cast(&(pLastMemoryPage->m_pNext)); - pLastMemoryPage = pLastMemoryPage->m_pNext; - } - } while (CryInterlockedCompareExchangePointer(ppLastMemoryPageAddress, pNewPage, NULL) != NULL); - } - } -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeRendererContainer::GetMemoryPageElement(size_t n) -{ - assert(m_bElementAccessSafe); - size_t nFirstListIndex = m_nCapacity; - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - - size_t nPageCapacity = pCurrentMemoryPage->Capacity(); - while (n >= (nFirstListIndex + nPageCapacity)) - { - // this is threadsafe because we assume that if we want to get element 'n' - // the clientcode did already fill the container up to element 'n' - // thus up to 'n', m_pNonContinousList will have valid pages - // NOTE: This is not safe when trying to read a element behind the valid - // range (same as std::vector) - nFirstListIndex += nPageCapacity; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - - // update page capacity, since it can differe due alignment - nPageCapacity = pCurrentMemoryPage->Capacity(); - } - - return pCurrentMemoryPage->GetElement(n - nFirstListIndex); -} - -/////////////////////////////////////////////////////////////////////////////// -// When not not in the 'Fill' phase, it is safe to colace all page entries into one continous memory block -template -inline void CThreadSafeRendererContainer::CoalesceMemory() -{ - assert(m_bElementAccessSafe); - if (m_pMemoryPages == NULL) - { - return; // nothing to do - } - // mark state as not accessable - m_bElementAccessSafe = false; - -#if !defined(NDEBUG) - size_t nOldSize = m_nSize; -#endif - - // compute required memory - size_t nRequieredElements = 0; - { - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - nRequieredElements += pCurrentMemoryPage->Size(); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } - } - - T* arrOldData = m_arrData; - m_arrData = reinterpret_cast(CryModuleMemalign((m_nCapacity + nRequieredElements) * sizeof(T), alignof(T))); - memcpy(m_arrData, arrOldData, m_nCapacity * sizeof(T)); - CryModuleMemalignFree(arrOldData); - - // copy page data into continous memory block - { - size_t nBeginToFillIndex = m_nCapacity; - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - // copy data - memcpy(&m_arrData[nBeginToFillIndex], pCurrentMemoryPage->GetData(), pCurrentMemoryPage->GetDataSize()); - nBeginToFillIndex += pCurrentMemoryPage->Size(); - - // free page - CMemoryPage* pOldPage = pCurrentMemoryPage; - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - CryModuleFree(pOldPage); - } - - m_pMemoryPages = NULL; - } - - assert(nOldSize == m_nSize); - m_nCapacity += nRequieredElements; - - // the container can be used again - m_bElementAccessSafe = true; -} - -/////////////////////////////////////////////////////////////////////////////// -// Collect information about used memory -template -void CThreadSafeRendererContainer::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_arrData, m_nCapacity * sizeof(T)); - - CMemoryPage* pCurrentMemoryPage = m_pMemoryPages; - while (pCurrentMemoryPage) - { - pSizer->AddObject(pCurrentMemoryPage, CMemoryPage::nMemoryPageSize); - pCurrentMemoryPage = pCurrentMemoryPage->m_pNext; - } -} - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeRendererContainer::CMemoryPage::CMemoryPage() - : m_pNext(NULL) - , m_nSize(0) -{ - // compute offset for actual data - size_t nObjectAlignment = alignof(T); - UINT_PTR nMemoryBlockBegin = alias_cast(this); - UINT_PTR nMemoryBlockEnd = alias_cast(this) + nMemoryPageSize; - - nMemoryBlockBegin += sizeof(CMemoryPage); - nMemoryBlockBegin = (nMemoryBlockBegin + nObjectAlignment - 1) & ~(nObjectAlignment - 1); - - // compute number of avaible elements - assert(nMemoryBlockEnd > nMemoryBlockBegin); - m_nCapacity = (LONG)((nMemoryBlockEnd - nMemoryBlockBegin) / sizeof(T)); - - // store pointer to store data to - m_arrData = alias_cast(nMemoryBlockBegin); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline typename CThreadSafeRendererContainer::CMemoryPage * CThreadSafeRendererContainer::CMemoryPage::AllocateNewPage() -{ - void* pNewPageMemoryChunk = CryModuleMalloc(nMemoryPageSize); - assert(pNewPageMemoryChunk != NULL); - - memset(pNewPageMemoryChunk, 0, nMemoryPageSize); - CMemoryPage* pNewPage = new(pNewPageMemoryChunk) CMemoryPage(); - return pNewPage; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline bool CThreadSafeRendererContainer::CMemoryPage::TryAllocateElement(size_t & nIndex, T * &pObj) -{ - LONG nSize = ~0; - LONG nCapacity = ~0; - do - { - // read volatile the new size - nSize = *const_cast(&m_nSize); - nCapacity = *const_cast(&m_nCapacity); - // stop trying if this page is full - if (nSize >= nCapacity) - { - return false; - } - } while (CryInterlockedCompareExchange(alias_cast(&m_nSize), nSize + 1, nSize) != nSize); - - //Note: this is the index in the page and it is adjusted in the calling context - nIndex = nSize; - pObj = &m_arrData[nSize]; - - return true; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T&CThreadSafeRendererContainer::CMemoryPage::GetElement(size_t n) -{ - assert((LONG)n < m_nSize); - assert(m_nSize <= m_nCapacity); - return m_arrData[n]; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline T * CThreadSafeRendererContainer::CMemoryPage::GetData() const -{ - return m_arrData; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::Size() const -{ - return m_nSize; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::GetDataSize() const -{ - return m_nSize * sizeof(T); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeRendererContainer::CMemoryPage::Capacity() const -{ - return m_nCapacity; -} - -#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H diff --git a/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h b/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h deleted file mode 100644 index 418b363ca1..0000000000 --- a/Code/CryEngine/CryCommon/CryThreadSafeWorkerContainer.h +++ /dev/null @@ -1,602 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Specialized Container for Renderer data with the following properties: -// Created during the 3DEngine Update, consumed in the renderer in the following frame -// This Container is very restricted and likely not optimal for other situations - - -#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H -#pragma once - - -#include "platform.h" -#include - -#include -#include -#include - - -// -// !!! BE CAREFULL WHEN USING THIS CONTAINER !!! -// -// --- Properties: --- -// - Stores data local to worker thread to avoid thread-safety semantics -// - Allows for a single non-worker thread to be tracked which is stored in m_workers[0] -// Hence: As m_workers[0] is shared between all non-worker threads, ensure that only one additional non-worker thread may access this container e.g. MainThread -// - Coalesce memory to obtain a continues memory block -// - Coalesce memory to for faster element access to a continues memory block -// -// --- Restrictions:--- -// - The workers own the memory structure -// - The coalesced memory stores a copy of the workers used memory -// Hence: Be careful when altering data within the coalesced memory. -// If the templated element is a pointer type than altering the memory pointed to, is not be an issue -// If the templated element is of type class or struct than ensure that data changes are done on the worker local data and not on the coalesced memory. Use worker encoded indices to do so. -// - -template -class CThreadSafeWorkerContainer -{ -public: - struct SDefaultNoOpFunctor - { - ILINE void operator()(T* pData) const{} - }; - - struct SDefaultDestructorFunctor - { - ILINE void operator()(T* pData) const - { - pData->~T(); - } - }; - -public: - CThreadSafeWorkerContainer(); - ~CThreadSafeWorkerContainer(); - - void Init(); - void SetNonWorkerThreadID(threadID nThreadId) { m_foreignThreadId = nThreadId; } - - // Safe access of elements for calling thread via operator[] - uint32 ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const; - - // Returns the number of threads that can use this container, including the one non-worker-thread. - uint32 GetNumWorkers() const; - - // Returns the Worker ID for the current thread. Ranges from 0 to GetNumWorkers()-1. - // Note, WorkerId is not the same thing as JobManager's WorkerThreadId. - uint32 GetWorkerId_threadlocal() const; - - //NOTE: be aware that these values can potentially change if some objects are added in parallel - size_t size() const; - size_t empty() const; - size_t capacity() const; - - size_t size_threadlocal() const; - size_t empty_threadlocal() const; - size_t capacity_threadlocal() const; - - //NOTE: be aware that this operator is more expensive if the memory was not coalesced before - T& operator[](size_t n); - const T& operator[](size_t n) const; - - T* push_back_new(); - T* push_back_new(size_t& nIndex); - - void push_back(const T& rObj); - void push_back(const T& rObj, size_t& nIndex); - - // NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe - void clear(); - template< class OnElementDeleteFunctor> - void clear(const OnElementDeleteFunctor& rFunctor = CThreadSafeWorkerContainer::SDefaultNoOpFunctor()); - void erase(const T& rObj); - void resize(size_t n); - void reserve(size_t n); - - // *not* thread-safe functions - void PrefillContainer(T* pElement, size_t numElements); - void CoalesceMemory(); - - void GetMemoryUsage(ICrySizer* pSizer) const; - -private: - - void clear(AZStd::true_type); - void clear(AZStd::false_type); - - class SWorker - { - public: - AZ_CLASS_ALLOCATOR(SWorker, AZ::LegacyAllocator, 0); - - SWorker() - : m_dataSize(0) {} - - uint32 m_dataSize; - AZStd::vector m_data; - } _ALIGN(128); - - T* push_back_impl(size_t& nIndex); - void ReserverCoalescedMemory(size_t n); - - threadID m_foreignThreadId; // OS thread ID of the non-job-manager-worker-thread allowed to use this container, too. - - AZStd::vector m_workers; // Holds data for each thread that can use this container. A non-worker-thread (Main) has data stored at 0. Actual worker threads range from 1 to m_nNumWorkers-1 - uint32 m_nNumWorkers = 0; // The number of threads that can use this container, including one non-worker-thread. - - uint32 m_coalescedArrCapacity; - T* m_coalescedArr; - bool m_isCoalesced; -}; - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeWorkerContainer::CThreadSafeWorkerContainer() - : m_nNumWorkers(0) - , m_coalescedArrCapacity(0) - , m_coalescedArr(0) - , m_isCoalesced(false) -{ -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline CThreadSafeWorkerContainer::~CThreadSafeWorkerContainer() -{ - clear(); - m_workers.clear(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::Init() -{ - m_nNumWorkers = AZ::JobContext::GetGlobalContext()->GetJobManager().GetNumWorkerThreads() + 1; - m_workers.resize(m_nNumWorkers); - - m_foreignThreadId = THREADID_NULL; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::size() const -{ - uint32 totalSize = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - totalSize += m_workers[i].m_dataSize; - } - return totalSize; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::empty() const -{ - return size() == 0; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::capacity() const -{ - uint32 totalCapacity = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - totalCapacity += m_workers[i].m_data.capacity(); - } - return totalCapacity; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::size_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_dataSize; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::empty_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_data.empty(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline size_t CThreadSafeWorkerContainer::capacity_threadlocal() const -{ - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - return m_workers[nWorkerThreadId].m_data.capacity(); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T& CThreadSafeWorkerContainer::operator[](size_t n) -{ - const uint32 nHasWorkerEncodedIndex = (n & 0x80000000) >> 31; - - IF ((m_isCoalesced && !nHasWorkerEncodedIndex), 1) - { - AZ_Assert(m_coalescedArr, "null array"); - AZ_Assert(n < m_coalescedArrCapacity, "Index out of bounds"); - return m_coalescedArr[n]; - } - else - { - const uint32 nWorkerThreadId = (n & 0x7F00007F) >> 24; // Mask bit 24-30 (0 is starting bit) - const uint32 nOffset = (n & ~0xFF000000); // Mask out top 8 bits - - // Encoded offset into worker local array - if (nHasWorkerEncodedIndex) - { - return m_workers[nWorkerThreadId].m_data[nOffset]; - } - else // None-coalesced and none worker encoded offset - { - uint32 nTotalOffset = nOffset; - for (int i = 0; i < m_nNumWorkers; ++i) - { - SWorker& worker = m_workers[i]; - - if (nTotalOffset < worker.m_dataSize) - { - return worker.m_data[nTotalOffset]; - } - else - { - nTotalOffset -= worker.m_dataSize; - } - } - - // Out of bound access detected! - CRY_ASSERT_MESSAGE(false, "CThreadSafeWorkerContainer::operator[] - Out of bounds access"); - __debugbreak(); - AZ_Assert(m_coalescedArr, "null array"); - AZ_Assert(m_coalescedArrCapacity > 0, "Index out of bounds"); - return m_coalescedArr[0]; - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline const T& CThreadSafeWorkerContainer::operator[](size_t n) const -{ - return const_cast(const_cast*>(this)->operator[](n)); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_new() -{ - size_t unused = ~0; - return push_back_impl(unused); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_new(size_t& nIndex) -{ - return push_back_impl(nIndex); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::push_back(const T& rObj) -{ - size_t nUnused = ~0; - T* pObj = push_back_impl(nUnused); - *pObj = rObj; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::push_back(const T& rObj, size_t& nIndex) -{ - T* pObj = push_back_impl(nIndex); - *pObj = rObj; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::clear() -{ - clear(typename std::is_destructible::type()); -} - -template -void CThreadSafeWorkerContainer::clear(AZStd::true_type) -{ - clear(SDefaultDestructorFunctor()); -} - -template -void CThreadSafeWorkerContainer::clear(AZStd::false_type) -{ - clear(SDefaultNoOpFunctor()); -} -/////////////////////////////////////////////////////////////////////////////// -template -template -inline void CThreadSafeWorkerContainer::clear(const OnElementDeleteFunctor& rFunctor) -{ - // Reset worker data - for (int i = 0; i < m_nNumWorkers; ++i) - { - // Delete elements - uint32 nSize = m_workers[i].m_data.size(); - for (int j = 0; j < nSize; ++j) - { - // Call on element delete functor - // Note: Default functor will do nothing with the element - rFunctor(&m_workers[i].m_data[j]); - } - - m_workers[i].m_data.clear(); - m_workers[i].m_dataSize = 0; - } - - // Reset container data - if (m_coalescedArr) - { - CryModuleMemalignFree(m_coalescedArr); - } - - m_coalescedArr = 0; - m_coalescedArrCapacity = 0; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::erase(const T& rObj) -{ - for (int i = 0; i < m_nNumWorkers; ++i) - { - typename std::vector::iterator iter = m_workers[i].m_data.begin(); - typename std::vector::iterator iterEnd = m_workers[i].m_data.end(); - - for (; iter != iterEnd; ++iter) - { - if (rObj == *iter) - { - m_workers[i].m_data.erase(iter); - --m_workers[i].m_dataSize; - m_isCoalesced = false; - return; - } - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::resize(size_t n) -{ - CoalesceMemory(); - - uint32 nSizePerWorker = n / m_nNumWorkers; - uint32 nExcessSize = n % m_nNumWorkers; - - // Resize workers evenly - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nWorkerSize = nSizePerWorker + nExcessSize; - - if (nWorkerSize > m_workers[i].m_data.size()) - { - m_workers[i].m_data.resize(nWorkerSize); - } - - m_workers[i].m_dataSize = nWorkerSize; - nExcessSize = 0; // First worker creates excess items - } - - ReserverCoalescedMemory(n); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::reserve(size_t n) -{ - CoalesceMemory(); - - uint32 nSizePerWorker = n / m_nNumWorkers; - uint32 nExcessSize = n % m_nNumWorkers; - - // Resize workers evenly - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nWorkerSize = nSizePerWorker + nExcessSize; - - if (nWorkerSize > m_workers[i].m_data.size()) - { - m_workers[i].m_data.resize(nWorkerSize); - } - - nExcessSize = 0; // First worker creates excess items - } - - ReserverCoalescedMemory(n); -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::PrefillContainer(T* pElement, size_t numElements) -{ - reserve(numElements); - - uint32 nOffset = 0; - uint32 nNumItemPerWorker = numElements / m_nNumWorkers; - uint32 nNumExcessItems = numElements % m_nNumWorkers; - - // Store items evenly in workers - for (int i = 0; i < m_nNumWorkers; ++i) - { - uint32 nNumItems = nNumItemPerWorker + nNumExcessItems; - for (int j = 0; j < nNumItems; ++j) - { - m_workers[i].m_data[j] = pElement[nOffset + j]; - } - - m_workers[i].m_dataSize = nNumItems; - nOffset += nNumItems; - nNumExcessItems = 0; // First worker stores excess items - } - - m_isCoalesced = false; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::CoalesceMemory() -{ - if (m_isCoalesced) - { - return; - } - - // Ensure enough memory exists - uint32 minSizeNeeded = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - minSizeNeeded += m_workers[i].m_dataSize; - } - - IF (minSizeNeeded >= m_coalescedArrCapacity, 0) - { - ReserverCoalescedMemory(minSizeNeeded + (minSizeNeeded / 4)); - } - - // Copy data to coalesced array - uint32 nOffest = 0; - for (int i = 0; i < m_nNumWorkers; ++i) - { - SWorker& rWorker = m_workers[i]; - if (rWorker.m_dataSize == 0) - { - continue; - } - AZ_Assert((nOffest + rWorker.m_dataSize) <= m_coalescedArrCapacity, "Index out of bounds"); - memcpy(m_coalescedArr + nOffest, &rWorker.m_data[0], sizeof(T) * rWorker.m_dataSize); - nOffest += rWorker.m_dataSize; - } - - m_isCoalesced = true; -} - -/////////////////////////////////////////////////////////////////////////////// -template -uint32 CThreadSafeWorkerContainer::ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const -{ - const uint32 workerId = GetWorkerId_threadlocal(); - assert(nIndex < m_workers[workerId].m_dataSize); - return (uint32)((1 << 31) | (workerId << 24) | nIndex); -} - -////////////////////////////////////////////////////////////////////////// -template -uint32 CThreadSafeWorkerContainer::GetNumWorkers() const -{ - return m_nNumWorkers; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::GetMemoryUsage(ICrySizer* pSizer) const -{ - pSizer->AddObject(m_coalescedArr, m_coalescedArrCapacity * sizeof(T)); - - for (int i = 0; i < m_nNumWorkers; ++i) - { - pSizer->AddContainer(m_workers[i].m_data); - } -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline void CThreadSafeWorkerContainer::ReserverCoalescedMemory(size_t n) -{ - if (n <= m_coalescedArrCapacity) - { - return; - } - - T* arrOldData = m_coalescedArr; - m_coalescedArr = reinterpret_cast(CryModuleMemalign(n * sizeof(T), alignof(T))); - memcpy(m_coalescedArr, arrOldData, m_coalescedArrCapacity * sizeof(T)); - if (arrOldData) - { - CryModuleMemalignFree(arrOldData); - } - m_coalescedArrCapacity = n; -} - -/////////////////////////////////////////////////////////////////////////////// -template -inline T* CThreadSafeWorkerContainer::push_back_impl(size_t& nIndex) -{ - // Avoid writing to thread share resource and take hit of 'if statement to avoid false-sharing between threads - IF (m_isCoalesced, 0) - { - m_isCoalesced = false; - } - - // Get worker id - const uint32 nWorkerThreadId = GetWorkerId_threadlocal(); - - SWorker& activeWorker = m_workers[nWorkerThreadId]; - - // Ensure enough space - if (activeWorker.m_dataSize >= activeWorker.m_data.size()) - { - activeWorker.m_data.resize(activeWorker.m_data.size() + (activeWorker.m_data.size() / 2) + 1); - } - - // Encode worker local offset into index and return - T* retItem = &activeWorker.m_data[activeWorker.m_dataSize]; - nIndex = (size_t)((1 << 31) | (nWorkerThreadId << 24) | activeWorker.m_dataSize); - ++activeWorker.m_dataSize; - return retItem; -} - -template -uint32 CThreadSafeWorkerContainer::GetWorkerId_threadlocal() const -{ - const uint32 workerThreadId = AZ::JobContext::GetGlobalContext()->GetJobManager().GetWorkerThreadId(); - - if (workerThreadId == AZ::JobManager::InvalidWorkerThreadId) - { - // Only one non-worker thread is allowed, so check to see if this is that thread. - - const threadID currentThreadId = CryGetCurrentThreadId(); - if (m_foreignThreadId != currentThreadId) - { - CryFatalError("Trying to access CThreadSafeWorkerContainer from an unspecified non-worker thread. The only non-worker threadId with access rights: %" PRI_THREADID ". Current threadId: %" PRI_THREADID, m_foreignThreadId, currentThreadId); - } - } - - // Non-worker has id of ~0 ... add +1 to shift to 0. Worker0 will use slot 1 etc. - static_assert(AZ::JobManager::InvalidWorkerThreadId == ~0u, "Assumptions about InvalidWorkerId no longer hold true"); - return workerThreadId + 1; -} - - -#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H diff --git a/Code/CryEngine/CryCommon/CryThread_windows.h b/Code/CryEngine/CryCommon/CryThread_windows.h index 1d9ea6dc31..b70260c7ac 100644 --- a/Code/CryEngine/CryCommon/CryThread_windows.h +++ b/Code/CryEngine/CryCommon/CryThread_windows.h @@ -249,10 +249,6 @@ public: void SetName(const char* Name) { m_name = Name; - if (m_threadId) - { - CryThreadSetName(m_threadId, m_name); - } } const char* GetName() { return m_name; } @@ -289,11 +285,6 @@ private: self->m_bIsStarted = true; self->m_bIsRunning = true; - if (!self->m_name.empty()) - { - CryThreadSetName(-1, self->m_name); - } - self->m_Runnable->Run(); self->m_bIsRunning = false; self->m_bCreatedThread = false; @@ -311,11 +302,6 @@ private: self->m_bIsStarted = true; self->m_bIsRunning = true; - if (!self->m_name.empty()) - { - CryThreadSetName(-1, self->m_name); - } - self->Run(); self->m_bIsRunning = false; self->m_bCreatedThread = false; diff --git a/Code/CryEngine/CryCommon/CryUtils.h b/Code/CryEngine/CryCommon/CryUtils.h deleted file mode 100644 index 314ee7bc5f..0000000000 --- a/Code/CryEngine/CryCommon/CryUtils.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include // size_t - -namespace Detail -{ - template - char (&ArrayCountHelper(T(&)[size]))[size]; -} - -#define CRY_ARRAY_COUNT(arr) sizeof(::Detail::ArrayCountHelper(arr)) diff --git a/Code/CryEngine/CryCommon/CryZlib.h b/Code/CryEngine/CryCommon/CryZlib.h deleted file mode 100644 index 8abb0d010a..0000000000 --- a/Code/CryEngine/CryCommon/CryZlib.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -// Include this file instead of including zlib.h directly -// because zconf.h (included by zlib.h) defines WINDOWS and WIN32 - those -// definitions conflict with CryEngine's definitions. - -#if defined(CRY_TMP_DEFINED_WINDOWS) || defined(CRY_TMP_DEFINED_WIN32) -# error CRY_TMP_DEFINED_WINDOWS and/or CRY_TMP_DEFINED_WIN32 already defined -#endif - -#if defined(WINDOWS) -# define CRY_TMP_DEFINED_WINDOWS 1 -#endif -#if defined(WIN32) -# define CRY_TMP_DEFINED_WIN32 1 -#endif - -#include - -#if !defined(CRY_TMP_DEFINED_WINDOWS) -# undef WINDOWS -#endif -#undef CRY_TMP_DEFINED_WINDOWS -#if !defined(CRY_TMP_DEFINED_WIN32) -# undef WIN32 -#endif -#undef CRY_TMP_DEFINED_WIN32 diff --git a/Code/CryEngine/CryCommon/Cry_Camera.h b/Code/CryEngine/CryCommon/Cry_Camera.h index 56a764d897..d0eb318e94 100644 --- a/Code/CryEngine/CryCommon/Cry_Camera.h +++ b/Code/CryEngine/CryCommon/Cry_Camera.h @@ -620,24 +620,24 @@ public: bool IsPointVisible(const Vec3& p) const; //sphere-frustum test - bool IsSphereVisible_F(const Sphere& s) const; - uint8 IsSphereVisible_FH(const Sphere& s) const; //this is going to be the exact version of sphere-culling + bool IsSphereVisible_F(const ::Sphere& s) const; + uint8 IsSphereVisible_FH(const ::Sphere& s) const; //this is going to be the exact version of sphere-culling // AABB-frustum test // Fast - bool IsAABBVisible_F(const AABB& aabb) const; - uint8 IsAABBVisible_FH(const AABB& aabb, bool* pAllInside) const; - uint8 IsAABBVisible_FH(const AABB& aabb) const; + bool IsAABBVisible_F(const ::AABB& aabb) const; + uint8 IsAABBVisible_FH(const ::AABB& aabb, bool* pAllInside) const; + uint8 IsAABBVisible_FH(const ::AABB& aabb) const; // Exact - bool IsAABBVisible_E(const AABB& aabb) const; - uint8 IsAABBVisible_EH(const AABB& aabb, bool* pAllInside) const; - uint8 IsAABBVisible_EH(const AABB& aabb) const; + bool IsAABBVisible_E(const ::AABB& aabb) const; + uint8 IsAABBVisible_EH(const ::AABB& aabb, bool* pAllInside) const; + uint8 IsAABBVisible_EH(const ::AABB& aabb) const; // Multi-camera - bool IsAABBVisible_EHM(const AABB& aabb, bool* pAllInside) const; - bool IsAABBVisible_EM(const AABB& aabb) const; - bool IsAABBVisible_FM(const AABB& aabb) const; + bool IsAABBVisible_EHM(const ::AABB& aabb, bool* pAllInside) const; + bool IsAABBVisible_EM(const ::AABB& aabb) const; + bool IsAABBVisible_FM(const ::AABB& aabb) const; //OBB-frustum test bool IsOBBVisible_F(const Vec3& wpos, const OBB& obb) const; @@ -1386,7 +1386,7 @@ inline bool CCamera::IsPointVisible(const Vec3& p) const // return values // CULL_EXCLUSION = sphere outside of frustum (very fast rejection-test) // CULL_INTERSECT = sphere and frustum intersects or sphere in completely inside frustum -inline bool CCamera::IsSphereVisible_F(const Sphere& s) const +inline bool CCamera::IsSphereVisible_F(const ::Sphere& s) const { if ((m_fp[0] | s.center) > s.radius) { @@ -1427,7 +1427,7 @@ inline bool CCamera::IsSphereVisible_F(const Sphere& s) const // CULL_EXCLUSION = sphere outside of frustum (very fast rejection-test) // CULL_INTERSECT = sphere intersects the borders of the frustum, further checks necessary // CULL_INCLUSION = sphere is complete inside the frustum, no further checks necessary -inline uint8 CCamera::IsSphereVisible_FH(const Sphere& s) const +inline uint8 CCamera::IsSphereVisible_FH(const ::Sphere& s) const { f32 nc, rc, lc, tc, bc, cc; if ((nc = m_fp[0] | s.center) > s.radius) diff --git a/Code/CryEngine/CryCommon/Cry_Geo.h b/Code/CryEngine/CryCommon/Cry_Geo.h index ebe27a469a..359896157c 100644 --- a/Code/CryEngine/CryCommon/Cry_Geo.h +++ b/Code/CryEngine/CryCommon/Cry_Geo.h @@ -794,7 +794,7 @@ struct HWVSphere radius = r; } - ILINE HWVSphere(const Sphere& sp) + ILINE HWVSphere(const ::Sphere& sp) { center = HWVLoadVecUnaligned(&sp.center); radius = SIMDFLoadFloat(sp.radius); diff --git a/Code/CryEngine/CryCommon/Cry_GeoDistance.h b/Code/CryEngine/CryCommon/Cry_GeoDistance.h index 47794c7671..2329038dc4 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoDistance.h +++ b/Code/CryEngine/CryCommon/Cry_GeoDistance.h @@ -1179,7 +1179,7 @@ namespace Distance { // float result = Distance::Point_TriangleSq( pos, triangle ); //---------------------------------------------------------------------------------- template - ILINE F Sphere_TriangleSq(const Sphere& s, const Triangle_tpl& t) + ILINE F Sphere_TriangleSq(const ::Sphere& s, const Triangle_tpl& t) { F sqdistance = Distance::Point_TriangleSq(s.center, t) - (s.radius * s.radius); if (sqdistance < 0) @@ -1190,7 +1190,7 @@ namespace Distance { } template - ILINE F Sphere_TriangleSq(const Sphere& s, const Triangle_tpl& t, Vec3_tpl& output) + ILINE F Sphere_TriangleSq(const ::Sphere& s, const Triangle_tpl& t, Vec3_tpl& output) { F sqdistance = Distance::Point_TriangleSq(s.center, t, output) - (s.radius * s.radius); if (sqdistance < 0) diff --git a/Code/CryEngine/CryCommon/Cry_GeoIntersect.h b/Code/CryEngine/CryCommon/Cry_GeoIntersect.h index 89f6d8ebaf..f0be567ce2 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoIntersect.h +++ b/Code/CryEngine/CryCommon/Cry_GeoIntersect.h @@ -792,7 +792,7 @@ namespace Intersect { //--- 0x03 = two intersection, lineseg has ENTRY and EXIT point -- //---------------------------------------------------------------------------------- - inline unsigned char Line_Sphere(const Line& line, const Sphere& s, Vec3& i0, Vec3& i1) + inline unsigned char Line_Sphere(const Line& line, const ::Sphere& s, Vec3& i0, Vec3& i1) { Vec3 end = line.pointonline + line.direction; @@ -830,7 +830,7 @@ namespace Intersect { //--- 0x03 = two intersection, lineseg has ENTRY and EXIT point -- //---------------------------------------------------------------------------------- - inline unsigned char Ray_Sphere(const Ray& ray, const Sphere& s, Vec3& i0, Vec3& i1) + inline unsigned char Ray_Sphere(const Ray& ray, const ::Sphere& s, Vec3& i0, Vec3& i1) { Vec3 end = ray.origin + ray.direction; float a = ray.direction | ray.direction; @@ -863,7 +863,7 @@ namespace Intersect { return intersection; } - inline bool Ray_SphereFirst(const Ray& ray, const Sphere& s, Vec3& intPoint) + inline bool Ray_SphereFirst(const Ray& ray, const ::Sphere& s, Vec3& intPoint) { Vec3 p2; unsigned char res = Ray_Sphere(ray, s, intPoint, p2); @@ -886,7 +886,7 @@ namespace Intersect { //--- 0x02 = one intersection, lineseg has just an EXIT point but no ENTRY point (ls.start is inside the sphere) -- //--- 0x03 = two intersection, lineseg has ENTRY and EXIT point -- //---------------------------------------------------------------------------------- - inline unsigned char Lineseg_Sphere(const Lineseg& ls, const Sphere& s, Vec3& i0, Vec3& i1) + inline unsigned char Lineseg_Sphere(const Lineseg& ls, const ::Sphere& s, Vec3& i0, Vec3& i1) { Vec3 dir = (ls.end - ls.start); @@ -931,7 +931,7 @@ namespace Intersect { } - inline bool Lineseg_SphereFirst(const Lineseg& lineseg, const Sphere& s, Vec3& intPoint) + inline bool Lineseg_SphereFirst(const Lineseg& lineseg, const ::Sphere& s, Vec3& intPoint) { Vec3 p2; uint8 res = Lineseg_Sphere(lineseg, s, intPoint, p2); diff --git a/Code/CryEngine/CryCommon/Cry_GeoOverlap.h b/Code/CryEngine/CryCommon/Cry_GeoOverlap.h index ab560b7518..14af81258a 100644 --- a/Code/CryEngine/CryCommon/Cry_GeoOverlap.h +++ b/Code/CryEngine/CryCommon/Cry_GeoOverlap.h @@ -103,7 +103,7 @@ namespace Overlap { // Checks if a point is inside a sphere. // Example: // bool result=Overlap::Point_Sphere( point, sphere ); - ILINE bool Point_Sphere(const Vec3& p, const Sphere& s) + ILINE bool Point_Sphere(const Vec3& p, const ::Sphere& s) { Vec3 distc = p - s.center; f32 sqrad = s.radius * s.radius; @@ -407,7 +407,7 @@ namespace Overlap { //! check if a Lineseg and a Sphere overlap - inline bool Lineseg_Sphere(const Lineseg& ls, const Sphere& s) + inline bool Lineseg_Sphere(const Lineseg& ls, const ::Sphere& s) { float radius2 = s.radius * s.radius; @@ -729,7 +729,7 @@ namespace Overlap { * 0 = no overlap * 1 = overlap *----------------------------------------------------------------------------------*/ - ILINE bool Sphere_AABB(const Sphere& s, const AABB& aabb) + ILINE bool Sphere_AABB(const ::Sphere& s, const AABB& aabb) { Vec3 center(s.center); @@ -746,7 +746,7 @@ namespace Overlap { } // As Sphere_AABB but ignores z parts - ILINE bool Sphere_AABB2D(const Sphere& s, const AABB& aabb) + ILINE bool Sphere_AABB2D(const ::Sphere& s, const AABB& aabb) { Vec3 center(s.center); @@ -776,7 +776,7 @@ namespace Overlap { * 0x01 = Sphere and AABB overlap * 0x02 = Sphere in inside AABB */ - ILINE char Sphere_AABB_Inside(const Sphere& s, const AABB& aabb) + ILINE char Sphere_AABB_Inside(const ::Sphere& s, const AABB& aabb) { if (Sphere_AABB(s, aabb)) { @@ -819,7 +819,7 @@ namespace Overlap { //--- 0 = no overlap --------------------------- //--- 1 = overlap ----------------- //---------------------------------------------------------------------------------- - inline bool Sphere_OBB(const Sphere& s, const OBB& obb) + inline bool Sphere_OBB(const ::Sphere& s, const OBB& obb) { //first we transform the sphere-center into the AABB-space of the OBB Vec3 SphereInOBBSpace = s.center * obb.m33; @@ -861,7 +861,7 @@ namespace Overlap { //--- 0 = no overlap --------------------------- //--- 1 = overlap ----------------- //---------------------------------------------------------------------------------- - inline bool Sphere_Sphere(const Sphere& s1, const Sphere& s2) + inline bool Sphere_Sphere(const ::Sphere& s1, const ::Sphere& s2) { Vec3 distc = s1.center - s2.center; f32 sqrad = (s1.radius + s2.radius) * (s1.radius + s2.radius); @@ -884,7 +884,7 @@ namespace Overlap { //--- 1 = overlap ----------------- //---------------------------------------------------------------------------------- template - ILINE bool Sphere_Triangle(const Sphere& s, const Triangle_tpl& t) + ILINE bool Sphere_Triangle(const ::Sphere& s, const Triangle_tpl& t) { //create a "bouding sphere" around triangle for fast rejection test Vec3_tpl middle = (t.v0 + t.v1 + t.v2) * (1 / 3.0f); @@ -899,7 +899,7 @@ namespace Overlap { SqRad0 = (F)fsel(SqRad0 - SqRad2, SqRad0, SqRad2); //first simple rejection-test... - if (Sphere_Sphere(s, Sphere(middle, sqrt_tpl(SqRad0))) == 0) + if (Sphere_Sphere(s, ::Sphere(middle, sqrt_tpl(SqRad0))) == 0) { return 0; //overlap not possible } diff --git a/Code/CryEngine/CryCommon/CustomMemoryHeap.h b/Code/CryEngine/CryCommon/CustomMemoryHeap.h deleted file mode 100644 index 2cb0c70713..0000000000 --- a/Code/CryEngine/CryCommon/CustomMemoryHeap.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __CustomMemoryHeap_h__ -#define __CustomMemoryHeap_h__ -#pragma once - -#include "IMemory.h" - -class CCustomMemoryHeap; - -////////////////////////////////////////////////////////////////////////// -class CCustomMemoryHeapBlock - : public ICustomMemoryBlock -{ -public: - CCustomMemoryHeapBlock(CCustomMemoryHeap* pHeap); - virtual ~CCustomMemoryHeapBlock(); - - ////////////////////////////////////////////////////////////////////////// - // IMemoryBlock - ////////////////////////////////////////////////////////////////////////// - virtual void* GetData(); - virtual int GetSize() { return m_nSize; } - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ICustomMemoryBlock - ////////////////////////////////////////////////////////////////////////// - virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize); - ////////////////////////////////////////////////////////////////////////// - -private: - friend class CCustomMemoryHeap; - CCustomMemoryHeap* m_pHeap; - string m_sUsage; - void* m_pData; - uint32 m_nGPUHandle; - size_t m_nSize; -}; - -////////////////////////////////////////////////////////////////////////// -class CCustomMemoryHeap - : public ICustomMemoryHeap -{ -public: - - explicit CCustomMemoryHeap(IMemoryManager::EAllocPolicy const eAllocPolicy); - ~CCustomMemoryHeap(); - - ////////////////////////////////////////////////////////////////////////// - // ICustomMemoryHeap - ////////////////////////////////////////////////////////////////////////// - virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16); - virtual void GetMemoryUsage(ICrySizer* pSizer); - virtual size_t GetAllocated(); - ////////////////////////////////////////////////////////////////////////// - - void DeallocateBlock(CCustomMemoryHeapBlock* pBlock); - -private: - - friend class CCustomMemoryHeapBlock; - int m_nAllocatedSize; - IMemoryManager::EAllocPolicy m_eAllocPolicy; - IMemoryManager::HeapHandle m_nTraceHeapHandle; -}; - -#endif // __CustomMemoryHeap_h__ diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackend.cpp b/Code/CryEngine/CryCommon/EngineSettingsBackend.cpp deleted file mode 100644 index caf7e03f31..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackend.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * - */ - - -#include "EngineSettingsBackend.h" - -#ifdef CRY_ENABLE_RC_HELPER - -CEngineSettingsBackend::CEngineSettingsBackend(CEngineSettingsManager* parent, const wchar_t* moduleName) - : m_parent(parent) - , m_moduleName() -{ - if (moduleName != nullptr) - { - m_moduleName = moduleName; - } -} - -CEngineSettingsBackend::~CEngineSettingsBackend() -{ - -} - -#endif // CRY_ENABLE_RC_HELPER - diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackend.h b/Code/CryEngine/CryCommon/EngineSettingsBackend.h deleted file mode 100644 index fce16517ec..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackend.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - * - */ -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H -#pragma once - -#include "ProjectDefines.h" - -#ifdef CRY_ENABLE_RC_HELPER - -#include "SettingsManagerHelpers.h" - -#include - -class CEngineSettingsManager; - -class CEngineSettingsBackend -{ -public: - CEngineSettingsBackend(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL); - virtual ~CEngineSettingsBackend(); - - virtual std::wstring GetModuleFilePath() const = 0; - - virtual bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) = 0; - virtual bool GetModuleSpecificIntEntry(const char* key, int& value) = 0; - virtual bool GetModuleSpecificBoolEntry(const char* key, bool& value) = 0; - - virtual bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) = 0; - virtual bool SetModuleSpecificIntEntry(const char* key, const int& value) = 0; - virtual bool SetModuleSpecificBoolEntry(const char* key, const bool& value) = 0; - - virtual bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) = 0; - - virtual void LoadEngineSettingsFromRegistry() = 0; - virtual bool StoreEngineSettingsToRegistry() = 0; - -protected: - CEngineSettingsManager* parent() const - { - return m_parent; - } - - const std::wstring& moduleName() const - { - return m_moduleName; - } - -private: - std::wstring m_moduleName; - CEngineSettingsManager* m_parent; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.cpp b/Code/CryEngine/CryCommon/EngineSettingsBackendApple.cpp deleted file mode 100644 index 06f8d532d3..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.cpp +++ /dev/null @@ -1,486 +0,0 @@ -/* - * 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. - * - */ - -#include "EngineSettingsBackendApple.h" - -#ifdef CRY_ENABLE_RC_HELPER - -#include "AzCore/PlatformDef.h" - -#if AZ_TRAIT_OS_PLATFORM_APPLE - -#include "EngineSettingsManager.h" -#include "SettingsManagerHelpers.h" - -#include "platform.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -using namespace SettingsManagerHelpers; - -static const char gDefaultRegistryLocation[] = "/EngineSettings.reg"; - -#define REG_SOFTWARE L"Software\\" -#define REG_COMPANY_NAME L"Amazon\\" -#define REG_PRODUCT_NAME L"Lumberyard\\" -#define REG_SETTING L"Settings\\" -#define REG_BASE_SETTING_KEY REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME REG_SETTING - -////////////////////////////////////////////////////////////////////////// -class SimpleRegistry -{ - typedef std::map< std::wstring, std::wstring > WStringMap; - std::map< std::wstring, WStringMap * > m_modules; - -public: - SimpleRegistry(); - ~SimpleRegistry(); - - void setBoolValue(const std::wstring& module, const std::wstring& key, bool value); - void setIntValue(const std::wstring& module, const std::wstring& key, int value); - void setStrValue(const std::wstring& module, const std::wstring& key, const std::wstring& value); - - bool getBoolValue(const std::wstring& module, const std::wstring& key, bool& value); - bool getIntValue(const std::wstring& module, const std::wstring& key, int& value); - bool getStrValue(const std::wstring& module, const std::wstring& key, std::wstring& value); - - bool loadFromFile(const char* fileName); - bool saveToFile(const char* fileName); - -protected: - void clear(); - -private: - static const wchar_t gSimpleMagic[]; - static const size_t gMetaCharCount; -}; - -const wchar_t SimpleRegistry::gSimpleMagic[] = L"FR0"; -const size_t SimpleRegistry::gMetaCharCount = sizeof(size_t) / sizeof(wchar_t); - -SimpleRegistry::SimpleRegistry() -{ -} - -SimpleRegistry::~SimpleRegistry() -{ - clear(); -} - -void SimpleRegistry::setBoolValue(const std::wstring& module, const std::wstring& key, bool value) -{ - return setStrValue(module, key, value ? L"true" : L"false"); -} - -void SimpleRegistry::setIntValue(const std::wstring& module, const std::wstring& key, int value) -{ - return setStrValue(module, key, std::to_wstring(value)); -} - -void SimpleRegistry::setStrValue(const std::wstring& module, const std::wstring& key, const std::wstring& value) -{ - WStringMap *map = nullptr; - - auto i = m_modules.find(module); - - if (i == m_modules.end()) - { - map = new WStringMap; - m_modules.emplace(module, map); - } - else - { - map = i->second; - } - - assert(map); - - (*map)[key] = value; -} - -bool SimpleRegistry::getBoolValue(const std::wstring& module, const std::wstring& key, bool& value) -{ - std::wstring str; - - if (!getStrValue(module, key, str)) - { - return false; - } - - value = (0 == str.compare(L"true")); - - return true; -} - -bool SimpleRegistry::getIntValue(const std::wstring& module, const std::wstring& key, int& value) -{ - std::wstring str; - - if (!getStrValue(module, key, str)) - { - return false; - } - - value = std::stoi(str); - - return true; -} - -bool SimpleRegistry::getStrValue(const std::wstring& module, const std::wstring& key, std::wstring& value) -{ - WStringMap *map = nullptr; - - auto mi = m_modules.find(module); - if (mi == m_modules.end()) - { - return false; - } - - map = mi->second; - assert(map); - - auto ki = map->find(key); - if (ki == map->end()) - { - return false; - } - - value = ki->second; - - return true; -} - -bool SimpleRegistry::loadFromFile(const char* fileName) -{ - clear(); - - std::wifstream file(fileName, std::ios_base::in|std::ios_base::binary); - file.imbue(std::locale(file.getloc(), new std::codecvt_utf16)); - if (!file.is_open()) - { - AZ_Warning("EngineSettings", false, "Failed to open registry settings file: %s", fileName); - return false; - } - - std::wstring module; - std::wstring key; - std::wstring value; - - wchar_t buffer[512]; - size_t size; - wchar_t meta[gMetaCharCount]; - - /* magic number */ - if(!file.read(buffer, sizeof(gSimpleMagic) / sizeof(wchar_t)) || - wcsncmp(gSimpleMagic, buffer, sizeof(gSimpleMagic) / sizeof(wchar_t)) != 0) - { - file.close(); - AZ_Warning("EngineSettings", false, "Failed to load registry settings from file: %s", fileName); - return false; - } - - while (file.good()) - { - file.read(meta, gMetaCharCount); - if (!file.good()) - { - break; - } - - memcpy(&size, meta, sizeof(size)); - file.read(buffer, size); - buffer[file.gcount()] = L'\0'; - module = buffer; - - file.read(meta, gMetaCharCount); - memcpy(&size, meta, sizeof(size)); - file.read(buffer, size); - buffer[file.gcount()] = L'\0'; - key = buffer; - - file.read(meta, gMetaCharCount); - memcpy(&size, meta, sizeof(size)); - file.read(buffer, size); - buffer[file.gcount()] = L'\0'; - value = buffer; - - setStrValue(module, key, value); - } - - file.close(); - - return true; -} - -bool SimpleRegistry::saveToFile(const char* fileName) -{ - std::wofstream file(fileName, std::ios_base::out|std::ios_base::trunc|std::ios_base::binary); - file.imbue(std::locale(file.getloc(), new std::codecvt_utf16)); - if (!file.is_open()) - { - return false; - } - - std::wstring module; - - size_t size; - wchar_t meta[gMetaCharCount]; - - /* magic number */ - file.write(gSimpleMagic, sizeof(gSimpleMagic) / sizeof(wchar_t)); - - for (auto j : m_modules) - { - module = j.first; - - for (auto i : *j.second) - { - size = module.size(); - memcpy(meta, &size, sizeof(meta)); - file.write(meta, gMetaCharCount); - file.write(module.c_str(), size); - - size = i.first.size(); - memcpy(meta, &size, sizeof(meta)); - file.write(meta, gMetaCharCount); - file.write(i.first.c_str(), size); - - size = i.second.size(); - memcpy(meta, &size, sizeof(meta)); - file.write(meta, gMetaCharCount); - file.write(i.second.c_str(), size); - } - } - - file.close(); - - return true; -} - -void SimpleRegistry::clear() -{ - for (auto pair : m_modules) - { - delete pair.second; - } - - m_modules.clear(); -} -////////////////////////////////////////////////////////////////////////// - -CEngineSettingsBackendApple::CEngineSettingsBackendApple(CEngineSettingsManager* parent, const wchar_t* moduleName) - : CEngineSettingsBackend(parent, moduleName) - , m_registry(new SimpleRegistry) - , m_registryFilePath() -{ - std::string rootValue = gEnv->pFileIO->GetAlias("@root@"); - if (rootValue.empty()) - { - AZ_Warning("EngineSettings", false, "Could not get engine root."); - return; - } - - rootValue.append(gDefaultRegistryLocation); - m_registryFilePath = rootValue; -} - -CEngineSettingsBackendApple::~CEngineSettingsBackendApple() -{ - delete m_registry, m_registry = nullptr; -} - -std::wstring CEngineSettingsBackendApple::GetModuleFilePath() const -{ - std::string path; - - std::wstring_convert> converter; - std::string module = converter.to_bytes(moduleName()); - - void* handle = ::dlopen(module.c_str(), RTLD_LAZY); - if (handle) - { - const int c = _dyld_image_count(); - for (int i = 0; i < c; ++i) - { - const char* image = _dyld_get_image_name(i); - const void* altHandle = dlopen(image, RTLD_LAZY); - if (handle == altHandle) - { - char absImage[PATH_MAX]; - realpath(image, absImage); - char *ext = rindex(absImage, '.'); - if (ext) - { - *ext = '\0'; - } - path.append(absImage); - path.append(".ini"); - break; - } - } - } - - return converter.from_bytes(path); -} - -bool CEngineSettingsBackendApple::GetModuleSpecificStringEntryUtf16(const char* key, CWCharBuffer wbuffer) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - std::wstring str; - if (!m_registry->getStrValue(moduleName(), wkey, str)) - { - return false; - } - - std::wcscpy(wbuffer.getPtr(), str.c_str()); - - return true; -} - -bool CEngineSettingsBackendApple::GetModuleSpecificIntEntry(const char* key, int& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - return m_registry->getIntValue(moduleName(), wkey, value); -} - -bool CEngineSettingsBackendApple::GetModuleSpecificBoolEntry(const char* key, bool& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - return m_registry->getBoolValue(moduleName(), wkey, value); -} - -bool CEngineSettingsBackendApple::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - m_registry->setStrValue(moduleName(), wkey, str); - - return true; -} - -bool CEngineSettingsBackendApple::SetModuleSpecificIntEntry(const char* key, const int& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - m_registry->setIntValue(moduleName(), wkey, value); - - return true; -} - -bool CEngineSettingsBackendApple::SetModuleSpecificBoolEntry(const char* key, const bool& value) -{ - std::wstring_convert> converter; - std::wstring wkey = converter.from_bytes(key); - - m_registry->setBoolValue(moduleName(), wkey, value); - - return true; -} - -bool CEngineSettingsBackendApple::GetInstalledBuildRootPathUtf16(const int index, CWCharBuffer name, CWCharBuffer path) -{ - return false; -} - -bool CEngineSettingsBackendApple::StoreEngineSettingsToRegistry() -{ - bool bRet = true; - wchar_t buffer[1024]; - - // ResourceCompiler Specific - if (parent()->GetValueByRef("RC_ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_ShowWindow", b); - } - - if (parent()->GetValueByRef("RC_HideCustom", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_HideCustom", b); - } - - if (parent()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - m_registry->setStrValue(REG_BASE_SETTING_KEY, L"RC_Parameters", buffer); - } - - if (parent()->GetValueByRef("RC_EnableSourceControl", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_EnableSourceControl", b); - } - - bRet &= m_registry->saveToFile(m_registryFilePath.c_str()); - return bRet; -} - -void CEngineSettingsBackendApple::LoadEngineSettingsFromRegistry() -{ - if (!m_registry->loadFromFile(m_registryFilePath.c_str())) - { - return; - } - - std::wstring wStrResult; - bool bResult; - - if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"RootPath", wStrResult)) - { - parent()->SetKey("ENG_RootPath", wStrResult.c_str()); - } - - // Engine Specific - if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"ENG_RootPath", wStrResult)) - { - parent()->SetKey("ENG_RootPath", wStrResult.c_str()); - } - - // ResourceCompiler Specific - if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_ShowWindow", bResult)) - { - parent()->SetKey("RC_ShowWindow", bResult); - } - if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_HideCustom", bResult)) - { - parent()->SetKey("RC_HideCustom", bResult); - } - if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"RC_Parameters", wStrResult)) - { - parent()->SetKey("RC_Parameters", wStrResult.c_str()); - } - if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_EnableSourceControl", bResult)) - { - parent()->SetKey("RC_EnableSourceControl", bResult); - } -} - -#endif // AZ_TRAIT_OS_PLATFORM_APPLE -#endif // CRY_ENABLE_RC_HELPER - diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.h b/Code/CryEngine/CryCommon/EngineSettingsBackendApple.h deleted file mode 100644 index efc5a12bed..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendApple.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - * - */ -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H -#pragma once - -#include "EngineSettingsBackend.h" - -#ifdef CRY_ENABLE_RC_HELPER - -class CEngineSettingsManager; -class SimpleRegistry; - -class CEngineSettingsBackendApple : public CEngineSettingsBackend -{ -public: - CEngineSettingsBackendApple(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL); - ~CEngineSettingsBackendApple(); - - std::wstring GetModuleFilePath() const override; - - bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) override; - bool GetModuleSpecificIntEntry(const char* key, int& value) override; - bool GetModuleSpecificBoolEntry(const char* key, bool& value) override; - - bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) override; - bool SetModuleSpecificIntEntry(const char* key, const int& value) override; - bool SetModuleSpecificBoolEntry(const char* key, const bool& value) override; - - bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) override; - - void LoadEngineSettingsFromRegistry() override; - bool StoreEngineSettingsToRegistry() override; - -private: - SimpleRegistry *m_registry; - std::string m_registryFilePath; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.cpp b/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.cpp deleted file mode 100644 index c2e9a67d57..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* - * 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. - * - */ - - -#include "EngineSettingsBackendWin32.h" - -#ifdef CRY_ENABLE_RC_HELPER - -#include "AzCore/PlatformDef.h" - -#ifdef AZ_PLATFORM_WINDOWS - -#include "EngineSettingsManager.h" - -#include "platform.h" -#include - -#define REG_SOFTWARE L"Software\\" -#define REG_COMPANY_NAME L"Amazon\\" -#define REG_PRODUCT_NAME L"Open 3D Engine\\" -#define REG_SETTING L"Settings\\" -#define REG_BASE_SETTING_KEY REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME REG_SETTING - -EXTERN_C IMAGE_DOS_HEADER __ImageBase; - -using namespace SettingsManagerHelpers; - -static bool g_bWindowQuit; -static CEngineSettingsManager* g_pThis = 0; -static const unsigned int IDC_hEditRootPath = 100; -static const unsigned int IDC_hBtnBrowse = 101; - -namespace -{ - class RegKey - { - public: - RegKey(const wchar_t* key, bool writeable); - ~RegKey(); - void* pKey; - }; - - RegKey::RegKey(const wchar_t* key, bool writeable) - { - HKEY hKey; - LONG result; - if (writeable) - { - result = RegCreateKeyExW(HKEY_CURRENT_USER, key, 0, 0, 0, KEY_WRITE, 0, &hKey, 0); - } - else - { - result = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey); - } - pKey = hKey; - } - - RegKey::~RegKey() - { - RegCloseKey((HKEY)pKey); - } -} - -CEngineSettingsBackendWin32::CEngineSettingsBackendWin32(CEngineSettingsManager* parent, const wchar_t* moduleName) - : CEngineSettingsBackend(parent, moduleName) -{ -} - -std::wstring CEngineSettingsBackendWin32::GetModuleFilePath() const -{ - wchar_t szFilename[_MAX_PATH]; - GetModuleFileNameW((HINSTANCE)&__ImageBase, szFilename, _MAX_PATH); - wchar_t drive[_MAX_DRIVE]; - wchar_t dir[_MAX_DIR]; - wchar_t fname[_MAX_FNAME]; - wchar_t ext[1] = L""; - _wsplitpath_s(szFilename, drive, dir, fname, ext); - _wmakepath_s(szFilename, drive, dir, fname, L"ini"); - return szFilename; -} - -bool CEngineSettingsBackendWin32::GetModuleSpecificStringEntryUtf16(const char* key, CWCharBuffer wbuffer) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), false); - if (!superKey.pKey) - { - wbuffer[0] = 0; - return false; - } - if (!GetRegValue(superKey.pKey, key, wbuffer)) - { - wbuffer[0] = 0; - return false; - } - - return true; -} - -bool CEngineSettingsBackendWin32::GetModuleSpecificIntEntry(const char* key, int& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), false); - if (!superKey.pKey) - { - return false; - } - if (!GetRegValue(superKey.pKey, key, value)) - { - value = 0; - return false; - } - - return true; -} - -bool CEngineSettingsBackendWin32::GetModuleSpecificBoolEntry(const char* key, bool& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), false); - if (!superKey.pKey) - { - return false; - } - if (!GetRegValue(superKey.pKey, key, value)) - { - value = false; - return false; - } - - return true; -} - -bool CEngineSettingsBackendWin32::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), true); - if (superKey.pKey) - { - return SetRegValue(superKey.pKey, key, str); - } - return false; -} - -bool CEngineSettingsBackendWin32::SetModuleSpecificIntEntry(const char* key, const int& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), true); - if (superKey.pKey) - { - return SetRegValue(superKey.pKey, key, value); - } - return false; -} - -bool CEngineSettingsBackendWin32::SetModuleSpecificBoolEntry(const char* key, const bool& value) -{ - CFixedString s = REG_BASE_SETTING_KEY; - s.append(moduleName().c_str()); - RegKey superKey(s.c_str(), true); - if (superKey.pKey) - { - return SetRegValue(superKey.pKey, key, value); - } - return false; -} - -bool CEngineSettingsBackendWin32::GetInstalledBuildRootPathUtf16(const int index, CWCharBuffer name, CWCharBuffer path) -{ - RegKey key(REG_BASE_SETTING_KEY L"O3DEExport\\ProjectBuilds", false); - if (key.pKey) - { - DWORD type; - DWORD nameSizeInBytes = DWORD(name.getSizeInBytes()); - DWORD pathSizeInBytes = DWORD(path.getSizeInBytes()); - LONG result = RegEnumValueW((HKEY)key.pKey, index, name.getPtr(), &nameSizeInBytes, NULL, &type, (BYTE*)path.getPtr(), &pathSizeInBytes); - if (result == ERROR_SUCCESS) - { - return true; - } - } - return false; -} - -bool CEngineSettingsBackendWin32::StoreEngineSettingsToRegistry() -{ - // make sure the path in registry exists - { - RegKey key0(REG_SOFTWARE REG_COMPANY_NAME, true); - if (!key0.pKey) - { - RegKey software(REG_SOFTWARE, true); - HKEY hKey; - RegCreateKeyW((HKEY)software.pKey, REG_COMPANY_NAME, &hKey); - if (!hKey) - { - return false; - } - } - - RegKey key1(REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME, true); - if (!key1.pKey) - { - RegKey softwareCompany(REG_SOFTWARE REG_COMPANY_NAME, true); - HKEY hKey; - RegCreateKeyW((HKEY)softwareCompany.pKey, REG_COMPANY_NAME, &hKey); - if (!hKey) - { - return false; - } - } - - RegKey key2(REG_BASE_SETTING_KEY, true); - if (!key2.pKey) - { - RegKey softwareCompanyProduct(REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME, true); - HKEY hKey; - RegCreateKeyW((HKEY)key2.pKey, REG_SETTING, &hKey); - if (!hKey) - { - return false; - } - } - } - - bool bRet = true; - - RegKey key(REG_BASE_SETTING_KEY, true); - if (!key.pKey) - { - bRet = false; - } - else - { - wchar_t buffer[1024]; - - // ResourceCompiler Specific - - if (parent()->GetValueByRef("RC_ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - SetRegValue(key.pKey, "RC_ShowWindow", b); - } - - if (parent()->GetValueByRef("RC_HideCustom", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - SetRegValue(key.pKey, "RC_HideCustom", b); - } - - if (parent()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - SetRegValue(key.pKey, "RC_Parameters", buffer); - } - - if (parent()->GetValueByRef("RC_EnableSourceControl", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - const bool b = wcscmp(buffer, L"true") == 0; - SetRegValue(key.pKey, "RC_EnableSourceControl", b); - } - } - - return bRet; -} - -void CEngineSettingsBackendWin32::LoadEngineSettingsFromRegistry() -{ - wchar_t buffer[1024]; - - bool bResult; - - // Engine Specific (Deprecated value) - RegKey key(REG_BASE_SETTING_KEY, false); - if (key.pKey) - { - if (GetRegValue(key.pKey, "RootPath", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - parent()->SetKey("ENG_RootPath", buffer); - } - - // Engine Specific - if (GetRegValue(key.pKey, "ENG_RootPath", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - parent()->SetKey("ENG_RootPath", buffer); - } - - // ResourceCompiler Specific - if (GetRegValue(key.pKey, "RC_ShowWindow", bResult)) - { - parent()->SetKey("RC_ShowWindow", bResult); - } - if (GetRegValue(key.pKey, "RC_HideCustom", bResult)) - { - parent()->SetKey("RC_HideCustom", bResult); - } - if (GetRegValue(key.pKey, "RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - parent()->SetKey("RC_Parameters", buffer); - } - if (GetRegValue(key.pKey, "RC_EnableSourceControl", bResult)) - { - parent()->SetKey("RC_EnableSourceControl", bResult); - } - } -} - -bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, const wchar_t* value) -{ - CFixedString name; - name.appendAscii(valueName); - - size_t const sizeInBytes = (wcslen(value) + 1) * sizeof(value[0]); - return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_SZ, (BYTE*)value, DWORD(sizeInBytes))); -} - -bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, bool value) -{ - CFixedString name; - name.appendAscii(valueName); - - DWORD dwVal = value; - return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_DWORD, (BYTE*)&dwVal, sizeof(dwVal))); -} - -bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, int value) -{ - CFixedString name; - name.appendAscii(valueName); - - DWORD dwVal = value; - return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_DWORD, (BYTE*)&dwVal, sizeof(dwVal))); -} - -bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, CWCharBuffer wbuffer) -{ - if (wbuffer.getSizeInElements() <= 0) - { - return false; - } - - CFixedString name; - name.appendAscii(valueName); - - DWORD type; - DWORD sizeInBytes = DWORD(wbuffer.getSizeInBytes()); - if (ERROR_SUCCESS != RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)wbuffer.getPtr(), &sizeInBytes)) - { - wbuffer[0] = 0; - return false; - } - - const size_t sizeInElements = sizeInBytes / sizeof(wbuffer[0]); - if (sizeInElements > wbuffer.getSizeInElements()) // paranoid check - { - wbuffer[0] = 0; - return false; - } - - // According to MSDN documentation for RegQueryValueEx(), strings returned by the function - // are not zero-terminated sometimes, so we need to terminate them by ourselves. - if (wbuffer[sizeInElements - 1] != 0) - { - if (sizeInElements >= wbuffer.getSizeInElements()) - { - // No space left to put terminating zero character - wbuffer[0] = 0; - return false; - } - wbuffer[sizeInElements] = 0; - } - - return true; -} - -bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, bool& value) -{ - CFixedString name; - name.appendAscii(valueName); - - // Open the appropriate registry key - DWORD type, dwVal = 0, size = sizeof(dwVal); - bool res = (ERROR_SUCCESS == RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)&dwVal, &size)); - if (res) - { - value = (dwVal != 0); - } - else - { - wchar_t buffer[100]; - res = GetRegValue(key, valueName, CWCharBuffer(buffer, sizeof(buffer))); - if (res) - { - value = (wcscmp(buffer, L"true") == 0); - } - } - return res; -} - -bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, int& value) -{ - CFixedString name; - name.appendAscii(valueName); - - // Open the appropriate registry key - DWORD type, dwVal = 0, size = sizeof(dwVal); - - bool res = (ERROR_SUCCESS == RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)&dwVal, &size)); - if (res) - { - value = dwVal; - } - - return res; -} - -#endif // AZ_PLATFORM_WINDOWS -#endif // CRY_ENABLE_RC_HELPER diff --git a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.h b/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.h deleted file mode 100644 index 47b4772ede..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsBackendWin32.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * - */ -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H -#pragma once - -#include "EngineSettingsBackend.h" - -#ifdef CRY_ENABLE_RC_HELPER - -class CEngineSettingsManager; - -class CEngineSettingsBackendWin32 : public CEngineSettingsBackend -{ -public: - CEngineSettingsBackendWin32(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL); - - std::wstring GetModuleFilePath() const override; - - bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) override; - bool GetModuleSpecificIntEntry(const char* key, int& value) override; - bool GetModuleSpecificBoolEntry(const char* key, bool& value) override; - - bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) override; - bool SetModuleSpecificIntEntry(const char* key, const int& value) override; - bool SetModuleSpecificBoolEntry(const char* key, const bool& value) override; - - bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) override; - - void LoadEngineSettingsFromRegistry() override; - bool StoreEngineSettingsToRegistry() override; - -protected: - bool SetRegValue(void* key, const char* valueName, const wchar_t* value); - bool SetRegValue(void* key, const char* valueName, bool value); - bool SetRegValue(void* key, const char* valueName, int value); - bool GetRegValue(void* key, const char* valueName, SettingsManagerHelpers::CWCharBuffer wbuffer); - bool GetRegValue(void* key, const char* valueName, bool& value); - bool GetRegValue(void* key, const char* valueName, int& value); -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H diff --git a/Code/CryEngine/CryCommon/EngineSettingsManager.cpp b/Code/CryEngine/CryCommon/EngineSettingsManager.cpp deleted file mode 100644 index 13ad568217..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsManager.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include "ProjectDefines.h" -#include "EngineSettingsManager.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include // assert() -#include "EngineSettingsBackend.h" - -#include "AzCore/PlatformDef.h" -#include "platform.h" - -#if defined(AZ_PLATFORM_WINDOWS) -#include "EngineSettingsBackendWin32.h" -#include -#elif AZ_TRAIT_OS_PLATFORM_APPLE -#include "EngineSettingsBackendApple.h" -#endif - - -#include -#include - -#define INFOTEXT L"Please specify the directory of your CryENGINE installation (RootPath):" - - -using namespace SettingsManagerHelpers; - - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// -CEngineSettingsManager::CEngineSettingsManager(const wchar_t* moduleName, const wchar_t* iniFileName) - : m_hWndParent(0) - , m_backend(NULL) -{ - m_sModuleName.clear(); - -#if defined(AZ_PLATFORM_WINDOWS) - m_backend = new CEngineSettingsBackendWin32(this, moduleName); -#elif AZ_TRAIT_OS_PLATFORM_APPLE - m_backend = new CEngineSettingsBackendApple(this, moduleName); -#endif - assert(m_backend); - - // std initialization - RestoreDefaults(); - - // try to load content from INI file - if (moduleName != NULL) - { - m_sModuleName = moduleName; - - if (iniFileName == NULL) - { - // find INI filename located in module path - m_sModuleFileName = m_backend->GetModuleFilePath().c_str(); - } - else - { - m_sModuleFileName = iniFileName; - } - - if (LoadValuesFromConfigFile(m_sModuleFileName.c_str())) - { - m_bGetDataFromBackend = false; - return; - } - } - - m_bGetDataFromBackend = true; - - // load basic content from registry - LoadEngineSettingsFromRegistry(); -} - -////////////////////////////////////////////////////////////////////////// -CEngineSettingsManager::~CEngineSettingsManager() -{ - delete m_backend, m_backend = NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::RestoreDefaults() -{ - // Engine - SetKey("ENG_RootPath", L""); - - // RC - SetKey("RC_ShowWindow", false); - SetKey("RC_HideCustom", false); - SetKey("RC_Parameters", L""); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) -{ - if (wbuffer.getSizeInElements() <= 0) - { - return false; - } - - if (!m_bGetDataFromBackend) - { - if (!HasKey(key)) - { - wbuffer[0] = 0; - return false; - } - if (!GetValueByRef(key, wbuffer)) - { - wbuffer[0] = 0; - return false; - } - } - else - { - assert(m_backend); - return m_backend->GetModuleSpecificStringEntryUtf16(key, wbuffer); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificStringEntryUtf8(const char* key, SettingsManagerHelpers::CCharBuffer buffer) -{ - if (buffer.getSizeInElements() <= 0) - { - return false; - } - - wchar_t wBuffer[1024]; - - if (!GetModuleSpecificStringEntryUtf16(key, SettingsManagerHelpers::CWCharBuffer(wBuffer, sizeof(wBuffer)))) - { - buffer[0] = 0; - return false; - } - - SettingsManagerHelpers::ConvertUtf16ToUtf8(wBuffer, buffer); - - return true; -} - - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificIntEntry(const char* key, int& value) -{ - value = 0; - - if (!m_bGetDataFromBackend) - { - if (!HasKey(key)) - { - return false; - } - if (!GetValueByRef(key, value)) - { - return false; - } - } - else - { - assert(m_backend); - return m_backend->GetModuleSpecificIntEntry(key, value); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetModuleSpecificBoolEntry(const char* key, bool& value) -{ - value = false; - - if (!m_bGetDataFromBackend) - { - if (!HasKey(key)) - { - return false; - } - if (!GetValueByRef(key, value)) - { - return false; - } - } - else - { - assert(m_backend); - return m_backend->GetModuleSpecificBoolEntry(key, value); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) -{ - SetKey(key, str); - if (!m_bGetDataFromBackend) - { - return StoreData(); - } - - assert(m_backend); - return m_backend->SetModuleSpecificStringEntryUtf16(key, str); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificIntEntry(const char* key, const int& value) -{ - SetKey(key, value); - if (!m_bGetDataFromBackend) - { - return StoreData(); - } - - assert(m_backend); - return m_backend->SetModuleSpecificIntEntry(key, value); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificBoolEntry(const char* key, const bool& value) -{ - SetKey(key, value); - if (!m_bGetDataFromBackend) - { - return StoreData(); - } - - assert(m_backend); - return m_backend->SetModuleSpecificBoolEntry(key, value); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::SetModuleSpecificStringEntryUtf8(const char* key, const char* str) -{ - wchar_t wbuffer[512]; - SettingsManagerHelpers::ConvertUtf8ToUtf16(str, SettingsManagerHelpers::CWCharBuffer(wbuffer, sizeof(wbuffer))); - - return SetModuleSpecificStringEntryUtf16(key, wbuffer); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::HasKey(const char* key) -{ - return m_keyValueArray.find(key) != 0; -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetKey(const char* key, const wchar_t* value) -{ - m_keyValueArray.set(key, value); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetKey(const char* key, bool value) -{ - m_keyValueArray.set(key, (value ? L"true" : L"false")); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetKey(const char* key, int value) -{ - m_keyValueArray.set(key, std::to_wstring(value).c_str()); -} - -bool CEngineSettingsManager::GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) -{ - assert(m_backend); - return m_backend->GetInstalledBuildRootPathUtf16(index, name, path); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::SetParentDialog(size_t window) -{ - m_hWndParent = window; -} - - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::StoreData() -{ - if (m_bGetDataFromBackend) - { - bool res = StoreEngineSettingsToRegistry(); - - if (!res) - { -#ifdef AZ_PLATFORM_WINDOWS - MessageBoxA(reinterpret_cast(m_hWndParent), "Could not store data to registry.", "Error", MB_OK | MB_ICONERROR); -#endif - } - return res; - } - - // store data to INI file - - FILE* file; -#ifdef AZ_PLATFORM_WINDOWS - _wfopen_s(&file, m_sModuleFileName.c_str(), L"wb"); -#else - char fname[MAX_PATH]; - memset(fname, 0, MAX_PATH); - wcstombs(fname, m_sModuleFileName.c_str(), MAX_PATH); - file = fopen(fname, "wb"); -#endif - if (file == NULL) - { - return false; - } - - char buffer[2048]; - - for (size_t i = 0; i < m_keyValueArray.size(); ++i) - { - const SKeyValue& kv = m_keyValueArray[i]; - - fprintf_s(file, kv.key.c_str()); - fprintf_s(file, " = "); - - if (kv.value.length() > 0) - { - SettingsManagerHelpers::ConvertUtf16ToUtf8(kv.value.c_str(), SettingsManagerHelpers::CCharBuffer(buffer, sizeof(buffer))); - fprintf_s(file, "%s", buffer); - } - - fprintf_s(file, "\r\n"); - } - - fclose(file); - - return true; -} - - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::LoadValuesFromConfigFile(const wchar_t* szFileName) -{ - m_keyValueArray.clear(); - - // read file to memory - - FILE* file; -#ifdef AZ_PLATFORM_WINDOWS - _wfopen_s(&file, szFileName, L"rb"); -#else - char fname[MAX_PATH]; - memset(fname, 0, MAX_PATH); - wcstombs(fname, szFileName, MAX_PATH); - file = fopen(fname, "rb"); -#endif - if (file == NULL) - { - return false; - } - - fseek(file, 0, SEEK_END); - long size = ftell(file); - fseek(file, 0, SEEK_SET); - char* data = new char[size + 1]; - fread_s(data, size, 1, size, file); - fclose(file); - - wchar_t wBuffer[1024]; - - // parse file for root path - - int start = 0, end = 0; - while (end < size) - { - while (end < size && data[end] != '\n') - { - end++; - } - - memcpy(data, &data[start], end - start); - data[end - start] = 0; - start = end = end + 1; - - CFixedString line(data); - size_t equalsOfs; - for (equalsOfs = 0; equalsOfs < line.length(); ++equalsOfs) - { - if (line[equalsOfs] == '=') - { - break; - } - } - if (equalsOfs < line.length()) - { - CFixedString key; - CFixedString value; - - key.appendAscii(line.c_str(), equalsOfs); - key.trim(); - - SettingsManagerHelpers::ConvertUtf8ToUtf16(line.c_str() + equalsOfs + 1, SettingsManagerHelpers::CWCharBuffer(wBuffer, sizeof(wBuffer))); - value.append(wBuffer); - value.trim(); - - m_keyValueArray.set(key.c_str(), value.c_str()); - } - } - delete[] data; - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::StoreEngineSettingsToRegistry() -{ - assert(m_backend); - return m_backend->StoreEngineSettingsToRegistry(); -} - -////////////////////////////////////////////////////////////////////////// -void CEngineSettingsManager::LoadEngineSettingsFromRegistry() -{ - assert(m_backend); - m_backend->LoadEngineSettingsFromRegistry(); -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetValueByRef(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) const -{ - if (wbuffer.getSizeInElements() <= 0) - { - return false; - } - - const SKeyValue* p = m_keyValueArray.find(key); - if (!p || (p->value.length() + 1) > wbuffer.getSizeInElements()) - { - wbuffer[0] = 0; - return false; - } - azwcscpy(wbuffer.getPtr(), wbuffer.getSizeInElements(), p->value.c_str()); - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetValueByRef(const char* key, bool& value) const -{ - wchar_t buffer[100]; - if (!GetValueByRef(key, SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - return false; - } - value = (wcscmp(buffer, L"true") == 0); - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CEngineSettingsManager::GetValueByRef(const char* key, int& value) const -{ - wchar_t buffer[100]; - if (!GetValueByRef(key, SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)))) - { - return false; - } - value = wcstol(buffer, 0, 10); - return true; -} - -#endif //(CRY_ENABLE_RC_HELPER) diff --git a/Code/CryEngine/CryCommon/EngineSettingsManager.h b/Code/CryEngine/CryCommon/EngineSettingsManager.h deleted file mode 100644 index 95216b3bf3..0000000000 --- a/Code/CryEngine/CryCommon/EngineSettingsManager.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H -#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H -#pragma once - -#include "ProjectDefines.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "SettingsManagerHelpers.h" - -class CEngineSettingsBackend; - -////////////////////////////////////////////////////////////////////////// -// Manages storage and loading of all information for tools and CryENGINE, by either registry or an INI file. -// Information can be read and set by key-to-value functions. -// Specific information can be set by a dialog application called by this class. -// If the engine root path is not found, a fall-back dialog is opened. -class CEngineSettingsManager -{ -public: - // prepares CEngineSettingsManager to get requested information either from registry or an INI file, - // if existent as a file with name an directory equal to the module, or from registry. - CEngineSettingsManager(const wchar_t* moduleName = NULL, const wchar_t* iniFileName = NULL); - ~CEngineSettingsManager(); - - void RestoreDefaults(); - - // stores/loads user specific information for modules to/from registry or INI file - bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer); - bool GetModuleSpecificStringEntryUtf8(const char* key, SettingsManagerHelpers::CCharBuffer buffer); - bool GetModuleSpecificIntEntry(const char* key, int& value); - bool GetModuleSpecificBoolEntry(const char* key, bool& value); - - bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str); - bool SetModuleSpecificStringEntryUtf8(const char* key, const char* str); - bool SetModuleSpecificIntEntry(const char* key, const int& value); - bool SetModuleSpecificBoolEntry(const char* key, const bool& value); - - bool GetValueByRef(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) const; - bool GetValueByRef(const char* key, bool& value) const; - bool GetValueByRef(const char* key, int& value) const; - - void SetKey(const char* key, const wchar_t* value); - void SetKey(const char* key, bool value); - void SetKey(const char* key, int value); - - bool StoreData(); - - bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path); - - void SetParentDialog(size_t window); - -private: - bool HasKey(const char* key); - - void LoadEngineSettingsFromRegistry(); - bool StoreEngineSettingsToRegistry(); - - // parses a file and stores all flags in a private key-value-map - bool LoadValuesFromConfigFile(const wchar_t* szFileName); - -private: - CEngineSettingsBackend *m_backend; - - SettingsManagerHelpers::CFixedString m_sModuleName; // name to store key-value pairs of modules in (registry) or to identify INI file - SettingsManagerHelpers::CFixedString m_sModuleFileName; // used in case of data being loaded from INI file - bool m_bGetDataFromBackend; - SettingsManagerHelpers::CKeyValueArray<30> m_keyValueArray; - - void* m_hBtnBrowse; - size_t m_hWndParent; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H diff --git a/Code/CryEngine/CryCommon/FinalizingSpline.h b/Code/CryEngine/CryCommon/FinalizingSpline.h deleted file mode 100644 index 1fb644eae9..0000000000 --- a/Code/CryEngine/CryCommon/FinalizingSpline.h +++ /dev/null @@ -1,1043 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_FINALIZINGSPLINE_H -#define CRYINCLUDE_CRYCOMMON_FINALIZINGSPLINE_H -#pragma once - - -#include // <> required for Interfuscator -#include -#include "CryCustomTypes.h" - -inline bool IsEquivalent(float a, float b, float eps) -{ - return abs(a - b) <= eps; -} - -// change this value to 1 run spline verification code; this was previously enabled in debug and -// was causing issues because triggering the assert would steal the focus from the editor -// and cause the user to put a control point in the wrong spot. we don't understand this code -// enough to triage the asserts yet, but things seem to be functioning properly. -#define VERIFY_SPLINE_CONVERSION 0 - -namespace spline -{ - ////////////////////////////////////////////////////////////////////////// - // FinalizingSpline - ////////////////////////////////////////////////////////////////////////// - - template - class FinalizingSpline - : public CBaseSplineInterpolator - { - public: - using_type(Source, value_type); - using_type(Source, key_type); - using_type(ISplineInterpolator, ValueType); - - FinalizingSpline() - : m_pFinal(0) - {} - - void SetFinal(Final* pFinal) - { - m_pFinal = pFinal; - m_pFinal->to_source(*this); - } - - // Most spline functions use source spline (base class). - // interpolate() uses dest, for fidelity. - virtual void Interpolate(float time, ValueType& value) - { - Source::update(); - assert(m_pFinal); - m_pFinal->interpolate(time, *(value_type*)&value); - } - - virtual void EvalInTangent(float time, ValueType& value) - { - Source::update(); - assert(m_pFinal); - m_pFinal->evalInTangent(time, *(value_type*)&value); - - } - - virtual void EvalOutTangent(float time, ValueType& value) - { - Source::update(); - assert(m_pFinal); - m_pFinal->evalOutTangent(time, *(value_type*)&value); - - } - - virtual void eval(float time, ValueType& value) - { - Source::update(); - assert(m_pFinal); - m_pFinal->interpolate(time, *(value_type*)&value); - } - - // Update dest when source modified. - // Should be called for every update to source spline. - virtual void SetModified(bool bOn, bool bSort = false) - { - Source::SetModified(bOn, bSort); - assert(m_pFinal); - m_pFinal->from_source(*this); - } - - virtual bool GetKeyTangents(int k, ValueType& tin, ValueType& tout) - { - if (k >= 0 && k < this->num_keys()) - { - this->ToValueType(Source::ds(k), tin); - this->ToValueType(Source::dd(k), tout); - return true; - } - else - { - return false; - } - } - - virtual int GetKeyFlags(int k) - { - return Source::flags(k); - } - - /////////////////////////////////////////// - - virtual void SerializeSpline([[maybe_unused]] XmlNodeRef& node, [[maybe_unused]] bool bLoading) - {} - - protected: - - Final* m_pFinal; - }; - -#if 0 - - ////////////////////////////////////////////////////////////////////////// - // LookupTableSpline - ////////////////////////////////////////////////////////////////////////// - - template - class LookupTableSplineInterpolater - { - public: - ILINE static void fast_interpolate(float t, value_type& val, S* m_table) - { - t *= nMAX_ENTRIES - 1.0f; - float frac = t - floorf(t); - int idx = int(t); - val = value_type(m_table[idx]) * (1.f - frac); - val += value_type(m_table[idx + 1]) * frac; - } - }; - - template - class LookupTableSplineInterpolater - { - enum - { - SHIFT_AMOUNT = 24 - }; - - public: - ILINE static void fast_interpolate(float t, value_type& val, UnitFloat8* m_table) - { - const float scale = (float)(1 << SHIFT_AMOUNT); - uint32 ti = uint32(t * scale * (nMAX_ENTRIES - 1.0f)); - uint32 idx = ti >> SHIFT_AMOUNT; - uint32 frac = ti - (idx << SHIFT_AMOUNT); - uint32 vali = (uint32)m_table[idx + 1].GetStore() * frac; - frac = (1 << SHIFT_AMOUNT) - frac; - vali += (uint32)m_table[idx].GetStore() * frac; - val = (value_type)vali * (1.0f / (255.0f * scale)); - } - }; - - - template - class LookupTableSpline - : public FinalizingSpline - { - typedef FinalizingSpline super_type; - using super_type::m_pSource; - using super_type::is_updated; - - enum - { - nSTORE_SIZE = 128 - }; - enum - { - nMAX_ENTRIES = nSTORE_SIZE - 1 - }; - enum - { - nMIN_VALUE = nMAX_ENTRIES - }; - - public: - - using_type(super_type, value_type); - - LookupTableSpline() - { - init(); - } - - LookupTableSpline(const LookupTableSpline& other) - : super_type(other) - { - init(); - update(); - } - void operator=(const LookupTableSpline& other) - { - super_type::operator=(other); - update(); - } - - ~LookupTableSpline() - { - delete[] m_table; - } - - void interpolate(float t, value_type& val) - { - if (!is_updated()) - { - update(); - } - fast_interpolate(clamp_tpl(t, 0.0f, 1.0f), val); - } - - void fast_interpolate(float t, value_type& val) const - { - LookupTableSplineInterpolater::fast_interpolate(t, val, m_table); - } - - ILINE void min_value(value_type& val) const - { - val = value_type(m_table[nMIN_VALUE]); - } - - void finalize() - { - if (!is_updated()) - { - update(); - } - super_type::finalize(); - } - - void GetMemoryUsage(ICrySizer* pSizer, bool bSelf = false) const - { - if (bSelf && !pSizer->AddObjectSize(this)) - { - return; - } - super_type::GetMemoryUsage(pSizer); - if (m_table) - { - pSizer->AddObject(m_table, nSTORE_SIZE * sizeof(S)); - } - } - - protected: - - void update() - { - value_type minVal(1.0f); - if (!m_table) - { - m_table = new S[nSTORE_SIZE]; - } - if (!m_pSource || m_pSource->empty()) - { - for (int i = 0; i < nMAX_ENTRIES; i++) - { - m_table[i] = value_type(1.f); - } - } - else - { - m_pSource->update(); - for (int i = 0; i < nMAX_ENTRIES; i++) - { - value_type val; - float t = float(i) * (1.0f / (float)(nMAX_ENTRIES - 1)); - m_pSource->interpolate(t, val); - minVal = min(minVal, val); - m_table[i] = val; - } - } - m_table[nMIN_VALUE] = minVal; - } - - void init() - { - m_table = NULL; - } - - bool is_updated() const - { - return super_type::is_updated() && m_table; - } - - S* m_table; - }; - -#endif // LookupTableSpline - - ////////////////////////////////////////////////////////////////////////// - // OptSpline - // Minimises memory for key-based storage. Uses 8-bit compressed key values. - ////////////////////////////////////////////////////////////////////////// - - /* - Choose basis vars t, u = 1-t, ttu, uut. - This produces exact values at t = 0 and 1, even with compressed coefficients. - For end points and slopes v0, v1, s0, s1, - solve for coefficients a, b, c, d: - - v(t) = a u + b t + c uut + d utt - s(t) = v'(t) = -a + b + c (1-4t+3t^2) + d (2t-3t^2) - - v(0) = a - v(1) = b - s(0) = -a + b + c - s(1) = -a + b - d - - So - - a = v0 - b = v1 - c = s0 + v0 - v1 - d = -s1 - v0 + v1 - - s0 = c + v1 - v0 - s1 = -d + v1 - v0 - - For compression, all values of v and t are limited to [0..1]. - Find the max possible slope values, such that values never exceed this range. - - If v0 = v1 = 0, then max slopes would have - - c = d - v(1/2) = 1 - c/8 + d/8 = 1 - c = 4 - - If v0 = 0 and v1 = 1, then max slopes would have - - c = d - v(1/3) = 1 - 1/3 + c 4/9 + d 2/9 = 1 - c = 1 - */ - - template - class OptSpline - { - typedef OptSpline self_type; - - public: - - typedef T value_type; - typedef SplineKey key_type; - typedef TSplineSlopes source_spline; - - protected: - - static const int DIM = sizeof(value_type) / sizeof(float); - - template - struct array - { - S elems[DIM]; - - ILINE array() - { - for (int i = 0; i < DIM; i++) - { - elems[i] = 0; - } - } - ILINE array(value_type const& val) - { - const float* aVal = reinterpret_cast(&val); - for (int i = 0; i < DIM; i++) - { - elems[i] = aVal[i]; - } - } - ILINE array& operator=(value_type const& val) - { - new(this)array(val); - return *this; - } - - ILINE operator value_type() const - { - PREFAST_SUPPRESS_WARNING(6001) - value_type val; - float* aVal = reinterpret_cast(&val); - for (int i = 0; i < DIM; i++) - { - aVal[i] = elems[i]; - } - return val; - } - - ILINE bool operator !() const - { - for (int i = 0; i < DIM; i++) - { - if (elems[i]) - { - return false; - } - } - return true; - } - ILINE bool operator ==(array const& o) const - { - for (int i = 0; i < DIM; i++) - { - if (!(elems[i] == o.elems[i])) - { - return false; - } - } - return true; - } - ILINE S& operator [](int i) - { - assert(i >= 0 && i < DIM); - return elems[i]; - } - ILINE const S& operator [](int i) const - { - assert(i >= 0 && i < DIM); - return elems[i]; - } - }; - - typedef UnitFloat8 TStore; - typedef array< UnitFloat8 > VStore; - typedef array< float> FStore; - typedef array< TFixed > SStore; - - // - // Element storage - // - struct Point - { - TStore st; // Time of this point. - VStore sv; // Value at this point. - FStore dd; // Out tangent - FStore ds; // In tangent - int flags; // key type flags - - void set_key(float t, value_type v) - { - st = t; - sv = v; - } - void set_flags(int f) - { - flags = f; - } - - void set_tangent(value_type _dd, value_type _ds) - { - dd = _dd; - ds = _ds; - } - - }; - - struct Elem - : Point - { - using Point::st; // Total BS required for idiotic gcc. - using Point::sv; - - SStore sc, sd; // Coefficients for uut and utt. - - // Compute coeffs based on 2 endpoints & slopes. - void set_slopes(value_type s0, value_type s1) - { - value_type dv = value_type((this)[1].sv) - value_type(sv); - sc = s0 - dv; - sd = dv - s1; - } - - ILINE void eval(value_type& val, float t) const - { - float u = 1.f - t, - tu = t * u; - - float* aF = reinterpret_cast(&val); - for (int i = 0; i < DIM; i++) - { - float elem = float(sv[i]) * u + float(this[1].sv[i]) * t; - elem += (float(sc[i]) * u + float(sd[i]) * t) * tu; - elem = elem < 0.f ? 0.f : elem; - elem = elem > 1.f ? 1.f : elem; - aF[i] = elem; - } - } - - // Use the derivative of eval formular to caculate the tangent of t - ILINE void dev_eval(value_type& val, float t, value_type value) const - { - float u = 1.f - t, - tu = t * u; - - float* aF = reinterpret_cast(&val); - float* currentValue = reinterpret_cast(&value); - for (int i = 0; i < DIM; i++) - { - float elem = -float(sv[i]) + float(currentValue[i]); - elem += float(sc[i]) * (1 - 4 * t + 3 * t * t) - + float(sd[i]) * (2 * t - 3 * t * t); - aF[i] = elem; - } - } - - value_type value() const - { - return sv; - } - - // Slopes - // v(t) = v0 u + v1 t + (c u + d t) t u - // v\t(t) = v1 - v0 + (d - c) t u + (d t + c u) (u-t) - // v\t(0) = v1 - v0 + c - // v\t(1) = v1 - v0 - d - value_type start_slope() const - { - return value_type((this)[1].sv) - value_type(sv) + value_type(sc); - } - value_type end_slope() const - { - return value_type((this)[1].sv) - value_type(sv) - value_type(sd); - } - }; - - struct Spline - { - uint8 nKeys; // Total number of keys. - Elem aElems[1]; // Points and slopes. Last element is just Point without slopes. - - Spline() - : nKeys(0) - { - // Empty spline sets dummy values to max, for consistency. - aElems[0].st = TStore(1); - aElems[0].sv = value_type(1); - aElems[0].flags = 0; - aElems[0].dd = FStore(0); - aElems[0].ds = FStore(0); - } - - Spline(int keys) - : nKeys(aznumeric_caster(keys)) - { - #ifdef _DEBUG - if (nKeys) - { - ((char*)this)[alloc_size()] = 77; - } - #endif - } - - static size_t alloc_size(int keys) - { - assert(keys > 0); - return sizeof(Spline) + max(keys - 1, 0) * sizeof(Elem); - } - size_t alloc_size() const - { - return alloc_size(nKeys); - } - - key_type key(int n) const - { - key_type key; - if (n < nKeys) - { - key.time = aElems[n].st; - key.value = aElems[n].sv; - - // Infer slope flags from slopes. - if (n >= 0) // bezier curve inTangent and outtangent will be asigned by user - { - key.flags = aElems[n].flags; - key.dd = aElems[n].dd; - key.ds = aElems[n].ds; - } - } - return key; - } - - void interpolate(float t, value_type& val) const - { - float prev_t = aElems[0].st; - if (t <= prev_t) - { - val = aElems[0].sv; - } - else - { - // Find spline segment. - const Elem* pEnd = aElems + nKeys - 1; - const Elem* pElem = aElems; - for (; pElem < pEnd; ++pElem) - { - float cur_t = pElem[1].st; - if (t <= cur_t) - { - // Eval - pElem->eval(val, (t - prev_t) / (cur_t - prev_t)); - return; - } - prev_t = cur_t; - } - - // Last point value. - val = pElem->sv; - } - } - - - void EvalInTangent(float t, value_type& val) const - { - // Compute coeffs dynamically. - - float prev_t = aElems[0].st; - value_type prev_v = aElems[0].sv; - if (t <= prev_t) - { - val = 0; - } - else - { - // Find spline segment. - const Elem* pEnd = aElems + nKeys - 1; - const Elem* pElem = aElems; - for (; pElem < pEnd; ++pElem) - { - float cur_t = pElem[1].st; - value_type cur_v = pElem[1].sv; - value_type Tvalue = value_type(0); - interpolate(t, Tvalue); - - if (t <= cur_t) - { - - Elem newElement; - newElement.set_key(prev_t, prev_v); - value_type dd = Tvalue - prev_v; - - value_type ds = aElems[0].ds; - - newElement.set_tangent(dd, ds); - - - value_type tds = Tvalue - prev_v; - if (pElem[0].dd == FStore(0)) - { - tds = 2 * tds; - } - - newElement.sc = dd - dd; - newElement.sd = dd - value_type(tds); - - newElement.dev_eval(val, 1, Tvalue); - return; - } - prev_t = cur_t; - prev_v = cur_v; - } - - // Last point value. - val = 0.0f; - } - - } - - - void EvalOutTangent(float t, value_type& val) const - { - // Compute coeffs dynamically. - - float prev_t = aElems[0].st; - value_type prev_v = aElems[0].sv; - if (t <= prev_t) - { - val = 0; - } - else - { - // Find spline segment. - const Elem* pEnd = aElems + nKeys - 1; - const Elem* pElem = aElems; - for (; pElem < pEnd; ++pElem) - { - float cur_t = pElem[1].st; - value_type cur_v = pElem[1].sv; - value_type Tvalue = value_type(0); - interpolate(t, Tvalue); - - if (t <= cur_t) - { - // Create a temporary Elem to hold the info of the inserted key. - // Since we will insert a key between pre_key and curr_key, the - // slop and in/out tangent need to be recaculated. - Elem newElement; - // Set value and time for new key - newElement.set_key(t, Tvalue); - - //Caculate out tangent of new key. - value_type dd = cur_v - Tvalue; - if (pElem[1].ds == FStore(0)) - { - dd = 2 * dd; - } - //Caculate in tangent of new key - value_type ds = Tvalue - prev_v; - if (pElem[0].dd == FStore(0)) - { - ds = 2 * ds; - } - newElement.set_tangent(dd,ds); - - value_type dv = cur_v - Tvalue; - newElement.sc = dd - dv; - newElement.sd = dv - value_type(pElem[1].ds); - - newElement.dev_eval(val, 0, cur_v); - return; - } - prev_t = cur_t; - prev_v = cur_v; - } - - // Last point value. - val = 0.0f; - } - } - - void min_value(value_type& val) const - { - VStore sval = aElems[0].sv; - for (int n = 1; n < nKeys; n++) - { - for (int i = 0; i < DIM; i++) - { - sval[i] = min(sval[i], aElems[n].sv[i]); - } - } - val = sval; - } - - void max_value(value_type& val) const - { - VStore sval = aElems[0].sv; - for (int n = 1; n < nKeys; n++) - { - for (int i = 0; i < DIM; i++) - { - sval[i] = max(sval[i], aElems[n].sv[i]); - } - } - val = sval; - } - - value_type default_slope(int n) const - { - return n > 0 && n < nKeys - 1 ? - minmag(aElems[n].value() - aElems[n - 1].value(), aElems[n + 1].value() - aElems[n].value()) - : value_type(0.f); - } - - void validate() const - { - #ifdef _DEBUG - if (nKeys) - { - assert(((char const*)this)[alloc_size()] == 77); - } - #endif - } - }; - - Spline* m_pSpline; - - void alloc(int nKeys) - { - if (nKeys) - { - size_t nAlloc = Spline::alloc_size(nKeys) - #ifdef _DEBUG - + 1 - #endif - ; - - //set the memory to 0 since the comparison between two splines are comparing memory directly. - //And set functions won't set the memory because of alignment. - m_pSpline = new(CryModuleCalloc(1, nAlloc))Spline(nKeys); - } - else - { - m_pSpline = NULL; - } - } - - void dealloc() - { - CryModuleFree(m_pSpline); - m_pSpline = nullptr; - } - - public: - - ~OptSpline() - { - dealloc(); - } - - OptSpline() - { - m_pSpline = NULL; - } - - OptSpline(const self_type& in) - { - if (!in.empty() && in.num_keys() != 0) - { - alloc(in.num_keys()); - memcpy(m_pSpline, in.m_pSpline, in.m_pSpline->alloc_size()); - m_pSpline->validate(); - } - else - { - m_pSpline = NULL; - } - } - - self_type& operator=(const self_type& in) - { - dealloc(); - new(this)self_type(in); - return *this; - } - - bool operator == (const self_type& o) const - { - if (empty() && o.empty()) - { - return true; - } - if (num_keys() != o.num_keys()) - { - return false; - } - return !memcmp(m_pSpline, o.m_pSpline, m_pSpline->alloc_size()); - } - - // - // Adaptors for CBaseSplineInterpolator - // - bool empty() const - { - return !m_pSpline; - } - void clear() - { - dealloc(); - m_pSpline = NULL; - } - ILINE int num_keys() const - { - return m_pSpline ? m_pSpline->nKeys : 0; - } - - ILINE key_type key(int n) const - { - assert(n < num_keys()); - return m_pSpline->key(n); - } - - ILINE void interpolate(float t, value_type& val) const - { - if (!empty()) - { - m_pSpline->interpolate(t, val); - } - else - { - val = value_type(1.f); - } - } - - - ILINE void evalInTangent(float t, value_type& val) const - { - if (!empty()) - { - m_pSpline->EvalInTangent(t, val); - } - else - { - val = value_type(0.f); - } - } - - ILINE void evalOutTangent(float t, value_type& val) const - { - if (!empty()) - { - m_pSpline->EvalOutTangent(t, val); - } - else - { - val = value_type(0.f); - } - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - if (!empty()) - { - pSizer->AddObject(m_pSpline, m_pSpline->alloc_size()); - } - } - - // - // Additional methods. - // - void min_value(value_type& val) const - { - if (!empty()) - { - m_pSpline->min_value(val); - } - else - { - val = value_type(1.f); - } - } - void max_value(value_type& val) const - { - if (!empty()) - { - m_pSpline->max_value(val); - } - else - { - val = value_type(1.f); - } - } - - void from_source(source_spline& source) - { - dealloc(); - source.update(); - int nKeys = source.num_keys(); - - // Check for trivial spline. - bool is_default = true; - for (int i = 0; i < nKeys; i++) - { - if (source.value(i) != value_type(1)) - { - is_default = false; - break; - } - } - if (is_default) - { - nKeys = 0; - } - - alloc(nKeys); - if (nKeys) - { - // First set key values, then compute slope coefficients. - for (int i = 0; i < nKeys; i++) - { - m_pSpline->aElems[i].set_key(source.time(i), source.value(i)); - m_pSpline->aElems[i].set_flags(source.flags(i)); - m_pSpline->aElems[i].set_tangent(source.dd(i), source.ds(i)); - - } - for (int i = 0; i < nKeys - 1; i++) - { - m_pSpline->aElems[i].set_slopes(source.dd(i), source.ds(i + 1)); - } - -#if VERIFY_SPLINE_CONVERSION - // Verify accurate conversion to OptSpline. - for (int i = 0; i < nKeys; i++) - { - key_type ks = source.key(i); - key_type kf = key(i); - - assert(TStore(ks.time) == TStore(kf.time)); - assert(VStore(ks.value) == VStore(kf.value)); - - static const float fSlopeEquivalence = 1.f / 60.f; - assert(IsEquivalent(ks.ds, kf.ds, fSlopeEquivalence)); - assert(IsEquivalent(ks.dd, kf.dd, fSlopeEquivalence)); - - // Verify accurate reconstruction of slope flags. - ks.flags &= (SPLINE_KEY_TANGENT_IN_MASK | SPLINE_KEY_TANGENT_OUT_MASK); - - value_type default_slope = i > 0 && i < nKeys - 1 ? - minmag(ks.value - source.key(i - 1).value, source.key(i + 1).value - ks.value) - : value_type(0.f); - if (i == 0 || IsEquivalent(ks.ds, default_slope, fSlopeEquivalence)) - { - ks.flags &= ~SPLINE_KEY_TANGENT_IN_MASK; - } - if (i == nKeys - 1 || IsEquivalent(ks.dd, default_slope, fSlopeEquivalence)) - { - ks.flags &= ~SPLINE_KEY_TANGENT_OUT_MASK; - } - assert(ks.flags == kf.flags); - } -#endif //VERIFY_SPLINE_CONVERSION - } - } - - void to_source(source_spline& source) const - { - int nKeys = num_keys(); - source.resize(nKeys); - for (int i = 0; i < nKeys; i++) - { - source.key(i) = key(i); - } - source.update(); - } - }; -}; - -#endif // CRYINCLUDE_CRYCOMMON_FINALIZINGSPLINE_H diff --git a/Code/CryEngine/CryCommon/GeomCacheFileFormat.h b/Code/CryEngine/CryCommon/GeomCacheFileFormat.h deleted file mode 100644 index a8328e8a14..0000000000 --- a/Code/CryEngine/CryCommon/GeomCacheFileFormat.h +++ /dev/null @@ -1,202 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H -#define CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H -#pragma once - -#include "CryExtension/CryGUID.h" - -#if !defined(LINUX) -#pragma pack(push) -#pragma pack(1) -#define PACK_GCC -#else -#define PACK_GCC __attribute__ ((packed)) -#endif - -namespace GeomCacheFile -{ - // Important: The enums are serialized, don't change the values - // without increasing the file version, conversion code etc! - - typedef Vec3_tpl Position; - typedef Vec2_tpl Texcoords; - typedef Vec4_tpl QTangent; - typedef uint8 Color; - - // ASCII "CAXCACHE" - const uint64 kFileSignature = 0x4548434143584143ull; - - // The smallest 'UVmax' we'll support - this avoids division by zero when encoding/decoding UVs - const float kMinUVrange = .01f; - - // Bit Precision of tangents quaternions - const uint kTangentQuatPrecision = 10; - - // Current file version GUID. Files with other GUIDs will not be loaded by the engine. - const CryGUID kCurrentVersion = MAKE_CRYGUID(0x1641defe440af501, 0x7ec5e9164c8c2d1c); - - // Mesh prediction look back array size - const uint kMeshPredictorLookBackMaxDist = 4096; - - // Number of frames between index frames. Needs to be <= g_kMaxBufferedFrames. - const uint kMaxIFrameDistance = 30; - - enum EFileHeaderFlags - { - eFileHeaderFlags_PlaybackFromMemory = BIT(0), - eFileHeaderFlags_32BitIndices = BIT(1) - }; - - enum EBlockCompressionFormat - { - eBlockCompressionFormat_None = 0, - eBlockCompressionFormat_Deflate = 1, // zlib - eBlockCompressionFormat_LZ4HC = 2, // LZ4 HC - eBlockCompressionFormat_ZSTD = 3, //ZStandard - }; - - enum EStreams - { - eStream_Indices = BIT(0), - eStream_Positions = BIT(1), - eStream_Texcoords = BIT(2), - eStream_QTangents = BIT(3), - eStream_Colors = BIT(4) - }; - - enum ETransformType - { - eTransformType_Constant, - eTransformType_Animated - }; - - enum ENodeType - { - eNodeType_Transform = 0, // Transforms all sub nodes - eNodeType_Mesh = 1, - eNodeType_PhysicsGeometry = 2, - }; - - // Common frame - enum EFrameType - { - eFrameType_IFrame = 0, - eFrameType_BFrame = 1 - }; - - // Common frame flags - enum EFrameFlags - { - eFrameFlags_Hidden = BIT(0) - }; - - // Flags for mesh index frames - enum EMeshIFrameFlags - { - eMeshIFrameFlags_UsePredictor = BIT(1) - }; - - struct SHeader - { - SHeader() - : m_signature(0) - , m_version(kCurrentVersion) - , m_blockCompressionFormat(0) - , m_flags(0) - , m_numFrames(0) {} - - uint64 m_signature; - CryGUID m_version; - uint16 m_blockCompressionFormat; - uint32 m_flags; - uint32 m_numFrames; - uint64 m_totalUncompressedAnimationSize; - float m_aabbMin[3]; - float m_aabbMax[3]; - } PACK_GCC; - - struct SFrameInfo - { - uint32 m_frameType; - uint32 m_frameSize; - uint64 m_frameOffset; - float m_frameTime; - } PACK_GCC; - - struct SCompressedBlockHeader - { - uint32 m_uncompressedSize; - uint32 m_compressedSize; - } PACK_GCC; - - struct SFrameHeader - { - uint32 m_nodeDataOffset; - float m_frameAABBMin[3]; - float m_frameAABBMax[3]; - uint32 m_padding; - } PACK_GCC; - - struct STemporalPredictorControl - { - uint8 m_acceleration; - uint8 m_indexFrameLerpFactor; - uint8 m_combineFactor; - uint8 m_padding; - } PACK_GCC; - - struct SMeshFrameHeader - { - uint32 m_flags; - STemporalPredictorControl m_positionStreamPredictorControl; - STemporalPredictorControl m_texcoordStreamPredictorControl; - STemporalPredictorControl m_qTangentStreamPredictorControl; - STemporalPredictorControl m_colorStreamPredictorControl[4]; - } PACK_GCC; - - struct SMeshInfo - { - uint8 m_constantStreams; - uint8 m_animatedStreams; - uint8 m_positionPrecision[3]; - float m_uvMax; - uint8 m_padding; - uint16 m_numMaterials; - uint32 m_numVertices; - uint32 m_flags; - float m_aabbMin[3]; - float m_aabbMax[3]; - uint32 m_nameLength; - uint64 m_hash; - } PACK_GCC; - - struct SNodeInfo - { - uint8 m_type; - uint8 m_bVisible; - uint16 m_transformType; - uint32 m_meshIndex; - uint32 m_numChildren; - uint32 m_nameLength; - } PACK_GCC; -} - -#undef PACK_GCC - -#if !defined(LINUX) -#pragma pack(pop) -#endif - -#endif // CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H diff --git a/Code/CryEngine/CryCommon/GeomQuery.h b/Code/CryEngine/CryCommon/GeomQuery.h deleted file mode 100644 index 6b59f92dce..0000000000 --- a/Code/CryEngine/CryCommon/GeomQuery.h +++ /dev/null @@ -1,469 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Facility for efficiently generating random positions on geometry - -#ifndef CRYINCLUDE_CRYCOMMON_GEOMQUERY_H -#define CRYINCLUDE_CRYCOMMON_GEOMQUERY_H -#pragma once - - -#include "Cry_Geo.h" -#include "CryArray.h" -#include "Random.h" - -////////////////////////////////////////////////////////////////////// -// Extents cache - -class CGeomExtent -{ -public: - - CGeomExtent() - : m_nEmptyEndParts(0) {} - - ILINE operator bool() const - { - return m_afCumExtents.capacity() + m_nEmptyEndParts != 0; - } - ILINE int NumParts() const - { - return m_afCumExtents.size(); - } - ILINE float TotalExtent() const - { - return !m_afCumExtents.empty() ? m_afCumExtents.back() : 0.f; - } - - void Clear() - { - m_afCumExtents.clear(); - m_nEmptyEndParts = 0; - } - void AddPart(float fExtent) - { - // Defer empty parts until a non-empty part is added. - if (fExtent <= 0.f) - { - m_nEmptyEndParts++; - } - else - { - float fTotal = TotalExtent(); - for (; m_nEmptyEndParts; m_nEmptyEndParts--) - { - m_afCumExtents.push_back(fTotal); - } - m_afCumExtents.push_back(fTotal + fExtent); - } - } - void ReserveParts(int nCount) - { - m_afCumExtents.reserve(nCount); - } - - // Find element in sorted array <= index (normalized 0 to 1) - int GetPart(float fIndex) const - { - int last = m_afCumExtents.size() - 1; - if (last <= 0) - { - return last; - } - - fIndex *= m_afCumExtents[last]; - - // Binary search thru array. - int lo = 0, hi = last; - while (lo < hi) - { - int i = (lo + hi) >> 1; - if (fIndex < m_afCumExtents[i]) - { - hi = i; - } - else - { - lo = i + 1; - } - } - - assert(lo == 0 || m_afCumExtents[lo] > m_afCumExtents[lo - 1]); - return lo; - } - - int RandomPart() const - { - return GetPart(cry_random(0.0f, 1.0f)); - } - -protected: - - DynArray m_afCumExtents; - int m_nEmptyEndParts; -}; - -class CGeomExtents -{ -public: - - ILINE CGeomExtents() - : m_aExtents(0) {} - ~CGeomExtents() - { delete[] m_aExtents; } - - void Clear() - { - delete[] m_aExtents; - m_aExtents = 0; - } - - ILINE CGeomExtent const& operator [](EGeomForm eForm) const - { - assert(eForm >= 0 && eForm < MaxGeomForm); - if (m_aExtents) - { - return m_aExtents[eForm]; - } - - static CGeomExtent s_empty; - return s_empty; - } - - ILINE CGeomExtent& Make(EGeomForm eForm) - { - assert(eForm >= 0 && eForm < MaxGeomForm); - if (!m_aExtents) - { - m_aExtents = new CGeomExtent[4]; - } - return m_aExtents[eForm]; - } - -protected: - CGeomExtent* m_aExtents; -}; - - -// Other random/extent functions - -inline float ScaleExtent(EGeomForm eForm, float fScale) -{ - switch (eForm) - { - default: - return 1; - case GeomForm_Edges: - return fScale; - case GeomForm_Surface: - return fScale * fScale; - case GeomForm_Volume: - return fScale * fScale * fScale; - } -} - -inline float BoxExtent(EGeomForm eForm, Vec3 const& vSize) -{ - switch (eForm) - { - default: - assert(0); - case GeomForm_Vertices: - return 8.f; - case GeomForm_Edges: - return (vSize.x + vSize.y + vSize.z) * 8.f; - case GeomForm_Surface: - return (vSize.x * vSize.y + vSize.x * vSize.z + vSize.y * vSize.z) * 8.f; - case GeomForm_Volume: - return vSize.x * vSize.y * vSize.z * 8.f; - } -} - -// Utility functions. - -template -inline -const typename T::value_type& RandomElem(const T& array) -{ - int n = cry_random(0U, array.size() - 1); - return array[n]; -} - -// Geometric primitive randomizing functions. -ILINE void BoxRandomPos(PosNorm& ran, EGeomForm eForm, Vec3 const& vSize) -{ - ran.vPos = cry_random_componentwise(-vSize, vSize); - ran.vNorm = ran.vPos; - - if (eForm != GeomForm_Volume) - { - // Generate a random corner, for collapsing random point. - int nCorner = cry_random(0, 7); - ran.vNorm.x = (((nCorner & 1) << 1) - 1) * vSize.x; - ran.vNorm.y = (((nCorner & 2)) - 1) * vSize.y; - ran.vNorm.z = (((nCorner & 4) >> 1) - 1) * vSize.z; - - if (eForm == GeomForm_Vertices) - { - ran.vPos = ran.vNorm; - } - else if (eForm == GeomForm_Surface) - { - // Collapse one axis. - float fAxis = cry_random(0.0f, vSize.x * vSize.y + vSize.y * vSize.z + vSize.z * vSize.x); - if ((fAxis -= vSize.y * vSize.z) < 0.f) - { - ran.vPos.x = ran.vNorm.x; - ran.vNorm.y = ran.vNorm.z = 0.f; - } - else if ((fAxis -= vSize.z * vSize.x) < 0.f) - { - ran.vPos.y = ran.vNorm.y; - ran.vNorm.x = ran.vNorm.z = 0.f; - } - else - { - ran.vPos.z = ran.vNorm.z; - ran.vNorm.x = ran.vNorm.y = 0.f; - } - } - else if (eForm == GeomForm_Edges) - { - // Collapse 2 axes. - float fAxis = cry_random(0.0f, vSize.x + vSize.y + vSize.z); - if ((fAxis -= vSize.x) < 0.f) - { - ran.vPos.y = ran.vNorm.y; - ran.vPos.z = ran.vNorm.z; - ran.vNorm.x = 0.f; - } - else if ((fAxis -= vSize.y) < 0.f) - { - ran.vPos.x = ran.vNorm.x; - ran.vPos.z = ran.vNorm.z; - ran.vNorm.y = 0.f; - } - else - { - ran.vPos.x = ran.vNorm.x; - ran.vPos.y = ran.vNorm.y; - ran.vNorm.z = 0.f; - } - } - } - - ran.vNorm.Normalize(); -} - -inline float CircleExtent(EGeomForm eForm, float fRadius) -{ - switch (eForm) - { - case GeomForm_Edges: - return gf_PI2 * fRadius; - case GeomForm_Surface: - return gf_PI * square(fRadius); - default: - return 1.f; - } -} - -inline Vec2 CircleRandomPoint(EGeomForm eForm, float fRadius) -{ - Vec2 vPt; - switch (eForm) - { - case GeomForm_Edges: - // Generate random angle. - sincos_tpl(cry_random(0.0f, gf_PI2), &vPt.y, &vPt.x); - vPt *= fRadius; - break; - case GeomForm_Surface: - // Generate random angle, and radius, adjusted for even distribution. - sincos_tpl(cry_random(0.0f, gf_PI2), &vPt.y, &vPt.x); - vPt *= sqrt(cry_random(0.0f, 1.0f)) * fRadius; - break; - default: - vPt.x = vPt.y = 0.f; - } - return vPt; -} - -inline float SphereExtent(EGeomForm eForm, float fRadius) -{ - switch (eForm) - { - default: - assert(0); - case GeomForm_Vertices: - case GeomForm_Edges: - return 0.f; - case GeomForm_Surface: - return gf_PI * 4.f * sqr(fRadius); - case GeomForm_Volume: - return gf_PI * 4.f / 3.f * cube(fRadius); - } -} - -inline void SphereRandomPos(PosNorm& ran, EGeomForm eForm, float fRadius) -{ - switch (eForm) - { - default: - assert(0); - case GeomForm_Vertices: - case GeomForm_Edges: - ran.vPos.zero(); - ran.vNorm.zero(); - return; - case GeomForm_Surface: - case GeomForm_Volume: - { - // Generate point on surface, as normal. - float fPhi = cry_random(0.0f, gf_PI2); - float fZ = cry_random(-1.f, 1.f); - float fH = sqrt_tpl(1.f - fZ * fZ); - sincos_tpl(fPhi, &ran.vNorm.y, &ran.vNorm.x); - ran.vNorm.x *= fH; - ran.vNorm.y *= fH; - ran.vNorm.z = fZ; - - ran.vPos = ran.vNorm; - if (eForm == GeomForm_Volume) - { - float fV = cry_random(0.0f, 1.0f); - float fR = pow_tpl(fV, 0.333333f); - ran.vPos *= fR; - } - ran.vPos *= fRadius; - break; - } - } -} - -// Triangle randomisation functions - -inline float TriExtent(EGeomForm eForm, Vec3 const aPos[3]) -{ - switch (eForm) - { - default: - assert(0); - case GeomForm_Edges: - return (aPos[1] - aPos[0]).GetLengthFast(); - case GeomForm_Surface: - return ((aPos[1] - aPos[0]) % (aPos[2] - aPos[0])).GetLengthFast() * 0.5f; - case GeomForm_Volume: - // Generate signed volume of pyramid by computing triple product of vertices. - return ((aPos[0] ^ aPos[1]) | aPos[2]) / 6.0f; - } -} - -inline void TriRandomPos(PosNorm& ran, EGeomForm eForm, PosNorm const aRan[3], bool bDoNormals) -{ - // Generate interpolators for verts. - switch (eForm) - { - default: - assert(0); - case GeomForm_Vertices: - ran = aRan[0]; - return; - case GeomForm_Edges: - { - float t = cry_random(0.0f, 1.0f); - ran.vPos = aRan[0].vPos * (1.f - t) + aRan[1].vPos * t; - if (bDoNormals) - { - ran.vNorm = aRan[0].vNorm * (1.f - t) + aRan[1].vNorm * t; - } - break; - } - case GeomForm_Surface: - { - float t0 = cry_random(0.0f, 1.0f); - float t1 = cry_random(0.0f, 1.0f); - float t2 = cry_random(0.0f, 1.0f); - float fSum = t0 + t1 + t2; - ran.vPos = (aRan[0].vPos * t0 + aRan[1].vPos * t1 + aRan[2].vPos * t2) * (1.f / fSum); - if (bDoNormals) - { - ran.vNorm = aRan[0].vNorm * t0 + aRan[1].vNorm * t1 + aRan[2].vNorm * t2; - } - break; - } - case GeomForm_Volume: - { - float t0 = cry_random(0.0f, 1.0f); - float t1 = cry_random(0.0f, 1.0f); - float t2 = cry_random(0.0f, 1.0f); - float t3 = cry_random(0.0f, 1.0f); - float fSum = t0 + t1 + t2 + t3; - ran.vPos = (aRan[0].vPos * t0 + aRan[1].vPos * t1 + aRan[2].vPos * t2) * (1.f / fSum); - if (bDoNormals) - { - ran.vNorm = (aRan[0].vNorm * t0 + aRan[1].vNorm * t1 + aRan[2].vNorm * t2) * (1.f - t3) + ran.vPos.GetNormalizedFast() * t3; - } - break; - } - } - if (bDoNormals) - { - ran.vNorm.Normalize(); - } -} - -// Mesh random pos functions - -inline int TriMeshPartCount(EGeomForm eForm, int nIndices) -{ - switch (eForm) - { - default: - assert(0); - case GeomForm_Vertices: - case GeomForm_Edges: - // Number of edges = verts. - return nIndices; - case GeomForm_Surface: - case GeomForm_Volume: - // Number of tris. - assert(nIndices % 3 == 0); - return nIndices / 3; - } -} - -inline int TriIndices(int aIndices[3], int nPart, EGeomForm eForm) -{ - switch (eForm) - { - default: - assert(0); - case GeomForm_Vertices: // Part is vert index - aIndices[0] = nPart; - return 1; - case GeomForm_Edges: // Part is vert index - aIndices[0] = nPart; - aIndices[1] = nPart % 3 < 2 ? nPart + 1 : nPart - 2; - return 2; - case GeomForm_Surface: // Part is tri index - case GeomForm_Volume: - aIndices[0] = nPart * 3; - aIndices[1] = aIndices[0] + 1; - aIndices[2] = aIndices[0] + 2; - return 3; - } -} - - -#endif // CRYINCLUDE_CRYCOMMON_GEOMQUERY_H diff --git a/Code/CryEngine/CryCommon/HashGrid.h b/Code/CryEngine/CryCommon/HashGrid.h deleted file mode 100644 index 31534e9654..0000000000 --- a/Code/CryEngine/CryCommon/HashGrid.h +++ /dev/null @@ -1,617 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_HASHGRID_H -#define CRYINCLUDE_CRYCOMMON_HASHGRID_H -#pragma once - - - -template -struct hash_grid_2d -{ - typedef Key key_type; - typedef typename key_type::value_type key_value; - - typedef DiscreetKey discreet_type; - typedef typename discreet_type::value_type discreet_value; - - typedef hash_grid_2d type; - - hash_grid_2d(const key_value& cellSizeX, const key_value& cellSizeY, const key_value& cellSizeZ) - : scaleFactorX(1 / cellSizeX) - , scaleFactorY(1 / cellSizeY) - { - } - - inline discreet_type discreet(const key_type& key) const - { - return discreet_type(static_cast(key[0] * scaleFactorX), - static_cast(key[1] * scaleFactorY), - static_cast(0)); - } - - inline size_t hash(const key_type& key) const - { - return hash(discreet(key)); - } - - inline size_t hash(const discreet_type& discreet) const - { - return static_cast( - (discreet[0] ^ 920129341) + - (discreet[1] ^ 1926129311)); - } - - inline void swap(type& other) - { - std::swap(scaleFactorX, other.scaleFactorX); - std::swap(scaleFactorY, other.scaleFactorY); - } - -private: - key_value scaleFactorX; - key_value scaleFactorY; -}; - - -template -struct hash_grid_3d -{ - typedef Key key_type; - typedef typename key_type::value_type key_value; - - typedef DiscreetKey discreet_type; - typedef typename discreet_type::value_type discreet_value; - - typedef hash_grid_3d type; - - hash_grid_3d(const key_value& cellSizeX, const key_value& cellSizeY, const key_value& cellSizeZ) - : scaleFactorX(1 / cellSizeX) - , scaleFactorY(1 / cellSizeY) - , scaleFactorZ(1 / cellSizeZ) - { - } - - inline discreet_type discreet(const key_type& key) const - { - return discreet_type(static_cast(key[0] * scaleFactorX), - static_cast(key[1] * scaleFactorY), - static_cast(key[2] * scaleFactorZ)); - } - - inline size_t hash(const key_type& key) const - { - return hash(discreet(key)); - } - - inline size_t hash(const discreet_type& discreet) const - { - return static_cast( - (discreet[0] ^ 920129341ul) + - (discreet[1] ^ 1926129311ul) + - (discreet[2] ^ 3926129401ul)); - } - - inline void swap(type& other) - { - std::swap(scaleFactorX, other.scaleFactorX); - std::swap(scaleFactorY, other.scaleFactorY); - std::swap(scaleFactorZ, other.scaleFactorZ); - } - -private: - key_value scaleFactorX; - key_value scaleFactorY; - key_value scaleFactorZ; -}; - - -template -struct hash_grid_no_position -{ - KeyType operator()(const ValueType&) const - { - switch (0) - { - case 0: - "hash_grid query performed without a valid position-retriever implementation"; - } - ; - - return KeyType(); - } -}; - - -template > -class hash_grid - : protected KeyHash -{ -public: - enum - { - CellCount = NumberOfCells, - }; - - typedef ValueType value_type; - typedef KeyHash key_hash; - - typedef typename key_hash::key_type key_type; - typedef typename key_type::value_type key_value; - typedef typename key_hash::discreet_type discreet_type; - typedef typename discreet_type::value_type discreet_value; - - - typedef PositionRetriever position_retriever_type; - - typedef hash_grid type; - - typedef std::vector items_type; - - struct cell_type - { - cell_type() - : query(0) - { - } - - mutable uint32 query; - items_type items; - }; - typedef std::vector cells_type; - - inline hash_grid(float cellSizeX = 20.0f, float cellSizeY = 20.0f, float cellSizeZ = 20.0f, - const position_retriever_type& _position = position_retriever_type()) - : key_hash(cellSizeX, cellSizeY, cellSizeZ) - , position(_position) - , m_cells(CellCount) - , m_count(0) - , m_query(0) - { - } - - inline void clear() - { - m_cells.clear(); - m_cells.resize(CellCount); - m_count = 0; - m_query = 0; - } - - inline void swap(type& other) - { - m_cells.swap(other); - - std::swap(m_count, other.m_count); - key_hash::swap(other); - } - - inline size_t size() const - { - return m_count; - } - - inline bool empty() const - { - return m_count == 0; - } - - struct iterator - { - iterator() - : cell(~0u) - , item(~0u) - , grid(0) - { - } - - value_type& operator*() - { - return grid->m_cells[cell][item]; - } - - const value_type& operator*() const - { - return grid->m_cells[cell][item]; - } - - value_type* operator->() const - { - return (&**this); - } - - iterator& operator++() - { - assert(cell < grid_type::CellCount); - cell_type& items = grid->m_cells[cell]; - - if (!items.empty() && (item < items.size() - 1)) - { - ++item; - } - else - { - item = 0; - ++cell; - - while ((cell < type::CellCount) && grid->m_cells[cell].empty()) - { - ++cell; - } - } - - return *this; - } - - iterator operator++(int) - { - iterator tmp = *this; - ++*this; - return tmp; - } - - iterator& operator--() - { - if (item > 0) - { - --item; - } - else - { - --cell; - while ((cell > 0) && grid->m_cells[cell].empty()) - { - --cell; - } - - assert(cell < type::CellCount); - cell_type& items = grid->m_cells[cell]; - item = items.size() - 1; - } - - return *this; - } - - iterator operator--(int) - { - iterator tmp = *this; - ++*this; - return tmp; - } - - bool operator==(const iterator& other) const - { - return (cell == other.cell) && (item == other.item) && (grid == other.grid); - } - - bool operator!=(const iterator& other) const - { - return !(*this == other); - } - - private: - friend class hash_grid; - typedef hash_grid grid_type; - - iterator(size_t _cell, size_t _item, grid_type* _grid) - : grid(_grid) - , item(_item) - , cell(_cell) - { - } - - grid_type* grid; - size_t cell; - size_t item; - }; - - inline iterator begin() - { - uint32 item = 0; - uint32 cell = 0; - - while ((cell < type::CellCount) && m_cells[cell].empty()) - { - ++cell; - } - - return iterator(cell, item, this); - } - - inline iterator end() - { - return iterator(CellCount, 0, this); - } - - inline iterator insert(const key_type& key, const value_type& value) - { - size_t hash_value = KeyHash::hash(key); - size_t index = hash_value % CellCount; - - cell_type& cell = m_cells[index]; - items_type& items = cell.items; - - items.push_back(value); - ++m_count; - - return iterator(index, items.size() - 1, this); - } - - inline void erase(const key_type& key, const value_type& value) - { - size_t hash_value = KeyHash::hash(key); - size_t index = hash_value % CellCount; - - cell_type& cell = m_cells[index]; - items_type& items = cell.items; - - typename items_type::iterator it = items.begin(); - typename items_type::iterator end = items.end(); - - for (; it != end; ++it) - { - if (*it == value) - { - std::swap(*it, items.back()); - items.pop_back(); - --m_count; - return; - } - } - } - - inline iterator erase(const iterator& it) - { - --m_count; - cell_type& cell = m_cells[it.cell]; - items_type& items = cell.items; - std::swap(items[it.item], items.back()); - items.pop_back(); - if (!items.empty()) - { - return it; - } - - uint32 index = it.cell; - while ((index < CellCount) && m_cells[index].items.empty()) - { - ++index; - } - - return iterator(index, 0, this); - } - - inline iterator find(const key_type& key, const value_type& value) - { - size_t index = KeyHash::hash(key) % CellCount; - - cell_type& cell = m_cells[index]; - items_type& items = cell.items; - typename items_type::iterator it = items.begin(); - typename items_type::iterator iend = items.end(); - - for (; it != iend; ++it) - { - if (*it == value) - { - return iterator(index, it - items.begin(), this); - } - } - - return end(); - } - - inline iterator move(const iterator& it, const key_type& to) - { - size_t index = KeyHash::hash(to) % CellCount; - - if (index == it.cell) - { - return it; - } - - cell_type& cell = m_cells[it.cell]; - items_type& items = cell.items; - typename items_type::iterator iit = items.begin() + it.item; - - cell_type& to_cell = m_cells[index]; - items_type& to_items = to_cell.items; - to_items.push_back(*iit); - - std::swap(items[it.item], items.back()); - items.pop_back(); - - return iterator(index, to_items.size() - 1, this); - } - - template - uint32 query_sphere(const key_type& center, const key_value& radius, Container& container) const - { - uint32 count = 0; - - if (!empty()) - { - ++m_query; - - key_type minc(center - key_type(radius)); - key_type maxc(center + key_type(radius)); - - discreet_type mind = KeyHash::discreet(minc); - discreet_type maxd = KeyHash::discreet(maxc); - discreet_type current = mind; - - float radius_sq = radius * radius; - - for (; current[0] <= maxd[0]; ++current[0]) - { - for (; current[1] <= maxd[1]; ++current[1]) - { - for (; current[2] <= maxd[2]; ++current[2]) - { - size_t hash_value = KeyHash::hash(current); - size_t index = hash_value % CellCount; - - const cell_type& cell = m_cells[index]; - - if (cell.query != m_query) - { - cell.query = m_query; - const items_type& items = cell.items; - - typename items_type::const_iterator it = items.begin(); - typename items_type::const_iterator end = items.end(); - - for (; it != end; ++it) - { - if ((position(*it) - center).len2() <= radius_sq) - { - container.push_back(*it); - ++count; - } - } - } - } - current[2] = mind[2]; - } - current[1] = mind[1]; - } - } - - return count; - } - - template - uint32 query_sphere_distance(const key_type& center, const key_value& radius, Container& container) const - { - uint32 count = 0; - - if (!empty()) - { - ++m_query; - - key_type minc(center - key_type(radius)); - key_type maxc(center + key_type(radius)); - - discreet_type mind = KeyHash::discreet(minc); - discreet_type maxd = KeyHash::discreet(maxc); - discreet_type current = mind; - - float radius_sq = radius * radius; - - for (; current[0] <= maxd[0]; ++current[0]) - { - for (; current[1] <= maxd[1]; ++current[1]) - { - for (; current[2] <= maxd[2]; ++current[2]) - { - size_t hash_value = KeyHash::hash(current); - size_t index = hash_value % CellCount; - - const cell_type& cell = m_cells[index]; - - if (cell.query != m_query) - { - cell.query = m_query; - const items_type& items = cell.items; - - typename items_type::const_iterator it = items.begin(); - typename items_type::const_iterator end = items.end(); - - for (; it != end; ++it) - { - float distance_sq = (position(*it) - center).len2(); - if (distance_sq <= radius_sq) - { - container.push_back(std::make_pair(distance_sq, *it)); - ++count; - } - } - } - } - current[2] = mind[2]; - } - current[1] = mind[1]; - } - } - - return count; - } - - template - uint32 query_box(const key_type& minc, const key_type& maxc, Container& container) const - { - uint32 count = 0; - - if (!empty()) - { - ++m_query; - - discreet_type mind = KeyHash::discreet(minc); - discreet_type maxd = KeyHash::discreet(maxc); - discreet_type current = mind; - - for (; current[0] <= maxd[0]; ++current[0]) - { - for (; current[1] <= maxd[1]; ++current[1]) - { - for (; current[2] <= maxd[2]; ++current[2]) - { - size_t hash_value = KeyHash::hash(current); - size_t index = hash_value % CellCount; - - const cell_type& cell = m_cells[index]; - - if (cell.query != m_query) - { - cell.query = m_query; - const items_type& items = cell.items; - - typename items_type::const_iterator it = items.begin(); - typename items_type::const_iterator end = items.end(); - - for (; it != end; ++it) - { - key_type pos = position(*it); - - if (pos[0] >= minc[0] && - pos[1] >= minc[1] && - pos[2] >= minc[2] && - pos[0] <= maxc[0] && - pos[1] <= maxc[1] && - pos[2] <= maxc[2]) - { - container.push_back(*it); - ++count; - } - } - } - } - current[2] = mind[2]; - } - current[1] = mind[1]; - } - } - - return count; - } - -protected: - position_retriever_type position; - cells_type m_cells; - uint32 m_count; - mutable uint32 m_query; -}; - -#endif // CRYINCLUDE_CRYCOMMON_HASHGRID_H diff --git a/Code/CryEngine/CryCommon/HeapAllocator.h b/Code/CryEngine/CryCommon/HeapAllocator.h index c0001ea497..4dfd9f66ec 100644 --- a/Code/CryEngine/CryCommon/HeapAllocator.h +++ b/Code/CryEngine/CryCommon/HeapAllocator.h @@ -420,7 +420,6 @@ namespace stl { nInterval++; nCount = 0; - assert(CryMemory::IsHeapValid()); } #endif } diff --git a/Code/CryEngine/CryCommon/HeapContainer.h b/Code/CryEngine/CryCommon/HeapContainer.h deleted file mode 100644 index 553444fe5f..0000000000 --- a/Code/CryEngine/CryCommon/HeapContainer.h +++ /dev/null @@ -1,250 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Containers that use their own heap for allocation. - - -#ifndef CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H -#pragma once - -#include "PoolAllocator.h" - -//--------------------------------------------------------------------------- -template -struct HeapQueue - : public L -{ - typedef typename L::Lock Lock; - - HeapQueue() - { - reset(); - } - - T* push_back() - { - Lock lock(*this); - return push_back(m_Allocator.New()); - } - - template - T* push_back(I const& init) - { - Lock lock(*this); - Node* pNode = (Node*)m_Allocator.Allocate(); - new(static_cast(pNode))T(init); - return push_back(pNode); - } - - template - T* push_back(I const& i, J const& j) - { - Lock lock(*this); - Node* pNode = (Node*)m_Allocator.Allocate(); - new(static_cast(pNode))T(i, j); - return push_back(pNode); - } - - T* pop_front() - { - Lock lock(*this); - - // Quick check, before locking. - if (empty()) - { - return 0; - } - - Node* pNode = *m_ppHead; - if (pNode) - { - m_ppHead = &(*m_ppHead)->pNext; - m_nQueued--; - validate(); - } - return pNode; - } - - void clear() - { - Lock lock(*this); - - validate(); - - // Destruct all elements. - size_t nCheckAlloc = 0; - while (m_pList) - { - nCheckAlloc++; - Node* pNext = m_pList->pNext; - m_pList->~Node(); - m_pList = pNext; - } - assert(nCheckAlloc == m_nAlloc); - - // Empty queue structure. - reset(); - - // Free pool memory all at once. - m_Allocator.FreeMemory(false); - } - - size_t size() const - { - return m_nQueued; - } - - bool empty() const - { - return m_nQueued == 0; - } - - size_t allocated_memory() const - { - // Amortise allocated mem over all list instances. - Lock lock(*this); - return m_Allocator.GetTotalMemory().nAlloc; - } - - // Additional lock against storage deletion. - L ClearLock; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_Allocator); - } -protected: - - struct Node - : T - { - Node* pNext; - }; - - Node* m_pList; // First (allocated) node in list. - Node** m_ppHead; // Points to pointer to front of queue, for popping. - Node** m_ppTail; // Points to pointer at end of list, and of queue, for pushing. - size_t m_nAlloc, m_nQueued; - - void validate() - { - assert(m_nQueued <= m_nAlloc); - assert(m_ppHead); - assert(m_ppTail); - assert(!*m_ppTail); - assert((m_nQueued == 0) == !*m_ppHead); - assert((m_nQueued == 0) == (m_ppHead == m_ppTail)); - assert((m_nAlloc == 0) == (m_ppTail == &m_pList)); - assert((m_nAlloc == 0) == !m_pList); - } - - void reset() - { - m_pList = 0; - m_ppHead = m_ppTail = &m_pList; - m_nAlloc = m_nQueued = 0; - validate(); - } - - Node* push_back(Node* pNode) - { - pNode->pNext = 0; - - *m_ppTail = pNode; - m_ppTail = &pNode->pNext; - m_nAlloc++; - m_nQueued++; - - validate(); - - return pNode; - } - - // Allocate all elements from an exclusive pool. - // Any locking is performed by the queue, no further locking needed in allocator. - stl::TPoolAllocator m_Allocator; -}; - -//--------------------------------------------------------------------------- -template, typename L = stl::PSyncNone> -struct HeapPriorityQueue - : public HeapQueue -{ - // Hand-holding for brain-dead template compiler. - typedef HeapQueue super; - typedef typename super::Node Node; - using super::empty; - using super::validate; - using super::m_ppHead; - using super::m_ppTail; - using super::m_nQueued; - -public: - - typedef typename super::Lock Lock; - - // Pop the "largest" element, using class C. - T* pop_largest() - { - Lock lock(*this); - - if (!empty()) - { - C comp; - - // Find highest-valued item. - // To do: improve linear search! Use priority queue. - Node** ppTop = m_ppHead; - for (Node** ppNode = &(*m_ppHead)->pNext; *ppNode; ppNode = &(*ppNode)->pNext) - { - if (comp(**ppTop, **ppNode)) - { - ppTop = ppNode; - } - } - Node* pTop = *ppTop; - - // Move link to head. - if (ppTop != m_ppHead) - { - if (!pTop->pNext) - { - // End of list. - m_ppTail = ppTop; - } - *ppTop = pTop->pNext; - pTop->pNext = *m_ppHead; - *m_ppHead = pTop; - } - - // Pop head. - m_ppHead = &pTop->pNext; - m_nQueued--; - - validate(); - return pTop; - } - else - { - return NULL; - } - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - HeapQueue::GetMemoryUsage(pSizer); - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_HEAPCONTAINER_H diff --git a/Code/CryEngine/CryCommon/IChunkFile.h b/Code/CryEngine/CryCommon/IChunkFile.h deleted file mode 100644 index ce6a913863..0000000000 --- a/Code/CryEngine/CryCommon/IChunkFile.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H -#define CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H -#pragma once - - -#include "CryHeaders.h" - -////////////////////////////////////////////////////////////////////////// -// Description: -// Chunked File (.cgf, .chr etc.) interface -////////////////////////////////////////////////////////////////////////// -struct IChunkFile - : _reference_target_t -{ - ////////////////////////////////////////////////////////////////////////// - // Chunk Description. - ////////////////////////////////////////////////////////////////////////// - struct ChunkDesc - { - ChunkTypes chunkType; - int chunkVersion; - int chunkId; - uint32 fileOffset; - void* data; - uint32 size; - bool bSwapEndian; - - ////////////////////////////////////////////////////////////////////////// - ChunkDesc() - : chunkType(ChunkType_ANY) - , chunkVersion(0) - , chunkId(0) - , fileOffset(0) - , data(0) - , size(0) - , bSwapEndian(false) - { - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{ /*nothing*/} - - static inline bool LessOffset(const ChunkDesc& d1, const ChunkDesc& d2) { return d1.fileOffset < d2.fileOffset; } - static inline bool LessOffsetByPtr(const ChunkDesc* d1, const ChunkDesc* d2) { return d1->fileOffset < d2->fileOffset; } - static inline bool LessId(const ChunkDesc& d1, const ChunkDesc& d2) { return d1.chunkId < d2.chunkId; } - }; - - // - - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - - // Releases chunk file interface. - virtual void Release() = 0; - - virtual bool IsReadOnly() const = 0; - virtual bool IsLoaded() const = 0; - - virtual bool Read(const char* filename) = 0; - virtual bool ReadFromMemory(const void* pData, int nDataSize) = 0; - - // Writes chunks to file. - virtual bool Write(const char* filename) = 0; - // Writes chunks to a memory buffer (allocated inside) and returns - // pointer to the allocated memory (pData) and its size (nSize). - // The memory will be released on destruction of the ChunkFile object, or - // on the next WriteToMemoryBuffer() call, or on ReleaseMemoryBuffer() call. - virtual bool WriteToMemoryBuffer(void** pData, int* nSize) = 0; - // Releases memory that was allocated in WriteToMemoryBuffer() - virtual void ReleaseMemoryBuffer() = 0; - - // Adds chunk to file, returns ChunkID of the added chunk. - virtual int AddChunk(ChunkTypes chunkType, int chunkVersion, EEndianness eEndianness, const void* chunkData, int chunkSize) = 0; - virtual void DeleteChunkById(int nChunkId) = 0; - virtual void DeleteChunksByType(ChunkTypes nChunkType) = 0; - - virtual ChunkDesc* FindChunkByType(ChunkTypes nChunkType) = 0; - virtual ChunkDesc* FindChunkById(int nChunkId) = 0; - - // Gets the number of chunks. - virtual int NumChunks() const = 0; - - // Gets chunk description at i-th index. - virtual ChunkDesc* GetChunk(int nIndex) = 0; - virtual const ChunkDesc* GetChunk(int nIndex) const = 0; - - virtual const char* GetLastError() const = 0; - - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ICHUNKFILE_H diff --git a/Code/CryEngine/CryCommon/IColorGradingController.h b/Code/CryEngine/CryCommon/IColorGradingController.h deleted file mode 100644 index ee6db2375b..0000000000 --- a/Code/CryEngine/CryCommon/IColorGradingController.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H -#define CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H -#pragma once - - - -struct SColorChartLayer -{ - int m_texID; - float m_blendAmount; - - SColorChartLayer() - : m_texID(-1) - , m_blendAmount(-1) - { - } - - SColorChartLayer(int texID, float blendAmount) - : m_texID(texID) - , m_blendAmount(blendAmount) - { - } - - SColorChartLayer(const SColorChartLayer& rhs) - : m_texID(rhs.m_texID) - , m_blendAmount(rhs.m_blendAmount) - { - } -}; - - -struct IColorGradingController -{ -public: - // - virtual ~IColorGradingController(){} - virtual int LoadColorChart(const char* pChartFilePath) const = 0; - virtual int LoadDefaultColorChart() const = 0; - virtual void UnloadColorChart(int texID) const = 0; - - virtual void SetLayers(const SColorChartLayer* pLayers, uint32 numLayers) = 0; - // -}; - - -#endif // CRYINCLUDE_CRYCOMMON_ICOLORGRADINGCONTROLLER_H diff --git a/Code/CryEngine/CryCommon/ICryMiniGUI.h b/Code/CryEngine/CryCommon/ICryMiniGUI.h deleted file mode 100644 index 95db2e6518..0000000000 --- a/Code/CryEngine/CryCommon/ICryMiniGUI.h +++ /dev/null @@ -1,286 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Mini GUI subsystem - - -#ifndef CRYINCLUDE_CRYCOMMON_ICRYMINIGUI_H -#define CRYINCLUDE_CRYCOMMON_ICRYMINIGUI_H -#pragma once - - -#include -#include -#include - -namespace minigui -{ - struct IMiniCtrl; - - // Rectangle class - struct Rect - { - float left; - float top; - float right; - float bottom; - - Rect() - : left(0) - , top(0) - , right(0) - , bottom(0) {} - Rect(float l, float t, float r, float b) - : left(l) - , top(t) - , right(r) - , bottom(b) {} - Rect(const Rect& rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; } - bool IsPointInside(float x, float y) const { return x >= left && x <= right && y >= top && y <= bottom; } - float Width() const { return right - left; } - float Height() const { return bottom - top; } - }; - - typedef void(* ClickCallback)(void* data, bool onOff); - typedef void(* RenderCallback)(float x, float y); - - enum EMiniCtrlStatus - { - eCtrl_Hidden = BIT(0), // Control is hidden. - eCtrl_Highlight = BIT(1), // Control is highlight (probably mouse over). - eCtrl_Focus = BIT(2), // Control have focus (from keyboard). - eCtrl_Checked = BIT(3), // Control have checked mark. - eCtrl_NoBorder = BIT(4), // Control have no border. - eCtrl_CheckButton = BIT(5), // Button control behave as a check button. - eCtrl_TextAlignCentre = BIT(6), // Draw text aligned centre - eCtrl_AutoResize = BIT(7), // Auto resize depending on text length - eCtrl_Moveable = BIT(8), // Dynamically reposition ctrl - eCtrl_CloseButton = BIT(9), // Control has close button - }; - enum EMiniCtrlEvent - { - eCtrlEvent_LButtonDown = BIT(0), - eCtrlEvent_LButtonUp = BIT(1), - eCtrlEvent_LButtonPressed = BIT(2), - eCtrlEvent_MouseOver = BIT(3), - eCtrlEvent_MouseOff = BIT(4), - eCtrlEvent_DPadLeft = BIT(5), - eCtrlEvent_DPadRight = BIT(6), - eCtrlEvent_DPadUp = BIT(7), - eCtrlEvent_DPadDown = BIT(8), - }; - - // Types of the supported controls - enum EMiniCtrlType - { - eCtrlType_Unknown = 0, - eCtrlType_Button, - eCtrlType_Menu, - eCtrlType_InfoBox, - eCtrlType_Table, - }; - - struct SMetrics - { - float fTextSize; - float fTitleSize; - - // Colors. - ColorB clrFrameBorder; - ColorB clrFrameBorderHighlight; - ColorB clrFrameBorderOutOfFocus; - ColorB clrChecked; - ColorB clrBackground; - ColorB clrBackgroundHighlight; - ColorB clrBackgroundSelected; - ColorB clrTitle; - ColorB clrText; - ColorB clrTextSelected; - - uint8 outOfFocusAlpha; - }; - - enum ECommand - { - eCommand_ButtonPress, - eCommand_ButtonChecked, - eCommand_ButtonUnchecked, - }; - // Command sent from the control. - struct SCommand - { - ECommand command; - IMiniCtrl* pCtrl; - int nCtrlID; - }; - - ////////////////////////////////////////////////////////////////////////// - // Event listener interface for the MiniGUI - ////////////////////////////////////////////////////////////////////////// - struct IMiniGUIEventListener - { - // - virtual ~IMiniGUIEventListener(){} - virtual void OnCommand(SCommand& cmd) = 0; - // - }; - - // Interface to the GUI - struct IMiniGUI - : public ICryUnknown - { - public: - CRYINTERFACE_DECLARE(IMiniGUI, 0xea09d34268814f2a, 0xaf1034e04b076011); - - // - virtual void Init() = 0; - virtual void Done() = 0; - virtual void Draw() = 0; - virtual void Reset() = 0; - - virtual void SaveState() = 0; - virtual void RestoreState() = 0; - - virtual void SetEnabled(bool status) = 0; - virtual void SetInFocus(bool status) = 0; - virtual bool InFocus() = 0; - - virtual void SetEventListener(IMiniGUIEventListener* pListener) = 0; - - virtual SMetrics& Metrics() = 0; - - // Makes a new control - virtual IMiniCtrl* CreateCtrl(IMiniCtrl* pParentCtrl, int nCtrlID, EMiniCtrlType type, int nCtrlFlags, const Rect& rc, const char* title) = 0; - - // Remove all controls. - virtual void RemoveAllCtrl() = 0; - - virtual void OnCommand(SCommand& cmd) = 0; - - virtual IMiniCtrl* GetCtrlFromPoint(float x, float y) const = 0; - - virtual void SetMovingCtrl(IMiniCtrl* pCtrl) = 0; - // - }; - - DECLARE_SMART_POINTERS(IMiniGUI); - - struct IMiniCtrl - : public _reference_target_t - { - // - virtual void Reset() = 0; - - virtual void SaveState() = 0; - virtual void RestoreState() = 0; - - // For system call only. - virtual void SetGUI(IMiniGUI* pGUI) = 0; - virtual IMiniGUI* GetGUI() const = 0; - - virtual EMiniCtrlType GetType() const = 0; - - virtual int GetId() const = 0; - virtual void SetId(int id) = 0; - - virtual const char* GetTitle() const = 0; - virtual void SetTitle(const char* title) = 0; - - virtual Rect GetRect() const = 0; - virtual void SetRect(const Rect& rc) = 0; - - virtual void SetFlag(uint32 flag) = 0; - virtual void ClearFlag(uint32 flag) = 0; - virtual bool CheckFlag(uint32 flag) const = 0; - - // Sub Controls handling. - virtual void AddSubCtrl(IMiniCtrl* pCtrl) = 0; - virtual void RemoveSubCtrl(IMiniCtrl* pCtrl) = 0; - virtual void RemoveAllSubCtrl() = 0; - virtual int GetSubCtrlCount() const = 0; - virtual IMiniCtrl* GetSubCtrl(int nIndex) const = 0; - virtual IMiniCtrl* GetParent() const = 0; - - // Check if point is inside any of the sub controls. - virtual IMiniCtrl* GetCtrlFromPoint(float x, float y) = 0; - - virtual void OnPaint(class CDrawContext& dc) = 0; - - virtual void SetVisible(bool state) = 0; - - // Events from GUI - virtual void OnEvent([[maybe_unused]] float x, [[maybe_unused]] float y, EMiniCtrlEvent) {}; - - ////////////////////////////////////////////////////////////////////////// - // When set, this control will be enabling/disabling specified cvar - // when button not checked fOffValue will be set on cvar, when checked fOnValue will be set. - virtual bool SetControlCVar(const char* sCVarName, float fOffValue, float fOnValue) = 0; - - virtual bool SetClickCallback(ClickCallback callback, void* pCallbackData) = 0; - - virtual bool SetRenderCallback(RenderCallback callback) = 0; - - virtual bool SetConnectedCtrl(IMiniCtrl* pConnectedCtrl) = 0; - - //resize text box based what text is present - virtual void AutoResize() = 0; - - //Create close 'X' button for control - virtual void CreateCloseButton() = 0; - - //Move control - virtual void Move(float x, float y) = 0; - // - }; - typedef _smart_ptr IMiniCtrlPtr; - - class IMiniGuiCommon - { - public: - // - virtual ~IMiniGuiCommon(){} - virtual bool IsHidden() = 0; - virtual void Hide(bool stat) = 0; - // - }; - - class IMiniTable - : public IMiniGuiCommon - { - public: - // - virtual int AddColumn(const char* name) = 0; - virtual void RemoveColumns() = 0; - virtual int AddData(int columnIndex, ColorB col, const char* format, ...) = 0; - virtual void ClearTable() = 0; - // - }; - - class IMiniInfoBox - : public IMiniGuiCommon - { - public: - // - virtual void SetTextIndent(float x) = 0; - virtual void SetTextSize(float sz) = 0; - virtual void ClearEntries() = 0; - virtual void AddEntry(const char* str, ColorB col, float textSize) = 0; - // - }; -} - - -#define MINIGUI_BEGIN namespace minigui { -#define MINIGUI_END } - -#endif // CRYINCLUDE_CRYCOMMON_ICRYMINIGUI_H diff --git a/Code/CryEngine/CryCommon/IDeferredCollisionEvent.h b/Code/CryEngine/CryCommon/IDeferredCollisionEvent.h deleted file mode 100644 index 2dee198d0a..0000000000 --- a/Code/CryEngine/CryCommon/IDeferredCollisionEvent.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IDEFERREDCOLLISIONEVENT_H -#define CRYINCLUDE_CRYCOMMON_IDEFERREDCOLLISIONEVENT_H -#pragma once - - -#include - -struct EventPhys; - -// Base class for all deferred physics events -// Basically this class works like a future, -// Start() start the computation(some in the main thread, major part in a task/job) -// Result() will sync the task operation and return the result -struct IDeferredPhysicsEvent - : public IThreadTask -{ - // enum list of all types of deferred events - enum DeferredEventType - { - PhysCallBack_OnCollision - }; - - IDeferredPhysicsEvent(){} - // - virtual ~IDeferredPhysicsEvent(){} - - // == "future" like interface == // - - // start the execution of the event - virtual void Start() = 0; - - // sync the event and do all necessary post-processing, then return the result - virtual int Result(EventPhys* pOrigEvent = 0) = 0; - - // just wait for the event to finish - virtual void Sync() = 0; - - // check if the async computation part has finished - virtual bool HasFinished() = 0; - - // Get the concrete Type of this deferred event - virtual DeferredEventType GetType() const = 0; - - // returns a ptr to the original physics event - virtual EventPhys* PhysicsEvent() = 0; - // -}; - - -// Manager class for deferred physics events -struct IDeferredPhysicsEventManager -{ - // type of create function used to create needed deferred events in the HandleEvent function - typedef IDeferredPhysicsEvent*(* CreateEventFunc)(const EventPhys* pEvent); - - IDeferredPhysicsEventManager(){} - // - virtual ~IDeferredPhysicsEventManager(){} - - // dispatch an deferred event to the task thread - virtual void DispatchDeferredEvent(IDeferredPhysicsEvent* pEvent) = 0; - - // Encapsulates common logic for deferred events, should be called from the physics callbacks - // handles the cvar management as well as deferred event creating - virtual int HandleEvent(const EventPhys* pEvent, IDeferredPhysicsEventManager::CreateEventFunc, IDeferredPhysicsEvent::DeferredEventType) = 0; - - // Register and Unregister Deferred events in the manager to allow - virtual void RegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent) = 0; - virtual void UnRegisterDeferredEvent(IDeferredPhysicsEvent* pDeferredEvent) = 0; - - // Delete all Deferred Events in flight, use only when also clearing the physics event queue - // or else this call results in dangling points, mostly used for save/load - virtual void ClearDeferredEvents() = 0; - - virtual void Update() = 0; - - virtual IDeferredPhysicsEvent* GetLastCollisionEventForEntity(IPhysicalEntity* pPhysEnt) = 0; - // -}; - - -#endif // CRYINCLUDE_CRYCOMMON_IDEFERREDCOLLISIONEVENT_H diff --git a/Code/CryEngine/CryCommon/IDefragAllocator.h b/Code/CryEngine/CryCommon/IDefragAllocator.h deleted file mode 100644 index a415b3af67..0000000000 --- a/Code/CryEngine/CryCommon/IDefragAllocator.h +++ /dev/null @@ -1,155 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IDEFRAGALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_IDEFRAGALLOCATOR_H -#pragma once - - -struct IDefragAllocatorStats -{ - size_t nCapacity; - size_t nInUseSize; - uint32 nInUseBlocks; - uint32 nFreeBlocks; - uint32 nPinnedBlocks; - uint32 nMovingBlocks; - uint32 nLargestFreeBlockSize; - uint32 nSmallestFreeBlockSize; - uint32 nMeanFreeBlockSize; - uint32 nCancelledMoveCount; -}; - -struct IDefragAllocatorCopyNotification -{ - IDefragAllocatorCopyNotification() - : bDstIsValid(false) - , bSrcIsUnneeded(false) - , bCancel(false) - { - } - - bool bDstIsValid; - bool bSrcIsUnneeded; - - // Flag to indicate that the copy can't be initiated after all - currently only cancelling before a relocate - // is begun is supported, and the destination region must be stable - bool bCancel; -}; - -class IDefragAllocatorPolicy -{ -public: - enum - { - InvalidUserMoveId = 0xffffffff - }; - -public: - // - virtual uint32 BeginCopy(void* pContext, UINT_PTR dstOffset, UINT_PTR srcOffset, UINT_PTR size, IDefragAllocatorCopyNotification* pNotification) = 0; - virtual void Relocate(uint32 userMoveId, void* pContext, UINT_PTR newOffset, UINT_PTR oldOffset, UINT_PTR size) = 0; - virtual void CancelCopy(uint32 userMoveId, void* pContext, bool bSync) = 0; - - // Perform the copy and relocate immediately - will only be called when UnAppendSegment is - virtual void SyncCopy(void* pContext, UINT_PTR dstOffset, UINT_PTR srcOffset, UINT_PTR size) = 0; - // - -protected: - virtual ~IDefragAllocatorPolicy() {} -}; - -class IDefragAllocator -{ -public: - typedef uint32 Hdl; - enum - { - InvalidHdl = 0, - }; - - struct AllocatePinnedResult - { - Hdl hdl; - UINT_PTR offs; - UINT_PTR usableSize; - }; - - enum EBlockSearchKind - { - eBSK_BestFit, - eBSK_FirstFit - }; - - struct Policy - { - Policy() - : pDefragPolicy(NULL) - , maxAllocs(0) - , maxSegments(1) - , blockSearchKind(eBSK_BestFit) - { - } - - IDefragAllocatorPolicy* pDefragPolicy; - size_t maxAllocs; - size_t maxSegments; - EBlockSearchKind blockSearchKind; - }; - -public: - // - virtual void Release(bool bDiscard = false) = 0; - - virtual void Init(UINT_PTR capacity, UINT_PTR alignment, const Policy& policy = Policy()) = 0; - - virtual bool AppendSegment(UINT_PTR capacity) = 0; - virtual void UnAppendSegment() = 0; - - virtual Hdl Allocate(size_t sz, const char* source, void* pContext = NULL) = 0; - virtual Hdl AllocateAligned(size_t sz, size_t alignment, const char* source, void* pContext = NULL) = 0; - virtual AllocatePinnedResult AllocatePinned(size_t sz, const char* source, void* pContext = NULL) = 0; - virtual bool Free(Hdl hdl) = 0; - - virtual void ChangeContext(Hdl hdl, void* pNewContext) = 0; - - virtual size_t GetAllocated() const = 0; - virtual IDefragAllocatorStats GetStats() = 0; - - virtual void DisplayMemoryUsage(const char* title, unsigned int allocatorDisplayOffset = 0) = 0; - - virtual size_t DefragmentTick(size_t maxMoves, size_t maxAmount, bool bForce = false) = 0; - - virtual UINT_PTR UsableSize(Hdl hdl) = 0; - - // Pin the chunk until the next defrag tick, when it will be automatically unpinned - virtual UINT_PTR WeakPin(Hdl hdl) = 0; - - // Pin the chunk until Unpin is called - virtual UINT_PTR Pin(Hdl hdl) = 0; - - virtual void Unpin(Hdl hdl) = 0; - - virtual const char* GetSourceOf(Hdl hdl) = 0; - // - -#ifndef _RELEASE - virtual void DumpState(const char* filename) = 0; - virtual void RestoreState(const char* filename) = 0; -#endif - -protected: - virtual ~IDefragAllocator() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IDEFRAGALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/IEngineModule.h b/Code/CryEngine/CryCommon/IEngineModule.h deleted file mode 100644 index 7835cde26e..0000000000 --- a/Code/CryEngine/CryCommon/IEngineModule.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Defines the extension interface for the CryEngine modules. - - -#ifndef CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H -#define CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H -#pragma once - -#include -#include -#include -#include - -struct SSystemInitParams; - -// Base Interface for all engine module extensions -struct IEngineModule - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IEngineModule, 0xf899cf661df04f61, 0xa341a8a7ffdf9de4); - - // - // Retrieve name of the extension module. - virtual const char* GetName() const = 0; - - // Retrieve category for the extension module (CryEngine for standard modules). - virtual const char* GetCategory() const = 0; - - // This is called to initialize the new module. - virtual bool Initialize(SSystemGlobalEnvironment& env, const SSystemInitParams& initParams) = 0; - // - - // This is called to register any AZ console vars declared within this engine module - virtual void RegisterConsoleVars() - { - AZ::ConsoleFunctorBase*& deferredHead = AZ::ConsoleFunctorBase::GetDeferredHead(); - AZ::Interface::Get()->LinkDeferredFunctors(deferredHead); - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H diff --git a/Code/CryEngine/CryCommon/IEntityRenderState.h b/Code/CryEngine/CryCommon/IEntityRenderState.h index 29b1bdc463..be26225226 100644 --- a/Code/CryEngine/CryCommon/IEntityRenderState.h +++ b/Code/CryEngine/CryCommon/IEntityRenderState.h @@ -27,7 +27,6 @@ namespace AZ struct IMaterial; struct IVisArea; struct SRenderingPassInfo; -struct IGeomCache; struct SRendItemSorter; struct SFrameLodInfo; struct pe_params_area; @@ -259,9 +258,6 @@ struct IRenderNode virtual struct IStatObj* GetEntityStatObj(unsigned int nPartId = 0, unsigned int nSubPartId = 0, Matrix34A* pMatrix = NULL, bool bReturnOnlyVisible = false); virtual _smart_ptr GetEntitySlotMaterial([[maybe_unused]] unsigned int nPartId, [[maybe_unused]] bool bReturnOnlyVisible = false, [[maybe_unused]] bool* pbDrawNear = NULL) { return NULL; } virtual void SetEntityStatObj([[maybe_unused]] unsigned int nSlot, [[maybe_unused]] IStatObj* pStatObj, [[maybe_unused]] const Matrix34A* pMatrix = NULL) {}; -#if defined(USE_GEOM_CACHES) - virtual struct IGeomCacheRenderNode* GetGeomCacheRenderNode([[maybe_unused]] unsigned int nSlot, [[maybe_unused]] Matrix34A* pMatrix = NULL, [[maybe_unused]] bool bReturnOnlyVisible = false) { return NULL; } -#endif virtual int GetSlotCount() const { return 1; } // Summary: @@ -572,7 +568,6 @@ struct IVoxelObject : public IRenderNode { // - virtual struct IMemoryBlock* GetCompiledData(EEndian eEndian) = 0; virtual void SetCompiledData(void* pData, int nSize, uint8 ucChildId, EEndian eEndian) = 0; virtual void SetObjectName(const char* pName) = 0; virtual void SetMatrix(const Matrix34& mat) = 0; @@ -794,81 +789,4 @@ struct IPrismRenderNode }; #endif // EXCLUDE_DOCUMENTATION_PURPOSE -////////////////////////////////////////////////////////////////////////// - -#if defined(USE_GEOM_CACHES) -struct IGeomCacheRenderNode - : public IRenderNode -{ - virtual bool LoadGeomCache(const char* sGeomCacheFileName) = 0; - - virtual void SetGeomCache(_smart_ptr geomCache) = 0; - - // Gets the geometry cache that is rendered - virtual IGeomCache* GetGeomCache() const = 0; - - // Sets the time in the animation for the current frame. - // Note that you should start streaming before calling this. - virtual void SetPlaybackTime(const float time) = 0; - - // Get the current playback time - virtual float GetPlaybackTime() const = 0; - - // Check if cache is streaming. - virtual bool IsStreaming() const = 0; - - // Need to start streaming before playback, otherwise there will be stalls. - virtual void StartStreaming(const float time = 0.0f) = 0; - - // Stops streaming and trashes the buffers - virtual void StopStreaming() = 0; - - // Checks if looping is enabled - virtual bool IsLooping() const = 0; - - // Enable/disable looping playback - virtual void SetLooping(const bool bEnable) = 0; - - // Gets time delta from current playback position to last ready to play frame - virtual float GetPrecachedTime() const = 0; - - // Check if bounds changed since last call to this function - virtual bool DidBoundsChange() = 0; - - // Set stand in CGFs and distance - virtual void SetStandIn(const char* pFilePath, const char* pMaterial) = 0; - virtual IStatObj* GetStandIn() = 0; - virtual void SetFirstFrameStandIn(const char* pFilePath, const char* pMaterial) = 0; - virtual IStatObj* GetFirstFrameStandIn() = 0; - virtual void SetLastFrameStandIn(const char* pFilePath, const char* pMaterial) = 0; - virtual IStatObj* GetLastFrameStandIn() = 0; - virtual void SetStandInDistance(const float distance) = 0; - virtual float GetStandInDistance() = 0; - - // Set distance at which cache will start streaming automatically (0 means no auto streaming) - virtual void SetStreamInDistance(const float distance) = 0; - virtual float GetStreamInDistance() = 0; - - // Start/Stop drawing the cache - virtual void SetDrawing(bool bDrawing) = 0; - - // Debug draw geometry - virtual void DebugDraw(const struct SGeometryDebugDrawInfo& info, float fExtrudeScale = 0.01f, uint nodeIndex = 0) const = 0; - - // Ray intersection against cache - virtual bool RayIntersection(struct SRayHitInfo& hitInfo, _smart_ptr pCustomMtl = NULL, uint* pHitNodeIndex = NULL) const = 0; - - // Set max view distance - virtual void SetBaseMaxViewDistance(float maxViewDistance) = 0; - - // Get node information - virtual uint GetNodeCount() const = 0; - virtual Matrix34 GetNodeTransform(const uint nodeIndex) const = 0; - virtual const char* GetNodeName(const uint nodeIndex) const = 0; // Node name is only stored in editor - virtual uint32 GetNodeNameHash(const uint nodeIndex) const = 0; - virtual bool IsNodeDataValid(const uint nodeIndex) const = 0; // Returns false if cache isn't loaded yet or index is out of range - -}; -#endif - #endif // CRYINCLUDE_CRYCOMMON_IENTITYRENDERSTATE_H diff --git a/Code/CryEngine/CryCommon/IFileChangeMonitor.h b/Code/CryEngine/CryCommon/IFileChangeMonitor.h deleted file mode 100644 index 4ad46852ed..0000000000 --- a/Code/CryEngine/CryCommon/IFileChangeMonitor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IFILECHANGEMONITOR_H -#define CRYINCLUDE_CRYCOMMON_IFILECHANGEMONITOR_H -#pragma once - -struct IFileChangeListener -{ - enum EChangeType - { - //! error or unknown change type - eChangeType_Unknown, - //! the file was created - eChangeType_Created, - //! the file was deleted - eChangeType_Deleted, - //! the file was modified (size changed,write) - eChangeType_Modified, - //! this is the old name of a renamed file - eChangeType_RenamedOldName, - //! this is the new name of a renamed file - eChangeType_RenamedNewName - }; - - virtual ~IFileChangeListener() = default; - - virtual void OnFileChange(const char* sFilename, EChangeType eType) = 0; -}; - -struct IFileChangeMonitor -{ - virtual ~IFileChangeMonitor() = default; - - // - // Register the path of a file or directory to monitor - // Path is relative to game directory, e.g. "Libs/WoundSystem/" or "Libs/WoundSystem/HitLocations.xml" - virtual bool RegisterListener(IFileChangeListener* pListener, const char* sMonitorItem) = 0; - // This function can be used to monitor files of specific type, e.g. - // RegisterListener(pListener, "Animations", "caf") - virtual bool RegisterListener(IFileChangeListener* pListener, const char* sFolder, const char* sExtension) = 0; - virtual bool UnregisterListener(IFileChangeListener* pListener) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IFILECHANGEMONITOR_H diff --git a/Code/CryEngine/CryCommon/IFlares.h b/Code/CryEngine/CryCommon/IFlares.h deleted file mode 100644 index d1626a83d9..0000000000 --- a/Code/CryEngine/CryCommon/IFlares.h +++ /dev/null @@ -1,228 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IFLARES_H -#define CRYINCLUDE_CRYCOMMON_IFLARES_H -#pragma once - -#include // <> required for Interfuscator -#include // <> required for Interfuscator -#include "smartptr.h" - -struct IShader; -class CCamera; - -class __MFPA -{ -}; -class __MFPB -{ -}; -#define MFP_SIZE_ENFORCE : public __MFPA, public __MFPB - -enum EFlareType -{ - eFT__Base__, - eFT_Root, - eFT_Group, - eFT_Ghost, - eFT_MultiGhosts, - eFT_Glow, - eFT_ChromaticRing, - eFT_IrisShafts, - eFT_CameraOrbs, - eFT_ImageSpaceShafts, - eFT_Streaks, - eFT_Reference, - eFT_Proxy, - eFT_Max -}; - -#define FLARE_LIBS_PATH "libs/flares/" -#define FLARE_EXPORT_FILE "LensFlareList.xml" -#define FLARE_EXPORT_FILE_VERSION "1" - -struct FlareInfo -{ - EFlareType type; - const char* name; -#if defined(FLARES_SUPPORT_EDITING) - const char* imagename; -#endif -}; - -#if defined(FLARES_SUPPORT_EDITING) -# define ADD_FLARE_INFO(type, name, imagename) {type, name, imagename} -#else -# define ADD_FLARE_INFO(type, name, imagename) {type, name} -#endif - -class FlareInfoArray -{ -public: - struct Props - { - const FlareInfo* p; - size_t size; - }; - - static const Props Get() - { - static const FlareInfo flareInfoArray[] = - { - ADD_FLARE_INFO(eFT__Base__, "__Base__", NULL), - ADD_FLARE_INFO(eFT_Root, "Root", NULL), - ADD_FLARE_INFO(eFT_Group, "Group", NULL), - ADD_FLARE_INFO(eFT_Ghost, "Ghost", "EngineAssets/Textures/flares/icons/ghost.dds"), - ADD_FLARE_INFO(eFT_MultiGhosts, "Multi Ghost", "EngineAssets/Textures/flares/icons/multi_ghost.dds"), - ADD_FLARE_INFO(eFT_Glow, "Glow", "EngineAssets/Textures/flares/icons/glow.dds"), - ADD_FLARE_INFO(eFT_ChromaticRing, "ChromaticRing", "EngineAssets/Textures/flares/icons/ring.dds"), - ADD_FLARE_INFO(eFT_IrisShafts, "IrisShafts", "EngineAssets/Textures/flares/icons/iris_shafts.dds"), - ADD_FLARE_INFO(eFT_CameraOrbs, "CameraOrbs", "EngineAssets/Textures/flares/icons/orbs.dds"), - ADD_FLARE_INFO(eFT_ImageSpaceShafts, "Vol Shafts", "EngineAssets/Textures/flares/icons/vol_shafts.dds"), - ADD_FLARE_INFO(eFT_Streaks, "Streaks", "EngineAssets/Textures/flares/icons/iris_shafts.dds") - }; - - Props ret; - ret.p = flareInfoArray; - ret.size = sizeof(flareInfoArray) / sizeof(flareInfoArray[0]); - return ret; - } - -private: - FlareInfoArray(); - ~FlareInfoArray(); -}; - -struct SLensFlareRenderParam -{ - SLensFlareRenderParam() - : pCamera(NULL) - , pShader(NULL) - { - } - ~SLensFlareRenderParam(){} - bool IsValid() const - { - return pCamera && pShader; - } - CCamera* pCamera; - IShader* pShader; -}; - -class ISoftOcclusionQuery -{ -public: - // - virtual ~ISoftOcclusionQuery() {} - - virtual void AddRef() = 0; - virtual void Release() = 0; - // -}; - -class IOpticsElementBase MFP_SIZE_ENFORCE -{ -public: - - IOpticsElementBase() - : m_nRefCount(0) - { - } - void AddRef() - { - CryInterlockedIncrement(&m_nRefCount); - } - void Release() - { - if (CryInterlockedDecrement(&m_nRefCount) <= 0) - { - delete this; - } - } - - // - virtual EFlareType GetType() = 0; - virtual bool IsGroup() const = 0; - virtual string GetName() const = 0; - virtual void SetName(const char* ch_name) = 0; - virtual void Load(IXmlNode* pNode) = 0; - - virtual IOpticsElementBase* GetParent() const = 0; - virtual ~IOpticsElementBase() { - } - - virtual bool IsEnabled() const = 0; - - virtual void AddElement(IOpticsElementBase* pElement) = 0; - virtual void InsertElement(int nPos, IOpticsElementBase* pElement) = 0; - virtual void Remove(int i) = 0; - virtual void RemoveAll() = 0; - virtual int GetElementCount() const = 0; - virtual IOpticsElementBase* GetElementAt(int i) const = 0; - - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - virtual void Invalidate() = 0; - - virtual void Render(SLensFlareRenderParam* pParam, const Vec3& vPos) = 0; - - virtual void SetOpticsReference([[maybe_unused]] IOpticsElementBase* pReference) {} - virtual IOpticsElementBase* GetOpticsReference() const { return NULL; } - // - -#if defined(FLARES_SUPPORT_EDITING) - virtual AZStd::vector GetEditorParamGroups() = 0; -#endif - - ///Basic Setters/////////////////////////////////////////////////////////////// - virtual void SetEnabled(bool enabled) { (void)enabled; } - virtual void SetSize(float size) { (void)size; } - virtual void SetPerspectiveFactor(float perspectiveFactor) { (void)perspectiveFactor; } - virtual void SetDistanceFadingFactor(float distanceFadingFactor) { (void)distanceFadingFactor; } - virtual void SetBrightness(float brightness) { (void)brightness; } - virtual void SetColor(ColorF color) { (void)color; } - virtual void SetMovement(Vec2 movement) { (void)movement; } - virtual void SetTransform(const Matrix33& xform) { (void)xform; } - virtual void SetOccBokehEnabled(bool occBokehEnabled) { (void)occBokehEnabled; } - virtual void SetOrbitAngle(float orbitAngle) { (void)orbitAngle; } - virtual void SetSensorSizeFactor(float sizeFactor) { (void)sizeFactor; } - virtual void SetSensorBrightnessFactor(float brightnessFactor) { (void)brightnessFactor; } - virtual void SetAutoRotation(bool autoRotation) { (void)autoRotation; } - virtual void SetAspectRatioCorrection(bool aspectRatioCorrection) { (void)aspectRatioCorrection; } - //////////////////////////////////////////////////////////////////////////////// - -private: - - volatile int m_nRefCount; -}; - -class IOpticsManager -{ -public: - // - virtual ~IOpticsManager(){} - virtual void Reset() = 0; - virtual IOpticsElementBase* Create(EFlareType type) const = 0; - virtual bool Load(const char* fullFlareName, int& nOutIndex, bool forceReload = false) = 0; - virtual bool Load(XmlNodeRef& rootNode, int& nOutIndex) = 0; - virtual IOpticsElementBase* GetOptics(int nIndex) = 0; - virtual bool AddOptics(IOpticsElementBase* pOptics, const char* name, int& nOutNewIndex, bool allowReplace = false) = 0; - virtual bool Rename(const char* fullFlareName, const char* newFullFlareName) = 0; - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - virtual void Invalidate() = 0; - // -}; - -typedef _smart_ptr IOpticsElementBasePtr; - -#endif // CRYINCLUDE_CRYCOMMON_IFLARES_H diff --git a/Code/CryEngine/CryCommon/IFont.h b/Code/CryEngine/CryCommon/IFont.h index c8634fa854..7e2a3480b1 100644 --- a/Code/CryEngine/CryCommon/IFont.h +++ b/Code/CryEngine/CryCommon/IFont.h @@ -33,8 +33,6 @@ struct ICryFont; struct IFFont; struct FontFamily; -struct IRenderer; - struct SVF_P2F_C4B_T2F_F4B; extern "C" @@ -100,9 +98,6 @@ struct ICryFont //! \param glyphSizeY Height (in pixels) of the characters to be rendered at in the font texture. virtual void AddCharsToFontTextures(FontFamilyPtr pFontFamily, const char* pChars, int glyphSizeX = defaultGlyphSizeX, int glyphSizeY = defaultGlyphSizeY) = 0; - // Summary: - // Globally sets common font render properties based on the initialized renderer - virtual void SetRendererProperties(IRenderer* pRenderer) = 0; // Summary: // Puts the objects used in this module into the sizer interface virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; @@ -150,6 +145,7 @@ struct STextDrawContext Vec2 m_size; Vec2i m_requestSize; float m_widthScale; + float m_lineSpacing; float m_clipX; float m_clipY; @@ -180,6 +176,7 @@ struct STextDrawContext , m_size(16.0f, 16.0f) , m_requestSize(static_cast(m_size.x), static_cast(m_size.y)) , m_widthScale(1.0f) + , m_lineSpacing(0.f) , m_clipX(0) , m_clipY(0) , m_clipWidth(0) @@ -214,11 +211,13 @@ struct STextDrawContext void SetTransform(const Matrix34& transform) { m_transform = transform; } void SetBaseState(int baseState) { m_baseState = baseState; } void SetOverrideViewProjMatrices(bool overrideViewProjMatrices) { m_overrideViewProjMatrices = overrideViewProjMatrices; } + void SetLineSpacing(float lineSpacing) { m_lineSpacing = lineSpacing; } float GetCharWidth() const { return m_size.x; } float GetCharHeight() const { return m_size.y; } float GetCharWidthScale() const { return m_widthScale; } int GetFlags() const { return m_drawTextFlags; } + float GetLineSpacing() const { return m_lineSpacing; } bool IsColorOverridden() const { return m_colorOverride.a != 0; } }; diff --git a/Code/CryEngine/CryCommon/IFuncVariable.h b/Code/CryEngine/CryCommon/IFuncVariable.h deleted file mode 100644 index 351a67daff..0000000000 --- a/Code/CryEngine/CryCommon/IFuncVariable.h +++ /dev/null @@ -1,268 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H -#define CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H -#pragma once - -#include "Cry_Vector2.h" -#include "Cry_Vector3.h" -#include "Cry_Matrix33.h" -#include "Cry_Color.h" -#include "smartptr.h" -#include "StringUtils.h" - -class ITexture; - -enum FuncParamType -{ - e_FLOAT, e_INT, e_BOOL, e_VEC2, e_VEC3, e_VEC4, e_COLOR, e_MATRIX33, - // Though all types of textures are using the same class, it's important for editor to differentiate between them: - e_TEXTURE2D, e_TEXTURE3D, e_TEXTURE_CUBE -}; - -class IFuncVariable - : public _reference_target_t -{ -public: - // - virtual ~IFuncVariable(){}; - - virtual float GetMin() const = 0; - virtual float GetMax() const = 0; - - virtual void InvokeSetter(void* param) = 0; - - virtual int GetInt() const = 0; - virtual float GetFloat() const = 0; - virtual bool GetBool() const = 0; - virtual Vec2 GetVec2() const = 0; - virtual Vec3 GetVec3() const = 0; - virtual Vec4 GetVec4() const = 0; - virtual ColorF GetColorF() const = 0; - virtual Matrix33 GetMatrix33() const = 0; - virtual ITexture* GetTexture() const = 0; - // - - enum FuncParamType paramType; // float, string, int, vec3 etc - string name; -#if defined(FLARES_SUPPORT_EDITING) - string humanName; - string description; -#endif -}; - -template -class MFPVariable - : public IFuncVariable -{ -public: - typedef void (T::* OpticsBase_MFPtr)(); - OpticsBase_MFPtr pSetter; - OpticsBase_MFPtr pGetter; - T* pObj; - std::pair range; - -private: - MFPVariable () - { - Set(e_INT, "", "", NULL, NULL, NULL); - } - -public: - - float GetMin() const override { return range.first; } - float GetMax() const override { return range.second; } - - MFPVariable(FuncParamType type, const char* _humanname, const char* _description, T* obj, OpticsBase_MFPtr setter, OpticsBase_MFPtr getter, float fMin = 0, float fMax = 1.0f) - { - Set(type, _humanname, _description, obj, setter, getter, fMin, fMax); - } - - void Set(FuncParamType type, const char* _humanname, const char* _description, T* obj, OpticsBase_MFPtr setter, OpticsBase_MFPtr getter, float fMin = 0, float fMax = 1.0f) - { - paramType = type; - - char _nameNoSpace[50]; - cry_strcpy(_nameNoSpace, _humanname); - char* p1 = _nameNoSpace; - char* p2 = p1; - while (*p1 != 0) - { - if ((*p1) == ' ') - { - ++p1; - } - else - { - *p2++ = *p1++; - } - } - - *p2 = 0; - name = _nameNoSpace; - -#if defined(FLARES_SUPPORT_EDITING) - humanName = _humanname; - description = _description; -#endif - - pObj = obj; - pSetter = setter; - pGetter = getter; - range.first = fMin; - range.second = fMax; - } - - #define INVOKE_SETTER(PARAM_TYPE, param) (pObj->*(reinterpret_cast(pSetter)))(*(PARAM_TYPE*)param) - #define INVOKE_SETTER_P(PARAM_TYPE, param) (pObj->*(reinterpret_cast(pSetter)))((PARAM_TYPE)param) - - void InvokeSetter(void* param) override - { - switch (paramType) - { - case e_FLOAT: - INVOKE_SETTER(float, param); - break; - case e_INT: - INVOKE_SETTER(int, param); - break; - case e_VEC2: - INVOKE_SETTER(Vec2, param); - break; - case e_VEC3: - INVOKE_SETTER(Vec3, param); - break; - case e_VEC4: - INVOKE_SETTER(Vec4, param); - break; - case e_BOOL: - INVOKE_SETTER(bool, param); - break; - case e_COLOR: - INVOKE_SETTER(ColorF, param); - break; - case e_MATRIX33: - INVOKE_SETTER(Matrix33, param); - break; - case e_TEXTURE2D: - INVOKE_SETTER_P(ITexture*, param); - break; - case e_TEXTURE3D: - INVOKE_SETTER_P(ITexture*, param); - break; - case e_TEXTURE_CUBE: - INVOKE_SETTER_P(ITexture*, param); - break; - } - } - - #define INVOKE_GETTER(PARAM_TYPE) ((pObj->*reinterpret_cast(pGetter))()) - - int GetInt() const override {return INVOKE_GETTER(int); } - float GetFloat() const override {return INVOKE_GETTER(float); } - bool GetBool() const override {return INVOKE_GETTER(bool); } - Vec2 GetVec2() const override {return INVOKE_GETTER(Vec2); } - Vec3 GetVec3() const override {return INVOKE_GETTER(Vec3); } - Vec4 GetVec4() const override {return INVOKE_GETTER(Vec4); } - ColorF GetColorF() const override {return INVOKE_GETTER(ColorF); } - Matrix33 GetMatrix33() const override {return INVOKE_GETTER(Matrix33); } - ITexture* GetTexture() const override {return INVOKE_GETTER(ITexture*); } -}; - -class FuncVariableGroup -{ -private: - AZStd::vector<_smart_ptr > variables; - string m_name; -#if defined(FLARES_SUPPORT_EDITING) - string m_humanname; -#endif - bool bCollapse; - -public: - FuncVariableGroup() - : bCollapse(false) - { - SetName(""); - } - - ~FuncVariableGroup() - { - } - - void SetName(const char* name, [[maybe_unused]] const char* humanname = 0) - { - if (!name) - { - return; - } - m_name = name; -#if defined(FLARES_SUPPORT_EDITING) - m_humanname = humanname ? humanname : name; -#endif - } - - const char* GetName() - { - return m_name.c_str(); - } - -#if defined(FLARES_SUPPORT_EDITING) - const char* GetHumanName() - { - return m_humanname.c_str(); - } -#endif - - void SetCollapse(bool _bCollapse) - { - bCollapse = _bCollapse; - } - - bool IsCollapse() - { - return bCollapse; - } - - IFuncVariable* FindVariable(const char* name) - { - for (int i = 0, iSize(variables.size()); i < iSize; ++i) - { - if (variables[i] == NULL) - { - continue; - } - if (!strcmp(variables[i]->name.c_str(), name)) - { - return variables[i]; - } - } - return NULL; - } - - void SetVariable(int nIndex, IFuncVariable* v){ variables[nIndex] = v; } - - int GetVariableCount() { return variables.size(); } - - IFuncVariable* GetVariable(int nIndex) - { - return variables[nIndex]; - } - - void AddVariable(IFuncVariable* var) - { - variables.push_back(var); - } -}; -#endif // CRYINCLUDE_CRYCOMMON_IFUNCVARIABLE_H diff --git a/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h b/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h deleted file mode 100644 index 7a9c0c8ebf..0000000000 --- a/Code/CryEngine/CryCommon/IGeneralMemoryHeap.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H -#define CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H -#pragma once - -namespace AZ -{ - class IAllocator; -} - -class IGeneralMemoryHeap -{ -public: - // - virtual bool Cleanup() = 0; - - virtual int AddRef() = 0; - virtual int Release() = 0; - - virtual bool IsInAddressRange(void* ptr) const = 0; - - virtual void* Calloc(size_t nmemb, size_t size, const char* sUsage) = 0; - virtual void* Malloc(size_t sz, const char* sUsage) = 0; - - // Attempts to free the allocation. Returns the size of the allocation if successful, 0 if the heap doesn't own the address. - virtual size_t Free(void* ptr) = 0; - virtual void* Realloc(void* ptr, size_t sz, const char* sUsage) = 0; - virtual void* ReallocAlign(void* ptr, size_t size, size_t alignment, const char* sUsage) = 0; - virtual void* Memalign(size_t boundary, size_t size, const char* sUsage) = 0; - - virtual AZ::IAllocator* GetAllocator() const = 0; - - // Get the size of the allocation. Returns 0 if the ptr doesn't belong to the heap. - virtual size_t UsableSize(void* ptr) const = 0; - // -protected: - virtual ~IGeneralMemoryHeap() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H diff --git a/Code/CryEngine/CryCommon/IGeomCache.h b/Code/CryEngine/CryCommon/IGeomCache.h deleted file mode 100644 index d7b10ffdd7..0000000000 --- a/Code/CryEngine/CryCommon/IGeomCache.h +++ /dev/null @@ -1,140 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface for CGeomCache class - - -#ifndef CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H -#define CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H -#pragma once - - -#include "smartptr.h" // TYPEDEF_AUTOPTR - -// Summary: -// Interface to hold geom cache data -struct IGeomCache - : public IStreamable -{ - // Description: - // Increase the reference count of the object. - // Summary: - // Notifies that the object is being used - virtual int AddRef() = 0; - - // Description: - // Decrease the reference count of the object. If the reference count - // reaches zero, the object will be deleted from memory. - // Summary: - // Notifies that the object is no longer needed - virtual int Release() = 0; - - // Description: - // Checks if the geometry cache was successfully loaded from disk - // Return Value: - // True if valid, otherwise false - virtual bool IsValid() const = 0; - - // Description: - // Set default material for the geometry. - // Arguments: - // pMaterial - A valid pointer to the material. - virtual void SetMaterial(_smart_ptr pMaterial) = 0; - - // Description: - // Returns default material of the geometry. - // Arguments: - // nType - Pass 0 to get the physic geometry or pass 1 to get the obstruct geometry - // Return Value: - // A pointer to a phys_geometry class. - virtual _smart_ptr GetMaterial() = 0; - virtual const _smart_ptr GetMaterial() const = 0; - - // Summary: - // Returns the filename of the object - // Return Value: - // A null terminated string which contain the filename of the object. - virtual const char* GetFilePath() const = 0; - - // Summary: - // Returns the duration of the geom cache animation - // Return value: - // float value in seconds - virtual float GetDuration() const = 0; - - // Summary: - // Reloads the cache. Need to call this when cache file changed. - virtual void Reload() = 0; - - // Summary: - // Returns the max AABB of the geom cache through the whole animation - // Return value: - // The geom cache's max axis aligned bounding box - virtual const AABB& GetAABB() const = 0; - - /** - * Tells the GeomCache whether or not it can release its static mesh data - * - * For the new AZ Geom Cache asset we have to be able - * to tell the Geom Cache not to release loaded data. - * This only matters when Geom Caches are not streamed. - * - * The legacy system works like this (if e_streamCGF is 0): - * Load a geom cache entity. - * Entity creates a geom cache render node. - * Node loads geom cache, cache is marked as loaded. - * Render node immediately initializes with the Geom Cache data. - * Because the Geom Cache is not streamed, it releases unneeded data next tick - * - * The AZ system works like this: - * Geom Cache component is created - * Asset is requested - * Asset loads Geom Cache - * Geom Cache loads data and is marked as loaded - * Asset calls AllowReleaseLoadedData(false) and locks loaded state - * Tick happens and data is not freed (this is good, we need that data) - * OnAssetReady event fires and is picked up by Geom Cache Component - * Data is fed from the asset to the Geom Cache Render Node - * Component calls AllowReleaseLoadedData(true) - * Next tick the Geom Cache cleans up unneeded data - */ - virtual void SetProcessedByRenderNode(bool) = 0; - - // Summary: - // Returns statistics - // Return value: - // SStatistics struct - struct SStatistics - { - bool m_bPlaybackFromMemory; - float m_averageAnimationDataRate; - uint m_numStaticMeshes; - uint m_numStaticVertices; - uint m_numStaticTriangles; - uint m_numAnimatedMeshes; - uint m_numAnimatedVertices; - uint m_numAnimatedTriangles; - uint m_numMaterials; - uint m_staticDataSize; - uint m_diskAnimationDataSize; - uint m_memoryAnimationDataSize; - }; - - virtual SStatistics GetStatistics() const = 0; - -protected: - virtual ~IGeomCache() {}; // should be never called, use Release() instead -}; - - -#endif // CRYINCLUDE_CRYCOMMON_IGEOMCACHE_H diff --git a/Code/CryEngine/CryCommon/IImage.h b/Code/CryEngine/CryCommon/IImage.h deleted file mode 100644 index 059c1e8174..0000000000 --- a/Code/CryEngine/CryCommon/IImage.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IIMAGE_H -#define CRYINCLUDE_CRYCOMMON_IIMAGE_H -#pragma once - -/** - * Possible errors for IImageFile::mfGet_error. - */ -enum EImFileError -{ - eIFE_OK = 0, eIFE_IOerror, eIFE_OutOfMemory, eIFE_BadFormat, eIFE_ChunkNotFound -}; - -// here are all of the flags that can be passed into the image load flags -#define FIM_NORMALMAP 0x0001 -#define FIM_NOTSUPPORTS_MIPS 0x0004 -#define FIM_ALPHA 0x0008 // request attached alpha image -#define FIM_DECAL 0x0010 -#define FIM_GREYSCALE 0x0020 // hint this texture is greyscale (could be DXT1 with colored artifacts) -#define FIM_STREAM_PREPARE 0x0080 -#define FIM_UNUSED_BIT 0x0100 // Free to use -#define FIM_BIG_ENDIANNESS 0x0400 // for textures converted to big endianness format -#define FIM_SPLITTED 0x0800 // for dds textures stored in splitted files -#define FIM_SRGB_READ 0x1000 -#define FIM_X360_NOT_PRETILED 0x2000 // for dds textures that cannot be pretiled -#define FIM_UNUSED_BIT_1 0x4000 // Free to use -#define FIM_RENORMALIZED_TEXTURE 0x8000 // for dds textures with EIF_RenormalizedTexture set in the dds header (not currently supported in the engine at runtime) -#define FIM_HAS_ATTACHED_ALPHA 0x10000 // image has an attached alpha image -#define FIM_SUPPRESS_DOWNSCALING 0x20000 // don't allow to drop mips when texture is non-streamable -#define FIM_DX10IO 0x40000 // for dds textures with extended DX10+ header -#define FIM_NOFALLBACKS 0x80000 // if the texture can't be loaded or is not found, do not replace it with a default 'not found' texture. - -class IImageFile -{ -public: - virtual int AddRef() = 0; - virtual int Release() = 0; - - virtual const string& mfGet_filename () const = 0; - - virtual int mfGet_width () const = 0; - virtual int mfGet_height () const = 0; - virtual int mfGet_depth () const = 0; - virtual int mfGet_NumSides () const = 0; - - virtual EImFileError mfGet_error () const = 0; - - virtual byte* mfGet_image (const int nSide) = 0; - virtual bool mfIs_image (const int nSide) const = 0; - - virtual ETEX_Format mfGetFormat() const = 0; - virtual ETEX_TileMode mfGetTileMode() const = 0; - virtual int mfGet_numMips () const = 0; - virtual int mfGet_numPersistentMips () const = 0; - virtual int mfGet_Flags () const = 0; - virtual const ColorF& mfGet_minColor () const = 0; - virtual const ColorF& mfGet_maxColor () const = 0; - virtual int mfGet_ImageSize() const = 0; - -protected: - virtual ~IImageFile() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IIMAGE_H diff --git a/Code/CryEngine/CryCommon/IImageHandler.h b/Code/CryEngine/CryCommon/IImageHandler.h deleted file mode 100644 index 3f2e0c871b..0000000000 --- a/Code/CryEngine/CryCommon/IImageHandler.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H -#define CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H -#pragma once - -#include - -/** -Utility for loading and saving images. only works with RGB data(no alpha), and lossless compressed tiff files for now. -*/ -struct IImageHandler -{ - struct IImage - { - virtual ~IImage() {} - - virtual const std::vector& GetData() const = 0; - virtual int GetWidth() const = 0; - virtual int GetHeight() const = 0; - }; - - virtual ~IImageHandler() {} - - ///data must be RGB, 3 bytes per pixel. - virtual std::unique_ptr CreateImage(std::vector&& data, int width, int height) const = 0; - virtual std::unique_ptr LoadImage(const char* filename) const = 0; - virtual bool SaveImage(IImage* image, const char* filename) const = 0; - virtual std::unique_ptr CreateDiffImage(IImage* image1, IImage* image2) const = 0; - virtual float CalculatePSNR(IImage* diffIimage) const = 0; -}; -#endif // CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H diff --git a/Code/CryEngine/CryCommon/ILZ4Decompressor.h b/Code/CryEngine/CryCommon/ILZ4Decompressor.h deleted file mode 100644 index c136a7518d..0000000000 --- a/Code/CryEngine/CryCommon/ILZ4Decompressor.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Provides the interface for the lz4 hc decompress wrapper - -#ifndef CRYINCLUDE_CRYCOMMON_ILZ4DECOMPRESSOR_H -#define CRYINCLUDE_CRYCOMMON_ILZ4DECOMPRESSOR_H -#pragma once - - -struct ILZ4Decompressor -{ -protected: - virtual ~ILZ4Decompressor() {}; // use Release() - -public: - virtual bool DecompressData(const char* pIn, char* pOut, const uint outputSize) const = 0; - - virtual void Release() = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMON_ILZ4DECOMPRESSOR_H diff --git a/Code/CryEngine/CryCommon/IMaterialEffects.h b/Code/CryEngine/CryCommon/IMaterialEffects.h deleted file mode 100644 index 73e03a1d80..0000000000 --- a/Code/CryEngine/CryCommon/IMaterialEffects.h +++ /dev/null @@ -1,504 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Material Effects System - - -#ifndef CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H -#define CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H -#pragma once - -#if !defined(_RELEASE) - #define MATERIAL_EFFECTS_DEBUG -#endif - - -#include "CryFixedArray.h" - -struct IRenderNode; -struct ISurfaceType; - -////////////////////////////////////////////////////////////////////////// -enum EMFXPlayFlags -{ - eMFXPF_Disable_Delay = BIT(0), - eMFXPF_Audio = BIT(1), - eMFXPF_Decal = BIT(2), - eMFXPF_Particles = BIT(3), - eMFXPF_Deprecated0 = BIT(4), // formerly eMFXPF_Flowgraph - eMFXPF_ForceFeedback = BIT(5), - eMFXPF_All = (eMFXPF_Audio | eMFXPF_Decal | eMFXPF_Particles | eMFXPF_Deprecated0 | eMFXPF_ForceFeedback), -}; - -#define MFX_INVALID_ANGLE (gf_PI2 + 1) - -////////////////////////////////////////////////////////////////////////// -struct SMFXAudioEffectRtpc -{ - SMFXAudioEffectRtpc() - { - rtpcName = ""; - rtpcValue = 0.0f; - } - const char* rtpcName; - float rtpcValue; -}; - -////////////////////////////////////////////////////////////////////////// -struct SMFXRunTimeEffectParams -{ - static const int MAX_AUDIO_RTPCS = 4; - - SMFXRunTimeEffectParams() - : playSoundFP(false) - , playflags(eMFXPF_All) - , fLastTime(0.0f) - , srcSurfaceId(0) - , trgSurfaceId(0) - , srcRenderNode(0) - , trgRenderNode(0) - , partID(0) - , pos(ZERO) - , decalPos(ZERO) - , normal(0.0f, 0.0f, 1.0f) - , angle(MFX_INVALID_ANGLE) - , scale(1.0f) - , audioComponentOffset(ZERO) - , numAudioRtpcs(0) - , fDecalPlacementTestMaxSize(1000.f) - { - dir[0].Set(0.0f, 0.0f, -1.0f); - dir[1].Set(0.0f, 0.0f, 1.0f); - } - - bool AddAudioRtpc(const char* name, float val) - { - if (numAudioRtpcs < MAX_AUDIO_RTPCS) - { - audioRtpcs[numAudioRtpcs].rtpcName = name; - audioRtpcs[numAudioRtpcs].rtpcValue = val; - ++numAudioRtpcs; - return true; - } - return false; - } - - void ResetAudioRtpcs() - { - numAudioRtpcs = 0; - } - -public: - uint16 playSoundFP; // Sets 1p/3p audio switch - uint16 playflags; // See EMFXPlayFlags - float fLastTime; // Last time this effect was played - float fDecalPlacementTestMaxSize; - - int srcSurfaceId; - int trgSurfaceId; - IRenderNode* srcRenderNode; - IRenderNode* trgRenderNode; - int partID; - - Vec3 pos; - Vec3 decalPos; - Vec3 dir[2]; - Vec3 normal; - float angle; - float scale; - - // audio related - Vec3 audioComponentOffset; // in case of audio component, uses this offset - - SMFXAudioEffectRtpc audioRtpcs[MAX_AUDIO_RTPCS]; - uint32 numAudioRtpcs; -}; - -struct SMFXBreakageParams -{ - enum EBreakageRequestFlags - { - eBRF_Matrix = BIT(0), - eBRF_HitPos = BIT(1), - eBRF_HitImpulse = BIT(2), - eBRF_Velocity = BIT(3), - eBRF_ExplosionImpulse = BIT(4), - eBRF_Mass = BIT(5), - eBFR_Entity = BIT(6), - }; - - SMFXBreakageParams() - : m_flags(0) - , m_worldTM(IDENTITY) - , m_vHitPos(ZERO) - , m_vHitImpulse(IDENTITY) - , m_vVelocity(ZERO) - , m_fExplosionImpulse(1.0f) - , m_fMass(0.0f) - { - } - - - // Matrix - void SetMatrix(const Matrix34& worldTM) - { - m_worldTM = worldTM; - SetFlag(eBRF_Matrix); - } - - const Matrix34& GetMatrix() const - { - return m_worldTM; - } - - // HitPos - void SetHitPos(const Vec3& vHitPos) - { - m_vHitPos = vHitPos; - SetFlag(eBRF_HitPos); - } - - const Vec3& GetHitPos() const - { - return m_vHitPos; - } - - // HitImpulse - void SetHitImpulse(const Vec3& vHitImpulse) - { - m_vHitImpulse = vHitImpulse; - SetFlag(eBRF_HitImpulse); - } - - const Vec3& GetHitImpulse() const - { - return m_vHitImpulse; - } - - // Velocity - void SetVelocity(const Vec3& vVelocity) - { - m_vVelocity = vVelocity; - SetFlag(eBRF_Velocity); - } - - const Vec3& GetVelocity() const - { - return m_vVelocity; - } - - // Explosion Impulse - void SetExplosionImpulse(float fExplosionImpulse) - { - m_fExplosionImpulse = fExplosionImpulse; - SetFlag(eBRF_ExplosionImpulse); - } - - float GetExplosionImpulse() const - { - return m_fExplosionImpulse; - } - - // Mass - void SetMass(float fMass) - { - m_fMass = fMass; - SetFlag(eBRF_Mass); - } - - float GetMass() const - { - return m_fMass; - } - - // Checking for flags - bool CheckFlag(EBreakageRequestFlags flag) const - { - return (m_flags & flag) != 0; - } - -protected: - void SetFlag(EBreakageRequestFlags flag) - { - m_flags |= flag; - } - - void ClearFlag(EBreakageRequestFlags flag) - { - m_flags &= ~flag; - } - - uint32 m_flags; - Matrix34 m_worldTM; - Vec3 m_vHitPos; - Vec3 m_vHitImpulse; - Vec3 m_vVelocity; - float m_fExplosionImpulse; - float m_fMass; -}; - -class IMFXParticleParams -{ -public: - IMFXParticleParams() - : name(NULL) - , userdata(NULL) - , scale(1.0f) - { - } - - const char* name; - const char* userdata; - float scale; -}; - -class SMFXParticleListNode -{ -public: - static SMFXParticleListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXParticleParams m_particleParams; - SMFXParticleListNode* pNext; - -private: - SMFXParticleListNode() - { - pNext = NULL; - } - ~SMFXParticleListNode() {} -}; - -class IMFXAudioParams -{ - const static uint MAX_SWITCH_DATA_ELEMENTS = 4; - -public: - - struct SSwitchData - { - SSwitchData() - : switchName(NULL) - , switchStateName(NULL) - { - } - - const char* switchName; - const char* switchStateName; - }; - - IMFXAudioParams() - : triggerName(NULL) - { - } - const char* triggerName; - - CryFixedArray triggerSwitches; -}; - -class SMFXAudioListNode -{ -public: - static SMFXAudioListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXAudioParams m_audioParams; - SMFXAudioListNode* pNext; - -private: - SMFXAudioListNode() - : pNext(NULL) - { - } - - ~SMFXAudioListNode() - { - } -}; - -class IMFXDecalParams -{ -public: - IMFXDecalParams() - { - filename = 0; - material = 0; - minscale = 1.f; - maxscale = 1.f; - rotation = -1.f; - lifetime = 10.0f; - assemble = false; - forceedge = false; - } - const char* filename; - const char* material; - float minscale; - float maxscale; - float rotation; - float lifetime; - bool assemble; - bool forceedge; -}; - -class SMFXDecalListNode -{ -public: - static SMFXDecalListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXDecalParams m_decalParams; - SMFXDecalListNode* pNext; - -private: - SMFXDecalListNode() - { - pNext = 0; - } - ~SMFXDecalListNode() {} -}; - -class IMFXForceFeedbackParams -{ -public: - IMFXForceFeedbackParams() - : forceFeedbackEventName (NULL) - , intensityFallOffMinDistanceSqr(0.0f) - , intensityFallOffMaxDistanceSqr(0.0f) - { - } - - const char* forceFeedbackEventName; - float intensityFallOffMinDistanceSqr; - float intensityFallOffMaxDistanceSqr; -}; - -class SMFXForceFeedbackListNode -{ -public: - static SMFXForceFeedbackListNode* Create(); - void Destroy(); - static void FreePool(); - - IMFXForceFeedbackParams m_forceFeedbackParams; - SMFXForceFeedbackListNode* pNext; - -private: - SMFXForceFeedbackListNode() - : pNext(NULL) - { - } - ~SMFXForceFeedbackListNode() {} -}; - -struct SMFXResourceList; -typedef _smart_ptr SMFXResourceListPtr; - -struct SMFXResourceList -{ -public: - SMFXParticleListNode* m_particleList; - SMFXAudioListNode* m_audioList; - SMFXDecalListNode* m_decalList; - SMFXForceFeedbackListNode* m_forceFeedbackList; - - void AddRef() { ++m_refs; } - void Release() - { - if (--m_refs <= 0) - { - Destroy(); - } - } - - static SMFXResourceListPtr Create(); - static void FreePool(); - -private: - int m_refs; - - virtual void Destroy(); - - SMFXResourceList() - : m_refs(0) - { - m_particleList = 0; - m_audioList = 0; - m_decalList = 0; - m_forceFeedbackList = 0; - } - virtual ~SMFXResourceList() - { - while (m_particleList != 0) - { - SMFXParticleListNode* next = m_particleList->pNext; - m_particleList->Destroy(); - m_particleList = next; - } - while (m_audioList != 0) - { - SMFXAudioListNode* next = m_audioList->pNext; - m_audioList->Destroy(); - m_audioList = next; - } - while (m_decalList != 0) - { - SMFXDecalListNode* next = m_decalList->pNext; - m_decalList->Destroy(); - m_decalList = next; - } - while (m_forceFeedbackList != 0) - { - SMFXForceFeedbackListNode* next = m_forceFeedbackList->pNext; - m_forceFeedbackList->Destroy(); - m_forceFeedbackList = next; - } - } -}; - -typedef uint16 TMFXEffectId; -static const TMFXEffectId InvalidEffectId = 0; - -struct SMFXCustomParamValue -{ - float fValue; -}; - -////////////////////////////////////////////////////////////////////////// -struct IMaterialEffects -{ - // - virtual ~IMaterialEffects(){} - virtual void LoadFXLibraries() = 0; - virtual void Reset(bool bCleanup) = 0; - virtual void ClearDelayedEffects() = 0; - virtual TMFXEffectId GetEffectIdByName(const char* libName, const char* effectName) = 0; - virtual TMFXEffectId GetEffectId(int surfaceIndex1, int surfaceIndex2) = 0; - virtual TMFXEffectId GetEffectId(const char* customName, int surfaceIndex2) = 0; - virtual SMFXResourceListPtr GetResources(TMFXEffectId effectId) const = 0; - virtual void PreLoadAssets() = 0; - virtual bool ExecuteEffect(TMFXEffectId effectId, SMFXRunTimeEffectParams& runtimeParams) = 0; - virtual int GetDefaultSurfaceIndex() = 0; - virtual int GetDefaultCanopyIndex() = 0; - - virtual bool PlayBreakageEffect(ISurfaceType* pSurfaceType, const char* breakageType, const SMFXBreakageParams& mfxBreakageParams) = 0; - - virtual void SetCustomParameter(TMFXEffectId effectId, const char* customParameter, const SMFXCustomParamValue& customParameterValue) = 0; - - virtual void CompleteInit() = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H diff --git a/Code/CryEngine/CryCommon/IMemory.h b/Code/CryEngine/CryCommon/IMemory.h deleted file mode 100644 index 4a96bae2c0..0000000000 --- a/Code/CryEngine/CryCommon/IMemory.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IMEMORY_H -#define CRYINCLUDE_CRYCOMMON_IMEMORY_H -#pragma once - -#include -#include // <> required for Interfuscator -#include // <> required for Interfuscator -#include - -struct IMemoryBlock - : public CMultiThreadRefCount -{ - // - virtual void* GetData() = 0; - virtual int GetSize() = 0; - // -}; -TYPEDEF_AUTOPTR(IMemoryBlock); - -////////////////////////////////////////////////////////////////////////// -struct ICustomMemoryBlock - : public IMemoryBlock -{ - // Copy region from from source memory to the specified output buffer - virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize) = 0; -}; - -////////////////////////////////////////////////////////////////////////// -struct ICustomMemoryHeap - : public CMultiThreadRefCount -{ - // - virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16) = 0; - virtual void GetMemoryUsage(ICrySizer* pSizer) = 0; - virtual size_t GetAllocated() = 0; - // -}; - -class IMemoryAddressRange -{ -public: - // - virtual void Release() = 0; - - virtual char* GetBaseAddress() const = 0; - virtual size_t GetPageCount() const = 0; - virtual size_t GetPageSize() const = 0; - - virtual void* MapPage(size_t pageIdx) = 0; - virtual void UnmapPage(size_t pageIdx) = 0; - // -protected: - virtual ~IMemoryAddressRange() {} -}; - -class IPageMappingHeap -{ -public: - // - virtual void Release() = 0; - - virtual size_t GetGranularity() const = 0; - virtual bool IsInAddressRange(void* ptr) const = 0; - - virtual size_t FindLargestFreeBlockSize() const = 0; - - virtual void* Map(size_t sz) = 0; - virtual void Unmap(void* ptr, size_t sz) = 0; - // -protected: - virtual ~IPageMappingHeap() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IMEMORY_H diff --git a/Code/CryEngine/CryCommon/IMeshBaking.h b/Code/CryEngine/CryCommon/IMeshBaking.h deleted file mode 100644 index 92b5e9bfa7..0000000000 --- a/Code/CryEngine/CryCommon/IMeshBaking.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IMESHBAKING_H -#define CRYINCLUDE_CRYCOMMON_IMESHBAKING_H -#pragma once - - -struct SMeshBakingMaterialParams -{ - float rayLength; - float rayIndent; - bool bAlphaCutout; - bool bIgnore; -}; - -struct SMeshBakingInputParams -{ - IStatObj* pCageMesh; - IStatObj* pInputMesh; - const SMeshBakingMaterialParams* pMaterialParams; - ColorF defaultBackgroundColour; - ColorF dilateMagicColour; - int outputTextureWidth; - int outputTextureHeight; - int numMaterialParams; - int nLodId; - bool bDoDilationPass; - bool bSmoothNormals; - bool bSaveSpecular; - _smart_ptr pMaterial; -}; - -struct SMeshBakingOutput -{ - ITexture* ppOuputTexture[3]; - ITexture* ppIntermediateTexture[3]; -}; - -#endif // CRYINCLUDE_CRYCOMMON_IMESHBAKING_H diff --git a/Code/CryEngine/CryCommon/INotificationNetwork.h b/Code/CryEngine/CryCommon/INotificationNetwork.h deleted file mode 100644 index 9ad44b24ab..0000000000 --- a/Code/CryEngine/CryCommon/INotificationNetwork.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H -#define CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H -#pragma once - - -// Constants - -#define NN_CHANNEL_NAME_LENGTH_MAX 16 - -struct INotificationNetworkClient; - -// User Interfaces - -struct INotificationNetworkListener -{ - // - virtual ~INotificationNetworkListener(){} - // Called upon receiving data from the Channel the Listener is binded to. - virtual void OnNotificationNetworkReceive(const void* pBuffer, size_t length) = 0; - // -}; - -struct INotificationNetworkConnectionCallback -{ - // - virtual ~INotificationNetworkConnectionCallback(){} - virtual void OnConnect(INotificationNetworkClient* pClient, bool bSucceeded) = 0; - virtual void OnDisconnected(INotificationNetworkClient* pClient) = 0; - // -}; - -// Interfaces - -struct INotificationNetworkClient -{ - // - virtual ~INotificationNetworkClient(){} - virtual void Release() = 0; - - // Binds a Listener to the given Notification Channel. - // Each Listener can be binded only to one Channel, calling the method - // again with an already added Listener and a different Channel will rebind it. - // The Channel name cannot exceed NN_CHANNEL_NAME_LENGTH_MAX chars. - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener) = 0; - - // If it exist, removes the given Listener form the Notification Network. - virtual bool ListenerRemove(INotificationNetworkListener* pListener) = 0; - - // Sends arbitrary data to the Notification Network the Client is connected to. - virtual bool Send(const char* channelName, const void* pBuffer, size_t length) = 0; - - // Checks if the current client is connected. - // Returns true if it is connected, false otherwise. - virtual bool IsConnected() = 0; - - // Checks if the connection attempt failed. - // Returns true if it failed to connect by any reason (such as timeout). - virtual bool IsFailedToConnect() const = 0; - - // Start the connection request for this particular client. - // Parameters: - // address - Is the host name or ipv4 (for now) address string to which - // we want to connect. - // port - Is the TCP port to which we want to connect. - // Remarks: Port 9432 is being used by the live preview already. - virtual bool Connect(const char* address, uint16 port) = 0; - - // Tries to register a callback listener object. - // A callback listener object will receive events from the client element, - // such as connection result information. - // Parameters: - // - pConnectionCallback - Is a pointer to an object implementing interface - // INotificationNetworkConnectionCallback which will be called when - // the events happen, such as connection, disconnection and failed attempt - // to connect. - // Return Value: - // - It will return true if registered the callback object successfully. - // - It will return false when there the callback object is already - // registered. - virtual bool RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) = 0; - - // Tries to unregister a callback listener object. - // A callback listener object will receive events from the client element, - // such as connection result information. - // Parameters: - // - pConnectionCallback - Is a pointer to an object implementing interface - // INotificationNetworkConnectionCallback which will be called when - // the events happen, such as connection, disconnection and failed attempt - // to connect and that we want to unregister. - // Return Value: - // - It will return true if unregistered the callback object successfully. - // - It will return false when no object matching the one requested is found - // int the object. - virtual bool UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) = 0; - // -}; - -struct INotificationNetwork -{ - // - virtual ~INotificationNetwork(){} - - virtual void Release() = 0; - - // Creates a disconnected client. - virtual INotificationNetworkClient* CreateClient() = 0; - - // Attempts to connect to the Notification Network at the given address, - // returns a Client interface if communication is possible. - virtual INotificationNetworkClient* Connect(const char* address, uint16 port) = 0; - - // Returns the Connection count of the given Channel. If NULL is passed - // instead of a valid Channel name the total count of all Connections is - // returned. - virtual size_t GetConnectionCount(const char* channelName = NULL) = 0; - - // Has to be called from the main thread to process received notifications. - virtual void Update() = 0; - - // Binds a Listener to the given Notification Channel. - // Each Listener can be binded only to one Channel, calling the method - // again with an already added Listener and a different Channel will rebind it. - // The Channel name cannot exceed NN_CHANNEL_NAME_LENGTH_MAX chars. - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener) = 0; - - // If it exist, removes the given Listener form the Notification Network. - virtual bool ListenerRemove(INotificationNetworkListener* pListener) = 0; - - // Sends arbitrary data to all the Connections listening to the given Channel. - virtual uint32 Send(const char* channel, const void* pBuffer, size_t length) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H diff --git a/Code/CryEngine/CryCommon/IObjManager.h b/Code/CryEngine/CryCommon/IObjManager.h deleted file mode 100644 index a63a252976..0000000000 --- a/Code/CryEngine/CryCommon/IObjManager.h +++ /dev/null @@ -1,252 +0,0 @@ -/* -* 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. -* -*/ -#pragma once - -struct IStreamable; -struct SCheckOcclusionJobData; -struct SCheckOcclusionOutput; -class COctreeNode; -struct IStatInstGroup; - -namespace NAsyncCull -{ - class CCullThread; -} - -// Inplace object for IStreamable* to cache StreamableMemoryContentSize -struct SStreamAbleObject -{ - explicit SStreamAbleObject(IStreamable* pObj, bool bUpdateMemUsage = true) - : m_pObj(pObj) - , fCurImportance(-1000.f) - { - if (pObj && bUpdateMemUsage) - { - m_nStreamableContentMemoryUsage = pObj->GetStreamableContentMemoryUsage(); - } - else - { - m_nStreamableContentMemoryUsage = 0; - } - } - - bool operator==(const SStreamAbleObject& rOther) const - { - return m_pObj == rOther.m_pObj; - } - - int GetStreamableContentMemoryUsage() const { return m_nStreamableContentMemoryUsage; } - IStreamable* GetStreamAbleObject() const { return m_pObj; } - uint32 GetLastDrawMainFrameId() const - { - return m_pObj->GetLastDrawMainFrameId(); - } - float fCurImportance; -private: - IStreamable* m_pObj; - int m_nStreamableContentMemoryUsage; -}; - -struct SObjManPrecacheCamera -{ - SObjManPrecacheCamera() - : vPosition(ZERO) - , vDirection(ZERO) - , bbox(AABB::RESET) - , fImportanceFactor(1.0f) - { - } - - Vec3 vPosition; - Vec3 vDirection; - AABB bbox; - float fImportanceFactor; -}; - -struct SObjManPrecachePoint -{ - SObjManPrecachePoint() - : nId(0) - { - } - - int nId; - CTimeValue expireTime; -}; - -struct IObjManager -{ - virtual ~IObjManager() {} - - virtual void PreloadLevelObjects() = 0; - virtual void UnloadObjects(bool bDeleteAll) = 0; - virtual void CheckTextureReadyFlag() = 0; - virtual void FreeStatObj(IStatObj* pObj) = 0; - virtual _smart_ptr GetDefaultCGF() = 0; - - typedef std::vector< IDecalRenderNode* > DecalsToPrecreate; - virtual DecalsToPrecreate& GetDecalsToPrecreate() = 0; - virtual PodArray& GetArrStreamableObjects() = 0; - virtual PodArray& GetStreamPreCacheCameras() = 0; - virtual PodArray& GetArrStreamingNodeStack() = 0; - virtual PodArray& GetStreamPreCachePointDefs() = 0; - - typedef std::map > ObjectsMap; - virtual ObjectsMap& GetNameToObjectMap() = 0; - - typedef std::set LoadedObjects; - virtual LoadedObjects& GetLoadedObjects() = 0; - - virtual Vec3 GetSunColor() = 0; - virtual void SetSunColor(const Vec3& color) = 0; - - virtual Vec3 GetSunAnimColor() = 0; - virtual void SetSunAnimColor(const Vec3& color) = 0; - - virtual float GetSunAnimSpeed() = 0; - virtual void SetSunAnimSpeed(float sunAnimSpeed) = 0; - - virtual AZ::u8 GetSunAnimPhase() = 0; - virtual void SetSunAnimPhase(AZ::u8 sunAnimPhase) = 0; - - virtual AZ::u8 GetSunAnimIndex() = 0; - virtual void SetSunAnimIndex(AZ::u8 sunAnimIndex) = 0; - - virtual float GetSSAOAmount() = 0; - virtual void SetSSAOAmount(float amount) = 0; - - virtual float GetSSAOContrast() = 0; - virtual void SetSSAOContrast(float amount) = 0; - - virtual SRainParams& GetRainParams() = 0; - virtual SSnowParams& GetSnowParams() = 0; - - virtual bool IsCameraPrecacheOverridden() = 0; - virtual void SetCameraPrecacheOverridden(bool state) = 0; - - virtual IStatObj* LoadNewCGF(IStatObj* pObject, int flagCloth, bool bUseStreaming, bool bForceBreakable, unsigned long nLoadingFlags, const char* normalizedFilename, const void* pData, int nDataSize, const char* originalFilename, const char* geomName, IStatObj::SSubObject** ppSubObject) = 0; - virtual IStatObj* LoadFromCacheNoRef(IStatObj* pObject, bool bUseStreaming, unsigned long nLoadingFlags, const char* geomName, IStatObj::SSubObject** ppSubObject) = 0; - - virtual IStatObj* AllocateStatObj() = 0; - virtual IStatObj* LoadStatObjUnsafeManualRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL) = 0; - virtual _smart_ptr LoadStatObjAutoRef(const char* szFileName, const char* szGeomName = NULL, IStatObj::SSubObject** ppSubObject = NULL, bool bUseStreaming = true, unsigned long nLoadingFlags = 0, const void* m_pData = 0, int m_nDataSize = 0, const char* szBlockName = NULL) = 0; - virtual void GetLoadedStatObjArray(IStatObj** pObjectsArray, int& nCount) = 0; - virtual bool InternalDeleteObject(IStatObj* pObject) = 0; - virtual void MakeShadowCastersList(CVisArea* pReceiverArea, const AABB& aabbReceiver, int dwAllowedTypes, int32 nRenderNodeFlags, Vec3 vLightPos, CDLight* pLight, ShadowMapFrustum* pFr, PodArray* pShadowHull, const SRenderingPassInfo& passInfo) = 0; - virtual int MakeStaticShadowCastersList(IRenderNode* pIgnoreNode, ShadowMapFrustum* pFrustum, int renderNodeExcludeFlags, int nMaxNodes, const SRenderingPassInfo& passInfo) = 0; - virtual void MakeDepthCubemapRenderItemList(CVisArea* pReceiverArea, const AABB& cubemapAABB, int renderNodeFlags, PodArray* objectsList, const SRenderingPassInfo& passInfo) = 0; - virtual void PrecacheStatObjMaterial(_smart_ptr pMaterial, const float fEntDistance, IStatObj* pStatObj, bool bFullUpdate, bool bDrawNear) = 0; - virtual void PrecacheStatObj(IStatObj* pStatObj, int nLod, const Matrix34A& statObjMatrix, _smart_ptr pMaterial, float fImportance, float fEntDistance, bool bFullUpdate, bool bHighPriority) = 0; - - virtual int GetLoadedObjectCount() = 0; - - virtual uint16 CheckCachedNearestCubeProbe(IRenderNode* pEnt) = 0; - virtual int16 GetNearestCubeProbe(IVisArea* pVisArea, const AABB& objBox, bool bSpecular = true) = 0; - - virtual void RenderObject(IRenderNode* o, const AABB& objBox, float fEntDistance, EERType eERType, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0; - virtual void RenderDecalAndRoad(IRenderNode* pEnt, const AABB& objBox, float fEntDistance, bool nCheckOcclusion, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0; - virtual void RenderObjectDebugInfo(IRenderNode* pEnt, float fEntDistance, const SRenderingPassInfo& passInfo) = 0; - virtual void RenderAllObjectDebugInfo() = 0; - virtual void RenderObjectDebugInfo_Impl(IRenderNode* pEnt, float fEntDistance) = 0; - virtual void RemoveFromRenderAllObjectDebugInfo(IRenderNode* pEnt) = 0; - - virtual float GetXYRadius(int nType, int nSID = DEFAULT_SID) = 0; - virtual bool GetStaticObjectBBox(int nType, Vec3& vBoxMin, Vec3& vBoxMax, int nSID = DEFAULT_SID) = 0; - - virtual IStatObj* GetStaticObjectByTypeID(int nTypeID, int nSID = DEFAULT_SID) = 0; - virtual IStatObj* FindStaticObjectByFilename(const char* filename) = 0; - - //virtual float GetBendingRandomFactor() = 0; - virtual float GetGSMMaxDistance() const = 0; - virtual void SetGSMMaxDistance(float value) = 0; - - virtual int GetUpdateStreamingPrioriryRoundIdFast() = 0; - virtual int GetUpdateStreamingPrioriryRoundId() = 0; - virtual void IncrementUpdateStreamingPrioriryRoundIdFast(int amount) = 0; - virtual void IncrementUpdateStreamingPrioriryRoundId(int amount) = 0; - - virtual NAsyncCull::CCullThread& GetCullThread() = 0; - - virtual void SetLockCGFResources(bool state) = 0; - virtual bool IsLockCGFResources() = 0; - - virtual bool IsBoxOccluded(const AABB& objBox, float fDistance, OcclusionTestClient* const __restrict pOcclTestVars, bool bIndoorOccludersOnly, EOcclusionObjectType eOcclusionObjectType, const SRenderingPassInfo& passInfo) = 0; - - virtual void AddDecalToRenderer(float fDistance, _smart_ptr pMat, const uint8 sortPrio, Vec3 right, Vec3 up, const UCol& ucResCol, const uint8 uBlendType, const Vec3& vAmbientColor, Vec3 vPos, const int nAfterWater, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0; - - virtual void RegisterForStreaming(IStreamable* pObj) = 0; - virtual void UnregisterForStreaming(IStreamable* pObj) = 0; - virtual void UpdateRenderNodeStreamingPriority(IRenderNode* pObj, float fEntDistance, float fImportanceFactor, bool bFullUpdate, const SRenderingPassInfo& passInfo, bool bHighPriority = false) = 0; - - virtual void GetMemoryUsage(class ICrySizer* pSizer) const = 0; - virtual void GetBandwidthStats(float* fBandwidthRequested) = 0; - - virtual void ReregisterEntitiesInArea(Vec3 vBoxMin, Vec3 vBoxMax) = 0; - virtual void UpdateObjectsStreamingPriority(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0; - virtual void ProcessObjectsStreaming(const SRenderingPassInfo& passInfo) = 0; - - virtual void ProcessObjectsStreaming_Impl(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0; - virtual void ProcessObjectsStreaming_Sort(bool bSyncLoad, const SRenderingPassInfo& passInfo) = 0; - virtual void ProcessObjectsStreaming_Release() = 0; - virtual void ProcessObjectsStreaming_InitLoad(bool bSyncLoad) = 0; - virtual void ProcessObjectsStreaming_Finish() = 0; - - // time counters - virtual bool IsAfterWater(const Vec3& vPos, const SRenderingPassInfo& passInfo) = 0; - virtual void FreeNotUsedCGFs() = 0; - virtual void MakeUnitCube() = 0; - - virtual bool CheckOcclusion_TestAABB(const AABB& rAABB, float fEntDistance) = 0; - virtual bool CheckOcclusion_TestQuad(const Vec3& vCenter, const Vec3& vAxisX, const Vec3& vAxisY) = 0; - - virtual void PushIntoCullQueue(const SCheckOcclusionJobData& rCheckOcclusionData) = 0; - virtual void PopFromCullQueue(SCheckOcclusionJobData* pCheckOcclusionData) = 0; - - virtual void PushIntoCullOutputQueue(const SCheckOcclusionOutput& rCheckOcclusionOutput) = 0; - virtual bool PopFromCullOutputQueue(SCheckOcclusionOutput* pCheckOcclusionOutput) = 0; - - virtual void BeginCulling() = 0; - virtual void RemoveCullJobProducer() = 0; - virtual void AddCullJobProducer() = 0; - -#ifndef _RELEASE - virtual void CoverageBufferDebugDraw() = 0; -#endif - - virtual bool LoadOcclusionMesh(const char* pFileName) = 0; - - virtual void ClearStatObjGarbage() = 0; - virtual void CheckForGarbage(IStatObj* pObject) = 0; - virtual void UnregisterForGarbage(IStatObj* pObject) = 0; - - virtual int GetObjectLOD(const IRenderNode* pObj, float fDistance) = 0; - virtual bool RayStatObjIntersection(IStatObj* pStatObj, const Matrix34& objMat, _smart_ptr pMat, Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, bool bFastTest) = 0; - virtual bool RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, _smart_ptr pMat) = 0; - virtual bool SphereRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const float fRadius, _smart_ptr pMat) = 0; - - virtual uint8 GetDissolveRef(float fDist, float fMaxViewDist) = 0; - virtual float GetLodDistDissolveRef(SLodDistDissolveTransitionState* pState, float curDist, int nNewLod, const SRenderingPassInfo& passInfo) = 0; - - virtual void CleanStreamingData() = 0; - virtual IRenderMesh* GetRenderMeshBox() = 0; - - virtual void PrepareCullbufferAsync(const CCamera& rCamera) = 0; - virtual void BeginOcclusionCulling(const SRenderingPassInfo& passInfo) = 0; - virtual void EndOcclusionCulling(bool waitForOcclusionJobCompletion = false) = 0; - virtual void RenderBufferedRenderMeshes(const SRenderingPassInfo& passInfo) = 0; - - virtual int GetListStaticTypesCount() = 0; - virtual int GetListStaticTypesGroupCount(int typeId) = 0; - virtual IStatInstGroup* GetIStatInstGroup(int typeId, int groupId) = 0; - - virtual int IncrementNextPrecachePointId() = 0; -}; diff --git a/Code/CryEngine/CryCommon/IOverloadSceneManager.h b/Code/CryEngine/CryCommon/IOverloadSceneManager.h deleted file mode 100644 index 9d391c5701..0000000000 --- a/Code/CryEngine/CryCommon/IOverloadSceneManager.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : IOverloadSceneManager interface declaration. - - -#ifndef CRYINCLUDE_CRYCOMMON_IOVERLOADSCENEMANAGER_H -#define CRYINCLUDE_CRYCOMMON_IOVERLOADSCENEMANAGER_H -#pragma once - -//================================================================================================== -// Name: COverloadSceneManager -// Desc: Manages overload values (eg CPU,GPU etc) -// 1.0="everything is ok" 0.0="very bad frame rate" -// various systems can use this information and control what is currently in the scene -// Author: James Chilvers -//================================================================================================== -struct IOverloadSceneManager -{ -public: - // - virtual ~IOverloadSceneManager() {} - - virtual void Reset() = 0; - virtual void Update() = 0; - - // Override auto-calculated scale to reach targetfps. - // frameScale is clamped to internal min/max values, - // dt is the length of time in seconds to transition - virtual void OverrideScale(float frameScale, float dt) = 0; - - // Go back to auto-calculated scale from an overridden scale - virtual void ResetScale(float dt) = 0; - // -};//------------------------------------------------------------------------------------------------ - -#endif // CRYINCLUDE_CRYCOMMON_IOVERLOADSCENEMANAGER_H diff --git a/Code/CryEngine/CryCommon/IPathfinder.h b/Code/CryEngine/CryCommon/IPathfinder.h index 3e50bb09cb..97e5f7b4f1 100644 --- a/Code/CryEngine/CryCommon/IPathfinder.h +++ b/Code/CryEngine/CryCommon/IPathfinder.h @@ -109,7 +109,7 @@ struct NavigationBlocker , costMultMod(0) , radialDecay(false) {AZ_Assert(false, "Should never get called"); } - Sphere sphere; + ::Sphere sphere; bool radialDecay; bool directional; diff --git a/Code/CryEngine/CryCommon/IPerfHud.h b/Code/CryEngine/CryCommon/IPerfHud.h deleted file mode 100644 index 33104435dc..0000000000 --- a/Code/CryEngine/CryCommon/IPerfHud.h +++ /dev/null @@ -1,145 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Performance HUD - - -#ifndef CRYINCLUDE_CRYCOMMON_IPERFHUD_H -#define CRYINCLUDE_CRYCOMMON_IPERFHUD_H -#pragma once - - -#include -#include -#include -#include - -struct ICryPerfHUDWidget - : public _reference_target_t -{ - // - enum EWidgetID - { - eWidget_Warnings = 0, - eWidget_RenderStats, - eWidget_StreamingStats, - eWidget_RenderBatchStats, - eWidget_FpsBuckets, - eWidget_Particles, - eWidget_PakFile, - eWidget_Num, //number of widgets - }; - - ICryPerfHUDWidget(int id = -1) - : m_id(id) - {} - - // - virtual ~ICryPerfHUDWidget() {} - - virtual void Reset() = 0; - virtual void Update() = 0; - virtual bool ShouldUpdate() = 0; - virtual void LoadBudgets(XmlNodeRef perfXML) = 0; - virtual void SaveStats(XmlNodeRef statsXML) = 0; - virtual void Enable(int mode) = 0; - virtual void Disable() = 0; - // - - int m_id; -}; - -// Base Interface for all engine module extensions -struct ICryPerfHUD - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(ICryPerfHUD, 0x268d142e043d464c, 0xa0776580f81b988a); - - struct PerfBucket - { - ILINE PerfBucket(float _target) - { - target = _target; - timeAtTarget = 0.f; - } - - float target; - float timeAtTarget; - }; - - enum EHudState - { - eHudOff = 0, - eHudInFocus, - eHudOutOfFocus, - eHudNumStates, - }; - - // - // Called once to initialize HUD. - virtual void Init() = 0; - virtual void Done() = 0; - virtual void Draw() = 0; - virtual void LoadBudgets() = 0; - virtual void SaveStats(const char* filename = NULL) = 0; - virtual void ResetWidgets() = 0; - virtual void SetState(EHudState state) = 0; - virtual void Reset() = 0; - virtual void Destroy() = 0; - - // Retrieve name of the extension module. - virtual void Show(bool bRestoreState) = 0; - - virtual void AddWidget(ICryPerfHUDWidget* pWidget) = 0; - virtual void RemoveWidget(ICryPerfHUDWidget* pWidget) = 0; - - virtual minigui::IMiniCtrl* CreateMenu(const char* name, minigui::IMiniCtrl* pParent = NULL) = 0; - virtual bool CreateCVarMenuItem(minigui::IMiniCtrl* pMenu, const char* name, const char* controlVar, float controlVarOn, float controlVarOff) = 0; - virtual bool CreateCallbackMenuItem(minigui::IMiniCtrl* pMenu, const char* name, minigui::ClickCallback clickCallback, void* pCallbackData) = 0; - virtual minigui::IMiniInfoBox* CreateInfoMenuItem(minigui::IMiniCtrl* pMenu, const char* name, minigui::RenderCallback renderCallback, const minigui::Rect& rect, bool onAtStart = false) = 0; - virtual minigui::IMiniTable* CreateTableMenuItem(minigui::IMiniCtrl* pMenu, const char* name) = 0; - - virtual minigui::IMiniCtrl* GetMenu(const char* name) = 0; - - virtual void EnableWidget(ICryPerfHUDWidget::EWidgetID id, int mode) = 0; - virtual void DisableWidget(ICryPerfHUDWidget::EWidgetID id) = 0; - - //Warnings - Widget Specific interface - virtual void AddWarning(float duration, const char* fmt, va_list argList) = 0; - virtual bool WarningsWindowEnabled() const = 0; - - //FPS - Widget Specific interface - virtual const std::vector* GetFpsBuckets(float& totalTime) const = 0; - // -}; - -DECLARE_SMART_POINTERS(ICryPerfHUD); - -void CryPerfHUDWarning(float duration, const char*, ...) PRINTF_PARAMS(2, 3); -inline void CryPerfHUDWarning(float duration, const char* format, ...) -{ - if (gEnv && gEnv->pSystem) - { - ICryPerfHUD* pPerfHud = gEnv->pSystem->GetPerfHUD(); - - if (pPerfHud) - { - va_list args; - va_start(args, format); - pPerfHud->AddWarning(duration, format, args); - va_end(args); - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_IPERFHUD_H diff --git a/Code/CryEngine/CryCommon/IPhysicsDebugRenderer.h b/Code/CryEngine/CryCommon/IPhysicsDebugRenderer.h deleted file mode 100644 index eb73a64dc9..0000000000 --- a/Code/CryEngine/CryCommon/IPhysicsDebugRenderer.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IPHYSICSDEBUGRENDERER_H -#define CRYINCLUDE_CRYCOMMON_IPHYSICSDEBUGRENDERER_H -#pragma once - - -#endif // CRYINCLUDE_CRYCOMMON_IPHYSICSDEBUGRENDERER_H diff --git a/Code/CryEngine/CryCommon/IProximityTriggerSystem.h b/Code/CryEngine/CryCommon/IProximityTriggerSystem.h deleted file mode 100644 index 496c8ade85..0000000000 --- a/Code/CryEngine/CryCommon/IProximityTriggerSystem.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H -#define CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H -#pragma once - -#include -#include -#include -#include -#include // AABB - - -/** - * Represents a registered proximity trigger. - * - * Contains the id of the trigger, its bounds, and whether or not it's active. - */ -struct SProximityElement -{ - AZ::EntityId id; - AABB aabb; - uint32 bActivated : 1; - std::vector inside; - - using NarrowPassCheckFunction = AZStd::function; - - // Can be used to do an optional narrow pass check on this proximity element - NarrowPassCheckFunction m_narrowPassChecker; - - SProximityElement() - { - id = AZ::EntityId(0); - bActivated = 0; - } - ~SProximityElement() - { - } - bool AddInside(SProximityElement* elem) - { - // Sorted add. - return stl::binary_insert_unique(inside, elem); - } - bool RemoveInside(SProximityElement* elem) - { - // sorted remove. - return stl::binary_erase(inside, elem); - } - bool IsInside(SProximityElement* elem) - { - return std::binary_search(inside.begin(), inside.end(), elem); - } - - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{} -}; - -/** - * Bus for events dispatched by the proximity trigger system as triggered are - * entered and exited by entities in the world. - */ -class ProximityTriggerEvents - : public AZ::EBusTraits -{ -public: - ////////////////////////////////////////////////////////////////////////// - // Ebus Traits - // ID'd on trigger entity Id - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - using BusIdType = AZ::EntityId; - ////////////////////////////////////////////////////////////////////////// - - virtual ~ProximityTriggerEvents() {} - - /// Dispatched when an entity enters a trigger. The bus message is ID'd on the triggers entity Id. - virtual void OnTriggerEnter(AZ::EntityId /*entityEntering*/) {}; - - /// Dispatched when an entity exits a trigger. The bus message is ID'd on the triggers entity Id. - virtual void OnTriggerExit(AZ::EntityId /*entityExiting*/) {}; -}; - -using ProximityTriggerEventBus = AZ::EBus; - -/** - * Bus for requests sent by components or game code to the proximity trigger system. - */ -class ProximityTriggerSystemRequests - : public AZ::EBusTraits -{ -public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - proximity trigger system is a singleton - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - virtual ~ProximityTriggerSystemRequests() {} - - /// Creates a new trigger instance. - virtual SProximityElement* CreateTrigger(SProximityElement::NarrowPassCheckFunction narrowPassChecker = nullptr) = 0; - - /// Removes a trigger and queues it for deletion. - virtual void RemoveTrigger(SProximityElement* pTrigger) = 0; - - /// Moves a trigger in the world or redefines its dimensions. - virtual void MoveTrigger(SProximityElement* pTrigger, const AABB& aabb, bool invalidateCachedAABB = false) = 0; - - /// Creates a proxy in the world associated with an entity (Component or Legacy) for interacting with proximity trigger instances. - virtual SProximityElement* CreateEntity(AZ::EntityId id) = 0; - - /** - * Set the entity's AABB to a unit AABB at the entity's world position if \aabb is empty, otherwise set the entity's AABB to \aabb - * @param pEntity The pointer to a SProximityElment whose AABB needs to be updated - * @param pos World position of the entity - * @param aabb The new AABB in world space to set - */ - virtual void MoveEntity(SProximityElement* pEntity, const Vec3& pos, const AABB& aabb) = 0; - - /// Removes an entity's proximity trigger proxy. - virtual void RemoveEntity(SProximityElement* pEntity, bool instantEvent = false) = 0; -}; - -using ProximityTriggerSystemRequestBus = AZ::EBus; - -#endif // CRYINCLUDE_CRYCOMMON_IPROXIMITYTRIGGERSYSTEM_H diff --git a/Code/CryEngine/CryCommon/IRemoteCommand.h b/Code/CryEngine/CryCommon/IRemoteCommand.h deleted file mode 100644 index 03adb89b44..0000000000 --- a/Code/CryEngine/CryCommon/IRemoteCommand.h +++ /dev/null @@ -1,763 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network interface - - -#ifndef CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H -#define CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H -#pragma once - -#include -#include - -//----------------------------------------------------------------------------- -// Helpers for writing/reading command data stream from network message packets. -// Those interfaces automatically handle byteswapping for big endian systems. -// The native format for data inside the messages is little endian. -//----------------------------------------------------------------------------- - -/// Write stream interface -struct IDataWriteStream -{ -public: - virtual ~IDataWriteStream() {}; - -public: - // Virtualized write method for general data buffer - virtual void Write(const void* pData, const uint32 size) = 0; - - // Virtualized write method for types with size 8 (support byteswapping, a little bit faster than general case) - virtual void Write8(const void* pData) = 0; - - // Virtualized write method for types with size 4 (support byteswapping, a little bit faster than general case) - virtual void Write4(const void* pData) = 0; - - // Virtualized write method for types with size 2 (support byteswapping, a little bit faster than general case) - virtual void Write2(const void* pData) = 0; - - // Virtualized write method for types with size 1 (a little bit faster than general case) - virtual void Write1(const void* pData) = 0; - - // Get number of bytes written - virtual const uint32 GetSize() const = 0; - - // Convert to service network message - virtual struct IServiceNetworkMessage* BuildMessage() const = 0; - - // Save the data from this writer stream to the provided buffer - virtual void CopyToBuffer(void* pData) const = 0; - - // Destroy object (if dynamically created) - virtual void Delete() = 0; - -public: - IDataWriteStream& operator<<(const uint8& val) - { - Write1(&val); - return *this; - } - - IDataWriteStream& operator<<(const uint16& val) - { - Write2(&val); - return *this; - } - - IDataWriteStream& operator<<(const uint32& val) - { - Write4(&val); - return *this; - } - - IDataWriteStream& operator<<(const uint64& val) - { - Write8(&val); - return *this; - } - - IDataWriteStream& operator<<(const int8& val) - { - Write1(&val); - return *this; - } - - IDataWriteStream& operator<<(const int16& val) - { - Write2(&val); - return *this; - } - - IDataWriteStream& operator<<(const int32& val) - { - Write4(&val); - return *this; - } - - IDataWriteStream& operator<<(const int64& val) - { - Write8(&val); - return *this; - } - - IDataWriteStream& operator<<(const float& val) - { - Write4(&val); - return *this; - } - - // Bool is saved by writing an 8 bit value to make it portable - IDataWriteStream& operator<<(const bool& val) - { - const uint8 uVal = val ? 1 : 0; - Write1(&uVal); - return *this; - } - -public: - // Write C string to stream - void WriteString(const char* str); - - // Write string to stream - void WriteString(const string& str); - - // Write int8 value to stream - void WriteInt8(const int8 val) - { - Write1(&val); - } - - // Write int16 value to stream - void WriteInt16(const int16 val) - { - Write2(&val); - } - - // Write int32 value to stream - void WriteInt32(const int32 val) - { - Write4(&val); - } - - // Write int64 value to stream - void WriteInt64(const int64 val) - { - Write8(&val); - } - - // Write uint8 value to stream - void WriteUint8(const uint8 val) - { - Write1(&val); - } - - // Write uint16 value to stream - void WriteUint16(const uint16 val) - { - Write2(&val); - } - - // Write uint32 value to stream - void WriteUint32(const uint32 val) - { - Write4(&val); - } - - // Write uint64 value to stream - void WriteUint64(const uint64 val) - { - Write8(&val); - } - - // Write float value to stream - void WriteFloat(const float val) - { - Write4(&val); - } -}; - -//----------------------------------------------------------------------------- - -/// Read stream interface -/// This interface should support endianess swapping -struct IDataReadStream -{ -public: - virtual ~IDataReadStream() {}; - -public: - // Destroy object (if dynamically created) - virtual void Delete() = 0; - - // Skip given amount of data without reading it - virtual void Skip(const uint32 size) = 0; - - // Virtualized read method (for general buffers) - virtual void Read(void* pData, const uint32 size) = 0; - - // Virtualized read method for types with size 8 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read8(void* pData) = 0; - - // Virtualized read method for types with size 4 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read4(void* pData) = 0; - - // Virtualized read method for types with size 2 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read2(void* pData) = 0; - - // Virtualized read method for types with size 1 (a little bit faster than general method, supports byte swapping for BE systems) - virtual void Read1(void* pData) = 0; - - // Optimization case - get direct pointer to the underlying buffer - virtual const void* GetPointer() = 0; - -public: - IDataReadStream& operator<<(uint8& val) - { - Read1(&val); - return *this; - } - - IDataReadStream& operator<<(uint16& val) - { - Read2(&val); - return *this; - } - - IDataReadStream& operator<<(uint32& val) - { - Read4(&val); - return *this; - } - - IDataReadStream& operator<<(uint64& val) - { - Read8(&val); - return *this; - } - - IDataReadStream& operator<<(int8& val) - { - Read1(&val); - return *this; - } - - IDataReadStream& operator<<(int16& val) - { - Read2(&val); - return *this; - } - - IDataReadStream& operator<<(int32& val) - { - Read4(&val); - return *this; - } - - IDataReadStream& operator<<(int64& val) - { - Read8(&val); - return *this; - } - - IDataReadStream& operator<<(float& val) - { - Read4(&val); - return *this; - } - - // Bool is saved by writing an 8 bit value to make it portable - IDataReadStream& operator<<(bool& val) - { - uint8 uVal = 0; - Read1(&uVal); - val = (uVal != 0); - return *this; - } - -public: - // Read string from stream - string ReadString(); - - // Skip string data in a stream without loading the data - void SkipString(); - - // Read int8 from stream - int8 ReadInt8() - { - int8 val = 0; - Read1(&val); - return val; - } - - // Read int16 from stream - int16 ReadInt16() - { - int16 val = 0; - Read2(&val); - return val; - } - - // Read int32 from stream - int32 ReadInt32() - { - int32 val = 0; - Read4(&val); - return val; - } - - // Read int64 from stream - int64 ReadInt64() - { - int64 val = 0; - Read8(&val); - return val; - } - - // Read uint8 from stream - uint8 ReadUint8() - { - uint8 val = 0; - Read1(&val); - return val; - } - - // Read uint16 from stream - uint16 ReadUint16() - { - uint16 val = 0; - Read2(&val); - return val; - } - - // Read uint32 from stream - uint32 ReadUint32() - { - uint32 val = 0; - Read4(&val); - return val; - } - - // Read int64 from stream - uint64 ReadUint64() - { - uint64 val = 0; - Read8(&val); - return val; - } - - // Read float from stream - float ReadFloat() - { - float val = 0.0f; - Read4(&val); - return val; - } -}; - -//----------------------------------------------------------------------------- - -/// Remote command class info (simple RTTI) -struct IRemoteCommandClass -{ -public: - virtual ~IRemoteCommandClass() {}; - - // Get class name - virtual const char* GetName() const = 0; - - // Create command instance - virtual struct IRemoteCommand* CreateObject() = 0; -}; - -/// Remote command interface -struct IRemoteCommand -{ -protected: - virtual ~IRemoteCommand() {}; - -public: - // Get command class - virtual IRemoteCommandClass* GetClass() const = 0; - - // Save to data stream - virtual void SaveToStream(struct IDataWriteStream& writeStream) const = 0; - - // Load from data stream - virtual void LoadFromStream(struct IDataReadStream& readStream) = 0; - - // Execute (remote call) = 0; - virtual void Execute() = 0; - - // Delete the command object (can be allocated from different heap) - virtual void Delete() = 0; -}; - -//----------------------------------------------------------------------------- - -// This is a implementation of a synchronous listener (limited to the engine tick rate) -// that processes and responds to the raw messages received from clients. -struct IRemoteCommandListenerSync -{ -public: - virtual ~IRemoteCommandListenerSync() {}; - - // Process a raw message and optionally provide an answer to the request, return true if you have processed the message. - // Messages is accessible via the data reader. Response can be written to a data writer. - virtual bool OnRawMessageSync(const class ServiceNetworkAddress& remoteAddress, struct IDataReadStream& msg, struct IDataWriteStream& response) = 0; -}; - -//----------------------------------------------------------------------------- - -// This is a implementation of a asynchronous listener (called from network thread) -// that processes and responds to the raw messages received from clients. -struct IRemoteCommandListenerAsync -{ -public: - virtual ~IRemoteCommandListenerAsync() {}; - - // Process a raw message and optionally provide an answer to the request, return true if you have processed the message. - // Messages is accessible via the data reader. Response can be written to a data writer. - virtual bool OnRawMessageAsync(const class ServiceNetworkAddress& remoteAddress, struct IDataReadStream& msg, struct IDataWriteStream& response) = 0; -}; - -//----------------------------------------------------------------------------- - -/// Remote command server -struct IRemoteCommandServer -{ -protected: - virtual ~IRemoteCommandServer() {}; - -public: - // Execute all of the received pending commands - // This should be called from a safe place (main thread) - virtual void FlushCommandQueue() = 0; - - // Suppress command execution - virtual void SuppressCommands() = 0; - - // Resume command execution - virtual void ResumeCommands() = 0; - - // Register/Unregister synchronous message listener (limited to tick rate) - virtual void RegisterSyncMessageListener(IRemoteCommandListenerSync* pListener) = 0; - virtual void UnregisterSyncMessageListener(IRemoteCommandListenerSync* pListener) = 0; - - // Register/Unregister asynchronous message listener (called from network thread) - virtual void RegisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) = 0; - virtual void UnregisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) = 0; - - // Broadcast a message to all connected clients - virtual void Broadcast(IServiceNetworkMessage* pMessage) = 0; - - // Do we have any clients connected ? - virtual bool HasConnectedClients() const = 0; - - // Delete the client - virtual void Delete() = 0; -}; - -//----------------------------------------------------------------------------- - -/// Connection to remote command server -struct IRemoteCommandConnection -{ -protected: - virtual ~IRemoteCommandConnection() {}; - -public: - // Are we connected ? - // This returns false when the underlying network connection has failed (sockets error). - // Also, this returns false if the remote connection was closed by remote peer. - virtual bool IsAlive() const = 0; - - // Get address of remote command server - // This returns the full address of the endpoint (with valid port) - virtual const ServiceNetworkAddress& GetRemoteAddress() const = 0; - - // Send raw message to the other side of this connection. - // Raw messages are not buffer and are sent right away, - // they also have precedence over internal command traffic. - // The idea is that you need some kind of bidirectional signaling - // channel to extend the rather one-directional nature of commands. - // Returns true if message was added to the send queue. - virtual bool SendRawMessage(IServiceNetworkMessage* pMessage) = 0; - - // See if there's a raw message waiting for us and if it is, get it - // Be aware that messages are reference counted. - virtual IServiceNetworkMessage* ReceiveRawMessage() = 0; - - // Close connection - // - pending commands are not sent - // - pending raw messages are sent or not (depending on the flag) - virtual void Close(bool bFlushQueueBeforeClosing = false) = 0; - - // Add internal reference to object (Refcounting interface) - virtual void AddRef() = 0; - - // Release internal reference to object (Refcounting interface) - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// Remote command client -struct IRemoteCommandClient -{ -protected: - virtual ~IRemoteCommandClient() {}; - -public: - // Connect to remote server, returns true on success, false on failure - virtual IRemoteCommandConnection* ConnectToServer(const class ServiceNetworkAddress& serverAddress) = 0; - - // Schedule command to be executed on the all of the remote servers - virtual bool Schedule(const IRemoteCommand& command) = 0; - - // Delete the client object - virtual void Delete() = 0; -}; - -//----------------------------------------------------------------------------- - -/// Remote command manager -struct IRemoteCommandManager -{ -public: - virtual ~IRemoteCommandManager() {}; - - // Set debug message verbose level - virtual void SetVerbosityLevel(const uint32 level) = 0; - - // Create local server for executing remote commands on given local port - virtual IRemoteCommandServer* CreateServer(uint16 localPort) = 0; - - // Create client interface for executing remote commands on remote servers - virtual IRemoteCommandClient* CreateClient() = 0; - - // Register command class (will be accessible by both clients and server) - virtual void RegisterCommandClass(IRemoteCommandClass& commandClass) = 0; -}; - -//----------------------------------------------------------------------------- - -/// Class RTTI wrapper for remote command classes -template< typename T > -class CRemoteCommandClass - : public IRemoteCommandClass -{ -private: - const char* m_szName; - -public: - CRemoteCommandClass(const char* szName) - : m_szName(szName) - {} - - virtual const char* GetName() const - { - return m_szName; - } - - virtual struct IRemoteCommand* CreateObject() - { - return new T(); - } -}; - -#define DECLARE_REMOTE_COMMAND(x) \ -public: static IRemoteCommandClass& GetStaticClass() { \ - static IRemoteCommandClass* theClass = new CRemoteCommandClass(#x); return *theClass; } \ -public: virtual IRemoteCommandClass* GetClass() const { return &GetStaticClass(); } \ -public: virtual void Delete() { delete this; } \ -public: virtual void SaveToStream(IDataWriteStream & writeStream) const { const_cast(this)->Serialize(writeStream); } \ -public: virtual void LoadFromStream(IDataReadStream & readStream) { Serialize(readStream); } - -//----------------------------------------------------------------------------- - -/// CryString serialization helper (read) -inline IDataReadStream& operator<<(IDataReadStream& stream, string& outString) -{ - const uint32 kMaxTempString = 256; - - // read length - uint32 length = 0; - stream << length; - - // load string - if (length > 0) - { - if (length < kMaxTempString) - { - // load the string into temporary buffer - char temp[kMaxTempString]; - stream.Read(&temp, length); - temp[length] = 0; - - // set the string with new value - outString = temp; - } - else - { - // allocate temporary memory and load the string - std::vector temp; - temp.resize(length + 1, 0); - stream.Read(&temp[0], length); - - // set the string with new value - outString = &temp[0]; - } - } - else - { - // empty string - outString.clear(); - } - - return stream; -} - -/// CryString serialization helper (write) -inline IDataWriteStream& operator<<(IDataWriteStream& stream, const string& str) -{ - // write length - const uint32 length = static_cast(str.length()); - stream << length; - - // write string data - if (length > 0) - { - stream.Write(str.c_str(), length); - } - - return stream; -} - -//------------------------------------------------------------------------ - -/// Vector serialization helper (reading) -template< class T > -IDataReadStream& operator<<(IDataReadStream& ar, std::vector& outVector) -{ - // Load item count - uint32 count = 0; - ar << count; - - // Adapt the vector size (exact fit) - outVector.resize(count); - - // Load items - for (uint32 i = 0; i < count; ++i) - { - ar << outVector[i]; - } - - return ar; -} - -/// Vector serialization helper (writing) -template< class T > -IDataWriteStream& operator<<(IDataWriteStream& ar, const std::vector& vec) -{ - // Save item count - const uint32 count = vec.size(); - ar << count; - - // Save items - for (uint32 i = 0; i < count; ++i) - { - ar << const_cast(vec[i]); - } - - return ar; -} - -//------------------------------------------------------------------------ - -inline void IDataWriteStream::WriteString(const char* str) -{ - string tempString(str); - *this << tempString; -} - -inline void IDataWriteStream::WriteString(const string& str) -{ - *this << str; -} - -inline string IDataReadStream::ReadString() -{ - string ret; - *this << ret; - return ret; -} - -inline void IDataReadStream::SkipString() -{ - // read length - uint32 length = 0; - *this << length; - Skip(length); -} - - -//------------------------------------------------------------------------ - -// Helper class for using the data reader and writer classes -// The only major differce betwen auto_ptr is that we call Delete() instead of operator delete -template -class TAutoDelete -{ -public: - T* m_ptr; - -public: - TAutoDelete(T* ptr) - : m_ptr(ptr) - { - } - - ~TAutoDelete() - { - if (NULL != m_ptr) - { - m_ptr->Delete(); - m_ptr = NULL; - } - } - - operator bool() - { - return (NULL != m_ptr); - } - - operator T& () - { - return *m_ptr; - } - - T* operator->() - { - return m_ptr; - } - -private: - TAutoDelete(const TAutoDelete& other) - : m_ptr(NULL){}; - TAutoDelete& operator=(const TAutoDelete& other) { return *this; } -}; - -//------------------------------------------------------------------------ - - -#endif // CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H diff --git a/Code/CryEngine/CryCommon/IRenderer.h b/Code/CryEngine/CryCommon/IRenderer.h index 71c2500d80..5b9a284edf 100644 --- a/Code/CryEngine/CryCommon/IRenderer.h +++ b/Code/CryEngine/CryCommon/IRenderer.h @@ -16,12 +16,17 @@ #include "Cry_Geo.h" #include "Cry_Camera.h" #include "ITexture.h" -#include // <> required for Interfuscator +#include "Cry_Vector2.h" +#include "Cry_Vector3.h" +#include "Cry_Matrix33.h" +#include "Cry_Color.h" +#include "smartptr.h" +#include "StringUtils.h" +#include // <> required for Interfuscator +#include "smartptr.h" #include #include -#include "IResourceCompilerHelper.h" // for IResourceCompilerHelper::ERcCallResult - // forward declarations struct SRenderingPassInfo; struct SRTStack; @@ -95,12 +100,10 @@ struct IFFont; struct IFFont_RenderProxy; struct STextDrawContext; struct IRenderMesh; -class IOpticsManager; struct ShadowFrustumMGPUCache; struct IAsyncTextureCompileListener; struct IClipVolume; struct SClipVolumeBlendInfo; -class IImageFile; class CRenderView; struct SDynTexture2; class CTexture; @@ -694,7 +697,6 @@ public: #include // <> required for Interfuscator //DOC-IGNORE-END #include -#include "IMeshBaking.h" // Flags passed in function FreeResources. #define FRR_SHADERS 1 @@ -955,25 +957,6 @@ protected: virtual ~ITextureStreamListener() {} }; -#if defined(CRY_ENABLE_RC_HELPER) -//////////////////////////////////////////////////////////////////////////// -// Listener for asynchronous texture compilation. -// Connects the listener to the task-queue of pending compilation requests. -enum ERcExitCode; -struct IAsyncTextureCompileListener -{ -public: - virtual void OnCompilationStarted(const char* source, const char* target, int nPending) = 0; - virtual void OnCompilationFinished(const char* source, const char* target, IResourceCompilerHelper::ERcCallResult nReturnCode) = 0; - - virtual void OnCompilationQueueTriggered(int nPending) = 0; - virtual void OnCompilationQueueDepleted() = 0; - -protected: - virtual ~IAsyncTextureCompileListener() {} -}; -#endif - enum eDolbyVisionMode { eDVM_Disabled, @@ -1071,11 +1054,6 @@ namespace AZ { namespace Vertex { class Format; } - namespace VideoRenderer - { - struct IVideoRenderer; - struct DrawArguments; - } } enum eRenderPrimitiveType : int8; enum RenderIndexType : int; @@ -1472,7 +1450,6 @@ struct IRenderer ///////////////////////////////////////////////////////////////////////////////// // Shaders/Shaders management ///////////////////////////////////////////////////////////////////////////////// - virtual void EF_SetShaderMissCallback(ShaderCacheMissCallback callback) = 0; virtual const char* EF_GetShaderMissLogPath() = 0; ///////////////////////////////////////////////////////////////////////////////// @@ -1485,7 +1462,6 @@ struct IRenderer // Is threadsafe virtual bool EF_ReloadFile_Request (const char* szFileName) = 0; - virtual _smart_ptr EF_LoadImage(const char* szFileName, uint32 nFlags) = 0; // Summary: // Remaps shader gen mask to common global mask. virtual uint64 EF_GetRemapedShaderMaskGen(const char* name, uint64 nMaskGen = 0, bool bFixup = 0) = 0; @@ -1531,11 +1507,6 @@ struct IRenderer // Summary: // Loads lightmap for name. virtual int EF_LoadLightmap (const char* name) = 0; - virtual bool EF_RenderEnvironmentCubeHDR (int size, Vec3& Pos, TArray& vecData) = 0; - - // Summary: - // Creates new RE (RenderElement) of type (edt). - virtual IRenderElement* EF_CreateRE (EDataType edt) = 0; // Summary: // Starts using of the shaders (return first index for allow recursions). @@ -1572,7 +1543,6 @@ struct IRenderer virtual int EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0; virtual uint32 EF_GetDeferredLightsNum(eDeferredLightType eLightType = eDLT_DeferredLight) = 0; virtual void EF_ClearDeferredLightsList() = 0; - virtual TArray* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, eDeferredLightType eLightType = eDLT_DeferredLight) = 0; virtual uint8 EF_AddDeferredClipVolume(const IClipVolume* pClipVolume) = 0; virtual bool EF_SetDeferredClipVolumeBlendData(const IClipVolume* pClipVolume, const SClipVolumeBlendInfo& blendInfo) = 0; @@ -1766,8 +1736,6 @@ struct IRenderer virtual void RemoveTexture(unsigned int TextureId) = 0; virtual void DeleteFont(IFFont* font) = 0; - virtual bool BakeMesh(const SMeshBakingInputParams* pInputParams, SMeshBakingOutput* pReturnValues) = 0; - ///////////////////////////////////////////////////////////////////////////////////////////////////// // This routines uses 2 destination surfaces. It triggers a backbuffer copy to one of its surfaces, // and then copies the other surface to system memory. This hopefully will remove any @@ -1874,8 +1842,6 @@ struct IRenderer virtual SDepthTexture* CreateDepthSurface(int nWidth, int nHeight, bool shaderResourceView = false) = 0; virtual void DestroyDepthSurface(SDepthTexture* pDepthSurf) = 0; - virtual IOpticsElementBase* CreateOptics(EFlareType type) const = 0; - // Note: // Used for pausing timer related stuff. // Example: @@ -2375,36 +2341,11 @@ struct IRenderer virtual void EndProfilerSection(const char* name) = 0; virtual void AddProfilerLabel(const char* name) = 0; - // Video Renderer interface - virtual void InitializeVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) = 0; - virtual void CleanupVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer) = 0; - virtual void DrawVideoRenderer(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments) = 0; - private: // use private for EF_Query to prevent client code to submit arbitrary combinations of output data/size virtual void EF_QueryImpl(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1) = 0; }; -// util class to change wireframe mode -class CScopedWireFrameMode -{ -public: - CScopedWireFrameMode(IRenderer* pRenderer, int nMode) - : m_pRenderer(pRenderer) - , m_nMode(nMode) - { - (void) m_nMode; // removes not used warning - pRenderer->PushWireframeMode(nMode); - } - ~CScopedWireFrameMode() - { - m_pRenderer->PopWireframeMode(); - } -private: - IRenderer* m_pRenderer; - int m_nMode; -}; - struct SShaderCacheStatistics { size_t m_nTotalLevelShaderCacheMisses; diff --git a/Code/CryEngine/CryCommon/IResourceCollector.h b/Code/CryEngine/CryCommon/IResourceCollector.h deleted file mode 100644 index a3c88f507b..0000000000 --- a/Code/CryEngine/CryCommon/IResourceCollector.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H -#pragma once - - -// used to collect the assets needed for streaming and to gather statistics -struct IResourceCollector -{ - // - // Arguments: - // dwMemSize 0xffffffff if size is unknown - // Returns: - // true=new resource was added, false=resource was already registered - virtual bool AddResource(const char* szFileName, const uint32 dwMemSize) = 0; - - // Arguments: - // szFileName - needs to be registered before with AddResource() - // pInstance - must not be 0 - virtual void AddInstance(const char* szFileName, void* pInstance) = 0; - // - // Arguments: - // szFileName - needs to be registered before with AddResource() - virtual void OpenDependencies(const char* szFileName) = 0; - // - virtual void CloseDependencies() = 0; - - // Resets the internal data structure for the resource collector. - virtual void Reset() = 0; - // -protected: - virtual ~IResourceCollector() {} -}; - - -class NullResCollector - : public IResourceCollector -{ -public: - virtual bool AddResource([[maybe_unused]] const char* szFileName, [[maybe_unused]] const uint32 dwMemSize) { return true; } - virtual void AddInstance([[maybe_unused]] const char* szFileName, [[maybe_unused]] void* pInstance) {} - virtual void OpenDependencies([[maybe_unused]] const char* szFileName) {} - virtual void CloseDependencies() {} - virtual void Reset() {} - - virtual ~NullResCollector() {} -}; - - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H - - diff --git a/Code/CryEngine/CryCommon/IResourceCompilerHelper.cpp b/Code/CryEngine/CryCommon/IResourceCompilerHelper.cpp deleted file mode 100644 index 380c94e4c7..0000000000 --- a/Code/CryEngine/CryCommon/IResourceCompilerHelper.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* -* 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. -* -*/ -#include "IResourceCompilerHelper.h" - -#include -// DO NOT USE AZSTD. - -#include // std string used here. -#include -#include - -// the following block is for _mkdir on windows and mkdir on other platforms. -#if defined(_WIN32) -# include -#else -# include -# include -#endif - -namespace RCPathUtil -{ - const char* GetExt(const char* filepath) - { - const char* str = filepath; - size_t len = strlen(filepath); - for (const char* p = str + len - 1; p >= str; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - // we've reached a path separator - it means there's no extension in this name - return ""; - case '.': - // there's an extension in this file name - return p + 1; - } - } - return ""; - } - - const char* GetFile(const char* filepath) - { - const size_t len = strlen(filepath); - for (const char* p = filepath + len - 1; p >= filepath; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - return p + 1; - } - } - return filepath; - } - - - //! Replace extension for given file. - std::string RemoveExtension(const char* filepath) - { - std::string filepathstr = filepath; - const char* str = filepathstr.c_str(); - for (const char* p = str + filepathstr.length() - 1; p >= str; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - // we've reached a path separator - it means there's no extension in this name - return filepathstr; - case '.': - // there's an extension in this file name - filepathstr.erase(p - str); - return filepathstr; - } - } - // it seems the file name is a pure name, without path or extension - return filepathstr; - } - - std::string ReplaceExtension(const char* filepath, const char* ext) - { - std::string str = filepath; - if (ext != 0) - { - str = RemoveExtension(str.c_str()); - if (ext[0] != 0 && ext[0] != '.') - { - str += "."; - } - str += ext; - } - return str; - } - - std::string GetPath(const char* filepath) - { - std::string filepathstr = filepath; - const char* str = filepathstr.c_str(); - for (const char* p = str + filepathstr.length() - 1; p >= str; --p) - { - switch (*p) - { - case ':': - case '/': - case '\\': - // we've reached a path separator - it means there's no extension in this name - return filepathstr.substr(0, p - str); - } - } - // it seems the file name is a pure name, without path - return ""; - } - - - ////////////////////////////////////////////////////////////////////////// - bool IsRelativePath(const char* p) - { - if (!p || !p[0]) - { - return true; - } - return p[0] != '/' && p[0] != '\\' && !strchr(p, ':'); - } -} - -const char* IResourceCompilerHelper::SourceImageFormatExts[NUM_SOURCE_IMAGE_TYPE] = { "tif", "bmp", "gif", "jpg", "jpeg", "jpe", "tga", "png" }; -const char* IResourceCompilerHelper::SourceImageFormatExtsWithDot[NUM_SOURCE_IMAGE_TYPE] = { ".tif", ".bmp", ".gif", ".jpg", ".jpeg", ".jpe", ".tga", ".png" }; -const char* IResourceCompilerHelper::EngineImageFormatExts[NUM_ENGINE_IMAGE_TYPE] = { "dds" }; -const char* IResourceCompilerHelper::EngineImageFormatExtsWithDot[NUM_ENGINE_IMAGE_TYPE] = { ".dds" }; - - -IResourceCompilerHelper::ERcCallResult IResourceCompilerHelper::ConvertResourceCompilerExitCodeToResultCode(int exitCode) -{ - switch (exitCode) - { - case eRcExitCode_Success: - case eRcExitCode_UserFixing: - return eRcCallResult_success; - - case eRcExitCode_Error: - return eRcCallResult_error; - - case eRcExitCode_FatalError: - return eRcCallResult_error; - case eRcExitCode_Crash: - return eRcCallResult_crash; - } - return eRcCallResult_error; -} - - -////////////////////////////////////////////////////////////////////////// -const char* IResourceCompilerHelper::GetCallResultDescription(IResourceCompilerHelper::ERcCallResult result) -{ - switch (result) - { - case eRcCallResult_success: - return "Success."; - case eRcCallResult_notFound: - return "ResourceCompiler executable was not found."; - case eRcCallResult_error: - return "ResourceCompiler exited with an error."; - case eRcCallResult_crash: - return "ResourceCompiler crashed! Please report this. Include source asset and this log in the report."; - default: - return "Unexpected failure in ResultCompilerHelper."; - } -} - -// Arguments: -// szFilePath - could be source or destination filename -void IResourceCompilerHelper::GetOutputFilename(const char* szFilePath, char* buffer, size_t bufferSizeInBytes) -{ - if (IResourceCompilerHelper::IsSourceImageFormatSupported(szFilePath)) - { - std::string newString = RCPathUtil::ReplaceExtension(szFilePath, "dds"); - azstrncpy(buffer, bufferSizeInBytes, newString.c_str(), bufferSizeInBytes - 1); - return; - } - - azstrncpy(buffer, bufferSizeInBytes, szFilePath, bufferSizeInBytes - 1); -} - -IResourceCompilerHelper::ERcCallResult IResourceCompilerHelper::InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog) -{ - - const char* szDstFileName = RCPathUtil::GetFile(szDstFilePath); - std::string pathOnly = RCPathUtil::GetPath(szDstFilePath); - const int maxStringSize = 512; - char szRemoteCmdLine[maxStringSize] = { 0 }; - char szFullPathToSourceFile[maxStringSize] = { 0 }; - - if (RCPathUtil::IsRelativePath(szSrcFilePath)) - { - azstrcat(szFullPathToSourceFile, maxStringSize, "#ENGINEROOT#"); - azstrcat(szFullPathToSourceFile, maxStringSize, "\\"); - } - azstrcat(szFullPathToSourceFile, maxStringSize, szSrcFilePath); - - azstrcat(szRemoteCmdLine, maxStringSize, " /targetroot=\""); - azstrcat(szRemoteCmdLine, maxStringSize, pathOnly.c_str()); - azstrcat(szRemoteCmdLine, maxStringSize, "\""); - - azstrcat(szRemoteCmdLine, maxStringSize, " /overwritefilename=\""); - azstrcat(szRemoteCmdLine, maxStringSize, szDstFileName); - azstrcat(szRemoteCmdLine, maxStringSize, "\""); - - return CallResourceCompiler(szFullPathToSourceFile, szRemoteCmdLine, nullptr, true, false, !bUserDialog); -} - -unsigned int IResourceCompilerHelper::GetNumSourceImageFormats() -{ - return NUM_SOURCE_IMAGE_TYPE; -} - -const char* IResourceCompilerHelper::GetSourceImageFormat(unsigned int index, bool bWithDot) -{ - if (index >= GetNumSourceImageFormats()) - { - return nullptr; - } - - if (bWithDot) - { - return SourceImageFormatExtsWithDot[index]; - } - else - { - return SourceImageFormatExts[index]; - } -} - -unsigned int IResourceCompilerHelper::GetNumEngineImageFormats() -{ - return NUM_ENGINE_IMAGE_TYPE; -} - -const char* IResourceCompilerHelper::GetEngineImageFormat(unsigned int index, bool bWithDot) -{ - if (index >= GetNumEngineImageFormats()) - { - return nullptr; - } - - if (bWithDot) - { - return EngineImageFormatExtsWithDot[index]; - } - else - { - return EngineImageFormatExts[index]; - } -} - -bool IResourceCompilerHelper::IsSourceImageFormatSupported(const char* szFileNameOrExtension) -{ - if (!szFileNameOrExtension) // if this hits, might want to check the call site - { - return false; - } - - //check the string length - size_t len = strlen(szFileNameOrExtension); - if (len < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //find the ext by starting at the last character and moving backward to first he first '.' - const char* szExtension = nullptr; - size_t cur = len - 1; - while (cur && !szExtension) - { - if (szFileNameOrExtension[cur] == '.') - { - szExtension = &szFileNameOrExtension[cur]; - } - cur--; - } - if (len - cur < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //if we didn't find a '.' it could still be valid, they may not have - //passed it in. i.e. "dds" instead of ".dds" which is still valid - if (!szExtension) - { - //with no '.' the largest ext is currently 4 characters - //no point in going on if it is larger - if (len > 4) - { - return false; - } - - szExtension = szFileNameOrExtension; - } - - //loop over all the valid exts and see if it is one of them - for (unsigned int i = 0; i < GetNumSourceImageFormats(); ++i) - { - if (!azstricmp(szExtension, GetSourceImageFormat(i, szExtension[0] == '.'))) - { - return true; - } - } - - return false; -} - -bool IResourceCompilerHelper::IsGameImageFormatSupported(const char* szFileNameOrExtension) -{ - if (!szFileNameOrExtension) // if this hits, might want to check the call site - { - return false; - } - - //check the string length - size_t len = strlen(szFileNameOrExtension); - if (len < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //find the ext by starting at the last character and moving backward to first he first '.' - const char* szExtension = nullptr; - size_t cur = len - 1; - while (cur && !szExtension) - { - if (szFileNameOrExtension[cur] == '.') - { - szExtension = &szFileNameOrExtension[cur]; - } - cur--; - } - if (len - cur < 3)//no point in going on if the smallest valid ext is 3 characters - { - return false; - } - - //if we didn't find a '.' it could still be valid, they may not have - //passed it in. i.e. "dds" instead of ".dds" which is still valid - if (!szExtension) - { - //with no '.' the largest ext is currently 4 characters - //no point in going on if it is larger - if (len > 4) - { - return false; - } - - szExtension = szFileNameOrExtension; - } - - //loop over all the valid exts and see if it is one of them - for (unsigned int i = 0; i < GetNumEngineImageFormats(); ++i) - { - if (!azstricmp(szExtension, GetEngineImageFormat(i, szExtension[0] == '.'))) - { - return true; - } - } - - return false; -} diff --git a/Code/CryEngine/CryCommon/IResourceCompilerHelper.h b/Code/CryEngine/CryCommon/IResourceCompilerHelper.h deleted file mode 100644 index 52f05b0c84..0000000000 --- a/Code/CryEngine/CryCommon/IResourceCompilerHelper.h +++ /dev/null @@ -1,167 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H - -#pragma once - -// DO NOT USE AZSTD - -#include - -// IResourceCompilerHelper exists to define an interface that allows -// remote or local compilation of resources through the "resource Compiler" executable -// in most tools it will be implemented as a local execution. However, in the engine -// it will be substituted for a remote RC invocation through the Asset Processor if -// that system is enabled (via con var and define) - -// DO NOT USE CRYSTRING or CRY ALLOCATORS HERE. This is used in maya plugins, that kind of thing. -// the following path utils are special versions of these functions which take pains -// to not use crystring. -// the functions in this interface must be cross platform. -namespace RCPathUtil -{ - // given a full path, return the extension (it will be a pointer into the existing string) - const char* GetExt(const char* filepath); - - // given a full path, return the file only (it will be a pointer into the existing string) - const char* GetFile(const char* filepath); - - // given a filepath, get only the path. - std::string GetPath(const char* filepath); - std::string ReplaceExtension(const char* filepath, const char* ext); - bool IsRelativePath(const char* p); -} - -class IResourceCompilerListener; - -enum ERcExitCode -{ - eRcExitCode_Success = 0, // must be 0 - eRcExitCode_Error = 1, - eRcExitCode_FatalError = 100, - eRcExitCode_Crash = 101, - eRcExitCode_UserFixing = 200, - eRcExitCode_Pending = 666, -}; - -/// A pure virtual interface to the RC Helper system -/// the RC helper system allows you to make requests to a remote process in order to process -/// an asset for you. -class IResourceCompilerHelper -{ -public: - virtual ~IResourceCompilerHelper() {} - - // defines the result of a call via this API to the RC system - enum ERcCallResult - { - eRcCallResult_success, // everything is OK - eRcCallResult_notFound, // the RC executable is not found - eRcCallResult_error, // the RC executable returned an error - eRcCallResult_crash, // the RC executable did not finish - }; - - // - // Arguments: - // szFileName null terminated ABSOLUTE file path or 0 can be used to test for rc.exe existence - // relative path needs to be relative to rc_plugins directory - // szAdditionalSettings - 0 or e.g. "/refresh" or "/refresh /xyz=56" - // - // this is a SYNCHRONOUS, BLOCKING call and will return once the process is complete - virtual ERcCallResult CallResourceCompiler( - const char* szFileName = 0, - const char* szAdditionalSettings = 0, - IResourceCompilerListener* listener = 0, - bool bMayShowWindow = true, - bool bSilent = false, - bool bNoUserDialog = false, - const wchar_t* szWorkingDirectory = 0, - const wchar_t* szRootPath = 0) = 0; - - // InvokeResourceCompiler - a utility that calls the above CallResourceCompiler function - // but generates appropriate settings so you don't have to specify each option. - // This is a BLOCKING call - // the srcFile can be relative to the project root or an absolute path - // the dstFilePath MUST be relative to the same folder as the Src File path - // this will output dstFilePath in the same folder as srcFile. - virtual ERcCallResult InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog); - - // --------------------- utility functions --------------------------------- - - // given a RC.EXE process exit code like 101, convert it to the above ERcCallResult - ERcCallResult ConvertResourceCompilerExitCodeToResultCode(int exitCode); - - // given a ERcCallResult, convert it to a simple english string for debugging. - static const char* GetCallResultDescription(ERcCallResult result); - - // given a filename such as "blah.tif" convert it to the appropriate output name "blah.dds" for example - static void GetOutputFilename(const char* szFilePath, char* buffer, size_t bufferSizeInBytes); - - ////////////////////////////////////////////////////////////////////////// - - enum SourceImageTypes - { - SOURCE_IMAGE_TYPE_TIF, - SOURCE_IMAGE_TYPE_BMP, - SOURCE_IMAGE_TYPE_GIF, - SOURCE_IMAGE_TYPE_JPG, - SOURCE_IMAGE_TYPE_JPEG, - SOURCE_IMAGE_TYPE_JPE, - SOURCE_IMAGE_TYPE_TGA, - SOURCE_IMAGE_TYPE_PNG, - NUM_SOURCE_IMAGE_TYPE - }; - - enum EngineImageTypes - { - ENGINE_IMAGE_TYPE_DDS, - NUM_ENGINE_IMAGE_TYPE - }; - -private: - static const char* SourceImageFormatExts[NUM_SOURCE_IMAGE_TYPE]; - static const char* SourceImageFormatExtsWithDot[NUM_SOURCE_IMAGE_TYPE]; - static const char* EngineImageFormatExts[NUM_ENGINE_IMAGE_TYPE]; - static const char* EngineImageFormatExtsWithDot[NUM_ENGINE_IMAGE_TYPE]; - -public: - static unsigned int GetNumSourceImageFormats(); - static const char* GetSourceImageFormat(unsigned int index, bool bWithDot); - - static unsigned int GetNumEngineImageFormats(); - static const char* GetEngineImageFormat(unsigned int index, bool bWithDot); - - static bool IsSourceImageFormatSupported(const char* szExtension); - static bool IsGameImageFormatSupported(const char* szExtension); -}; - -//////////////////////////////////////////////////////////////////////////// -// Listener for synchronous resource-compilation. -// Connects the listener to the output of the RC process. -class IResourceCompilerListener -{ -public: - // FbxImportDialog relies on this enum being in the order from most verbose to least verbose - enum MessageSeverity - { - MessageSeverity_Debug = 0, - MessageSeverity_Info, - MessageSeverity_Warning, - MessageSeverity_Error - }; - - virtual void OnRCMessage(MessageSeverity /*severity*/, const char* /*text*/) {} - virtual ~IResourceCompilerListener() {} -}; - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H diff --git a/Code/CryEngine/CryCommon/IResourceManager.h b/Code/CryEngine/CryCommon/IResourceManager.h deleted file mode 100644 index 482cb30a5e..0000000000 --- a/Code/CryEngine/CryCommon/IResourceManager.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Resource Manager - - -#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H -#define CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H -#pragma once - -namespace AZ::IO -{ - struct IResourceList; -} - -struct SLayerPakStats -{ - struct SEntry - { - string name; - size_t nSize; - string status; - bool bStreaming; - }; - typedef std::vector TEntries; - TEntries m_entries; - - size_t m_MaxSize; - size_t m_UsedSize; -}; - -////////////////////////////////////////////////////////////////////////// -// IResource manager interface -////////////////////////////////////////////////////////////////////////// -struct IResourceManager -{ - // - virtual ~IResourceManager(){} - // Called by level system to set the level folder - virtual void PrepareLevel(const char* sLevelFolder, const char* sLevelName) = 0; - // Called by level system after the level has been unloaded. - virtual void UnloadLevel() = 0; - // Call to get current level resource list. - virtual AZ::IO::IResourceList* GetLevelResourceList() = 0; - // Load pak file from level cache to memory. - // sBindRoot is a path in virtual file system, where new pak will be mapper to (ex. LevelCache/mtl) - virtual bool LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading = true) = 0; - // Unloads level cache pak file from memory. - virtual void UnloadLevelCachePak(const char* sPakName) = 0; - - //Loads the pak file for mode switching into memory e.g. Single player mode to Multiplayer mode - virtual bool LoadModeSwitchPak(const char* sPakName, const bool multiplayer) = 0; - //Unloads the mode switching pak file - virtual void UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer) = 0; - - // Load general pak file to memory. - virtual bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) = 0; - // Unload all aync paks - virtual void UnloadAllAsyncPaks() = 0; - // Load pak file from active layer to memory. - virtual bool LoadLayerPak(const char* sLayerName) = 0; - // Unloads layer pak file from memory if no more references. - virtual void UnloadLayerPak(const char* sLayerName) = 0; - // Retrieve stats on the layer pak - virtual void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const = 0; - - // Return time it took to load and precache the level. - virtual CTimeValue GetLastLevelLoadTime() const = 0; - - virtual void GetMemoryStatistics(ICrySizer* pSizer) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H diff --git a/Code/CryEngine/CryCommon/ISerialize.h b/Code/CryEngine/CryCommon/ISerialize.h index 9ca4fb665c..5fb0d9a3aa 100644 --- a/Code/CryEngine/CryCommon/ISerialize.h +++ b/Code/CryEngine/CryCommon/ISerialize.h @@ -20,7 +20,6 @@ #include #include -#include "CountedValue.h" #include "MiniQueue.h" #include #include @@ -471,58 +470,6 @@ public: } } - template - void Value(const char* name, CountedValue& countedValue) - { - if (!BeginOptionalGroup(name, true)) - { - return; - } - if (IsWriting()) - { - T rawValue = countedValue.Peek(); - Value("Value", rawValue); - typename CountedValue::TCountedID rawId = countedValue.GetLatestID(); - Value("Id", rawId, 'ui32'); - } - - if (IsReading()) - { - T rawValue; - Value("Value", rawValue); - typename CountedValue::TCountedID rawId; - Value("Id", rawId, 'ui32'); - countedValue.UpdateDuringSerializationOnly(rawValue, rawId); - } - EndGroup(); - } - - template - void Value(const char* name, CountedValue& countedValue, int policy) - { - if (!BeginOptionalGroup(name, true)) - { - return; - } - if (IsWriting()) - { - T rawValue = countedValue.Peek(); - Value("Value", rawValue, policy); - typename CountedValue::TCountedID rawId = countedValue.GetLatestID(); - Value("Id", rawId, 'ui32'); - } - - if (IsReading()) - { - T rawValue; - Value("Value", rawValue, policy); - typename CountedValue::TCountedID rawId; - Value("Id", rawId, 'ui32'); - countedValue.UpdateDuringSerializationOnly(rawValue, rawId); - } - EndGroup(); - } - bool ValueChar(const char* name, char* buffer, int len) { string temp; diff --git a/Code/CryEngine/CryCommon/IServiceNetwork.h b/Code/CryEngine/CryCommon/IServiceNetwork.h deleted file mode 100644 index 3df3f79abd..0000000000 --- a/Code/CryEngine/CryCommon/IServiceNetwork.h +++ /dev/null @@ -1,344 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network interface - - -#ifndef CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H -#define CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H -#pragma once - - -#include -//----------------------------------------------------------------------------- -// -// Service network is a simple abstract interface for connecting between instances -// of the editor and game running on various platforms. It implements it's own -// small message based communication layer and shall not be used for raw communication -// with anything else. -// -// Features currently implemented by the service network: -// - Completely thread safe (so can be used from within other threads) -// - Completely asynchronous (only one thread) -// - Message based approach (both on the send and receive ends) -// - Automatic and transparent reconnection -// - Debug-friendly (will not time-out easily when one of the endpoints is being debugged) -// - Easy to use -// -// Usage case (server) -// - Create listener (IServiceListener) on some pre-defined port -// - Poll the incoming connections by calling Accept() method -// - Service the traffic by calling connection's ReceiveMessage()/SendMessage() methods -// - Close() and Release() connections -// - Close() and Release() listener -// -// Usage case (client) -// - Connect to a remote listener by calling Connect() method -// - Service the traffic by calling connection's ReceiveMessage()/SendMessage() methods -// - Close() and Release() connection -// -// Both sending and receiving is asynchronous. Calling the SendMessage()/ReceiveMessage() methods -// only pushes/pops the message buffers to/from the queue. -// NOTE: Message buffers are internally reference counted by the network system and they are kept around -// untill they are sent (in case of outgoing traffic) or untill they are polled by ReceiveMessage(). -// Be aware that this can cause memory spikes, especially when incoming traffic is not serviced fast enough. -// There are customizable limits (around 1MB) on the amount of data that can be buffered internally by -// the service network before the new messages are rejected. -// It's up to the higher layer to ensure damage control in such situation. -// -// NOTE: connection is also a reference counted object, make sure to call Close() before calling Release(). -// -//----------------------------------------------------------------------------- - -/// Network address abstraction -class ServiceNetworkAddress -{ -public: - struct StringAddress - { - char m_data[32]; - - ILINE const char* c_str() const - { - return m_data; - } - }; - - struct Address - { - uint8 m_ip0; - uint8 m_ip1; - uint8 m_ip2; - uint8 m_ip3; - uint16 m_port; - - ILINE Address() - : m_ip0(0) - , m_ip1(0) - , m_ip2(0) - , m_ip3(0) - , m_port(0) - {} - }; - -private: - Address m_address; - -public: - // By default creates ("invalid address") - ILINE ServiceNetworkAddress() - { - } - - // Copy (with optional port change) - ILINE ServiceNetworkAddress(const ServiceNetworkAddress& other, uint16 newPort = 0) - : m_address(other.m_address) - { - if (newPort != 0) - { - m_address.m_port = newPort; - } - } - - // Initialize from ip:host pattern (if you want to initialize from host name use the DebugNetwork interface) - ILINE ServiceNetworkAddress(uint8 ip0, uint8 ip1, uint8 ip2, uint8 ip3, uint16 port) - { - m_address.m_ip0 = ip0; - m_address.m_ip1 = ip1; - m_address.m_ip2 = ip2; - m_address.m_ip3 = ip3; - m_address.m_port = port; - } - - // Set new port value - ILINE void SetPort(uint16 port) - { - m_address.m_port = port; - } - - // Is this a valid address - ILINE bool IsValid() const - { - return (m_address.m_ip0 != 0) && - (m_address.m_ip1 != 1) && - (m_address.m_ip2 != 1) && - (m_address.m_ip3 != 1) && - (m_address.m_port != 0); - } - - // Convert to human readable string - ILINE StringAddress ToString() const - { - // format the string buffer - StringAddress ret; - sprintf_s(ret.m_data, sizeof(ret.m_data), - "%d.%d.%d.%d:%d", - m_address.m_ip0, m_address.m_ip1, m_address.m_ip2, m_address.m_ip3, - m_address.m_port); - - // return as managed string - return ret; - } - - // Get the literal data - ILINE const Address& GetAddress() const - { - return m_address; - } - -public: - // Compare base address (IP only) of two connections - static bool CompareBaseAddress(const ServiceNetworkAddress& a, const ServiceNetworkAddress& b) - { - return (a.m_address.m_ip0 == b.m_address.m_ip0) && - (a.m_address.m_ip1 == b.m_address.m_ip1) && - (a.m_address.m_ip2 == b.m_address.m_ip2) && - (a.m_address.m_ip3 == b.m_address.m_ip3); - } - - // Compare full address (IP+port) of two connections - static bool CompareFullAddress(const ServiceNetworkAddress& a, const ServiceNetworkAddress& b) - { - return (a.m_address.m_ip0 == b.m_address.m_ip0) && - (a.m_address.m_ip1 == b.m_address.m_ip1) && - (a.m_address.m_ip2 == b.m_address.m_ip2) && - (a.m_address.m_ip3 == b.m_address.m_ip3) && - (a.m_address.m_port == b.m_address.m_port); - } -}; - -//----------------------------------------------------------------------------- - -/// Message buffer used by the network system -struct IServiceNetworkMessage -{ -protected: - IServiceNetworkMessage() {}; - virtual ~IServiceNetworkMessage() {}; - -public: - // Get unique message ID (message ID is used just once) - virtual uint32 GetId() const = 0; - - // Get the size of message buffer - virtual uint32 GetSize() const = 0; - - // Get pointer to the message data - virtual void* GetPointer() = 0; - - // Get pointer to the message data - virtual const void* GetPointer() const = 0; - - // Create reader interface for reading message data, returned object is not - // reference counted but it will hold a reference to the message. - virtual struct IDataReadStream* CreateReader() const = 0; - - // Add reference (buffer is internally refcounted) - virtual void AddRef() = 0; - - // Release reference - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// General network TCP/IP connection -struct IServiceNetworkConnection -{ -protected: - IServiceNetworkConnection() {}; - virtual ~IServiceNetworkConnection() {}; - -public: - static const uint32 kDefaultFlushTime = 10000; // ms - - // Get the unique connection ID (is shared between host and client) - virtual const CryGUID& GetGUID() const = 0; - - // Get remote endpoint address - virtual const ServiceNetworkAddress& GetRemoteAddress() const = 0; - - // Get local endpoint address - virtual const ServiceNetworkAddress& GetLocalAddress() const = 0; - - // Add a message buffer to the connection send queue. - // Connection can refuse to send the buffer if it's full or invalid. - // If a message is rejected this function returns false. - virtual bool SendMsg(IServiceNetworkMessage* message) = 0; - - // Get a message from connection receive queue. - // If there are no pending messages a NULL is returned. - // Since message is a ref-counted you need to call Release() when you are done with the buffer. - virtual IServiceNetworkMessage* ReceiveMsg() = 0; - - // Checks if connection is still alive. - // Returns false only if connection has been damaged beyond repair. - virtual bool IsAlive() const = 0; - - // Get number of messages sent by this connection so far - virtual uint32 GetMessageSendCount() const = 0; - - // Get number of messages received by this connection so far - virtual uint32 GetMessageReceivedCount() const = 0; - - // Get size of data sent by this connection so far - virtual uint64 GetMessageSendDataSize() const = 0; - - // Get size of data received by this connection so far - virtual uint64 GetMessageReceivedDataSize() const = 0; - - // Request connection to be closed but not before sending out all of the pending messages. Incoming messages are ignored. - // Processing and sending the messages is done on the networking thread so this function will not block. - // As an option, connection can be forcefully closed after given amount of time (in ms). - virtual void FlushAndClose(const uint32 timeoutMs = kDefaultFlushTime) = 0; - - // Synchronous wait for the connection to send all outgoing messages - virtual void FlushAndWait() = 0; - - // Request connection to be closed now. All pending messages are discarded. - virtual void Close() = 0; - - // Add reference (connection is an internally reference counted object) - virtual void AddRef() = 0; - - // Release reference - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// General listening socket (async) -struct IServiceNetworkListener -{ -protected: - IServiceNetworkListener() {}; - virtual ~IServiceNetworkListener() {}; - -public: - // Get the local address - virtual const ServiceNetworkAddress& GetLocalAddress() const = 0; - - // Get number of active connections handled by this listener - virtual uint GetConnectionCount() const = 0; - - // Accept incoming connection (asynchronously) - // Will return NULL if there's nothing to accept - // Will return new IDebugNetworkConnection if something was received - virtual IServiceNetworkConnection* Accept() = 0; - - // Is listener able to accept connections ? - virtual bool IsAlive() const = 0; - - // Request listener to be closed (closes the socket) - virtual void Close() = 0; - - // Add reference (listener is an internally reference counted object) - virtual void AddRef() = 0; - - // Release reference - virtual void Release() = 0; -}; - -//----------------------------------------------------------------------------- - -/// General service (background) network interface -struct IServiceNetwork -{ -public: - virtual ~IServiceNetwork() {}; - - // Set verbosity level of debug messages that got printed to log, levels 0-3 are commonly used - virtual void SetVerbosityLevel(const uint32 level) = 0; - - // Allocate empty message buffer of given size, message buffer is a reference counted object - virtual IServiceNetworkMessage* AllocMessageBuffer(const uint32 size) = 0; - - // Create general message writer stream, object is not reference counted - virtual struct IDataWriteStream* CreateMessageWriter() = 0; - - // Create general message reader stream and initialize it with data - virtual struct IDataReadStream* CreateMessageReader(const void* pData, const uint32 dataSize) = 0; - - // Translate host address (string:port) to network address - virtual ServiceNetworkAddress GetHostAddress(const string& addressString, uint16 optionalPort = 0) const = 0; - - // Create network listener on given local port, listening and accepting connections is done on network thread - virtual IServiceNetworkListener* CreateListener(uint16 localPort) = 0; - - // Connect to remote address (will block until connection is made or refused) - virtual IServiceNetworkConnection* Connect(const ServiceNetworkAddress& remoteAddress) = 0; -}; - -//----------------------------------------------------------------------------- - -#endif // CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H diff --git a/Code/CryEngine/CryCommon/IShader.h b/Code/CryEngine/CryCommon/IShader.h index 7fcbdefebb..81fe18706d 100644 --- a/Code/CryEngine/CryCommon/IShader.h +++ b/Code/CryEngine/CryCommon/IShader.h @@ -24,7 +24,14 @@ #endif #include "smartptr.h" -#include // <> required for Interfuscator +#include "Cry_Vector2.h" +#include "Cry_Vector3.h" +#include "Cry_Matrix33.h" +#include "Cry_Color.h" +#include "smartptr.h" +#include "StringUtils.h" +#include // <> required for Interfuscator +#include "smartptr.h" #include "VertexFormats.h" #include #include @@ -34,8 +41,6 @@ #include #include -#include - struct IMaterial; class CRendElementBase; class CRenderObject; @@ -767,7 +772,6 @@ _MS_ALIGN(16) struct SSkinningData void* pCharInstCB; // used if per char instance cbs are available in renderdll (d3d11+); // members below are for Software Skinning void* pCustomData; // client specific data, used for example for sw-skinning on animation side - SSkinningData** pMasterSkinningDataList; // used by the SkinningData for a Character Instance, contains a list of all Skin Instances which need SW-Skinning SSkinningData* pNextSkinningData; // List to the next element which needs SW-Skinning } _ALIGN(16); @@ -2236,74 +2240,6 @@ struct SShaderTexSlots } }; -struct SShaderGenBit -{ - SShaderGenBit() - { - m_Mask = 0; - m_Flags = 0; - m_nDependencySet = 0; - m_nDependencyReset = 0; - m_NameLength = 0; - m_dwToken = 0; - } - string m_ParamName; - string m_ParamProp; - string m_ParamDesc; - int m_NameLength; - uint64 m_Mask; - uint32 m_Flags; - uint32 m_dwToken; - std::vector m_PrecacheNames; - std::vector m_DependSets; - std::vector m_DependResets; - uint32 m_nDependencySet; - uint32 m_nDependencyReset; - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_ParamName); - pSizer->AddObject(m_ParamProp); - pSizer->AddObject(m_ParamDesc); - pSizer->AddObject(m_PrecacheNames); - pSizer->AddObject(m_DependSets); - pSizer->AddObject(m_DependResets); - } -}; - -struct SShaderGen -{ - uint32 m_nRefCount; - TArray m_BitMask; - SShaderGen() - { - m_nRefCount = 1; - } - ~SShaderGen() - { - uint32 i; - for (i = 0; i < m_BitMask.Num(); i++) - { - SShaderGenBit* pBit = m_BitMask[i]; - SAFE_DELETE(pBit); - } - m_BitMask.Free(); - } - void Release() - { - m_nRefCount--; - if (!m_nRefCount) - { - delete this; - } - } - - void GetMemoryUsage(ICrySizer* pSizer) const - { - pSizer->AddObject(m_BitMask); - } -}; - //=================================================================================== enum EShaderType @@ -2568,7 +2504,6 @@ public: virtual void SetFlags2(int Flags) = 0; virtual void ClearFlags2(int Flags) = 0; virtual bool Reload(int nFlags, const char* szShaderName) = 0; - virtual TArray* GetREs (int nTech) = 0; virtual AZStd::vector& GetPublicParams() = 0; virtual int GetTexId () = 0; virtual ITexture* GetBaseTexture(int* nPass, int* nTU) = 0; @@ -2577,7 +2512,6 @@ public: virtual ECull GetCull(void) = 0; virtual int Size(int Flags) = 0; virtual uint64 GetGenerationMask() = 0; - virtual SShaderGen* GetGenerationParams() = 0; virtual size_t GetNumberOfUVSets() = 0; virtual int GetTechniqueID(int nTechnique, int nRegisteredTechnique) = 0; virtual AZ::Vertex::Format GetVertexFormat(void) = 0; @@ -2828,7 +2762,6 @@ struct SRenderLight m_ObjMatrix.SetIdentity(); m_BaseObjMatrix.SetIdentity(); m_sName = ""; - m_pSoftOccQuery = NULL; m_pLightAnim = NULL; m_fAreaWidth = 1; m_fAreaHeight = 1; @@ -2884,11 +2817,6 @@ struct SRenderLight return m_pLightImage ? m_pLightImage : NULL; } - IOpticsElementBase* GetLensOpticsElement() const - { - return m_pLensOpticsElement; - } - void SetOpticsParams(const SOpticsInstanceParameters& params) { m_opticsParams = params; @@ -2899,24 +2827,6 @@ struct SRenderLight return m_opticsParams; } - void SetLensOpticsElement(IOpticsElementBase* pOptics) - { - if (m_pLensOpticsElement == pOptics) - { - return; - } - if (pOptics && pOptics->GetType() != eFT_Root) - { - return; - } - SAFE_RELEASE(m_pLensOpticsElement); - m_pLensOpticsElement = pOptics; - if (m_pLensOpticsElement) - { - m_pLensOpticsElement->AddRef(); - } - } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*LATER*/} void AcquireResources() @@ -2937,14 +2847,6 @@ struct SRenderLight { m_pSpecularCubemap->AddRef(); } - if (m_pLensOpticsElement) - { - m_pLensOpticsElement->AddRef(); - } - if (m_pSoftOccQuery) - { - m_pSoftOccQuery->AddRef(); - } if (m_pLightAnim) { m_pLightAnim->AddRef(); @@ -2961,8 +2863,6 @@ struct SRenderLight SAFE_RELEASE(m_pLightImage); SAFE_RELEASE(m_pDiffuseCubemap); SAFE_RELEASE(m_pSpecularCubemap); - SAFE_RELEASE(m_pLensOpticsElement); - SAFE_RELEASE(m_pSoftOccQuery); SAFE_RELEASE(m_pLightAnim); SAFE_RELEASE(m_pLightAttenMap); } @@ -3046,8 +2946,6 @@ struct SRenderLight const char* m_sName; // Optional name of the light source. SShaderItem m_Shader; // Shader item CRenderObject* m_pObject[MAX_RECURSION_LEVELS]; // Object for light coronas and light flares. - IOpticsElementBase* m_pLensOpticsElement; // Optics element for this shader instance - ISoftOcclusionQuery* m_pSoftOccQuery; ILightAnimWrapper* m_pLightAnim; Matrix34 m_BaseObjMatrix; @@ -3146,9 +3044,7 @@ public: m_fShadowSlopeBias = dl.m_fShadowSlopeBias; m_fShadowResolutionScale = dl.m_fShadowResolutionScale; m_fHDRDynamic = dl.m_fHDRDynamic; - m_pLensOpticsElement = dl.m_pLensOpticsElement; m_LensOpticsFrustumAngle = dl.m_LensOpticsFrustumAngle; - m_pSoftOccQuery = dl.m_pSoftOccQuery; m_fLightFrustumAngle = dl.m_fLightFrustumAngle; m_fProjectorNearPlane = dl.m_fProjectorNearPlane; m_Flags = dl.m_Flags; @@ -3413,6 +3309,6 @@ struct SShaderGraphBlock typedef std::vector FXShaderGraphBlocks; typedef FXShaderGraphBlocks::iterator FXShaderGraphBlocksItor; -#include "RendElement.h" +#include #endif // CRYINCLUDE_CRYCOMMON_ISHADER_H diff --git a/Code/CryEngine/CryCommon/IShader_info.h b/Code/CryEngine/CryCommon/IShader_info.h deleted file mode 100644 index f48c1b08a2..0000000000 --- a/Code/CryEngine/CryCommon/IShader_info.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include // <> required for Interfuscator - -// Traits -#if defined(AZ_RESTRICTED_PLATFORM) - #include AZ_RESTRICTED_FILE(IShader_info_h) -#elif !defined(LINUX) && !defined(APPLE) -#define ISHADER_INFO_H_TRAIT_DEFINE_ETEX_INFO 1 -#endif - -#if ISHADER_INFO_H_TRAIT_DEFINE_ETEX_INFO -ENUM_INFO_BEGIN(ETEX_Format) -ENUM_ELEM_INFO(, eTF_Unknown) -ENUM_ELEM_INFO(, eTF_R8G8B8A8S) -ENUM_ELEM_INFO(, eTF_R8G8B8A8) -ENUM_ELEM_INFO(, eTF_A8) -ENUM_ELEM_INFO(, eTF_R8) -ENUM_ELEM_INFO(, eTF_R8S) -ENUM_ELEM_INFO(, eTF_R16) -ENUM_ELEM_INFO(, eTF_R16F) -ENUM_ELEM_INFO(, eTF_R32F) -ENUM_ELEM_INFO(, eTF_R8G8) -ENUM_ELEM_INFO(, eTF_R8G8S) -ENUM_ELEM_INFO(, eTF_R16G16) -ENUM_ELEM_INFO(, eTF_R16G16S) -ENUM_ELEM_INFO(, eTF_R16G16F) -ENUM_ELEM_INFO(, eTF_R11G11B10F) -ENUM_ELEM_INFO(, eTF_R10G10B10A2) -ENUM_ELEM_INFO(, eTF_R16G16B16A16) -ENUM_ELEM_INFO(, eTF_R16G16B16A16S) -ENUM_ELEM_INFO(, eTF_R16G16B16A16F) -ENUM_ELEM_INFO(, eTF_R32G32B32A32F) -ENUM_ELEM_INFO(, eTF_CTX1) -ENUM_ELEM_INFO(, eTF_BC1) -ENUM_ELEM_INFO(, eTF_BC2) -ENUM_ELEM_INFO(, eTF_BC3) -ENUM_ELEM_INFO(, eTF_BC4U) -ENUM_ELEM_INFO(, eTF_BC4S) -ENUM_ELEM_INFO(, eTF_BC5U) -ENUM_ELEM_INFO(, eTF_BC5S) -ENUM_ELEM_INFO(, eTF_BC6UH) -ENUM_ELEM_INFO(, eTF_BC6SH) -ENUM_ELEM_INFO(, eTF_BC7) -ENUM_ELEM_INFO(, eTF_R9G9B9E5) -ENUM_ELEM_INFO(, eTF_D16) -ENUM_ELEM_INFO(, eTF_D24S8) -ENUM_ELEM_INFO(, eTF_D32F) -ENUM_ELEM_INFO(, eTF_D32FS8) -ENUM_ELEM_INFO(, eTF_B5G6R5) -ENUM_ELEM_INFO(, eTF_B5G5R5) -ENUM_ELEM_INFO(, eTF_B4G4R4A4) -ENUM_ELEM_INFO(, eTF_EAC_R11) -ENUM_ELEM_INFO(, eTF_EAC_RG11) -ENUM_ELEM_INFO(, eTF_ETC2) -ENUM_ELEM_INFO(, eTF_ETC2A) -ENUM_ELEM_INFO(, eTF_A8L8) -ENUM_ELEM_INFO(, eTF_L8) -ENUM_ELEM_INFO(, eTF_L8V8U8) -ENUM_ELEM_INFO(, eTF_B8G8R8) -ENUM_ELEM_INFO(, eTF_L8V8U8X8) -ENUM_ELEM_INFO(, eTF_B8G8R8X8) -ENUM_ELEM_INFO(, eTF_B8G8R8A8) -ENUM_INFO_END(ETEX_Format) -#endif diff --git a/Code/CryEngine/CryCommon/ISoftCodeMgr.h b/Code/CryEngine/CryCommon/ISoftCodeMgr.h deleted file mode 100644 index b3cef7e1f0..0000000000 --- a/Code/CryEngine/CryCommon/ISoftCodeMgr.h +++ /dev/null @@ -1,276 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to manage SoftCode module loading and patching - - -#ifndef CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H -#define CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H -#pragma once - - -// Provides the generic interface for exchanging member values between SoftCode modules, -struct IExchangeValue -{ - // - virtual ~IExchangeValue() {} - - // Allocates a new IExchangeValue with the underlying type - virtual IExchangeValue* Clone() const = 0; - // Returns the size of the underlying type (to check compatibility) - virtual size_t GetSizeOf() const = 0; - // -}; - -template -struct ExchangeValue - : public IExchangeValue -{ - ExchangeValue(T& value) - : m_value(value) - {} - - virtual IExchangeValue* Clone() const { return new ExchangeValue(*this); } - virtual size_t GetSizeOf() const { return sizeof(m_value); } - - T m_value; -}; - -template -struct ExchangeArray - : public IExchangeValue -{ - ExchangeArray(T* pArr) - { - for (size_t i = 0; i < S; ++i) - { - m_array[i] = pArr[i]; - } - } - - virtual IExchangeValue* Clone() const { return new ExchangeArray(*this); } - virtual size_t GetSizeOf() const { return sizeof(m_array); } - - T m_array[S]; -}; - -/* - This is a non-intrusive support function for types where default construction does no initialization. - SoftCoding relies on default construction to initialize object state correctly. - For most types this works as expected but for some types (typically things like vectors or matrices) - default initialization would be too costly and is therefore not implemented. - This function allows a specialized implementation to be used for such types that will perform - initialization on the newly constructed instance. For example: - - inline void DefaultInitialize(Matrix34& matrix) - { - matrix.SetIdentity(); - } -*/ -template -void DefaultInitialize(T& t) -{ - t = T(); -} - -// Vector support -template -struct Vec2_tpl; -template -struct Vec3_tpl; -template -void DefaultInitialize(Vec2_tpl& vec) { vec.zero(); } -template -void DefaultInitialize(Vec3_tpl& vec) { vec.zero(); } - -// Matrix support -template -struct Matrix33_tpl; -template -struct Matrix34_tpl; -template -struct Matrix44_tpl; - -template -void DefaultInitialize(Matrix33_tpl& matrix) { matrix.SetIdentity(); } -template -void DefaultInitialize(Matrix34_tpl& matrix) { matrix.SetIdentity(); } -template -void DefaultInitialize(Matrix44_tpl& matrix) { matrix.SetIdentity(); } - -// Quat support -template -struct Quat_tpl; -template -void DefaultInitialize(Quat_tpl& quat) { quat.SetIdentity(); } - -// Interface for performing an exchange of instance data -struct IExchanger -{ - // - virtual ~IExchanger() {} - - // True if data is being read from instance members - virtual bool IsLoading() const = 0; - - virtual size_t InstanceCount() const = 0; - - virtual bool BeginInstance(void* pInstance) = 0; - virtual bool SetValue(const char* name, IExchangeValue& value) = 0; - virtual IExchangeValue* GetValue(const char* name, void* pTarget, size_t targetSize) = 0; - // - - template - void Visit(const char* name, T& instance); - - template - void Visit(const char* name, T (&arr)[S]); -}; - -template -void IExchanger::Visit(const char* name, T& value) -{ - if (IsLoading()) - { - IExchangeValue* pValue = GetValue(name, &value, sizeof(value)); - if (pValue) - { - ExchangeValue* pTypedValue = static_cast*>(pValue); - value = pTypedValue->m_value; - } - } - else // Saving - { - // If this member is stored - if (SetValue(name, ExchangeValue(value))) - { - // Set the original value to the default state (to allow safe destruction) - DefaultInitialize(value); - } - } -} - -template -void IExchanger::Visit(const char* name, T (&arr)[S]) -{ - if (IsLoading()) - { - IExchangeValue* pValue = GetValue(name, &arr, sizeof(arr)); - if (pValue) - { - ExchangeArray* pTypedArray = static_cast*>(pValue); - // TODO: Accommodate array resizing? Complex however... - for (size_t i = 0; i < S; ++i) - { - arr[i] = pTypedArray->m_array[i]; - } - } - } - else // Saving - { - // If this member is stored - if (SetValue(name, ExchangeArray(arr))) - { - T defaultValue; - DefaultInitialize(defaultValue); - - // Set the original value to the default value (to allow safe destruction) - for (size_t i = 0; i < S; ++i) - { - arr[i] = defaultValue; - } - } - } -} - -struct InstanceTracker; - -struct ITypeRegistrar -{ - // - virtual ~ITypeRegistrar() {} - - virtual const char* GetName() const = 0; - - // Creates an instance of the type - virtual void* CreateInstance() = 0; - // - -#ifdef SOFTCODE_ENABLED - // How many active instances exist of this type? - virtual size_t InstanceCount() const = 0; - // Used to remove a tracked instance from the Registrar - virtual void RemoveInstance(InstanceTracker* pTracker) = 0; - // Exchanges the instance state with the given exchanger data set - virtual bool ExchangeInstances(IExchanger& exchanger) = 0; - // Destroys all tracked instances of this type - virtual bool DestroyInstances() = 0; - // Returns true if pInstance is of this type (linear search) - virtual bool HasInstance(void* pInstance) const = 0; -#endif -}; - -struct ITypeLibrary -{ - // - virtual ~ITypeLibrary() {} - - virtual const char* GetName() = 0; - virtual void* CreateInstanceVoid(const char* typeName) = 0; - // - -#ifdef SOFTCODE_ENABLED - virtual void SetOverride(ITypeLibrary* pOverrideLib) = 0; - - // Fills in the supplied type list if large enough, and sets count to number of types - virtual size_t GetTypes(ITypeRegistrar** ppRegistrar, size_t& count) const = 0; -#endif -}; - -struct ISoftCodeListener -{ - // - virtual ~ISoftCodeListener() {} - - // Called when an instance is replaced to allow managing systems to fixup pointers - virtual void InstanceReplaced(void* pOldInstance, void* pNewInstance) = 0; - // -}; - -/// Interface for ... -struct ISoftCodeMgr -{ - // - virtual ~ISoftCodeMgr() {} - - // Used to register built-in libraries on first use - virtual void RegisterLibrary(ITypeLibrary* pLib) = 0; - - // Loads any new SoftCode modules - virtual void LoadNewModules() = 0; - - virtual void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) = 0; - virtual void RemoveListener(const char* libraryName, ISoftCodeListener* pListener) = 0; - - // To be called regularly to poll for library updates - virtual void PollForNewModules() = 0; - - // Stops thread execution until a new SoftCode instance is available - virtual void* WaitForUpdate(void* pInstance) = 0; - - /// Frees this instance from memory - //virtual void Release() = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H diff --git a/Code/CryEngine/CryCommon/IStreamEngine.h b/Code/CryEngine/CryCommon/IStreamEngine.h deleted file mode 100644 index f325eec389..0000000000 --- a/Code/CryEngine/CryCommon/IStreamEngine.h +++ /dev/null @@ -1,494 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// This is the prototypes of interfaces that will be used for asynchronous -// I/O (streaming). -// THIS IS NOT FINAL AND IS SUBJECT TO CHANGE WITHOUT NOTICE - -// Some excerpts explaining basic ideas behind streaming design here: - -/* - * The idea is that the data loaded is ready for usage and ideally doesn't need further transformation, - * therefore the client allocates the buffer (to avoid extra copy). All the data transformations should take place in the Resource Compiler. If you have to allocate a lot of small memory objects, you should revise this strategy in favor of one big allocation (again, that will be read directly from the compiled file). - * Anyway, we can negotiate that the streaming engine allocates this memory. - * In the end, it could make use of a memory pool, and copying data is not the bottleneck in our engine - * - * The client should take care of all fast operations. Looking up file size should be fast on the virtual - * file system in a pak file, because the directory should be preloaded in memory - */ - -#ifndef CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H -#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H -#pragma once - - -#include -#include "smartptr.h" -#include // <> required for Interfuscator -#include "CryThread.h" - -#include "IStreamEngineDefs.h" - -class IStreamCallback; -class ICrySizer; - -#define STREAM_TASK_TYPE_AUDIO_ALL ((1 << eStreamTaskTypeMusic) | (1 << eStreamTaskTypeSound) | (1 << eStreamTaskTypeFSBCache)) - -// Description: -// This is used as parameter to the asynchronous read function -// all the unnecessary parameters go here, because there are many of them. -struct StreamReadParams -{ -public: - StreamReadParams() - { - memset(this, 0, sizeof(*this)); - ePriority = estpNormal; - } - - StreamReadParams ( - DWORD_PTR _dwUserData, - EStreamTaskPriority _ePriority = estpNormal, - unsigned _nLoadTime = 0, - unsigned _nMaxLoadTime = 0, - unsigned _nOffset = 0, - unsigned _nSize = 0, - void* _pBuffer = NULL, - unsigned _nFlags = 0 - ) - : dwUserData (_dwUserData) - , ePriority(_ePriority) - , nPerceptualImportance(0) - , nLoadTime(_nLoadTime) - , nMaxLoadTime(_nMaxLoadTime) - , pBuffer (_pBuffer) - , nOffset (_nOffset) - , nSize (_nSize) - , eMediaType(eStreamSourceTypeUnknown) - , nFlags (_nFlags) - { - } - - // Summary: - // File name. - //const char* szFile; - - // Summary: - // The callback. - //IStreamCallback* pAsyncCallback; - - // Summary: - // The user data that'll be used to call the callback. - DWORD_PTR dwUserData; - - // The priority of this read - EStreamTaskPriority ePriority; - - // Value from 0-255 of the perceptual importance of the task (used for debugging task sheduling) - uint8 nPerceptualImportance; - - // Description: - // The desirable loading time, in milliseconds, from the time of call - // 0 means as fast as possible (desirably in this frame). - unsigned nLoadTime; - - // Description: - // The maximum load time, in milliseconds. 0 means forever. If the read lasts longer, it can be discarded. - // WARNING: avoid too small max times, like 1-10 ms, because many loads will be discarded in this case. - unsigned nMaxLoadTime; - - // Description: - // The buffer into which to read the file or the file piece - // if this is NULL, the streaming engine will supply the buffer. - // Notes: - // DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption! - void* pBuffer; - - // Description: - // Offset in the file to read; if this is not 0, then the file read - // occurs beginning with the specified offset in bytes. - // The callback interface receives the size of already read data as nSize - // and generally behaves as if the piece of file would be a file of its own. - unsigned nOffset; - - // Description: - // Number of bytes to read; if this is 0, then the whole file is read, - // if nSize == 0 && nOffset != 0, then the file from the offset to the end is read. - // If nSize != 0, then the file piece from nOffset is read, at most nSize bytes - // (if less, an error is reported). So, from nOffset byte to nOffset + nSize - 1 byte in the file. - unsigned nSize; - - // Description: - // Media type to use when starting file request - if wrong, the request may take longer to complete - EStreamSourceMediaType eMediaType; - - // Description: - // The combination of one or several flags from the stream engine general purpose flags. - // See also: - // IStreamEngine::EFlags - unsigned nFlags; -}; - -struct StreamReadBatchParams -{ - StreamReadBatchParams() - : tSource((EStreamTaskType)0) - , szFile(NULL) - , pCallback(NULL) - { - } - - EStreamTaskType tSource; - const char* szFile; - IStreamCallback* pCallback; - StreamReadParams params; -}; - -struct IStreamEngineListener -{ - // - virtual ~IStreamEngineListener() {} - - virtual void OnStreamEnqueue(const void* pReq, const char* filename, EStreamTaskType source, const StreamReadParams& readParams) = 0; - virtual void OnStreamComputedSortKey(const void* pReq, uint64 key) = 0; - virtual void OnStreamBeginIO(const void* pReq, uint32 compressSize, uint32 readSize, EStreamSourceMediaType mediaType) = 0; - virtual void OnStreamEndIO(const void* pReq) = 0; - virtual void OnStreamBeginInflate(const void* pReq) = 0; - virtual void OnStreamEndInflate(const void* pReq) = 0; - virtual void OnStreamBeginAsyncCallback(const void* pReq) = 0; - virtual void OnStreamEndAsyncCallback(const void* pReq) = 0; - virtual void OnStreamDone(const void* pReq) = 0; - virtual void OnStreamPreempted(const void* pReq) = 0; - virtual void OnStreamResumed(const void* pReq) = 0; - // -}; - -// Description: -// The highest level. There is only one StreamingEngine in the application -// and it controls all I/O streams. -struct IStreamEngine -{ -public: - - - enum EJobType - { - ejtStarted = 1 << 0, - ejtPending = 1 << 1, - ejtFinished = 1 << 2, - }; - - // Summary: - // General purpose flags. - enum EFlags - { - // Description: - // If this is set only asynchronous callback will be called. - FLAGS_NO_SYNC_CALLBACK = BIT(0), - // Description: - // If this is set the file will be read from disc directly, instead of from the pak system. - FLAGS_FILE_ON_DISK = BIT(1), - // Description: - // Ignore the tmp out of streaming memory for this request - FLAGS_IGNORE_TMP_OUT_OF_MEM = BIT(2), - // Description: - // External buffer is write only - FLAGS_WRITE_ONLY_EXTERNAL_BUFFER = BIT(3), - }; - - // - // Description: - // Starts asynchronous read from the specified file (the file may be on a - // virtual file system, in pak or zip file or wherever). - // Reads the file contents into the given buffer, up to the given size. - // Upon success, calls success callback. If the file is truncated or for other - // reason can not be read, calls error callback. The callback can be NULL (in this case, the client should poll - // the returned IReadStream object; the returned object must be locked for that) - // NOTE: the error/success/ progress callbacks can also be called from INSIDE this function. - // Arguments: - // tSource - - // szFile - - // pCallback - - // pParams - PLACEHOLDER for the future additional parameters (like priority), or really - // a pointer to a structure that will hold the parameters if there are too many of them. - // Return Value: - // IReadStream is reference-counted and will be automatically deleted if you don't refer to it; - // if you don't store it immediately in an auto-pointer, it may be deleted as soon as on the next line of code, - // because the read operation may complete immediately inside StartRead() and the object is self-disposed - // as soon as the callback is called. - // Remarks: - // In some implementations disposal of the old pointers happen synchronously - // (in the main thread) outside StartRead() (it happens in the entity update), - // so you're guaranteed that it won't trash inside the calling function. However, this may change in the future - // and you'll be required to assign it to IReadStream immediately (StartRead will return IReadStream_AutoPtr then). - // See also: - // IReadStream,IReadStream_AutoPtr - virtual IReadStreamPtr StartRead (const EStreamTaskType tSource, const char* szFile, IStreamCallback* pCallback = NULL, const StreamReadParams* pParams = NULL) = 0; - - // Pass a callback to preRequestCallback if you need to execute code right before the requests get enqueued; the callback is called only once per execution - virtual size_t StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback = nullptr) = 0; - - // Call this methods before/after submitting large number of new requests. - virtual void BeginReadGroup() = 0; - virtual void EndReadGroup() = 0; - - // Pause/resumes streaming of specific data types. - // nPauseTypesBitmask is a bit mask of data types (ex, 1< -}; - -// Description: -// This is the file "handle" that can be used to query the status -// of the asynchronous operation on the file. The same object may be returned -// for the same file to multiple clients. -// Notes: -// It will actually represent the asynchronous object in memory, and will be -// thread-safe reference-counted (both AddRef() and Release() will be virtual -// and thread-safe, just like the others) -// Example: -// USE: -// IReadStream_AutoPtr pReadStream = pStreamEngine->StartRead ("bla.xxx", this); -// OR: -// pStreamEngine->StartRead ("MusicSystem","bla.xxx", this); -class IReadStream -{ -public: - // - // Summary: - // Increment ref count, returns new count - virtual int AddRef() = 0; - // Summary: - // Decrement ref count, returns new count - virtual int Release() = 0; - // Summary: - // Returns true if the file read was not successful. - virtual bool IsError() = 0; - // Return Value: - // True if the file read was completed successfully. - // Summary: - // Checks IsError to check if the whole requested file (piece) was read. - virtual bool IsFinished() = 0; - // Description: - // Returns the number of bytes read so far (the whole buffer size if IsFinished()) - // Arguments: - // bWait - if == true, then waits until the pending I/O operation completes. - // Return Value: - // The total number of bytes read (if it completes successfully, returns the size of block being read) - virtual unsigned int GetBytesRead(bool bWait = false) = 0; - // Description: - // Returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read. - // Notes: - // DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption! - virtual const void* GetBuffer () = 0; - - // Description: - // Returns the transparent DWORD that was passed in the StreamReadParams::dwUserData field - // of the structure passed in the call to IStreamEngine::StartRead. - // See also: - // StreamReadParams::dwUserData,IStreamEngine::StartRead - virtual DWORD_PTR GetUserData() = 0; - - // Summary: - // Set user defined data into stream's params. - virtual void SetUserData(DWORD_PTR dwUserData) = 0; - - // Description: - // Tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - virtual void Abort() = 0; - - // Description: - // Tries to stop reading the stream, as long as IO or the async callback is not currently - // in progress. - virtual bool TryAbort() = 0; - - // Summary: - // Unconditionally waits until the callback is called. - // if nMaxWaitMillis is not negative wait for the specified ammount of milliseconds then exit. - // Example: - // If the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified). - virtual void Wait(int nMaxWaitMillis = -1) = 0; - - // Summary: - // Returns stream params. - virtual const StreamReadParams& GetParams() const = 0; - - // Summary: - // Returns caller type. - virtual const EStreamTaskType GetCallerType() const = 0; - - // Summary: - // Returns media type used to satisfy request - only valid once stream has begun read. - virtual EStreamSourceMediaType GetMediaType() const = 0; - - // Summary: - // Returns pointer to callback routine(can be NULL). - virtual IStreamCallback* GetCallback() const = 0; - - // Summary: - // Returns IO error #. - virtual unsigned GetError() const = 0; - - // Summary: - // Returns IO error name - virtual const char* GetErrorName() const = 0; - - // Summary: - // Returns stream name. - virtual const char* GetName() const = 0; - - // Summary: - // Free temporary memory allocated for this stream, when not needed anymore. - // Can be called from Async callback, to free memory earlier, not waiting for synchrounus callback. - virtual void FreeTemporaryMemory() = 0; - // - -protected: - // Summary: - // The clients are not allowed to destroy this object directly; only via Release(). - virtual ~IReadStream() {} -}; - -TYPEDEF_AUTOPTR(IReadStream); - -// Description: -// CryPak supports asynchronous reading through this interface. The callback -// is called from the main thread in the frame update loop. -// -// The callback receives packets through StreamOnComplete() and -// StreamOnProgress(). The second one can be used to update the asset based -// on the partial data that arrived. the callback that will be called by the -// streaming engine must be implemented by all clients that want to use -// StreamingEngine services -// Remarks: -// the pStream interface is guaranteed to be locked (have reference count > 0) -// while inside the function, but can vanish any time outside the function. -// If you need it, keep it from the beginning (after call to StartRead()) -// some or all callbacks MAY be called from inside IStreamEngine::StartRead() -// -// Example: -// -// IStreamEngine *pStreamEngine = g_pISystem->GetStreamEngine(); // get streaming engine -// IStreamCallback *pAsyncCallback = &MyClass; // user -// -// StreamReadParams params; -// -// params.dwUserData = 0; -// params.nSize = 0; -// params.pBuffer = NULL; -// params.nLoadTime = 10000; -// params.nMaxLoadTime = 10000; -// -// pStreamEngine->StartRead( .. pAsyncCallback .. params .. ); // registers callback -// -class IStreamCallback -{ -public: - // - virtual ~IStreamCallback(){} - - // Description: - // Signals that the file length for the request has been found, and that storage is needed - // Either a pointer to a block of nSize bytes can be returned, into which the file will be - // streamed, or NULL can be returned, in which case temporary memory will be allocated - // internally by the stream engine (which will be freed upon job completion). - virtual void* StreamOnNeedStorage ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nSize, [[maybe_unused]] bool& bAbortOnFailToAlloc) {return NULL; } - - // Description: - // Signals that reading the requested data has completed (with or without error). - // This callback is always called, whether an error occurs or not. - // pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released. - // GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end - // or the size of partially read data in case of error (0 if nothing was read). - // Pending status is true during this callback, because the callback itself is the part of IO operation. - // nError == 0 : Success - // nError != 0 : Error code - virtual void StreamAsyncOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {} - - // Description: - // Signals that reading the requested data has completed (with or without error). - // This callback is always called, whether an error occurs or not. - // pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released. - // GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end - // or the size of partially read data in case of error (0 if nothing was read). - // Pending status is true during this callback, because the callback itself is the part of IO operation. - // nError == 0 : Success - // nError != 0 : Error code - virtual void StreamOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {} - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H diff --git a/Code/CryEngine/CryCommon/IStreamEngineDefs.h b/Code/CryEngine/CryCommon/IStreamEngineDefs.h deleted file mode 100644 index e931a6201e..0000000000 --- a/Code/CryEngine/CryCommon/IStreamEngineDefs.h +++ /dev/null @@ -1,236 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H -#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H -#pragma once - - -#if defined(ENABLE_PROFILING_CODE) -#define STREAMENGINE_ENABLE_LISTENER -#define STREAMENGINE_ENABLE_STATS -#endif - -enum : unsigned int -{ - ERROR_UNKNOWN_ERROR = 0xF0000000, - ERROR_UNEXPECTED_DESTRUCTION = 0xF0000001, - ERROR_INVALID_CALL = 0xF0000002, - ERROR_CANT_OPEN_FILE = 0xF0000003, - ERROR_REFSTREAM_ERROR = 0xF0000004, - ERROR_OFFSET_OUT_OF_RANGE = 0xF0000005, - ERROR_REGION_OUT_OF_RANGE = 0xF0000006, - ERROR_SIZE_OUT_OF_RANGE = 0xF0000007, - ERROR_CANT_START_READING = 0xF0000008, - ERROR_OUT_OF_MEMORY = 0xF0000009, - ERROR_ABORTED_ON_SHUTDOWN = 0xF000000A, - ERROR_OUT_OF_MEMORY_QUOTA = 0xF000000B, - ERROR_ZIP_CACHE_FAILURE = 0xF000000C, - ERROR_USER_ABORT = 0xF000000D, - ERROR_MISSCHEDULED = 0xF000000F, - ERROR_VERIFICATION_FAIL = 0xF0000010, - ERROR_PREEMPTED = 0xF0000011, - ERROR_DECOMPRESSION_FAIL = 0xF0000012 -}; - -// Summary: -// Types of streaming tasks -// Affects priority directly -enum EStreamTaskType -{ - eStreamTaskTypeCount = 14, - eStreamTaskTypeGeomCache = 13, - eStreamTaskTypePak = 12, - eStreamTaskTypeFlash = 11, - eStreamTaskTypeVideo = 10, - - eStreamTaskTypeMergedMesh = 9, - eStreamTaskTypeShader = 8, - eStreamTaskTypeSound = 7, - eStreamTaskTypeMusic = 6, - eStreamTaskTypeFSBCache = 5, - eStreamTaskTypeAnimation = 4, - eStreamTaskTypeTerrain = 3, - eStreamTaskTypeGeometry = 2, - eStreamTaskTypeTexture = 1, -}; - -// Summary: -// Priority types of streaming tasks -// Affects priority directly -// Limiting number of priority values allows streaming system to minimize seek time -enum EStreamTaskPriority -{ - estpUrgent = 0, - estpPreempted = 1, //For internal use only - estpAboveNormal = 2, - estpNormal = 3, - estpBelowNormal = 4, - estpIdle = 5, -}; - -enum EStreamSourceMediaType : int32_t -{ - eStreamSourceTypeUnknown = 0, - eStreamSourceTypeHDD, - eStreamSourceTypeDisc, - eStreamSourceTypeMemory, -}; - -#if defined(STREAMENGINE_ENABLE_STATS) -struct SStreamEngineStatistics -{ - struct SMediaTypeInfo - { - SMediaTypeInfo() - { - ResetStats(); - } - void ResetStats() - { - memset(this, 0, sizeof(SMediaTypeInfo)); - } - - float fActiveDuringLastSecond; // Amount of time media device was active during last second - float fAverageActiveTime; // Average time since last reset that the media device was active - - uint32 nBytesRead; // Bytes read during last second. - uint32 nRequestCount; // Amount of requests during last second. - uint64 nTotalBytesRead; // Read bytes total from reset. - uint32 nTotalRequestCount; // Number of request from reset. - - uint64 nSeekOffsetLastSecond; // Average seek offset during the last second - uint64 nAverageSeekOffset; // Average seek offset since last reset - - uint32 nCurrentReadBandwidth; // Bytes/second for last second - uint32 nSessionReadBandwidth; // Bytes/second for last second - - uint32 nActualReadBandwidth; // Bytes/second for last second - only taking actual reading into account - uint32 nAverageActualReadBandwidth; // Average read bandwidth in total from reset - only taking actual read time into account - }; - - SMediaTypeInfo hddInfo; - SMediaTypeInfo memoryInfo; - SMediaTypeInfo discInfo; - - uint32 nTotalSessionReadBandwidth;// Average read bandwidth in total from reset - taking full time into account from reset - uint32 nTotalCurrentReadBandwidth;// Total bytes/sec over all types and systems. - - int nPendingReadBytes; // How many bytes still need to be read - float fAverageCompletionTime; // Time in seconds on average takes to complete file request. - float fAverageRequestCount; // Average requests per second being done to streaming engine - - uint64 nMainStreamingThreadWait; - - uint64 nTotalBytesRead; // Read bytes total from reset. - uint32 nTotalRequestCount; // Number of request from reset to the streaming engine. - uint32 nTotalStreamingRequestCount; // Number of request from reset which actually resulted in streaming data. - - int nCurrentDecompressCount; // Number of requests currently waiting to be decompresses - int nCurrentAsyncCount; // Number of requests currently waiting to be async callback - int nCurrentFinishedCount; // Number of requests currently waiting to be finished by mainthread - - uint32 nDecompressBandwidth; // Bytes/second for last second - uint32 nVerifyBandwidth; // Bytes/second for last second - uint32 nDecompressBandwidthAverage; // Bytes/second in total. - uint32 nVerifyBandwidthAverage; // Bytes/second in total. - - bool bTempMemOutOfBudget; // Was the temporary streaming memory out of budget during the last second - int nMaxTempMemory; // Maximum temporary memory used by the streaming system - int nTempMemory; - - struct SRequestTypeInfo - { - SRequestTypeInfo() - : nPendingReadBytes(0) - { - ResetStats(); - } - void ResetStats() - { - nTmpReadBytes = 0; - nTotalStreamingRequestCount = 0; - nTotalReadBytes = 0; - nTotalRequestDataSize = 0; - nTotalRequestCount = 0; - nCurrentReadBandwidth = 0; - nSessionReadBandwidth = 0; - fTotalCompletionTime = .0f; - fAverageCompletionTime = .0f; - } - - void Merge(const SRequestTypeInfo& _other) - { - nPendingReadBytes += _other.nPendingReadBytes; - nTmpReadBytes += _other.nTmpReadBytes; - nTotalStreamingRequestCount += _other.nTotalStreamingRequestCount; - nTotalReadBytes += _other.nTotalReadBytes; - nTotalRequestDataSize += _other.nTotalRequestDataSize; - nTotalRequestCount += _other.nTotalRequestCount; - fTotalCompletionTime += _other.fTotalCompletionTime; - } - - int nPendingReadBytes; // How many bytes still need to be read from media - - uint64 nTmpReadBytes; // Read bytes since last update to compute current bandwidth - - uint32 nTotalStreamingRequestCount; // Total actual streaming requests of this type - uint64 nTotalReadBytes; // Total actual read bytes (compressed data) - uint64 nTotalRequestDataSize; // Total requested bytes from client (uncompressed data) - uint32 nTotalRequestCount; // Total number of finished requests - - uint32 nCurrentReadBandwidth; // Bytes/second for this type during last second - uint32 nSessionReadBandwidth; // Average read bandwidth in total from reset - taking full time into account from reset - - float fTotalCompletionTime; // Time it took to finish all current requests - float fAverageCompletionTime; // Average time it takes to fully complete a request of this type - float fAverageRequestCount; // Average amount of requests made per second - }; - - SRequestTypeInfo typeInfo[eStreamTaskTypeCount]; - - struct SAsset - { - CryStringLocal m_sName; - int m_nSize; - const bool operator<(const SAsset& a) const { return m_nSize > a.m_nSize; } - SAsset() {} - SAsset(const CryStringLocal& sName, const int nSize) - : m_sName(sName) - , m_nSize(nSize) { } - - friend void swap(SAsset& a, SAsset& b) - { - using std::swap; - - a.m_sName.swap(b.m_sName); - swap(a.m_nSize, b.m_nSize); - } - }; - DynArray vecHeavyAssets; -}; -#endif - -struct SStreamEngineOpenStats -{ - int nOpenRequestCount; - int nOpenRequestCountByType[eStreamTaskTypeCount]; -}; - -class IReadStream; -TYPEDEF_AUTOPTR(IReadStream); - -// typedef IReadStream_AutoPtr auto ptr wrapper -typedef IReadStream_AutoPtr IReadStreamPtr; - -#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H diff --git a/Code/CryEngine/CryCommon/ISystem.h b/Code/CryEngine/CryCommon/ISystem.h index 96d9a6ad10..653776f55b 100644 --- a/Code/CryEngine/CryCommon/ISystem.h +++ b/Code/CryEngine/CryCommon/ISystem.h @@ -49,19 +49,15 @@ #include // <> required for Interfuscator #include "CryVersion.h" #include "smartptr.h" -#include // <> required for Interfuscator #include // shared_ptr #include struct ISystem; struct ILog; -struct IProfileLogSystem; namespace AZ::IO { struct IArchive; } -struct IKeyboard; -struct IMouse; struct IConsole; struct IRemoteConsole; struct IRenderer; @@ -69,44 +65,22 @@ struct IProcess; struct ITimer; struct ICryFont; struct IMovieSystem; -struct IMemoryManager; namespace Audio { struct IAudioSystem; } // namespace Audio -struct IStreamEngine; struct SFileVersion; struct INameTable; struct ILevelSystem; struct IViewSystem; -struct IMaterialEffects; -class IOpticsManager; class ICrySizer; class IXMLBinarySerializer; struct IReadWriteXMLSink; -struct IThreadTaskManager; -struct IResourceManager; -struct ITextModeConsole; struct IAVI_Reader; class CPNoise3; -struct IFileChangeMonitor; -struct IVisualLog; struct ILocalizationManager; -struct ICryFactoryRegistry; -struct ISoftCodeMgr; -struct IZLibCompressor; -struct IZLibDecompressor; -struct ILZ4Decompressor; -class IZStdDecompressor; struct IOutputPrintSink; -struct IOverloadSceneManager; -struct IThreadManager; -struct IServiceNetwork; -struct IRemoteCommandManager; struct IWindowMessageHandler; -struct IImageHandler; -class IResourceCompilerHelper; -class ILmbrAWS; namespace AZ { @@ -116,12 +90,6 @@ namespace AZ } } -class IResourceCompilerHelper; - -namespace Serialization { - struct IArchiveHost; -} - typedef void* WIN_HWND; class CCamera; @@ -129,40 +97,13 @@ struct CLoadingTimeProfiler; class ICmdLine; -struct INotificationNetwork; -struct ICryPerfHUD; class ILyShine; -namespace JobManager { - struct IJobManager; -} - -#define PROC_MENU 1 -#define PROC_3DENGINE 2 - -// Summary: -// IDs for script userdata typing. -// Remarks: -// Maybe they should be moved into the game.dll . -//##@{ -#define USER_DATA_SOUND 1 -#define USER_DATA_TEXTURE 2 -#define USER_DATA_OBJECT 3 -#define USER_DATA_LIGHT 4 -#define USER_DATA_BONEHANDLER 5 -#define USER_DATA_POINTER 6 -//##@} - enum ESystemUpdateFlags { - ESYSUPDATE_IGNORE_PHYSICS = 0x0002, // Summary: // Special update mode for editor. - ESYSUPDATE_EDITOR = 0x0004, - ESYSUPDATE_MULTIPLAYER = 0x0008, - ESYSUPDATE_EDITOR_AI_PHYSICS = 0x0010, - ESYSUPDATE_EDITOR_ONLY = 0x0020, - ESYSUPDATE_UPDATE_VIEW_ONLY = 0x0040 + ESYSUPDATE_EDITOR = 0x0004 }; // Description: @@ -184,7 +125,7 @@ enum ESystemConfigPlatform { CONFIG_INVALID_PLATFORM = 0, CONFIG_PC = 1, - CONFIG_OSX_GL = 2, + CONFIG_MAC = 2, CONFIG_OSX_METAL = 3, CONFIG_ANDROID = 4, CONFIG_IOS = 5, @@ -195,29 +136,6 @@ enum ESystemConfigPlatform END_CONFIG_PLATFORM_ENUM, // MUST BE LAST VALUE. USED FOR ERROR CHECKING. }; -enum ESubsystem -{ - ESubsys_3DEngine = 0, - ESubsys_AI = 1, - ESubsys_Physics = 2, - ESubsys_Renderer = 3, - ESubsys_Script = 4 -}; - -// Summary: -// Collates cycles taken per update. -struct sUpdateTimes -{ - uint32 PhysYields; - uint64 SysUpdateTime; - uint64 PhysStepTime; - uint64 RenderTime; - //extended yimes info - uint64 physWaitTime; - uint64 streamingWaitTime; - uint64 animationWaitTime; -}; - enum ESystemGlobalState { ESYSTEM_GLOBAL_STATE_UNKNOWN, @@ -574,33 +492,6 @@ struct IErrorObserver // }; -enum ESystemProtectedFunctions -{ - eProtectedFunc_Save = 0, - eProtectedFunc_Load = 1, - eProtectedFuncsLast = 10, -}; - -struct SCvarsDefault -{ - SCvarsDefault() - { - sz_r_DriverDef = NULL; - } - - const char* sz_r_DriverDef; -}; - -#if defined(CVARS_WHITELIST) -struct ICVarsWhitelist -{ - // - virtual ~ICVarsWhitelist() {}; - virtual bool IsWhiteListed(const string& command, bool silent) = 0; - // -}; -#endif // defined(CVARS_WHITELIST) - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION ISYSTEM_H_SECTION_3 #include AZ_RESTRICTED_FILE(ISystem_h) @@ -622,16 +513,12 @@ struct SSystemInitParams { void* hInstance; // void* hWnd; // - void* hWndForInputSystem; // the HWND for the input devices, distinct from the hWnd, which the rendering system overrides anyways - - bool remoteResourceCompiler; ILog* pLog; // You can specify your own ILog to be used by System. ILogCallback* pLogCallback; // You can specify your own ILogCallback to be added on log creation (used by Editor). ISystemUserCallback* pUserCallback; const char* sLogFileName; // File name to use for log. bool autoBackupLogs; // if true, logs will be automatically backed up each startup - IValidator* pValidator; // You can specify different validator object to use by System. IOutputPrintSink* pPrintSync; // Print Sync which can be used to catch all output from engine char szSystemCmdLine[2048]; // Command line. @@ -639,35 +526,14 @@ struct SSystemInitParams bool bPreview; // When running in Preview mode (Minimal initialization). bool bTestMode; // When running in Automated testing mode. bool bDedicatedServer; // When running a dedicated server. - bool bExecuteCommandLine; // can be switched of to suppress the feature or do it later during the initialization. - bool bSkipFont; // Don't load CryFont.dll - bool bSkipRenderer; // Don't load Renderer bool bSkipConsole; // Don't create console - bool bSkipNetwork; // Don't create Network - bool bSkipWebsocketServer; // Don't create the WebSocket server - bool bMinimal; // Don't load banks - bool bTesting; // CryUnit - bool bNoRandom; //use fixed generator init/seed - bool bShaderCacheGen; // When running in shadercache gen mode bool bUnattendedMode; // When running as part of a build on build-machines: Prevent popping up of any dialog bool bSkipMovie; // Don't load movie - bool bSkipAnimation; // Don't load animation bool bToolMode; // System is running inside a tool. Will not create USER directory or anything else that the game needs to do - bool bSkipPhysics; // Don't initialize CryPhysics. - ISystem* pSystem; // Pointer to existing ISystem interface, it will be reused if not NULL. - typedef void* (*ProtectedFunction)(void* param1, void* param2); - ProtectedFunction pProtectedFunctions[eProtectedFuncsLast]; // Protected functions. - - SCvarsDefault* pCvarsDefault; // to override the default value of some cvar - -#if defined(CVARS_WHITELIST) - ICVarsWhitelist* pCVarsWhitelist; // CVars whitelist callback -#endif // defined(CVARS_WHITELIST) - SharedEnvironmentInstance* pSharedEnvironment; // Summary: @@ -676,19 +542,12 @@ struct SSystemInitParams { hInstance = NULL; hWnd = NULL; - hWndForInputSystem = NULL; - - remoteResourceCompiler = false; pLog = NULL; pLogCallback = NULL; pUserCallback = NULL; -#if defined(CVARS_WHITELIST) - pCVarsWhitelist = NULL; -#endif // defined(CVARS_WHITELIST) sLogFileName = NULL; autoBackupLogs = true; - pValidator = NULL; pPrintSync = NULL; memset(szSystemCmdLine, 0, sizeof(szSystemCmdLine)); @@ -696,34 +555,13 @@ struct SSystemInitParams bPreview = false; bTestMode = false; bDedicatedServer = false; - bExecuteCommandLine = true; - bExecuteCommandLine = true; - bSkipFont = false; - bSkipRenderer = false; bSkipConsole = false; - bSkipNetwork = false; -#if defined(WIN32) || defined(WIN64) - // create websocket server by default. bear in mind that USE_HTTP_WEBSOCKETS is not defined in release. - bSkipWebsocketServer = false; -#else - // CTCPStreamSocket only seems to fully support Win32 and 64 - bSkipWebsocketServer = true; -#endif - bMinimal = false; - bTesting = false; - bNoRandom = false; - bShaderCacheGen = false; bUnattendedMode = false; bSkipMovie = false; - bSkipAnimation = false; bToolMode = false; - bSkipPhysics = false; pSystem = NULL; - memset(pProtectedFunctions, 0, sizeof(pProtectedFunctions)); - pCvarsDefault = NULL; - pSharedEnvironment = nullptr; } }; @@ -792,9 +630,6 @@ struct SSystemGlobalEnvironment { AZ::IO::IArchive* pCryPak; AZ::IO::FileIOBase* pFileIO; - IFileChangeMonitor* pFileChangeMonitor; - IProfileLogSystem* pProfileLogSystem; - IOpticsManager* pOpticsManager; ITimer* pTimer; ICryFont* pCryFont; ::IConsole* pConsole; @@ -802,84 +637,27 @@ struct SSystemGlobalEnvironment ILog* pLog; IMovieSystem* pMovieSystem; INameTable* pNameTable; - IVisualLog* pVisualLog; IRenderer* pRenderer; - IMaterialEffects* pMaterialEffects; - ISoftCodeMgr* pSoftCodeMgr; - IOverloadSceneManager* pOverloadSceneManager; - IServiceNetwork* pServiceNetwork; - IRemoteCommandManager* pRemoteCommandManager; ILyShine* pLyShine; - IResourceCompilerHelper* pResourceCompilerHelper; SharedEnvironmentInstance* pSharedEnvironment; - IThreadManager* pThreadManager; #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION ISYSTEM_H_SECTION_4 #include AZ_RESTRICTED_FILE(ISystem_h) #endif - ISystemScheduler* pSystemScheduler; - threadID mMainThreadId; //The main thread ID is used in multiple systems so should be stored globally - ////////////////////////////////////////////////////////////////////////// - uint32 nMainFrameID; - - ////////////////////////////////////////////////////////////////////////// - const char* szCmdLine; // Startup command line. - - ////////////////////////////////////////////////////////////////////////// - // Generic debug string which can be easily updated by any system and output by the debug handler - enum - { - MAX_DEBUG_STRING_LENGTH = 128 - }; - char szDebugStatus[MAX_DEBUG_STRING_LENGTH]; - - ////////////////////////////////////////////////////////////////////////// - // Used to tell if this is a server/multiplayer instance - bool bServer; - bool bMultiplayer; - bool bHostMigrating; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // Indicate Editor status. - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // Used by CRY_ASSERT bool bIgnoreAllAsserts; bool bNoAssertDialog; - bool bTesting; ////////////////////////////////////////////////////////////////////////// - bool bNoRandomSeed; - - SPlatformInfo pi; - - // Protected functions. - SSystemInitParams::ProtectedFunction pProtectedFunctions[eProtectedFuncsLast]; // Protected functions. - - ////////////////////////////////////////////////////////////////////////// - // Flag to able to print out of memory conditon - bool bIsOutOfMemory; - bool bIsOutOfVideoMemory; - bool bToolMode; int retCode = 0; - ILINE const bool IsClient() const - { -#if defined(CONSOLE) - return true; -#else - return bClient; -#endif - } - ILINE const bool IsDedicated() const { #if defined(CONSOLE) @@ -909,11 +687,6 @@ struct SSystemGlobalEnvironment { bDedicated = isDedicated; } - - ILINE void SetIsClient(bool isClient) - { - bClient = isClient; - } #endif //this way the compiler can strip out code for consoles @@ -953,26 +726,6 @@ struct SSystemGlobalEnvironment #endif } - ILINE const bool IsFMVPlaying() const - { - return m_isFMVPlaying; - } - - ILINE void SetFMVIsPlaying(const bool isPlaying) - { - m_isFMVPlaying = isPlaying; - } - - ILINE const bool IsCutscenePlaying() const - { - return m_isCutscenePlaying; - } - - ILINE void SetCutsceneIsPlaying(const bool isPlaying) - { - m_isCutscenePlaying = isPlaying; - } - ILINE bool IsInToolMode() const { return bToolMode; @@ -983,35 +736,17 @@ struct SSystemGlobalEnvironment bToolMode = bNewToolMode; } - ILINE void SetDynamicMergedMeshGenerationEnabled(bool mmgenEnable) - { - m_bDynamicMergedMeshGenerationEnabled = mmgenEnable; - } - - ILINE const bool IsDynamicMergedMeshGenerationEnabled() const - { - return m_bDynamicMergedMeshGenerationEnabled; - } - #if !defined(CONSOLE) private: - bool bClient; bool bEditor; // Engine is running under editor. bool bEditorGameMode; // Engine is in editor game mode. bool bEditorSimulationMode; // Engine is in editor simulation mode. bool bDedicated; // Engine is in dedicated #endif - bool m_isFMVPlaying; - bool m_isCutscenePlaying; - bool m_bDynamicMergedMeshGenerationEnabled; - public: SSystemGlobalEnvironment() - : pSystemScheduler(nullptr) - , szCmdLine("") - , bToolMode(false) - , m_bDynamicMergedMeshGenerationEnabled(false) + : bToolMode(false) { }; }; @@ -1049,37 +784,11 @@ struct IProfilingSystem // Initialize and dispatch all engine's subsystems. struct ISystem { - struct ILoadingProgressListener - { - // - virtual ~ILoadingProgressListener() {} - virtual void OnLoadingProgress(int steps) = 0; - // - }; - -#ifndef _RELEASE - enum LevelLoadOrigin - { - eLLO_Unknown, - eLLO_NewLevel, - eLLO_Level2Level, - eLLO_Resumed, - eLLO_MapCmd, - }; - - struct ICheckpointData - { - int m_totalLoads; - LevelLoadOrigin m_loadOrigin; - }; -#endif - // virtual ~ISystem() {} // Summary: // Releases ISystem. virtual void Release() = 0; - virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const = 0; // will return NULL if no whitelisting // Summary: // Returns pointer to the global environment structure. @@ -1108,33 +817,10 @@ struct ISystem virtual void DoWorkDuringOcclusionChecks() = 0; virtual bool NeedDoWorkDuringOcclusionChecks() = 0; - //! Update screen and call some important tick functions during loading. - virtual void SynchronousLoadingTick(const char* pFunc, int line) = 0; - - // Summary: - // Returns the current used memory. - virtual uint32 GetUsedMemory() = 0; - // Summary: // Retrieve the name of the user currently logged in to the computer. virtual const char* GetUserName() = 0; - // Summary: - // Gets current supported CPU features flags. (CPUF_SSE, CPUF_SSE2, CPUF_3DNOW, CPUF_MMX) - virtual int GetCPUFlags() = 0; - - // Summary: - // Gets number of CPUs - virtual int GetLogicalCPUCount() = 0; - - // Summary: - // Return the rendering driver name. GL or Metal - virtual const char* GetRenderingDriverName() const = 0; - - // Summary: - // Dumps the memory usage statistics to the logging default MB. (can be KB) - virtual void DumpMemoryUsageStatistics(bool bUseKB = false) = 0; - // Summary: // Quits the application. virtual void Quit() = 0; @@ -1145,22 +831,12 @@ struct ISystem // Returns true if the application is in the shutdown phase. virtual bool IsQuitting() const = 0; // Summary: - // Returns true if the application was initialized to generate the shader cache. - virtual bool IsShaderCacheGenMode() const = 0; - // Summary: // Tells the system in which way we are using the serialization system. virtual void SerializingFile(int mode) = 0; virtual int IsSerializingFile() const = 0; virtual bool IsRelaunch() const = 0; - // Summary: - // Displays an error message to display info for certain time - // Arguments: - // acMessage - Message to show - // fTime - Amount of seconds to show onscreen - virtual void DisplayErrorMessage(const char* acMessage, float fTime, const float* pfColor = 0, bool bHardError = true) = 0; - // Description: // Displays error message. // Logs it to console and file and error message box then terminates execution. @@ -1191,57 +867,20 @@ struct ISystem // return the related subsystem interface // - virtual IZLibCompressor* GetIZLibCompressor() = 0; - virtual IZLibDecompressor* GetIZLibDecompressor() = 0; - virtual ILZ4Decompressor* GetLZ4Decompressor() = 0; - virtual IZStdDecompressor* GetZStdDecompressor() = 0; - virtual ICryPerfHUD* GetPerfHUD() = 0; - virtual INotificationNetwork* GetINotificationNetwork() = 0; virtual IViewSystem* GetIViewSystem() = 0; virtual ILevelSystem* GetILevelSystem() = 0; virtual INameTable* GetINameTable() = 0; - virtual IValidator* GetIValidator() = 0; - virtual IStreamEngine* GetStreamEngine() = 0; virtual ICmdLine* GetICmdLine() = 0; virtual ILog* GetILog() = 0; virtual AZ::IO::IArchive* GetIPak() = 0; virtual ICryFont* GetICryFont() = 0; - virtual IMemoryManager* GetIMemoryManager() = 0; virtual IMovieSystem* GetIMovieSystem() = 0; virtual ::IConsole* GetIConsole() = 0; virtual IRemoteConsole* GetIRemoteConsole() = 0; - // Returns: - // Can be NULL, because it only exists when running through the editor, not in pure game mode. - virtual IResourceManager* GetIResourceManager() = 0; - virtual IThreadTaskManager* GetIThreadTaskManager() = 0; virtual IProfilingSystem* GetIProfilingSystem() = 0; virtual ISystemEventDispatcher* GetISystemEventDispatcher() = 0; - virtual IVisualLog* GetIVisualLog() = 0; - virtual IFileChangeMonitor* GetIFileChangeMonitor() = 0; - virtual WIN_HWND GetHWND() = 0; - - virtual IRenderer* GetIRenderer() = 0; virtual ITimer* GetITimer() = 0; - virtual IThreadManager* GetIThreadManager() = 0; - - //irtual IThreadManager* GetIThreadManager() = 0; - - virtual void SetLoadingProgressListener(ILoadingProgressListener* pListener) = 0; - virtual ISystem::ILoadingProgressListener* GetLoadingProgressListener() const = 0; - - // Summary: - // Game is created after System init, so has to be set explicitly. - virtual void SetIMaterialEffects(IMaterialEffects* pMaterialEffects) = 0; - virtual void SetIOpticsManager(IOpticsManager* pOpticsManager) = 0; - virtual void SetIFileChangeMonitor(IFileChangeMonitor* pFileChangeMonitor) = 0; - virtual void SetIVisualLog(IVisualLog* pVisualLog) = 0; - - //virtual const char *GetGamePath()=0; - - virtual void DebugStats(bool checkpoint, bool leaks) = 0; - virtual void DumpWinHeaps() = 0; - virtual int DumpMMStats(bool log) = 0; // Arguments: // bValue - Set to true when running on a cheat protected server or a client that is connected to it (not used in singleplayer). @@ -1251,8 +890,6 @@ struct ISystem virtual bool GetForceNonDevMode() const = 0; virtual bool WasInDevMode() const = 0; virtual bool IsDevMode() const = 0; - virtual bool IsMODValid(const char* szMODName) const = 0; - virtual bool IsMinimalMode() const = 0; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// @@ -1272,10 +909,6 @@ struct ISystem // Retrieves access to XML utilities interface. virtual IXmlUtils* GetXmlUtils() = 0; - // Summary: - // Interface to access different implementations of Serialization::IArchive in a centralized way. - virtual Serialization::IArchiveHost* GetArchiveHost() const = 0; - virtual void SetViewCamera(CCamera& Camera) = 0; virtual CCamera& GetViewCamera() = 0; @@ -1313,13 +946,6 @@ struct ISystem // Gets build version. virtual const SFileVersion& GetBuildVersion() = 0; - // Summary: - // Data compression - //##@{ - virtual bool CompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize, int level = 3) = 0; - virtual bool DecompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize) = 0; - //##@} - ////////////////////////////////////////////////////////////////////////// // Configuration. ////////////////////////////////////////////////////////////////////////// @@ -1341,21 +967,8 @@ struct ISystem // pCallback - 0 means normal LoadConfigVar behaviour is used virtual void LoadConfiguration(const char* sFilename, ILoadConfigurationEntrySink* pSink = 0, bool warnIfMissing = true) = 0; - // Summary: - // Retrieves current configuration specification for client or server. - // Arguments: - // bClient - If true returns local client config spec, if false returns server config spec. - virtual ESystemConfigSpec GetConfigSpec(bool bClient = true) = 0; - virtual ESystemConfigSpec GetMaxConfigSpec() const = 0; - // Summary: - // Changes current configuration specification for client or server. - // Arguments: - // bClient - If true changes client config spec (sys_spec variable changed), - // if false changes only server config spec (as known on the client). - virtual void SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient) = 0; - ////////////////////////////////////////////////////////////////////////// // Summary: @@ -1367,20 +980,6 @@ struct ISystem virtual void SetConfigPlatform(ESystemConfigPlatform platform) = 0; ////////////////////////////////////////////////////////////////////////// - // Summary: - // Detects and set optimal spec. - virtual void AutoDetectSpec(bool detectResolution) = 0; - - // Summary: - // Thread management for subsystems - // Return Value: - // Non-0 if the state was indeed changed, 0 if already in that state. - virtual int SetThreadState(ESubsystem subsys, bool bActive) = 0; - - // Summary: - // Creates and returns a usable object implementing ICrySizer interface. - virtual ICrySizer* CreateSizer() = 0; - // Summary: // Query if system is now paused. // Pause flag is set when calling system update with pause mode. @@ -1390,8 +989,6 @@ struct ISystem // Retrieves localized strings manager interface. virtual ILocalizationManager* GetLocalizationManager() = 0; - virtual ITextModeConsole* GetITextModeConsole() = 0; - // Summary: // Retrieves the perlin noise singleton instance. virtual CPNoise3* GetNoiseGen() = 0; @@ -1400,10 +997,6 @@ struct ISystem // Retrieves system update counter. virtual uint64 GetUpdateCounter() = 0; - // Summary: - // Gets access to all registered factories. - virtual ICryFactoryRegistry* GetCryFactoryRegistry() const = 0; - ////////////////////////////////////////////////////////////////////////// // Error callback handling @@ -1451,14 +1044,6 @@ struct ISystem // Get log index of the currently running Open 3D Engine application. (0 = first instance, 1 = second instance, etc) virtual int GetApplicationLogInstance(const char* logFilePath) = 0; - // Summary: - // Retrieves the current stats for systems to update the respective time taken - virtual sUpdateTimes& GetCurrentUpdateTimeStats() = 0; - - // Summary: - // Retrieves the array of update times and the number of entries - virtual const sUpdateTimes* GetUpdateTimeStats(uint32&, uint32&) = 0; - // Summary: // Clear all currently logged and drawn on screen error messages virtual void ClearErrorMessages() = 0; @@ -1491,52 +1076,13 @@ struct ISystem // returns zeroes if no updates happened yet virtual void GetUpdateStats(SSystemUpdateStats& stats) = 0; - // Description: - // Useful to investigate memory fragmentation. - // Every time you call this from the console: #System.DumpMemoryCoverage() - // it adds a line to "MemoryCoverage.bmp" (generated the first time, there is a max line count). - virtual void DumpMemoryCoverage() = 0; virtual ESystemGlobalState GetSystemGlobalState(void) = 0; virtual void SetSystemGlobalState(ESystemGlobalState systemGlobalState) = 0; - // Summary: - // Asynchronous memcpy - // Note sync variable will be incremented (in calling thread) before job starts - // and decremented when job finishes. Multiple async copies can therefore be - // tied to the same sync variable, therefore it's advised to wait for completion with - // while(*sync) (yield()); - virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync) = 0; - // - - -#if defined(CVARS_WHITELIST) - virtual ICVarsWhitelist* GetCVarsWhiteList() const = 0; -#endif // defined(CVARS_WHITELIST) - -#ifndef _RELEASE - virtual void GetCheckpointData(ICheckpointData& data) = 0; - virtual void IncreaseCheckpointLoadCount() = 0; - virtual void SetLoadOrigin(LevelLoadOrigin origin) = 0; -#endif - #if !defined(_RELEASE) virtual bool IsSavingResourceList() const = 0; #endif - // Initializes Steam if needed and returns if it was successful - virtual bool SteamInit() = 0; - - virtual const IImageHandler* GetImageHandler() const = 0; - - // Summary: - // Loads a dynamic library, creates and initializes an instance of the module class - - virtual bool InitializeEngineModule(const char* dllName, const char* moduleClassName, const SSystemInitParams& initParams) = 0; - - // Summary: - // Unloads a dynamic library as well as the corresponding instance of the module class - virtual bool UnloadEngineModule(const char* dllName, const char* moduleClassName) = 0; - // Summary: // Gets the root window message handler function // The returned pointer is platform-specific: @@ -1572,11 +1118,6 @@ struct ISystem using CrySystemNotificationBus = AZ::EBus; }; -//JAT - this is a very important function for the dedicated server - it lets us run >1000 players per piece of server hardware -//JAT - this saves us lots of money on the dedicated server hardware -#define SYNCHRONOUS_LOADING_TICK() do { if (gEnv && gEnv->pSystem) {gEnv->pSystem->SynchronousLoadingTick(__FUNC__, __LINE__); } \ -} while (0) - #if defined(USE_DISK_PROFILER) struct DiskOperationInfo @@ -1653,7 +1194,7 @@ typedef ISystem* (*PFNCREATESYSTEMINTERFACE)(SSystemInitParams& initParams); ////////////////////////////////////////////////////////////////////////// // Global environment variable. ////////////////////////////////////////////////////////////////////////// -extern SC_API SSystemGlobalEnvironment* gEnv; +extern SSystemGlobalEnvironment* gEnv; // Summary: @@ -1672,11 +1213,6 @@ inline ISystem* GetISystem() } return systemInterface; }; - -inline ISystemScheduler* GetISystemScheduler(void) -{ - return gEnv->pSystemScheduler; -}; ////////////////////////////////////////////////////////////////////////// // Description: @@ -1699,7 +1235,6 @@ void* GetDetachEnvironmentSymbol(); extern bool g_bProfilerEnabled; -extern int g_iTraceAllocations; // Summary: // Interface of the DLL. @@ -2151,44 +1686,6 @@ inline void CryLogAlways(const char* format, ...) #endif // EXCLUDE_NORMAL_LOG -/***************************************************** -ASYNC MEMCPY FUNCTIONS -*****************************************************/ - -// Complex delegation required because it is not really easy to -// export a external standalone symbol like a memcpy function when -// building with modules. Dll pay an extra indirection cost for calling this -// function. -#if !defined(AZ_MONOLITHIC_BUILD) -# define CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM -#endif -#define CRY_ASYNC_MEMCPY_API extern "C" - -// Note sync variable will be incremented (in calling thread) before job starts -// and decremented when job finishes. Multiple async copies can therefore be -// tied to the same sync variable, therefore wait for completion with -// while(*sync) (yield()); -#if defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) -inline void cryAsyncMemcpy( - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync) -{ - GetISystem()->AsyncMemcpy(dst, src, size, nFlags, sync); -} -# else -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpy( - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync); -#endif - - - ////////////////////////////////////////////////////////////////////////// // Additional headers. ////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CryCommon/ISystemScheduler.h b/Code/CryEngine/CryCommon/ISystemScheduler.h deleted file mode 100644 index 9280eb2ea6..0000000000 --- a/Code/CryEngine/CryCommon/ISystemScheduler.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H -#define CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H -#pragma once - -#if defined(__cplusplus) -#define SLICE_AND_SLEEP() do { if (GetISystemScheduler()) { GetISystemScheduler()->SliceAndSleep(__FUNC__, __LINE__); } \ -} while (0) -#define SLICE_SCOPE_DEFINE() CSliceLoadingMonitor sliceScope -#else -extern void SliceAndSleep(const char* pFunc, int line); -#define SLICE_AND_SLEEP() SliceAndSleep(__FILE__, __LINE__) -#endif - -struct ISystemScheduler -{ - virtual ~ISystemScheduler(){} - - // - // Map load slicing functionality support - virtual void SliceAndSleep(const char* sliceName, int line) = 0; - virtual void SliceLoadingBegin() = 0; - virtual void SliceLoadingEnd() = 0; - - virtual void SchedulingSleepIfNeeded(void) = 0; - // -}; - -ISystemScheduler* GetISystemScheduler(void); - -class CSliceLoadingMonitor -{ -public: - CSliceLoadingMonitor() - { - if (GetISystemScheduler()) - { - GetISystemScheduler()->SliceLoadingBegin(); - } - } - - ~CSliceLoadingMonitor() - { - if (GetISystemScheduler()) - { - GetISystemScheduler()->SliceLoadingEnd(); - } - } -}; - -#endif // CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H diff --git a/Code/CryEngine/CryCommon/ITerrain_info.h b/Code/CryEngine/CryCommon/ITerrain_info.h deleted file mode 100644 index 2a6ae29428..0000000000 --- a/Code/CryEngine/CryCommon/ITerrain_info.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef CRYINCLUDE_CRY3DENGINE_ITERRAIN_INFO_H -#define CRYINCLUDE_CRY3DENGINE_ITERRAIN_INFO_H -#pragma once - -#include -#include - -STRUCT_INFO_BEGIN(ITerrain::SurfaceWeight) -STRUCT_VAR_INFO(Ids, TYPE_ARRAY(WeightCount, TYPE_INFO(uint8))) -STRUCT_VAR_INFO(Weights, TYPE_ARRAY(WeightCount, TYPE_INFO(uint8))) -STRUCT_INFO_END(ITerrain::SurfaceWeight) - -#endif diff --git a/Code/CryEngine/CryCommon/ITextModeConsole.h b/Code/CryEngine/CryCommon/ITextModeConsole.h deleted file mode 100644 index 026f6d945f..0000000000 --- a/Code/CryEngine/CryCommon/ITextModeConsole.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Allows creation of text mode displays the for dedicated server - - -#ifndef CRYINCLUDE_CRYCOMMON_ITEXTMODECONSOLE_H -#define CRYINCLUDE_CRYCOMMON_ITEXTMODECONSOLE_H -#pragma once - - -struct ITextModeConsole -{ - // - virtual ~ITextModeConsole() {} - virtual Vec2_tpl BeginDraw() = 0; - virtual void PutText(int x, int y, const char* msg) = 0; - virtual void EndDraw() = 0; - virtual void OnShutdown() = 0; - - virtual void SetTitle([[maybe_unused]] const char* title) {} - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ITEXTMODECONSOLE_H diff --git a/Code/CryEngine/CryCommon/IThreadManager.h b/Code/CryEngine/CryCommon/IThreadManager.h deleted file mode 100644 index 448e3eec16..0000000000 --- a/Code/CryEngine/CryCommon/IThreadManager.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -class IThreadConfigManager; - -enum EJoinMode -{ - eJM_TryJoin, - eJM_Join, -}; - -class IThread -{ -public: - // - virtual ~IThread() - { - } - - //! Entry functions for code executed on thread. - virtual void ThreadEntry() = 0; - // -}; - -enum EFPE_Severity -{ - eFPE_None, //!< No Floating Point Exceptions. - eFPE_Basic, //!< Invalid operation, Div by 0. - eFPE_All, //!< Invalid operation, Div by 0, Denormalized operand, Overflow, Underflow, Inexact. - eFPE_LastEntry -}; - -//temp disable CRY DX12 -//#define SCOPED_ENABLE_FLOAT_EXCEPTIONS(eFPESeverity) CScopedFloatingPointException scopedSetFloatExceptionMask(eFPESeverity) -//#define SCOPED_DISABLE_FLOAT_EXCEPTIONS() CScopedFloatingPointException scopedSetFloatExceptionMask(eFPE_None) - -struct IThreadManager -{ -public: - // - virtual ~IThreadManager() - { - } - - //! Get thread config manager. - virtual IThreadConfigManager* GetThreadConfigManager() = 0; - - //! Spawn a new thread and apply thread config settings at thread beginning. - virtual bool SpawnThread(IThread* pThread, const char* sThreadName, ...) = 0; - - //! Wait on another thread to exit (Blocking). - //! Use eJM_TryJoin if you cannot be sure that the target thread is awake. - //! \retval true if target thread has not been started yet or has already exited. - //! \retval false if target thread is still running and therefore not in a state to exit. - virtual bool JoinThread(IThread* pThreadTask, EJoinMode joinStatus) = 0; - - //! Register 3rd party thread with the thread manager. - //! Applies thread config for thread if found. - //! \param pThreadHandle If NULL, the current thread handle will be used. - virtual bool RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) = 0; - - //! Unregister 3rd party thread with the thread manager. - virtual bool UnRegisterThirdPartyThread(const char* sThreadName, ...) = 0; - - //! Get Thread Name. - //! Returns "" if thread not found. - virtual const char* GetThreadName(threadID nThreadId) = 0; - - //! Get ThreadID. - virtual threadID GetThreadId(const char* sThreadName, ...) = 0; - - //! Execute function for each other thread but this one. - typedef void (* ThreadModifFunction)(threadID nThreadId, void* pData); - virtual void ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData = 0) = 0; - - virtual void EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId = 0) = 0; - virtual void EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) = 0; - - virtual uint GetFloatingPointExceptionMask() = 0; - virtual void SetFloatingPointExceptionMask(uint nMask) = 0; - // -}; -/*TEMP DISABLE CRY DX12 -class CScopedFloatingPointException -{ -public: - CScopedFloatingPointException(EFPE_Severity eFPESeverity) - { - oldMask = gEnv->pThreadManager->GetFloatingPointExceptionMask(); - gEnv->pThreadManager->EnableFloatExceptions(eFPESeverity); - } - ~CScopedFloatingPointException() - { - gEnv->pThreadManager->SetFloatingPointExceptionMask(oldMask); - } -private: - uint oldMask; -}; -*/ diff --git a/Code/CryEngine/CryCommon/IThreadTask.h b/Code/CryEngine/CryCommon/IThreadTask.h deleted file mode 100644 index d4a565fcff..0000000000 --- a/Code/CryEngine/CryCommon/IThreadTask.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "BitFiddling.h" - -#ifndef CRYINCLUDE_CRYCOMMON_ITHREADTASK_H -#define CRYINCLUDE_CRYCOMMON_ITHREADTASK_H -#pragma once - -#include - -// forward declarations -struct SThreadTaskInfo; - -enum EThreadTaskFlags -{ - THREAD_TASK_BLOCKING = BIT(0), // Blocking tasks will be allocated on their own thread. - THREAD_TASK_ASSIGN_TO_POOL = BIT(1), // Task can be assigned to any thread in the group of threads -}; - -class IThreadTask_Thread -{ -public: - // - virtual ~IThreadTask_Thread() {}; - virtual void AddTask(SThreadTaskInfo* pTaskInfo) = 0; - virtual void RemoveTask(SThreadTaskInfo* pTaskInfo) = 0; - virtual void RemoveAllTasks() = 0; - virtual void SingleUpdate() = 0; - // -}; - -typedef int ThreadPoolHandle; - -struct SThreadTaskParams -{ - uint32 nFlags; // Task flags. @see ETaskFlags - union - { - int nPreferedThread; // Preferred Thread index (0,1,2,3...) - ThreadPoolHandle nThreadsGroupId; // Id of group of threads(useful only if THREAD_TASK_ASSIGN_TO_POOL is set) - }; - int16 nPriorityOff; // If THREAD_TASK_BLOCKING, this will adjust the priority of the thread - int16 nStackSizeKB; // If THREAD_TASK_BLOCKING, this will adjust the stack size of the thread - const char* name; // Name for this task (thread for the blocking task will be named using this string) - - SThreadTaskParams() - : nFlags(0) - , nPreferedThread(-1) - , nPriorityOff(0) - , name("") - , nStackSizeKB(SIMPLE_THREAD_STACK_SIZE_KB) {} -}; - -////////////////////////////////////////////////////////////////////////// -// Tasks must implement this interface. -////////////////////////////////////////////////////////////////////////// -struct IThreadTask -{ - // - // The function to be called on every update for non bocking tasks. - // Or will be called only once for the blocking threads. - virtual void OnUpdate() = 0; - - // Called to indicate that this task must quit. - // Warning! can be called from different thread then OnUpdate call. - virtual void Stop() = 0; - - // Returns task info - virtual struct SThreadTaskInfo* GetTaskInfo() = 0; - - virtual ~IThreadTask() {} - // -}; - -struct SThreadTaskInfo - : public CMultiThreadRefCount -{ - IThreadTask_Thread* m_pThread; - IThreadTask* m_pTask; - SThreadTaskParams m_params; - - SThreadTaskInfo() - : m_pThread(NULL) - , m_pTask(NULL) { m_params.nFlags = 0; m_params.nPreferedThread = -1; } -}; - -// Might be changed to uint64 etc in the future -typedef uint32 ThreadPoolAffinityMask; -#define INVALID_AFFINITY 0 - -////////////////////////////////////////////////////////////////////////// -// Description of thread pool to create -////////////////////////////////////////////////////////////////////////// -struct ThreadPoolDesc -{ - ThreadPoolAffinityMask AffinityMask; // number of bits means number of threads. affinity overlapping is prohibited - string sPoolName; - int32 nThreadPriority; - int32 nThreadStackSizeKB; - - ThreadPoolDesc() - : AffinityMask(INVALID_AFFINITY) - , sPoolName("UnnamedPool") - , nThreadPriority(-1) - , nThreadStackSizeKB(-1) { } - - ILINE bool CreateThread(ThreadPoolAffinityMask affinityMask) - { - if (this->AffinityMask & affinityMask) - { - return false; - } - - this->AffinityMask |= affinityMask; - return true; - } - - ILINE uint32 GetThreadCount() const - { - return CountBits(AffinityMask); - } -}; - -////////////////////////////////////////////////////////////////////////// -// Task manager. -////////////////////////////////////////////////////////////////////////// -struct IThreadTaskManager -{ - // - virtual ~IThreadTaskManager(){} - // Register new task to the manager. - virtual void RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options) = 0; - virtual void UnregisterTask(IThreadTask* pTask) = 0; - - // Limit number of threads to this amount. - virtual void SetMaxThreadCount(int nMaxThreads) = 0; - - // Create a pool of threads - virtual ThreadPoolHandle CreateThreadsPool(const ThreadPoolDesc& desc) = 0; - virtual const bool DestroyThreadsPool(const ThreadPoolHandle& handle) = 0; - virtual const bool GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const = 0; - virtual const bool SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask) = 0; - - virtual void SetThreadName(threadID dwThreadId, const char* sThreadName) = 0; - virtual const char* GetThreadName(threadID dwThreadId) = 0; - - // Return thread handle by thread name - virtual threadID GetThreadByName(const char* sThreadName) = 0; - - // if bMark=true the calling thread will dump its stack during crashes - virtual void MarkThisThreadForDebugging(const char* name, bool bDump) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_ITHREADTASK_H diff --git a/Code/CryEngine/CryCommon/IVideoRenderer.h b/Code/CryEngine/CryCommon/IVideoRenderer.h deleted file mode 100644 index 7108731110..0000000000 --- a/Code/CryEngine/CryCommon/IVideoRenderer.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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. - * - */ - -#pragma once - -#include - -namespace AZ -{ - // General purpose video 'rendering' solution that abstracts video data into textures - // and data to update those textures with. - namespace VideoRenderer - { - enum Constants - { - MaxInputTextureCount = 4, - }; - - struct VideoTextureDesc - { - CryFixedStringT<64> m_name; // fixed string to avoid dll string copying issues - uint32 m_width{ 4 }; - uint32 m_height{ 4 }; - ETEX_Format m_format{ eTF_Unknown }; - uint32 m_used{ 0 }; - }; - - // Full description of video texture resources for the renderer to create. - struct VideoTexturesDesc - { - VideoTextureDesc m_outputTextureDesc; - VideoTextureDesc m_inputTextureDescs[MaxInputTextureCount]; - }; - - // Full set of textures created from the VideoTexturesDesc provided to the renderer. - struct VideoTextures - { - uint32 m_outputTextureId{ 0 }; - uint32 m_inputTextureIds[MaxInputTextureCount]{ 0 }; - }; - - struct VideoUpdateData - { - struct VideoTextureUpdateData - { - // Data to update the texture with, can be null. - const void* m_data{ nullptr }; - - // Format of above data, required for format conversions if needed. - ETEX_Format m_dataFormat{ eTF_Unknown }; - } - m_inputTextureData[MaxInputTextureCount]; - }; - - // Set of data to update and render a frame of video textures. - // Everything should be passed through by value except for the update data, which should be double buffered at the source. - struct DrawArguments - { - // Set of textures to draw with. - VideoTextures m_textures; - - // Set of data to update the above textures with if set. - VideoUpdateData m_updateData; - - // Flag to indicate that we want to draw to the backbuffer. - uint32 m_drawingToBackbuffer{ 0 }; - - // Payload information for reference. Useful for debugging. - uint32 m_frameReference{ 0 }; - - // Scale applied to each texture. - Vec4 m_textureScales[MaxInputTextureCount]{}; - - // Value added to final composited texture. - Vec4 m_colorAdjustment{ ZERO }; - }; - - // Video Rendering interface to provide callbacks from the Render Thread - struct IVideoRenderer - { - // Called from the Render Thread to request the description of the video textures. - virtual bool GetVideoTexturesDesc(AZ::VideoRenderer::VideoTexturesDesc& videoTexturesDesc) const = 0; - // Called from the Render Thread to get the set of video textures that were previously created. Used at cleanup time. - virtual bool GetVideoTextures(AZ::VideoRenderer::VideoTextures& videoTextures) const = 0; - - // Called from the Render Thread to provide the video textures it created from the VideoTexturesDesc. - virtual bool NotifyTexturesCreated(const AZ::VideoRenderer::VideoTextures& videoTextures) = 0; - // CAlled from the Render Thread to notify the video manager that its textures were destroyed. - virtual bool NotifyTexturesDestroyed() = 0; - }; - } -} diff --git a/Code/CryEngine/CryCommon/IZLibCompressor.h b/Code/CryEngine/CryCommon/IZLibCompressor.h deleted file mode 100644 index df85992eef..0000000000 --- a/Code/CryEngine/CryCommon/IZLibCompressor.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IZLIBCOMPRESSOR_H -#define CRYINCLUDE_CRYCOMMON_IZLIBCOMPRESSOR_H -#pragma once - - -/* - wrapper interface for the zlib compression / deflate interface - - supports multiple compression streams with an async compatible wrapper - - Gotchas: - the ptr to the input data must remain valid whilst the stream is deflating - the ptr to the output buffer must remain valid whilst the stream is deflating - - **************************************************************************************** - - usage example: - - IZLibCompressor *pComp=GetISystem()->GetIZLibCompressor(); - // see deflateInit2() documentation zlib manual for more info on the parameters here - // this initializes the stream to produce a gzip format block with fairly low memory requirements - IZLibDeflateStream *pStream=pComp->CreateDeflateStream(2,eZMeth_Deflated,24,3,eZStrat_Default,eZFlush_NoFlush); - char *pOutput=new char[512]; // arbitrary size - const char *pInputData="This is an example piece of data that is to be compressed. It can be any arbitrary block of binary data - not just text"; - const int inputBlockSize=16; // to simulate streaming of input, this example provides the input in 16 byte blocks - int totalInput=sizeof(pInputData); - int bytesInput=0; - bool done=false; - FILE *outputFile=fopen("myfile.gz","rb"); - - do - { - EZDeflateState state=pStream->GetState(); - - switch (state) - { - case eZDefState_AwaitingInput: - // 'stream' input data, there is no restriction on the block size you can input, if all the data is available immediately, input all of it at once - { - int inputSize=min(inputBlockSize,totalInput-bytesInput); - - if (inputSize<=0) - { - pStream->EndInput(); - } - else - { - pStream->Input(pInputData+bytesInput,inputSize); - bytesInput+=inputSize; - } - } - break; - - case eZDefState_Deflating: - // do something more interesting... like getting out of this loop and running the rest of your game... - break; - - case eZDefState_ConsumeOutput: - // stream output to a file - { - int bytesToOutput=pStream->GetBytesOutput(); - - if (bytesToOutput>0) - { - fwrite(pOutput,1,bytesToOutput,outputFile); - } - - pStream->SetOutputBuffer(pOutput,sizeof(pOutput)); - } - break; - - case eZDefState_Finished: - case ezDefState_Error: - done=true; - break; - } - - } while (!done); - - fclose(outputFile); - - pStream->Release(); - delete [] pOutput; - -****************************************************************************************/ - -// don't change the order of these zlib wrapping enum values without updating the mapping -// implementation in CZLibCompressorStream -enum EZLibStrategy -{ - eZStrat_Default, // Z_DEFAULT_STRATEGY - eZStrat_Filtered, // Z_FILTERED - eZStrat_HuffmanOnly, // Z_HUFFMAN_ONLY - eZStrat_RLE // Z_RLE -}; -enum EZLibMethod -{ - eZMeth_Deflated // Z_DEFLATED -}; -enum EZLibFlush -{ - eZFlush_NoFlush, // Z_NO_FLUSH - eZFlush_PartialFlush, // Z_PARTIAL_FLUSH - eZFlush_SyncFlush, // Z_SYNC_FLUSH - eZFlush_FullFlush, // Z_FULL_FLUSH -}; - -enum EZDeflateState -{ - eZDefState_AwaitingInput, // caller must call Input() or Finish() to continue - eZDefState_Deflating, // caller must wait - eZDefState_ConsumeOutput, // caller must consume output and then call SetOutputBuffer() to continue - eZDefState_Finished, // stream finished, caller must call Release() to destroy stream - eZDefState_Error // error has occurred and the stream has been closed and will no longer compress -}; - -struct IZLibDeflateStream -{ -protected: - virtual ~IZLibDeflateStream() {}; // use Release() - -public: - struct SStats - { - int bytesInput; - int bytesOutput; - int curMemoryUsed; - int peakMemoryUsed; - }; - - // - // Description: - // Specifies the output buffer for the deflate operation - // Should be set before providing input - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZDefState_Deflating) - virtual void SetOutputBuffer(char* pInBuffer, int inSize) = 0; - - // Description: - // Returns the number of bytes from the output buffer that are ready to be consumed. After consuming any output, you should call SetOutputBuffer() again to mark the buffer as available - virtual int GetBytesOutput() = 0; - - // Description: - // Begins compressing the source data pInSource of length inSourceSize to a previously specified output buffer - // Only valid to be called if the stream is in state eZDefState_AwaitingInput - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZDefState_Deflating) - virtual void Input(const char* pInSource, int inSourceSize) = 0; - - // Description: - // Finishes the compression, causing all data to be flushed to the output buffer - // Once called no more data can be input - // After calling the caller must wait until GetState() reutrns eZDefState_Finished - virtual void EndInput() = 0; - - // Description: - // Returns the state of the stream, - virtual EZDeflateState GetState() = 0; - - // Description: - // Gets stats on deflate stream, valid to call at anytime - virtual void GetStats(SStats* pOutStats) = 0; - - // Description: - // Deletes the deflate stream. Will assert if stream is in an invalid state to be released (in state eZDefState_Deflating) - virtual void Release() = 0; - // -}; - -// md5 support structure -struct SMD5Context -{ - uint32 buf[4]; - uint32 bits[2]; - unsigned char in[64]; -}; - -struct IZLibCompressor -{ -protected: - virtual ~IZLibCompressor() {}; // use Release() - -public: - // - // Description: - // Creates a deflate stream to compress data using zlib - // See documentation for zlib deflateInit2() for usage details - // inFlushMethod is passed to calls to zlib deflate(), see zlib docs on deflate() for more details - virtual IZLibDeflateStream* CreateDeflateStream(int inLevel, EZLibMethod inMethod, int inWindowBits, int inMemLevel, EZLibStrategy inStrategy, EZLibFlush inFlushMethod) = 0; - - virtual void Release() = 0; - - // Description: - // Initializes an MD5 context - virtual void MD5Init(SMD5Context* pIOCtx) = 0; - - // Description: - // Digests some data into an existing MD5 context - virtual void MD5Update(SMD5Context* pIOCtx, const char* pInBuff, unsigned int len) = 0; - - // Description: - // Closes the MD5 context and extract the final 16 byte MD5 digest value - virtual void MD5Final(SMD5Context * pIOCtx, char outDigest[16]) = 0; - // -}; - -#endif // CRYINCLUDE_CRYCOMMON_IZLIBCOMPRESSOR_H - diff --git a/Code/CryEngine/CryCommon/IZStdDecompressor.h b/Code/CryEngine/CryCommon/IZStdDecompressor.h deleted file mode 100644 index b5ab0f3088..0000000000 --- a/Code/CryEngine/CryCommon/IZStdDecompressor.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - - -class IZStdDecompressor -{ -public: - virtual bool DecompressData(const char* pIn, const uint inputSize, char* pOut, const uint outputSize) = 0; - virtual void Release() = 0; - -protected: - virtual ~IZStdDecompressor() = default; // use Release() -}; - diff --git a/Code/CryEngine/CryCommon/IZlibDecompressor.h b/Code/CryEngine/CryCommon/IZlibDecompressor.h deleted file mode 100644 index bd9417c935..0000000000 --- a/Code/CryEngine/CryCommon/IZlibDecompressor.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Provides the interface for the zlib inflate wrapper - - -#ifndef CRYINCLUDE_CRYCOMMON_IZLIBDECOMPRESSOR_H -#define CRYINCLUDE_CRYCOMMON_IZLIBDECOMPRESSOR_H -#pragma once - - -enum EZInflateState -{ - eZInfState_AwaitingInput, // caller must call Input() to continue - eZInfState_Inflating, // caller must wait - eZInfState_ConsumeOutput, // caller must consume output and then call SetOutputBuffer() to continue - eZInfState_Finished, // caller must call Release() - eZInfState_Error // error has occurred and the stream has been closed and will no longer compress -}; - -struct IZLibInflateStream -{ -protected: - virtual ~IZLibInflateStream() {}; // use Release() - -public: - struct SStats - { - int bytesInput; - int bytesOutput; - int curMemoryUsed; - int peakMemoryUsed; - }; - - // Description: - // Specifies the output buffer for the inflate operation - // Should be set before providing input - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZInfState_Inflating) - virtual void SetOutputBuffer(char* pInBuffer, unsigned int inSize) = 0; - - // Description: - // Returns the number of bytes from the output buffer that are ready to be consumed. After consuming any output, you should call SetOutputBuffer() again to mark the buffer as available - virtual unsigned int GetBytesOutput() = 0; - - // Description: - // Begins decompressing the source data pInSource of length inSourceSize to a previously specified output buffer - // Only valid to be called if the stream is in state eZInfState_AwaitingInput - // The specified buffer must remain valid (ie do not free) whilst compression is in progress (state == eZInfState_Inflating) - virtual void Input(const char* pInSource, unsigned int inSourceSize) = 0; - - // Description: - // Finishes the compression, causing all data to be flushed to the output buffer - // Once called no more data can be input - // After calling the caller must wait until GetState() reuturns eZInfState_Finished - virtual void EndInput() = 0; - - // Description: - // Returns the state of the stream, - virtual EZInflateState GetState() = 0; - - // Description: - // Gets stats on inflate stream, valid to call at anytime - virtual void GetStats(SStats* pOutStats) = 0; - - // Description: - // Deletes the inflate stream. Will assert if stream is in an invalid state to be released (in state eZInfState_Inflating) - virtual void Release() = 0; -}; - -struct IZLibDecompressor -{ -protected: - virtual ~IZLibDecompressor() {}; // use Release() - -public: - // Description: - // Creates a inflate stream to decompress data using zlib - virtual IZLibInflateStream* CreateInflateStream() = 0; - - virtual void Release() = 0; -}; - -#endif // CRYINCLUDE_CRYCOMMON_IZLIBDECOMPRESSOR_H - diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp b/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp deleted file mode 100644 index 8cf29bcb2a..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -namespace CImageExtensionHelper -{ - ColorF GetAverageColor(uint8 const* pMem) - { - pMem = _findChunkStart(pMem, FOURCC_AvgC); - - if (pMem) - { - ColorF ret = ColorF(SwapEndianValue(*(uint32*)pMem)); - //flip red and blue - const float cRed = ret.r; - ret.r = ret.b; - ret.b = cRed; - return ret; - } - - return Col_White; // chunk does not exist - } - - bool IsRangeless(ETEX_Format eTF) - { - return (eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_R9G9B9E5 || - eTF == eTF_R16G16B16A16F || - eTF == eTF_R32G32B32A32F || - eTF == eTF_R16F || - eTF == eTF_R32F || - eTF == eTF_R16G16F || - eTF == eTF_R11G11B10F); - } - - bool IsQuantized(ETEX_Format eTF) - { - return (eTF == eTF_B4G4R4A4 || - eTF == eTF_B5G6R5 || - eTF == eTF_B5G5R5 || - eTF == eTF_BC1 || - eTF == eTF_BC2 || - eTF == eTF_BC3 || - eTF == eTF_BC4U || - eTF == eTF_BC4S || - eTF == eTF_BC5U || - eTF == eTF_BC5S || - eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_BC7 || - eTF == eTF_R9G9B9E5 || - eTF == eTF_ETC2 || - eTF == eTF_EAC_R11 || - eTF == eTF_ETC2A || - eTF == eTF_EAC_RG11 || - eTF == eTF_PVRTC2 || - eTF == eTF_PVRTC4 || - eTF == eTF_ASTC_4x4 || - eTF == eTF_ASTC_5x4 || - eTF == eTF_ASTC_5x5 || - eTF == eTF_ASTC_6x5 || - eTF == eTF_ASTC_6x6 || - eTF == eTF_ASTC_8x5 || - eTF == eTF_ASTC_8x6 || - eTF == eTF_ASTC_8x8 || - eTF == eTF_ASTC_10x5 || - eTF == eTF_ASTC_10x6 || - eTF == eTF_ASTC_10x8 || - eTF == eTF_ASTC_10x10 || - eTF == eTF_ASTC_12x10 || - eTF == eTF_ASTC_12x12 - ); - } -} diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper.h b/Code/CryEngine/CryCommon/ImageExtensionHelper.h deleted file mode 100644 index 71e58074c9..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper.h +++ /dev/null @@ -1,2155 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#undef AZ_RESTRICTED_SECTION -#define IMAGEEXTENSIONHELPER_H_SECTION_1 1 -#define IMAGEEXTENSIONHELPER_H_SECTION_2 2 -#define IMAGEEXTENSIONHELPER_H_SECTION_CONSTS 3 -#define IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE 4 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_1 - #include AZ_RESTRICTED_FILE(ImageExtensionHelper_h) -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_2 - #include AZ_RESTRICTED_FILE(ImageExtensionHelper_h) -#endif - -#ifndef MAKEFOURCC - #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \ - ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24)) -#endif /* defined(MAKEFOURCC) */ - - -// This header defines constants and structures that are useful when parsing -// DDS files. DDS files were originally designed to use several structures -// and constants that are native to DirectDraw and are defined in ddraw.h, -// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar -// (compatible) constants and structures so that one can use DDS files -// without needing to include ddraw.h. - -// Crytek specific image extensions -// -// usually added to the end of DDS files - -//Needed to write out DDS files on Mac -#if AZ_TRAIT_OS_PLATFORM_APPLE || defined(AZ_PLATFORM_LINUX) -#define DDPF_ALPHAPIXELS 0x00000001 // Texture contains alpha data -#define DDPF_ALPHA 0x00000002 // For alpha channel only uncompressed data -#define DDPF_FOURCC 0x00000004 // Texture contains compressed RGB data -#define DDPF_RGB 0x00000040 // Texture contains uncompressed RGB data -#define DDPF_YUV 0x00000200 // For YUV uncompressed data -#define DDPF_LUMINANCE 0x00020000 // For single channel color uncompressed data - -#define DDSCAPS_COMPLEX 0x00000008 // Must be used on any file that contains more than one surface -#define DDSCAPS_MIPMAP 0x00400000 // Should be used for a mipmap -#define DDSCAPS_TEXTURE 0x00001000 // Required -#endif - -#define DDS_FOURCC 0x00000004 // DDPF_FOURCC -#define DDS_RGB 0x00000040 // DDPF_RGB -#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE -#define DDS_SIGNED 0x00080000 // DDPF_SIGNED -#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS -#define DDS_LUMINANCEA 0x00020001 // DDS_LUMINANCE | DDPF_ALPHAPIXELS -#define DDS_A 0x00000001 // DDPF_ALPHAPIXELS -#define DDS_A_ONLY 0x00000002 // DDPF_ALPHA - -#define DDS_FOURCC_A16B16G16R16 0x00000024 // FOURCC A16B16G16R16 -#define DDS_FOURCC_V16U16 0x00000040 // FOURCC V16U16 -#define DDS_FOURCC_Q16W16V16U16 0x0000006E // FOURCC Q16W16V16U16 -#define DDS_FOURCC_R16F 0x0000006F // FOURCC R16F -#define DDS_FOURCC_G16R16F 0x00000070 // FOURCC G16R16F -#define DDS_FOURCC_A16B16G16R16F 0x00000071 // FOURCC A16B16G16R16F -#define DDS_FOURCC_R32F 0x00000072 // FOURCC R32F -#define DDS_FOURCC_G32R32F 0x00000073 // FOURCC G32R32F -#define DDS_FOURCC_A32B32G32R32F 0x00000074 // FOURCC A32B32G32R32F - -#define DDSD_CAPS 0x00000001l // default -#define DDSD_PIXELFORMAT 0x00001000l -#define DDSD_WIDTH 0x00000004l -#define DDSD_HEIGHT 0x00000002l -#define DDSD_LINEARSIZE 0x00080000l - -#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT -#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT -#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH -#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH -#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE - -#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE -#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP -#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX - -#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX -#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX -#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY -#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY -#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ -#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ - -#define DDS_CUBEMAP_ALLFACES (DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX | \ - DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY | \ - DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ) - -#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME - -#define DDS_RESF1_NORMALMAP 0x01000000 -#define DDS_RESF1_DSDT 0x02000000 - -#define CRY_DDS_DX10_SUPPORT - -#include - -#if defined(WIN32) && !defined(DXGI_FORMAT_DEFINED) -#include // DX10+ formats -#endif // #if defined(WIN32) && !defined(DXGI_FORMAT_DEFINED) - - -namespace CImageExtensionHelper -{ - struct DDS_PIXELFORMAT - { - DWORD dwSize; - DWORD dwFlags; - DWORD dwFourCC; - DWORD dwRGBBitCount; - DWORD dwRBitMask; - DWORD dwGBitMask; - DWORD dwBBitMask; - DWORD dwABitMask; - - const bool operator == (const DDS_PIXELFORMAT& fmt) const - { - return dwFourCC == fmt.dwFourCC && - dwFlags == fmt.dwFlags && - dwRGBBitCount == fmt.dwRGBBitCount && - dwRBitMask == fmt.dwRBitMask && - dwGBitMask == fmt.dwGBitMask && - dwBBitMask == fmt.dwBBitMask && - dwABitMask == fmt.dwABitMask && - dwSize == fmt.dwSize; - } - - AUTO_STRUCT_INFO - }; - - struct DDS_HEADER_DXT10 - { - // we're unable to use native enums because of TypeInfo(), so we use DWORD instead. - DWORD /*DXGI_FORMAT*/ dxgiFormat; - DWORD /*D3D10_RESOURCE_DIMENSION*/ resourceDimension; - unsigned int miscFlag; - unsigned int arraySize; - unsigned int reserved; - - AUTO_STRUCT_INFO - }; - - struct DDS_HEADER - { - DWORD dwSize; - DWORD dwHeaderFlags; - DWORD dwHeight; - DWORD dwWidth; - DWORD dwPitchOrLinearSize; - DWORD dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags - DWORD dwMipMapCount; - DWORD dwAlphaBitDepth; - DWORD dwReserved1; // Crytek image flags - float fAvgBrightness; // Average top mip brightness. Could be f16/half - ColorF cMinColor; - ColorF cMaxColor; - DDS_PIXELFORMAT ddspf; - DWORD dwSurfaceFlags; - DWORD dwCubemapFlags; - BYTE bNumPersistentMips; - BYTE bTileMode; - BYTE bReserved2[6]; - DWORD dwTextureStage; - - AUTO_STRUCT_INFO - - inline const bool IsValid() const { return sizeof(*this) == dwSize; } - inline const bool IsDX10Ext() const { return ddspf.dwFourCC == MAKEFOURCC('D', 'X', '1', '0'); } - inline const uint32 GetMipCount() const { return max(1u, (uint32)dwMipMapCount); } - - inline const size_t GetFullHeaderSize() const - { - if (IsDX10Ext()) - { - return sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); - } - - return sizeof(DDS_HEADER); - } - }; - - // standard description of file header - struct DDS_FILE_DESC - { - DWORD dwMagic; - DDS_HEADER header; - - AUTO_STRUCT_INFO - - inline const bool IsValid() const { return dwMagic == MAKEFOURCC('D', 'D', 'S', ' ') && header.IsValid(); } - inline const size_t GetFullHeaderSize() const { return sizeof(dwMagic) + header.GetFullHeaderSize(); } - }; - - // chunk identifier - const static uint32 FOURCC_CExt = MAKEFOURCC('C', 'E', 'x', 't'); // Crytek extension start - const static uint32 FOURCC_AvgC = MAKEFOURCC('A', 'v', 'g', 'C'); // average color - const static uint32 FOURCC_CEnd = MAKEFOURCC('C', 'E', 'n', 'd'); // Crytek extension end - const static uint32 FOURCC_AttC = MAKEFOURCC('A', 't', 't', 'C'); // Chunk Attached Channel - - // flags to propagate from the RC to the engine through GetImageFlags() - // 32bit bitmask, numbers should not change as engine relies on them - const static uint32 EIF_Cubemap = 0x1; - const static uint32 EIF_Volumetexture = 0x2; - const static uint32 EIF_Decal = 0x4; // this is usually set through the preset - const static uint32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color - const static uint32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture - const static uint32 EIF_UNUSED_BIT = 0x40; // Free to use - const static uint32 EIF_AttachedAlpha = 0x400; // info for the engine: it's a texture with attached alpha channel - const static uint32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear) - const static uint32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized with r_TexResolution - const static uint32 EIF_RenormalizedTexture = 0x10000; // info for the engine: for dds textures that have renormalized color range - const static uint32 EIF_CafeNative = 0x20000; // info for the engine: native Cafe texture format - const static uint32 EIF_Tiled = 0x80000; // info for the engine: texture has been tiled for the platform - const static uint32 EIF_Splitted = 0x200000; // info for the engine: this texture is splitted - const static uint32 EIF_Colormodel = 0x7000000; // info for the engine: bitmask: colormodel used in the texture - const static uint32 EIF_Colormodel_RGB = 0x0000000; // info for the engine: colormodel is RGB (default) - const static uint32 EIF_Colormodel_CIE = 0x1000000; // info for the engine: colormodel is CIE (used for terrain) - const static uint32 EIF_Colormodel_YCC = 0x2000000; // info for the engine: colormodel is Y'CbCr (used for reflectance) - const static uint32 EIF_Colormodel_YFF = 0x3000000; // info for the engine: colormodel is Y'FbFr (used for reflectance) - const static uint32 EIF_Colormodel_IRB = 0x4000000; // info for the engine: colormodel is IRB (used for reflectance) - -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, jasper) - #undef AZ_RESTRICTED_SECTION -#endif - -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, provo) - #undef AZ_RESTRICTED_SECTION -#endif - -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_CONSTS - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, salem) - #undef AZ_RESTRICTED_SECTION -#endif - - enum ETileMode - { - eTM_None = 0, - eTM_LinearPadded, - eTM_Optimal, - }; - - // Arguments: - // pDDSHeader - must not be 0 - // Returns: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - inline uint32 GetImageFlags(DDS_HEADER* pDDSHeader) - { - assert(pDDSHeader); - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - if (pDDSHeader->dwSize >= sizeof(DDS_HEADER)) - { - if (pDDSHeader->dwTextureStage == 'CRYF') - { - return pDDSHeader->dwReserved1; - } - } - - return 0; - } - - // Arguments: - // pDDSHeader - must not be 0 - // Returns: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - inline bool SetImageFlags(DDS_HEADER* pDDSHeader, uint32 flags) - { - assert(pDDSHeader); - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - if (pDDSHeader->dwSize >= sizeof(DDS_HEADER)) - { - if (pDDSHeader->dwTextureStage == 'CRYF') - { - pDDSHeader->dwReserved1 = flags; - return true; - } - } - - return false; - } - - // Arguments: - // Chunk flags (combined from EIF_Cubemap,EIF_Volumetexture,EIF_Decal,...) - // Returns: - // true, if this texture is ready for this platform - inline const bool IsImageNative(const uint32 nFlags) - { - return (nFlags & (0 -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, jasper) -#endif -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, provo) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) - #define AZ_RESTRICTED_SECTION IMAGEEXTENSIONHELPER_H_SECTION_ISNATIVE - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageExtensionHelper_h, salem) -#endif - )) == 0; - } - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - // Returns: - // 0 if not existing - inline uint8 const* _findChunkStart(uint8 const* pMem, const uint32 dwChunkName, uint32* dwOutSize = NULL) - { - if (pMem) - { - if (*(uint32*)pMem == SwapEndianValue(FOURCC_CExt)) - { - pMem += 4; // jump over chunk name - while (*(uint32*)pMem != SwapEndianValue(FOURCC_CEnd)) - { - if (*(uint32*)pMem == SwapEndianValue(dwChunkName)) - { - pMem += 4; // jump over chunk name - const uint32 size = SwapEndianValue(*(uint32*)(pMem)); - if (dwOutSize) - { - *dwOutSize = size; - } - pMem += 4; // jump over chunk size - return size > 0 ? pMem : NULL; - } - - pMem += 8 + SwapEndianValue(*(uint32*)(&pMem[4])); // jump over chunk - } - } - } - - return 0; // chunk does not exist - } - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - ColorF GetAverageColor(uint8 const* pMem); - - // Arguments: - // pMem - usually first byte behind DDS file data, can be 0 (e.g. in case there no more bytes than DDS file data) - // Returns: - // pointer to the DDS header - inline DDS_HEADER* GetAttachedImage(uint8 const* pMem, uint32* dwOutSize = NULL) - { - pMem = _findChunkStart(pMem, FOURCC_AttC, dwOutSize); - if (pMem) - { - return (DDS_HEADER*)(pMem + 4); - } - - if (dwOutSize) - { - *dwOutSize = 0; - } - return 0; // chunk does not exist - } - - static ILINE Vec2i GetBlockDim(const ETEX_Format eTF) - { - if (eTF == eTF_BC1 || eTF == eTF_BC2 || eTF == eTF_BC3 || eTF == eTF_BC5U || eTF == eTF_BC5S || eTF == eTF_BC4U || eTF == eTF_BC4S || eTF == eTF_CTX1 || eTF == eTF_BC6UH || eTF == eTF_BC6SH || eTF == eTF_BC7 || eTF == eTF_EAC_R11 || eTF == eTF_EAC_RG11 || eTF == eTF_ETC2 || eTF == eTF_ETC2A) - { - return Vec2i(4, 4); - } - // Apple requires the following for the texture: - // Height and width must be a power of 2 - // Height and width must be at least 8 - // Must be square - switch (eTF) - { - case eTF_PVRTC2: - return Vec2i(8, 4); - case eTF_PVRTC4: - return Vec2i(4, 4); - case eTF_ASTC_4x4: - return Vec2i(4, 4); - case eTF_ASTC_5x4: - return Vec2i(5, 4); - case eTF_ASTC_5x5: - return Vec2i(5, 5); - case eTF_ASTC_6x5: - return Vec2i(6, 5); - case eTF_ASTC_6x6: - return Vec2i(6, 6); - case eTF_ASTC_8x5: - return Vec2i(8, 5); - case eTF_ASTC_8x6: - return Vec2i(8, 6); - case eTF_ASTC_8x8: - return Vec2i(8, 8); - case eTF_ASTC_10x5: - return Vec2i(10, 5); - case eTF_ASTC_10x6: - return Vec2i(10, 6); - case eTF_ASTC_10x8: - return Vec2i(10, 8); - case eTF_ASTC_10x10: - return Vec2i(10, 10); - case eTF_ASTC_12x10: - return Vec2i(12, 10); - case eTF_ASTC_12x12: - return Vec2i(12, 12); - } - - return Vec2i(1, 1); - } - - inline int BytesPerBlock(ETEX_Format eTF) - { - switch (eTF) - { - case eTF_R8G8B8A8S: - return 32 / 8; - case eTF_R8G8B8A8: - return 32 / 8; - - case eTF_A8: - return 8 / 8; - case eTF_R8: - return 8 / 8; - case eTF_R8S: - return 8 / 8; - case eTF_R16: - return 16 / 8; - case eTF_R16U: - return 16 / 8; - case eTF_R16G16U: - return 32 / 8; - case eTF_R10G10B10A2UI: - return 32 / 8; - case eTF_R16F: - return 16 / 8; - case eTF_R32F: - return 32 / 8; - case eTF_R8G8: - return 16 / 8; - case eTF_R8G8S: - return 16 / 8; - case eTF_R16G16: - return 32 / 8; - case eTF_R16G16S: - return 32 / 8; - case eTF_R16G16F: - return 32 / 8; - case eTF_R11G11B10F: - return 32 / 8; - case eTF_R10G10B10A2: - return 32 / 8; - case eTF_R16G16B16A16: - return 64 / 8; - case eTF_R16G16B16A16S: - return 64 / 8; - case eTF_R16G16B16A16F: - return 64 / 8; - case eTF_R32G32B32A32F: - return 128 / 8; - - case eTF_R9G9B9E5: - return 32 / 8; - - case eTF_D16: - return 16 / 8; - case eTF_D24S8: - return 32 / 8; - case eTF_D32F: - return 32 / 8; - case eTF_D32FS8: - return 32 / 8; - - case eTF_B5G6R5: - return 16 / 8; - case eTF_B5G5R5: - return 16 / 8; - case eTF_B4G4R4A4: - return 16 / 8; - - case eTF_A8L8: - return 16 / 8; - case eTF_L8: - return 8 / 8; - case eTF_L8V8U8: - return 24 / 8; - case eTF_B8G8R8: - return 24 / 8; - case eTF_L8V8U8X8: - return 32 / 8; - case eTF_B8G8R8X8: - return 32 / 8; - case eTF_B8G8R8A8: - return 32 / 8; - - case eTF_CTX1: - case eTF_BC1: - case eTF_BC4U: - case eTF_BC4S: - case eTF_ETC2: - case eTF_EAC_R11: - return 8; - - case eTF_BC2: - case eTF_BC3: - case eTF_BC5U: - case eTF_BC5S: - case eTF_BC6UH: - case eTF_BC6SH: - case eTF_BC7: - case eTF_ETC2A: - case eTF_EAC_RG11: - return 16; - - case eTF_PVRTC2: - case eTF_PVRTC4: - return 8; - - case eTF_ASTC_4x4: - case eTF_ASTC_5x4: - case eTF_ASTC_5x5: - case eTF_ASTC_6x5: - case eTF_ASTC_6x6: - case eTF_ASTC_8x5: - case eTF_ASTC_8x6: - case eTF_ASTC_8x8: - case eTF_ASTC_10x5: - case eTF_ASTC_10x6: - case eTF_ASTC_10x8: - case eTF_ASTC_10x10: - case eTF_ASTC_12x10: - case eTF_ASTC_12x12: - return 16; - default: - assert(0); - } - return 0; - } - - - inline bool IsBlockCompressed(ETEX_Format eTF) - { - return (eTF == eTF_BC1 || - eTF == eTF_BC2 || - eTF == eTF_BC3 || - eTF == eTF_BC4U || - eTF == eTF_BC4S || - eTF == eTF_BC5S || - eTF == eTF_BC5U || - eTF == eTF_BC6UH || - eTF == eTF_BC6SH || - eTF == eTF_BC7 || - eTF == eTF_CTX1 || - eTF == eTF_ETC2 || - eTF == eTF_EAC_R11 || - eTF == eTF_ETC2A || - eTF == eTF_EAC_RG11 || - eTF == eTF_PVRTC2 || - eTF == eTF_PVRTC4 || - eTF == eTF_ASTC_4x4 || - eTF == eTF_ASTC_5x4 || - eTF == eTF_ASTC_5x5 || - eTF == eTF_ASTC_6x5 || - eTF == eTF_ASTC_6x6 || - eTF == eTF_ASTC_8x5 || - eTF == eTF_ASTC_8x6 || - eTF == eTF_ASTC_8x8 || - eTF == eTF_ASTC_10x5 || - eTF == eTF_ASTC_10x6 || - eTF == eTF_ASTC_10x8 || - eTF == eTF_ASTC_10x10 || - eTF == eTF_ASTC_12x10 || - eTF == eTF_ASTC_12x12 - ); - } - - bool IsRangeless(ETEX_Format eTF); - - bool IsQuantized(ETEX_Format eTF); - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const char* NameForTextureFormat(ETEX_Format ETF) - { - switch (ETF) - { - case eTF_Unknown: - return "Unknown"; - - case eTF_R8G8B8A8S: - return "R8G8B8A8S"; - case eTF_R8G8B8A8: - return "R8G8B8A8"; - - case eTF_A8: - return "A8"; - case eTF_R8: - return "R8"; - case eTF_R8S: - return "R8S"; - case eTF_R16: - return "R16"; - case eTF_R16F: - return "R16F"; - case eTF_R32F: - return "R32F"; - case eTF_R8G8: - return "R8G8"; - case eTF_R8G8S: - return "R8G8S"; - case eTF_R16G16: - return "R16G16"; - case eTF_R16G16S: - return "R16G16S"; - case eTF_R16G16F: - return "R16G16F"; - case eTF_R11G11B10F: - return "R11G11B10F"; - case eTF_R10G10B10A2: - return "R10G10B10A2"; - case eTF_R16G16B16A16: - return "R16G16B16A16"; - case eTF_R16G16B16A16S: - return "R16G16B16A16S"; - case eTF_R16G16B16A16F: - return "R16G16B16A16F"; - case eTF_R32G32B32A32F: - return "R32G32B32A32F"; - - case eTF_CTX1: - return "CTX1"; - case eTF_BC1: - return "BC1"; - case eTF_BC2: - return "BC2"; - case eTF_BC3: - return "BC3"; - case eTF_BC4U: - return "BC4"; - case eTF_BC4S: - return "BC4S"; - case eTF_BC5U: - return "BC5"; - case eTF_BC5S: - return "BC5S"; - case eTF_BC6UH: - return "BC6UH"; - case eTF_BC6SH: - return "BC6SH"; - case eTF_BC7: - return "BC7"; - case eTF_R9G9B9E5: - return "R9G9B9E5"; - - case eTF_D16: - return "D16"; - case eTF_D24S8: - return "D24S8"; - case eTF_D32F: - return "D32F"; - case eTF_D32FS8: - return "D32FS8"; - - case eTF_B5G6R5: - return "R5G5B5"; - case eTF_B5G5R5: - return "R5G6B5"; - case eTF_B4G4R4A4: - return "B4G4R4A4"; - - case eTF_EAC_R11: - return "EAC_R11"; - case eTF_EAC_RG11: - return "EAC_RG11"; - case eTF_ETC2: - return "ETC2"; - case eTF_ETC2A: - return "ETC2A"; - - case eTF_PVRTC2: - return "PVRTC2"; - case eTF_PVRTC4: - return "PVRTC4"; - - case eTF_ASTC_4x4: - return "ASTC_4x4"; - case eTF_ASTC_5x4: - return "ASTC_5x4"; - case eTF_ASTC_5x5: - return "ASTC_5x5"; - case eTF_ASTC_6x5: - return "ASTC_6x5"; - case eTF_ASTC_6x6: - return "ASTC_6x6"; - case eTF_ASTC_8x5: - return "ASTC_8x5"; - case eTF_ASTC_8x6: - return "ASTC_8x6"; - case eTF_ASTC_8x8: - return "ASTC_8x8"; - case eTF_ASTC_10x5: - return "ASTC_10x5"; - case eTF_ASTC_10x6: - return "ASTC_10x6"; - case eTF_ASTC_10x8: - return "ASTC_10x8"; - case eTF_ASTC_10x10: - return "ASTC_10x10"; - case eTF_ASTC_12x10: - return "ASTC_12x10"; - case eTF_ASTC_12x12: - return "ASTC_12x12"; - - case eTF_A8L8: - return "A8L8"; - case eTF_L8: - return "L8"; - case eTF_L8V8U8: - return "L8V8U8"; - case eTF_B8G8R8: - return "B8G8R8"; - case eTF_L8V8U8X8: - return "L8V8U8X8"; - case eTF_B8G8R8X8: - return "B8G8R8X8"; - case eTF_B8G8R8A8: - return "B8G8R8A8"; - - default: - assert(0); // pass through for better behaviour in non debug - } - - return "Unknown"; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline ETEX_Format TextureFormatForName(const char* sETF) - { - if (!azstricmp(sETF, "Unknown")) - { - return eTF_Unknown; - } - - if (!azstricmp(sETF, "R8G8B8A8S")) - { - return eTF_R8G8B8A8S; - } - if (!azstricmp(sETF, "R8G8B8A8")) - { - return eTF_R8G8B8A8; - } - - if (!azstricmp(sETF, "A8")) - { - return eTF_A8; - } - if (!azstricmp(sETF, "R8")) - { - return eTF_R8; - } - if (!azstricmp(sETF, "R8S")) - { - return eTF_R8S; - } - if (!azstricmp(sETF, "R16")) - { - return eTF_R16; - } - if (!azstricmp(sETF, "R16F")) - { - return eTF_R16F; - } - if (!azstricmp(sETF, "R32F")) - { - return eTF_R32F; - } - if (!azstricmp(sETF, "R8G8")) - { - return eTF_R8G8; - } - if (!azstricmp(sETF, "R8G8S")) - { - return eTF_R8G8S; - } - if (!azstricmp(sETF, "R16G16")) - { - return eTF_R16G16; - } - if (!azstricmp(sETF, "R16G16S")) - { - return eTF_R16G16S; - } - if (!azstricmp(sETF, "R16G16F")) - { - return eTF_R16G16F; - } - if (!azstricmp(sETF, "R11G11B10F")) - { - return eTF_R11G11B10F; - } - if (!azstricmp(sETF, "R10G10B10A2")) - { - return eTF_R10G10B10A2; - } - if (!azstricmp(sETF, "R16G16B16A16")) - { - return eTF_R16G16B16A16; - } - if (!azstricmp(sETF, "R16G16B16A16S")) - { - return eTF_R16G16B16A16S; - } - if (!azstricmp(sETF, "R16G16B16A16F")) - { - return eTF_R16G16B16A16F; - } - if (!azstricmp(sETF, "R32G32B32A32F")) - { - return eTF_R32G32B32A32F; - } - - if (!azstricmp(sETF, "CTX1")) - { - return eTF_CTX1; - } - if (!azstricmp(sETF, "BC1")) - { - return eTF_BC1; - } - if (!azstricmp(sETF, "BC2")) - { - return eTF_BC2; - } - if (!azstricmp(sETF, "BC3")) - { - return eTF_BC3; - } - if (!azstricmp(sETF, "BC4")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "BC4S")) - { - return eTF_BC4S; - } - if (!azstricmp(sETF, "BC5")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "BC5S")) - { - return eTF_BC5S; - } - if (!azstricmp(sETF, "BC6UH")) - { - return eTF_BC6UH; - } - if (!azstricmp(sETF, "BC6SH")) - { - return eTF_BC6SH; - } - if (!azstricmp(sETF, "BC7")) - { - return eTF_BC7; - } - if (!azstricmp(sETF, "R9G9B9E5")) - { - return eTF_R9G9B9E5; - } - - if (!azstricmp(sETF, "D16")) - { - return eTF_D16; - } - if (!azstricmp(sETF, "D24S8")) - { - return eTF_D24S8; - } - if (!azstricmp(sETF, "D32F")) - { - return eTF_D32F; - } - if (!azstricmp(sETF, "D32FS8")) - { - return eTF_D32FS8; - } - - if (!azstricmp(sETF, "R5G5B5")) - { - return eTF_B5G6R5; - } - if (!azstricmp(sETF, "R5G6B5")) - { - return eTF_B5G5R5; - } - if (!azstricmp(sETF, "B4G4R4A4")) - { - return eTF_B4G4R4A4; - } - - if (!azstricmp(sETF, "EAC_R11")) - { - return eTF_EAC_R11; - } - if (!azstricmp(sETF, "EAC_RG11")) - { - return eTF_EAC_RG11; - } - if (!azstricmp(sETF, "ETC2")) - { - return eTF_ETC2; - } - if (!azstricmp(sETF, "ETC2A")) - { - return eTF_ETC2A; - } - - if (!azstricmp(sETF, "PVRTC2")) - { - return eTF_PVRTC2; - } - if (!azstricmp(sETF, "PVRTC4")) - { - return eTF_PVRTC4; - } - - if (!azstricmp(sETF, "ASTC_4x4")) - { - return eTF_ASTC_4x4; - } - if (!azstricmp(sETF, "ASTC_5x4")) - { - return eTF_ASTC_5x4; - } - if (!azstricmp(sETF, "ASTC_5x5")) - { - return eTF_ASTC_5x5; - } - if (!azstricmp(sETF, "ASTC_6x5")) - { - return eTF_ASTC_6x5; - } - if (!azstricmp(sETF, "ASTC_6x6")) - { - return eTF_ASTC_6x6; - } - if (!azstricmp(sETF, "ASTC_8x5")) - { - return eTF_ASTC_8x5; - } - if (!azstricmp(sETF, "ASTC_8x6")) - { - return eTF_ASTC_8x6; - } - if (!azstricmp(sETF, "ASTC_8x8")) - { - return eTF_ASTC_8x8; - } - if (!azstricmp(sETF, "ASTC_10x5")) - { - return eTF_ASTC_10x5; - } - if (!azstricmp(sETF, "ASTC_10x6")) - { - return eTF_ASTC_10x6; - } - if (!azstricmp(sETF, "ASTC_10x8")) - { - return eTF_ASTC_10x8; - } - if (!azstricmp(sETF, "ASTC_10x10")) - { - return eTF_ASTC_10x10; - } - if (!azstricmp(sETF, "ASTC_12x10")) - { - return eTF_ASTC_12x10; - } - if (!azstricmp(sETF, "ASTC_12x12")) - { - return eTF_ASTC_12x12; - } - - if (!azstricmp(sETF, "A8L8")) - { - return eTF_A8L8; - } - if (!azstricmp(sETF, "L8")) - { - return eTF_L8; - } - if (!azstricmp(sETF, "L8V8U8")) - { - return eTF_L8V8U8; - } - if (!azstricmp(sETF, "B8G8R8")) - { - return eTF_B8G8R8; - } - if (!azstricmp(sETF, "L8V8U8X8")) - { - return eTF_L8V8U8X8; - } - if (!azstricmp(sETF, "B8G8R8X8")) - { - return eTF_B8G8R8X8; - } - if (!azstricmp(sETF, "B8G8R8A8")) - { - return eTF_B8G8R8A8; - } - - if (!azstricmp(sETF, "V8U8")) - { - return eTF_R8G8S; - } - if (!azstricmp(sETF, "V16U16")) - { - return eTF_R16G16S; - } - - if (!azstricmp(sETF, "DXT1")) - { - return eTF_BC1; - } - if (!azstricmp(sETF, "DXT3")) - { - return eTF_BC2; - } - if (!azstricmp(sETF, "DXT5")) - { - return eTF_BC3; - } - if (!azstricmp(sETF, "ATI1")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "ATI2")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "3DCp")) - { - return eTF_BC4U; - } - if (!azstricmp(sETF, "3DC")) - { - return eTF_BC5U; - } - if (!azstricmp(sETF, "RGBE")) - { - return eTF_R9G9B9E5; - } - - assert (0); - return eTF_Unknown; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const char* NameForTextureType(ETEX_Type eTT) - { - const char* sETT; - switch (eTT) - { - case eTT_1D: - sETT = "1D"; - break; - case eTT_2D: - sETT = "2D"; - break; - case eTT_2DArray: - sETT = "2D array"; - break; - case eTT_2DMS: - sETT = "2D multi-sampled"; - break; - case eTT_3D: - sETT = "3D"; - break; - case eTT_Cube: - sETT = "Cube"; - break; - case eTT_CubeArray: - sETT = "CubeArray"; - break; - case eTT_Auto2D: - sETT = "Auto2D"; - break; - case eTT_Dyn2D: - sETT = "Dyn2D"; - break; - default: - assert(0); - sETT = "Unknown"; // for better behaviour in non debug - break; - } - return sETT; - } - - inline ETEX_Type TextureTypeForName(const char* sETT) - { - if (!azstricmp(sETT, "1D")) - { - return eTT_1D; - } - if (!azstricmp(sETT, "2D")) - { - return eTT_2D; - } - if (!azstricmp(sETT, "3D")) - { - return eTT_3D; - } - if (!azstricmp(sETT, "Cube")) - { - return eTT_Cube; - } - if (!azstricmp(sETT, "Auto2D")) - { - return eTT_Auto2D; - } - if (!azstricmp(sETT, "Dyn2D")) - { - return eTT_Dyn2D; - } - if (!azstricmp(sETT, "User")) - { - return eTT_User; - } - assert(0); - return eTT_2D; - } - - inline bool HasAlphaForName(const char* sETF) - { - if (!azstricmp(sETF, "R8G8B8A8S")) - { - return true; - } - if (!azstricmp(sETF, "R8G8B8A8")) - { - return true; - } - if (!azstricmp(sETF, "A8")) - { - if (!azstricmp(sETF, "A8L8")) - { - if (!azstricmp(sETF, "BC1") || !azstricmp(sETF, "DXT1")) - { - if (!azstricmp(sETF, "BC2") || !azstricmp(sETF, "DXT3")) - { - if (!azstricmp(sETF, "BC3") || !azstricmp(sETF, "DXT5")) - { - if (!azstricmp(sETF, "BC7")) - { - if (!azstricmp(sETF, "A8")) - { - return true; - } - } - } - } - } - } - } - if (!azstricmp(sETF, "R10G10B10A2")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16S")) - { - return true; - } - if (!azstricmp(sETF, "R16G16B16A16F")) - { - return true; - } - if (!azstricmp(sETF, "R32G32B32A32F")) - { - return true; - } - - if (!azstricmp(sETF, "BC2")) - { - return true; - } - if (!azstricmp(sETF, "BC3")) - { - return true; - } - if (!azstricmp(sETF, "BC7")) - { - return true; - } - - if (!azstricmp(sETF, "B4G4R4A4")) - { - return true; - } - - if (!azstricmp(sETF, "ETC2A")) - { - return true; - } - - if (!azstricmp(sETF, "A8L8")) - { - return true; - } - if (!azstricmp(sETF, "B8G8R8A8")) - { - return true; - } - - if (!azstricmp(sETF, "DXT3")) - { - return true; - } - if (!azstricmp(sETF, "DXT5")) - { - return true; - } - - return false; - } - - inline bool HasAlphaForTextureFormat(ETEX_Format ETF) - { - if (ETF == eTF_R8G8B8A8S) - { - return true; - } - if (ETF == eTF_R8G8B8A8) - { - return true; - } - - if (ETF == eTF_A8) - { - return true; - } - if (ETF == eTF_R10G10B10A2) - { - return true; - } - if (ETF == eTF_R16G16B16A16) - { - return true; - } - if (ETF == eTF_R16G16B16A16S) - { - return true; - } - if (ETF == eTF_R16G16B16A16F) - { - return true; - } - if (ETF == eTF_R32G32B32A32F) - { - return true; - } - - if (ETF == eTF_BC2) - { - return true; - } - if (ETF == eTF_BC3) - { - return true; - } - if (ETF == eTF_BC7) - { - return true; - } - - if (ETF == eTF_B4G4R4A4) - { - return true; - } - - if (ETF == eTF_ETC2A) - { - return true; - } - - if (ETF == eTF_A8L8) - { - return true; - } - if (ETF == eTF_B8G8R8A8) - { - return true; - } - - return false; - } - - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf, DWORD /*DXGI_FORMAT*/ dxgif); -}; - -namespace DDSFormats -{ - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DX10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', '1', '0'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT1 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT3 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '3'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_DXT5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D', 'X', 'T', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_CTX1 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('C', 'T', 'X', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_3DC = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_3DCP = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'T', 'I', '1'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_EAC_R11 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'A', 'R', ' '), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_EAC_RG11 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'A', 'R', 'G'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ETC2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'T', '2', ' '), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ETC2A = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('E', 'T', '2', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_PVRTC2 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('P', 'V', 'R', '2'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_PVRTC4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('P', 'V', 'R', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_4x4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '4', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_5x4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '5', '4'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_5x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '5', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_6x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '6', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_6x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '6', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '5'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x6 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '6'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_8x8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', '8', '8'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', '8'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_10x10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'A', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_12x10 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'C', 'A'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_ASTC_12x12 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', 'S', 'C', 'C'), 0, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_R32F, 32, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G32R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_G32R32F, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A32B32G32R32F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A32B32G32R32F, 128, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_R16F, 16, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G16R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_G16R16F, 32, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A16B16G16R16F = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A16B16G16R16F, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_U16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_SIGNED, 0, 16, 0x0000ffff, 0x00000000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_V16U16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_SIGNED, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_Q16W16V16U16 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_Q16W16V16U16, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000ffff, 0x00000000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_G16R16 = // unofficial - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A16B16G16R16 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_FOURCC, DDS_FOURCC_A16B16G16R16, 64, 0, 0, 0, 0 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8B8G8R8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A1R5G5B5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A4R4G4B4 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_X8R8G8B8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_R5G6B5 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_A, 0, 8, 0x00000000, 0x00000000, 0x00000000, 0x000000ff }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_L8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 8, 0x000000ff, 0x000000ff, 0x000000ff, 0x00000000 }; - - const CImageExtensionHelper::DDS_PIXELFORMAT DDSPF_A8L8 = - { sizeof(CImageExtensionHelper::DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 8, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff }; - - inline ETEX_Format GetFormatByDesc(const CImageExtensionHelper::DDS_PIXELFORMAT& ddspf) - { - if (ddspf.dwFourCC == DDSPF_DXT1.dwFourCC) - { - return eTF_BC1; - } - else if (ddspf.dwFourCC == DDSPF_DXT3.dwFourCC) - { - return eTF_BC2; - } - else if (ddspf.dwFourCC == DDSPF_DXT5.dwFourCC) - { - return eTF_BC3; - } - else if (ddspf.dwFourCC == DDSPF_3DCP.dwFourCC) - { - return eTF_BC4U; - } - else if (ddspf.dwFourCC == DDSPF_3DC.dwFourCC) - { - return eTF_BC5U; - } - else if (ddspf.dwFourCC == DDSPF_CTX1.dwFourCC) - { - return eTF_CTX1; - } - else if (ddspf.dwFourCC == DDSPF_R32F.dwFourCC) - { - return eTF_R32F; - } - // else if( ddspf.dwFourCC == DDSPF_G32R32F.dwFourCC) - // return eTF_R32G32F; // TODO: add to engine - else if (ddspf.dwFourCC == DDSPF_A32B32G32R32F.dwFourCC) - { - return eTF_R32G32B32A32F; - } - else if (ddspf.dwFourCC == DDSPF_R16F.dwFourCC) - { - return eTF_R16F; - } - else if (ddspf.dwFourCC == DDSPF_G16R16F.dwFourCC) - { - return eTF_R16G16F; - } - else if (ddspf.dwFourCC == DDSPF_A16B16G16R16F.dwFourCC) - { - return eTF_R16G16B16A16F; - } - // else if( ddspf == DDSPF_U16) - // return eTF_R16S; // TODO: add to engine - else if (ddspf == DDSPF_V16U16) - { - return eTF_R16G16S; - } - else if (ddspf.dwFourCC == DDSPF_Q16W16V16U16.dwFourCC) - { - return eTF_R16G16B16A16S; - } - else if (ddspf == DDSPF_R16) - { - return eTF_R16; - } - else if (ddspf == DDSPF_G16R16) - { - return eTF_R16G16; - } - else if (ddspf.dwFourCC == DDSPF_A16B16G16R16.dwFourCC) - { - return eTF_R16G16B16A16; - } - else if (ddspf.dwFourCC == DDSPF_EAC_R11.dwFourCC) - { - return eTF_EAC_R11; - } - else if (ddspf.dwFourCC == DDSPF_EAC_RG11.dwFourCC) - { - return eTF_EAC_RG11; - } - else if (ddspf.dwFourCC == DDSPF_ETC2.dwFourCC) - { - return eTF_ETC2; - } - else if (ddspf.dwFourCC == DDSPF_ETC2A.dwFourCC) - { - return eTF_ETC2A; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x000000ff && ddspf.dwABitMask == 0xff000000) - { - return eTF_R8G8B8A8; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x00ff0000 && ddspf.dwABitMask == 0xff000000) - { - return eTF_B8G8R8A8; - } - else if (ddspf.dwFlags == DDS_RGB && ddspf.dwRGBBitCount == 32 && ddspf.dwRBitMask == 0x00ff0000) - { - return eTF_B8G8R8X8; - } - else if (ddspf.dwFlags == DDS_RGBA && ddspf.dwRGBBitCount == 16) - { - return eTF_B4G4R4A4; - } - else if (ddspf.dwFlags == DDS_RGB && ddspf.dwRGBBitCount == 24) - { - return eTF_B8G8R8; - } - else if (ddspf.dwFlags == DDS_LUMINANCEA && ddspf.dwRGBBitCount == 8) - { - return eTF_A8L8; - } - else if (ddspf.dwFlags == DDS_LUMINANCE && ddspf.dwRGBBitCount == 8) - { - return eTF_L8; - } - else if ((ddspf.dwFlags == DDS_A || ddspf.dwFlags == DDS_A_ONLY || ddspf.dwFlags == (DDS_A | DDS_A_ONLY)) && ddspf.dwRGBBitCount == 8) - { - return eTF_A8; - } - else if (ddspf.dwFourCC == DDSPF_PVRTC2.dwFourCC) - { - return eTF_PVRTC2; - } - else if (ddspf.dwFourCC == DDSPF_PVRTC4.dwFourCC) - { - return eTF_PVRTC4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_4x4.dwFourCC) - { - return eTF_ASTC_4x4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_5x4.dwFourCC) - { - return eTF_ASTC_5x4; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_5x5.dwFourCC) - { - return eTF_ASTC_5x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_6x5.dwFourCC) - { - return eTF_ASTC_6x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_6x6.dwFourCC) - { - return eTF_ASTC_6x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x5.dwFourCC) - { - return eTF_ASTC_8x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x6.dwFourCC) - { - return eTF_ASTC_8x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_8x8.dwFourCC) - { - return eTF_ASTC_8x8; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x5.dwFourCC) - { - return eTF_ASTC_10x5; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x6.dwFourCC) - { - return eTF_ASTC_10x6; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x8.dwFourCC) - { - return eTF_ASTC_10x8; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_10x10.dwFourCC) - { - return eTF_ASTC_10x10; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_12x10.dwFourCC) - { - return eTF_ASTC_12x10; - } - else if (ddspf.dwFourCC == DDSPF_ASTC_12x12.dwFourCC) - { - return eTF_ASTC_12x12; - } - - assert(0); - return eTF_Unknown; - } - - inline ETEX_Format GetFormatByDesc(const CImageExtensionHelper::DDS_PIXELFORMAT& ddspf, const DWORD /*DXGI_FORMAT*/ dxgif) - { - // 'DX10' indicates the format is not in the FourCC, but in the extended header - if (ddspf.dwFourCC == DDSPF_DX10.dwFourCC) - { -#if defined(CRY_DDS_DX10_SUPPORT) - switch (dxgif) - { - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - return eTF_R8G8B8A8; - case DXGI_FORMAT_R8G8B8A8_SNORM: - return eTF_R8G8B8A8S; - - case DXGI_FORMAT_A8_UNORM: - return eTF_A8; - case DXGI_FORMAT_R8_UNORM: - return eTF_R8; - case DXGI_FORMAT_R8_SNORM: - return eTF_R8S; - case DXGI_FORMAT_R16_UNORM: - return eTF_R16; - // case DXGI_FORMAT_R16_SNORM: return eTF_R16S; - case DXGI_FORMAT_R16_FLOAT: - return eTF_R16F; - case DXGI_FORMAT_R16_TYPELESS: - return eTF_R16F; // arbitrary choice for F - case DXGI_FORMAT_R32_FLOAT: - return eTF_R32F; - case DXGI_FORMAT_R32_TYPELESS: - return eTF_R32F; - case DXGI_FORMAT_R8G8_UNORM: - return eTF_R8G8; - case DXGI_FORMAT_R8G8_SNORM: - return eTF_R8G8S; - case DXGI_FORMAT_R16G16_UNORM: - return eTF_R16G16; - case DXGI_FORMAT_R16G16_SNORM: - return eTF_R16G16S; - case DXGI_FORMAT_R16G16_FLOAT: - return eTF_R16G16F; - // case DXGI_FORMAT_R32G32_FLOAT: return eTF_R32G32F; - case DXGI_FORMAT_R11G11B10_FLOAT: - return eTF_R11G11B10F; - case DXGI_FORMAT_R10G10B10A2_UNORM: - return eTF_R10G10B10A2; - case DXGI_FORMAT_R16G16B16A16_UNORM: - return eTF_R16G16B16A16; - case DXGI_FORMAT_R16G16B16A16_SNORM: - return eTF_R16G16B16A16S; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return eTF_R16G16B16A16F; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return eTF_R32G32B32A32F; - - case DXGI_FORMAT_BC1_TYPELESS: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM: - return eTF_BC1; - case DXGI_FORMAT_BC1_UNORM_SRGB: - return eTF_BC1; - case DXGI_FORMAT_BC2_TYPELESS: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM: - return eTF_BC2; - case DXGI_FORMAT_BC2_UNORM_SRGB: - return eTF_BC2; - case DXGI_FORMAT_BC3_TYPELESS: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM: - return eTF_BC3; - case DXGI_FORMAT_BC3_UNORM_SRGB: - return eTF_BC3; - case DXGI_FORMAT_BC4_TYPELESS: - return eTF_BC4U; - case DXGI_FORMAT_BC4_UNORM: - return eTF_BC4U; - case DXGI_FORMAT_BC4_SNORM: - return eTF_BC4S; - case DXGI_FORMAT_BC5_TYPELESS: - return eTF_BC5U; - case DXGI_FORMAT_BC5_UNORM: - return eTF_BC5U; - case DXGI_FORMAT_BC5_SNORM: - return eTF_BC5S; - case DXGI_FORMAT_BC6H_UF16: - return eTF_BC6UH; - case DXGI_FORMAT_BC6H_SF16: - return eTF_BC6SH; - case DXGI_FORMAT_BC7_TYPELESS: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM: - return eTF_BC7; - case DXGI_FORMAT_BC7_UNORM_SRGB: - return eTF_BC7; - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - return eTF_R9G9B9E5; - - // only available as hardware format under DX11.1 with DXGI 1.2 - case DXGI_FORMAT_B5G6R5_UNORM: - return eTF_B5G6R5; - case DXGI_FORMAT_B5G5R5A1_UNORM: - return eTF_B5G5R5; - // case DXGI_FORMAT_B4G4R4A4_UNORM: return eTF_B4G4R4A4; - -#if defined(OPENGL) || defined(CRY_USE_METAL) - // only available as hardware format under OpenGL - case DXGI_FORMAT_EAC_R11_TYPELESS: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_R11_UNORM: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_R11_SNORM: - return eTF_EAC_R11; - case DXGI_FORMAT_EAC_RG11_TYPELESS: - return eTF_EAC_RG11; - case DXGI_FORMAT_EAC_RG11_UNORM: - return eTF_EAC_RG11; - case DXGI_FORMAT_EAC_RG11_SNORM: - return eTF_EAC_RG11; - case DXGI_FORMAT_ETC2_TYPELESS: - return eTF_ETC2; - case DXGI_FORMAT_ETC2_UNORM: - return eTF_ETC2; - case DXGI_FORMAT_ETC2_UNORM_SRGB: - return eTF_ETC2; - case DXGI_FORMAT_ETC2A_TYPELESS: - return eTF_ETC2A; - case DXGI_FORMAT_ETC2A_UNORM: - return eTF_ETC2A; - case DXGI_FORMAT_ETC2A_UNORM_SRGB: - return eTF_ETC2A; -#endif //defined(OPENGL) - -#ifdef CRY_USE_METAL - case DXGI_FORMAT_PVRTC2_TYPELESS: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC2_UNORM: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC2_UNORM_SRGB: - return eTF_PVRTC2; - case DXGI_FORMAT_PVRTC4_TYPELESS: - return eTF_PVRTC4; - case DXGI_FORMAT_PVRTC4_UNORM: - return eTF_PVRTC4; - case DXGI_FORMAT_PVRTC4_UNORM_SRGB: - return eTF_PVRTC4; -#endif -#if defined(ANDROID) //|| defined(CRY_USE_METAL) - case DXGI_FORMAT_ASTC_4x4_TYPELESS: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_4x4_UNORM: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_4x4_UNORM_SRGB: - return eTF_ASTC_4x4; - case DXGI_FORMAT_ASTC_5x4_TYPELESS: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x4_UNORM: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x4_UNORM_SRGB: - return eTF_ASTC_5x4; - case DXGI_FORMAT_ASTC_5x5_TYPELESS: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_5x5_UNORM: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_5x5_UNORM_SRGB: - return eTF_ASTC_5x5; - case DXGI_FORMAT_ASTC_6x5_TYPELESS: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x5_UNORM: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x5_UNORM_SRGB: - return eTF_ASTC_6x5; - case DXGI_FORMAT_ASTC_6x6_TYPELESS: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_6x6_UNORM: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_6x6_UNORM_SRGB: - return eTF_ASTC_6x6; - case DXGI_FORMAT_ASTC_8x5_TYPELESS: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x5_UNORM: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x5_UNORM_SRGB: - return eTF_ASTC_8x5; - case DXGI_FORMAT_ASTC_8x6_TYPELESS: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x6_UNORM: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x6_UNORM_SRGB: - return eTF_ASTC_8x6; - case DXGI_FORMAT_ASTC_8x8_TYPELESS: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_8x8_UNORM: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_8x8_UNORM_SRGB: - return eTF_ASTC_8x8; - case DXGI_FORMAT_ASTC_10x5_TYPELESS: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x5_UNORM: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x5_UNORM_SRGB: - return eTF_ASTC_10x5; - case DXGI_FORMAT_ASTC_10x6_TYPELESS: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x6_UNORM: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x6_UNORM_SRGB: - return eTF_ASTC_10x6; - case DXGI_FORMAT_ASTC_10x8_TYPELESS: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x8_UNORM: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x8_UNORM_SRGB: - return eTF_ASTC_10x8; - case DXGI_FORMAT_ASTC_10x10_TYPELESS: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_10x10_UNORM: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_10x10_UNORM_SRGB: - return eTF_ASTC_10x10; - case DXGI_FORMAT_ASTC_12x10_TYPELESS: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x10_UNORM: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x10_UNORM_SRGB: - return eTF_ASTC_12x10; - case DXGI_FORMAT_ASTC_12x12_TYPELESS: - return eTF_ASTC_12x12; - case DXGI_FORMAT_ASTC_12x12_UNORM: - return eTF_ASTC_12x12; - case DXGI_FORMAT_ASTC_12x12_UNORM_SRGB: - return eTF_ASTC_12x12; -#endif - // only available as hardware format under DX9 - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - return eTF_B8G8R8A8; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return eTF_B8G8R8X8; - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - return eTF_B8G8R8X8; - } -#endif - return eTF_Unknown; - } - else - { - return GetFormatByDesc(ddspf); - } - } - - inline const bool IsNormalMap(const ETEX_Format eTF) - { - if (eTF == eTF_BC5U || eTF == eTF_BC5S || eTF == eTF_CTX1 || eTF == eTF_EAC_RG11) - { - return true; - } - return false; - } - - inline const bool IsSigned(const ETEX_Format eTF) - { - if (eTF == eTF_BC4S || eTF == eTF_BC5S || eTF == eTF_BC6SH || eTF == eTF_R8S || eTF == eTF_R8G8S || eTF == eTF_R16G16S || eTF == eTF_R8G8B8A8S || eTF == eTF_R16G16B16A16S) - { - return true; - } - return false; - } - - // Added this code from Image, as it has less dependencies here. - // Warning: duplicate code. - inline const CImageExtensionHelper::DDS_PIXELFORMAT& GetDescByFormat(const ETEX_Format eTF) - { - switch (eTF) - { - case eTF_BC1: - return DDSPF_DXT1; - case eTF_BC2: - return DDSPF_DXT3; - case eTF_BC3: - return DDSPF_DXT5; - case eTF_BC4U: - return DDSPF_3DCP; - case eTF_BC5U: - return DDSPF_3DC; - case eTF_CTX1: - return DDSPF_CTX1; - case eTF_R32F: - return DDSPF_R32F; - // case eTF_R32G32F: - // return DDSPF_G32R32F; - case eTF_R32G32B32A32F: - return DDSPF_A32B32G32R32F; - case eTF_R16F: - return DDSPF_R16F; - case eTF_R16G16F: - return DDSPF_G16R16F; - case eTF_R16G16B16A16F: - return DDSPF_A16B16G16R16F; - case eTF_R16: - return DDSPF_R16; - case eTF_R16G16: - return DDSPF_G16R16; - case eTF_R16G16B16A16: - return DDSPF_A16B16G16R16; - // case eTF_R16S: - // return DDSPF_U16; - case eTF_R16G16S: - return DDSPF_V16U16; - case eTF_R16G16B16A16S: - return DDSPF_Q16W16V16U16; - case eTF_B8G8R8: - case eTF_L8V8U8: - return DDSPF_R8G8B8; - case eTF_R8G8B8A8: - return DDSPF_A8B8G8R8; - case eTF_B8G8R8X8: - case eTF_L8V8U8X8: - return DDSPF_X8R8G8B8; - case eTF_B8G8R8A8: - return DDSPF_A8R8G8B8; - case eTF_B5G6R5: - return DDSPF_R5G6B5; - case eTF_A8: - return DDSPF_A8; - case eTF_L8: - return DDSPF_L8; - case eTF_A8L8: - return DDSPF_A8L8; - case eTF_EAC_R11: - return DDSPF_EAC_R11; - case eTF_EAC_RG11: - return DDSPF_EAC_RG11; - case eTF_ETC2: - return DDSPF_ETC2; - case eTF_ETC2A: - return DDSPF_ETC2A; - case eTF_PVRTC2: - return DDSPF_PVRTC2; - case eTF_PVRTC4: - return DDSPF_PVRTC4; - - case eTF_ASTC_4x4: - return DDSPF_ASTC_4x4; - case eTF_ASTC_5x4: - return DDSPF_ASTC_5x4; - case eTF_ASTC_5x5: - return DDSPF_ASTC_5x5; - case eTF_ASTC_6x5: - return DDSPF_ASTC_6x5; - case eTF_ASTC_6x6: - return DDSPF_ASTC_6x6; - case eTF_ASTC_8x5: - return DDSPF_ASTC_8x5; - case eTF_ASTC_8x6: - return DDSPF_ASTC_8x6; - case eTF_ASTC_8x8: - return DDSPF_ASTC_8x8; - case eTF_ASTC_10x5: - return DDSPF_ASTC_10x5; - case eTF_ASTC_10x6: - return DDSPF_ASTC_10x6; - case eTF_ASTC_10x8: - return DDSPF_ASTC_10x8; - case eTF_ASTC_10x10: - return DDSPF_ASTC_10x10; - case eTF_ASTC_12x10: - return DDSPF_ASTC_12x10; - case eTF_ASTC_12x12: - return DDSPF_ASTC_12x12; - default: - assert(0); - return DDSPF_A8B8G8R8; - } - } - - inline const CImageExtensionHelper::DDS_PIXELFORMAT& GetDescByFormat(DWORD& dxgifOut, const ETEX_Format eTF) - { - dxgifOut = 0; - - switch (eTF) - { -#if defined(CRY_DDS_DX10_SUPPORT) - case eTF_R8: - dxgifOut = DXGI_FORMAT_R8_UNORM; - return DDSPF_DX10; - case eTF_R8S: - dxgifOut = DXGI_FORMAT_R8_SNORM; - return DDSPF_DX10; - case eTF_R16: - dxgifOut = DXGI_FORMAT_R16_UNORM; - return DDSPF_DX10; - case eTF_R16F: - dxgifOut = DXGI_FORMAT_R16_FLOAT; - return DDSPF_DX10; - case eTF_R8G8: - dxgifOut = DXGI_FORMAT_R8G8_UNORM; - return DDSPF_DX10; - case eTF_R8G8S: - dxgifOut = DXGI_FORMAT_R8G8_SNORM; - return DDSPF_DX10; - case eTF_R16G16: - dxgifOut = DXGI_FORMAT_R16G16_UNORM; - return DDSPF_DX10; - case eTF_R11G11B10F: - dxgifOut = DXGI_FORMAT_R11G11B10_FLOAT; - return DDSPF_DX10; - case eTF_R10G10B10A2: - dxgifOut = DXGI_FORMAT_R10G10B10A2_UNORM; - return DDSPF_DX10; - case eTF_R16G16B16A16: - dxgifOut = DXGI_FORMAT_R16G16B16A16_UNORM; - return DDSPF_DX10; - case eTF_R16G16B16A16S: - dxgifOut = DXGI_FORMAT_R16G16B16A16_SNORM; - return DDSPF_DX10; - case eTF_R32G32B32A32F: - dxgifOut = DXGI_FORMAT_R32G32B32A32_FLOAT; - return DDSPF_DX10; - case eTF_R8G8B8A8S: - dxgifOut = DXGI_FORMAT_R8G8B8A8_SNORM; - return DDSPF_DX10; - - case eTF_BC4S: - dxgifOut = DXGI_FORMAT_BC4_SNORM; - return DDSPF_DX10; - case eTF_BC5S: - dxgifOut = DXGI_FORMAT_BC5_SNORM; - return DDSPF_DX10; - case eTF_BC6SH: - dxgifOut = DXGI_FORMAT_BC6H_SF16; - return DDSPF_DX10; - case eTF_BC6UH: - dxgifOut = DXGI_FORMAT_BC6H_UF16; - return DDSPF_DX10; - case eTF_BC7: - dxgifOut = DXGI_FORMAT_BC7_UNORM; - return DDSPF_DX10; - case eTF_R9G9B9E5: - dxgifOut = DXGI_FORMAT_R9G9B9E5_SHAREDEXP; - return DDSPF_DX10; -#endif - - default: - return GetDescByFormat(eTF); - } - } -}; - -namespace CImageExtensionHelper -{ - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf) - { - ETEX_Format nFormat = DDSFormats::GetFormatByDesc(ddspf); - return NameForTextureFormat(nFormat); - } - - inline const char* NameForDesc(const DDS_PIXELFORMAT& ddspf, DWORD /*DXGI_FORMAT*/ dxgif) - { - ETEX_Format nFormat = DDSFormats::GetFormatByDesc(ddspf, dxgif); - return NameForTextureFormat(nFormat); - } -}; diff --git a/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h b/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h deleted file mode 100644 index dae6f9cb2d..0000000000 --- a/Code/CryEngine/CryCommon/ImageExtensionHelper_info.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H -#define CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H -#pragma once - -#include "CryString.h" -#include "TypeInfo_decl.h" -#include "ImageExtensionHelper.h" - -// Crytek specific image extensions -// -// usually added to the end of DDS files - - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_PIXELFORMAT) -STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwFourCC, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwRGBBitCount, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwRBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwGBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwBBitMask, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwABitMask, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_PIXELFORMAT) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER_DXT10) -STRUCT_VAR_INFO(dxgiFormat, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(resourceDimension, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(miscFlag, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(arraySize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(reserved, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER_DXT10) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER) -STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwHeaderFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwHeight, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwWidth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwPitchOrLinearSize, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwDepth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwMipMapCount, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwAlphaBitDepth, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwReserved1, TYPE_ARRAY(10, TYPE_INFO(DWORD))) -STRUCT_VAR_INFO(ddspf, TYPE_INFO(CImageExtensionHelper::DDS_PIXELFORMAT)) -STRUCT_VAR_INFO(dwSurfaceFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(dwCubemapFlags, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(bNumPersistentMips, TYPE_INFO(BYTE)) -STRUCT_VAR_INFO(bReserved2, TYPE_ARRAY(7, TYPE_INFO(BYTE))) -STRUCT_VAR_INFO(dwTextureStage, TYPE_INFO(DWORD)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER) - -STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_FILE_DESC) -STRUCT_VAR_INFO(dwMagic, TYPE_INFO(DWORD)) -STRUCT_VAR_INFO(header, TYPE_INFO(CImageExtensionHelper::DDS_HEADER)) -STRUCT_INFO_END(CImageExtensionHelper::DDS_FILE_DESC) - -#endif // CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H diff --git a/Code/CryEngine/CryCommon/InplaceFactory.h b/Code/CryEngine/CryCommon/InplaceFactory.h deleted file mode 100644 index 6dc2279df8..0000000000 --- a/Code/CryEngine/CryCommon/InplaceFactory.h +++ /dev/null @@ -1,310 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Helper to enable inplace construction and destruction of objects -#ifndef CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H -#define CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H -#pragma once - - -// Inspired by the boost inplace/typed_inplace factory, written by -// Fernando Luis Cacciola Carballal and Tobias Schwinger -// -// See -// http://www.boost.org/doc/libs/1_42_0/libs/utility/in_place_factories.html -// for a detailed description -// - -class CInplaceFactory0 -{ -public: - - explicit CInplaceFactory0() - {} - - template - void* apply(void* address) const - { - return new(address) T(); - } - - template - void* apply(void* address, std::size_t n) const - { - for (char* next = address = this->template apply(address); !!--n; ) - { - this->template apply(next = next + sizeof(T)); - } - return address; - } -}; - -template < typename Arg0 > -class CInplaceFactory1 -{ - Arg0& m_Arg0; - -public: - - explicit CInplaceFactory1(Arg0& arg) - : m_Arg0(arg) - {} - - template - void* apply(void* address) const - { - return new(address) T(m_Arg0); - } - - template - void* apply(void* address, std::size_t n) const - { - for (char* next = address = this->template apply(address); !!--n; ) - { - this->template apply(next = next + sizeof(T)); - } - return address; - } -}; - -template -< - typename Arg0, - typename Arg1 -> -class CInplaceFactory2 -{ - Arg0& m_Arg0; - Arg1& m_Arg1; - -public: - - explicit CInplaceFactory2(Arg0& arg0, Arg1& arg1) - : m_Arg0(arg0) - , m_Arg1(arg1) - {} - - template - void* apply(void* address) const - { - return new(address) T( - m_Arg0, - m_Arg1); - } - - template - void* apply(void* address, std::size_t n) const - { - for (char* next = address = this->template apply(address); !!--n; ) - { - this->template apply(next = next + sizeof(T)); - } - return address; - } -}; - -template -< - typename Arg0, - typename Arg1, - typename Arg2 -> -class CInplaceFactory3 -{ - Arg0& m_Arg0; - Arg1& m_Arg1; - Arg2& m_Arg2; - -public: - - explicit CInplaceFactory3(Arg0& arg0, Arg1& arg1, Arg2& arg2) - : m_Arg0(arg0) - , m_Arg1(arg1) - , m_Arg2(arg2) - {} - - template - void* apply(void* address) const - { - return new(address) T( - m_Arg0, - m_Arg1, - m_Arg2); - } - - template - void* apply(void* address, std::size_t n) const - { - for (char* next = address = this->template apply(address); !!--n; ) - { - this->template apply(next = next + sizeof(T)); - } - return address; - } -}; - -template -< - typename Arg0, - typename Arg1, - typename Arg2, - typename Arg3 -> -class CInplaceFactory4 -{ - Arg0& m_Arg0; - Arg1& m_Arg1; - Arg2& m_Arg2; - Arg3& m_Arg3; - -public: - - explicit CInplaceFactory4(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3) - : m_Arg0(arg0) - , m_Arg1(arg1) - , m_Arg2(arg2) - , m_Arg3(arg3) - {} - - template - void* apply(void* address) const - { - return new(address) T( - m_Arg0, - m_Arg1, - m_Arg2, - m_Arg3); - } - - template - void* apply(void* address, std::size_t n) const - { - for (char* next = address = this->template apply(address); !!--n; ) - { - this->template apply(next = next + sizeof(T)); - } - return address; - } -}; - -template -< - typename Arg0, - typename Arg1, - typename Arg2, - typename Arg3, - typename Arg4 -> -class CInplaceFactory5 -{ - Arg0& m_Arg0; - Arg1& m_Arg1; - Arg2& m_Arg2; - Arg3& m_Arg3; - Arg4& m_Arg4; - -public: - - explicit CInplaceFactory5(Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4) - : m_Arg0(arg0) - , m_Arg1(arg1) - , m_Arg2(arg2) - , m_Arg3(arg3) - , m_Arg4(arg4) - {} - - template - void* apply(void* address) const - { - return new(address) T( - m_Arg0, - m_Arg1, - m_Arg2, - m_Arg3, - m_Arg4); - } - - template - void* apply(void* address, std::size_t n) const - { - for (char* next = address = this->template apply(address); !!--n; ) - { - this->template apply(next = next + sizeof(T)); - } - return address; - } -}; - -inline CInplaceFactory0 InplaceFactory() -{ - return CInplaceFactory0(); -} - -template < typename Arg0 > -inline CInplaceFactory1 InplaceFactory(Arg0& arg0) -{ - return CInplaceFactory1(arg0); -} - -template -< - typename Arg0, - typename Arg1 - -> -inline CInplaceFactory2 InplaceFactory(Arg0& arg0, Arg1& arg1) -{ - return CInplaceFactory2(arg0, arg1); -} - -template -< - typename Arg0, - typename Arg1, - typename Arg2 -> -inline CInplaceFactory3 InplaceFactory(Arg0& arg0, Arg1& arg1, Arg2& arg2) -{ - return CInplaceFactory3 (arg0, arg1, arg2); -} - - -template -< - typename Arg0, - typename Arg1, - typename Arg2, - typename Arg3 -> -inline CInplaceFactory4 InplaceFactory( - Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3) -{ - return CInplaceFactory4(arg0, arg1, arg2, arg3); -} - - -template -< - typename Arg0, - typename Arg1, - typename Arg2, - typename Arg3, - typename Arg4 -> -inline CInplaceFactory5 InplaceFactory( - Arg0& arg0, Arg1& arg1, Arg2& arg2, Arg3& arg3, Arg4& arg4) -{ - return CInplaceFactory5(arg0, arg1, arg2, arg3, arg4); -} - -#endif // CRYINCLUDE_CRYCOMMON_INPLACEFACTORY_H diff --git a/Code/CryEngine/CryCommon/LoadScreenComponent.cpp b/Code/CryEngine/CryCommon/LoadScreenComponent.cpp deleted file mode 100644 index 3059e8a1fc..0000000000 --- a/Code/CryEngine/CryCommon/LoadScreenComponent.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* - * 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. - * - */ - -#include -#include -#include - -#include "LoadScreenComponent.h" -#include - -#if AZ_LOADSCREENCOMPONENT_ENABLED - -namespace -{ - // Due to issues with DLLs sometimes there can be different values of gEnv in different DLLs. - // So we use this preferred method of getting the global environment - SSystemGlobalEnvironment* GetGlobalEnv() - { - if (!GetISystem()) - { - return nullptr; - } - - return GetISystem()->GetGlobalEnvironment(); - } - - static const char* const s_gameFixedFpsCvarName = "game_load_screen_sequence_fixed_fps"; - static const char* const s_gameMaxFpsCvarName = "game_load_screen_max_fps"; - static const char* const s_gameMinimumLoadTimeCvarName = "game_load_screen_minimum_time"; - - static const char* const s_levelFixedFpsCvarName = "level_load_screen_sequence_fixed_fps"; - static const char* const s_levelMaxFpsCvarName = "level_load_screen_max_fps"; - static const char* const s_levelMinimumLoadTimeCvarName = "level_load_screen_minimum_time"; -} - -void LoadScreenComponent::Reflect(AZ::ReflectContext* context) -{ - AZ::SerializeContext* serializeContext = azrtti_cast(context); - - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ; - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - if (editContext) - { - editContext->Class( - "Load screen manager", "Allows management of a load screen") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Game") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) - ; - } - } -} - -void LoadScreenComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) -{ - provided.push_back(AZ_CRC("LoadScreenService", 0x901b031c)); -} - -void LoadScreenComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) -{ - incompatible.push_back(AZ_CRC("LoadScreenService", 0x901b031c)); -} - -void LoadScreenComponent::Reset() -{ - m_loadScreenState = LoadScreenState::None; - - m_fixedDeltaTimeInSeconds = -1.0f; - m_maxDeltaTimeInSeconds = -1.0f; - m_previousCallTimeForUpdateAndRender = CTimeValue(); - m_processingLoadScreen.store(false); - - // Reset CVars so they're not carried over to other levels - SSystemGlobalEnvironment* pGEnv = GetGlobalEnv(); - if (pGEnv && pGEnv->pConsole) - { - if (ICVar* var = pGEnv->pConsole->GetCVar(s_levelFixedFpsCvarName)) - { - var->Set(""); - } - if (ICVar* var = pGEnv->pConsole->GetCVar(s_levelMaxFpsCvarName)) - { - var->Set(""); - } - if (ICVar* var = pGEnv->pConsole->GetCVar(s_levelMinimumLoadTimeCvarName)) - { - var->Set(""); - } - } -} - -void LoadScreenComponent::LoadConfigSettings(const char* fixedFpsVarName, const char* maxFpsVarName, const char* minimumLoadTimeVarName) -{ - m_fixedDeltaTimeInSeconds = -1.0f; - m_maxDeltaTimeInSeconds = -1.0f; - m_minimumLoadTimeInSeconds = 0.0f; - - SSystemGlobalEnvironment* pGEnv = GetGlobalEnv(); - if (pGEnv && pGEnv->pConsole) - { - ICVar* fixedFpsVar = pGEnv->pConsole->GetCVar(fixedFpsVarName); - if (fixedFpsVar && fixedFpsVar->GetFVal() > 0.0f) - { - m_fixedDeltaTimeInSeconds = (1.0f / fixedFpsVar->GetFVal()); - } - - ICVar* maxFpsVar = pGEnv->pConsole->GetCVar(maxFpsVarName); - if (maxFpsVar && maxFpsVar->GetFVal() > 0.0f) - { - m_maxDeltaTimeInSeconds = (1.0f / maxFpsVar->GetFVal()); - } - - if (ICVar* minimumLoadTimeVar = pGEnv->pConsole->GetCVar(minimumLoadTimeVarName)) - { - // Never allow values below 0 seconds - m_minimumLoadTimeInSeconds = AZStd::max(minimumLoadTimeVar->GetFVal(), 0.0f); - } - } -} - -void LoadScreenComponent::Init() -{ - Reset(); -} - -void LoadScreenComponent::Activate() -{ - CrySystemEventBus::Handler::BusConnect(); - LoadScreenBus::Handler::BusConnect(GetEntityId()); -} - -void LoadScreenComponent::Deactivate() -{ - CrySystemEventBus::Handler::BusDisconnect(); - LoadScreenBus::Handler::BusDisconnect(GetEntityId()); -} - -void LoadScreenComponent::OnCrySystemInitialized(ISystem& system, const SSystemInitParams&) -{ - SSystemGlobalEnvironment* pGEnv = system.GetGlobalEnvironment(); - - // Can't use macros here because we have to use our pointer. - if (pGEnv && pGEnv->pConsole) - { - pGEnv->pConsole->Register("ly_EnableLoadingThread", &m_loadingThreadEnabled, 0, VF_NULL, - "EXPERIMENTAL. Enable fully threaded loading where the LoadingScreen is drawn on a thread that isn't loading data."); - } - - if (pGEnv && !pGEnv->IsEditor()) - { - // If not running from the editor, then run GameStart - GameStart(); - } -} - -void LoadScreenComponent::OnCrySystemShutdown(ISystem&) -{ -} - -void LoadScreenComponent::UpdateAndRender() -{ - SSystemGlobalEnvironment* pGEnv = GetGlobalEnv(); - - if (m_loadScreenState == LoadScreenState::Showing && pGEnv && pGEnv->pTimer) - { - AZ_Assert(GetCurrentThreadId() == pGEnv->mMainThreadId, "UpdateAndRender should only be called from the main thread"); - - // Throttling. - if (!m_previousCallTimeForUpdateAndRender.GetValue()) - { - // This is the first call to UpdateAndRender(). - m_previousCallTimeForUpdateAndRender = pGEnv->pTimer->GetAsyncTime(); - } - - const CTimeValue callTimeForUpdateAndRender = pGEnv->pTimer->GetAsyncTime(); - const float deltaTimeInSeconds = fabs((callTimeForUpdateAndRender - m_previousCallTimeForUpdateAndRender).GetSeconds()); - - // Early-out: We DON'T need to execute UpdateAndRender() at a higher frequency than 30 FPS. - const bool shouldThrottle = m_maxDeltaTimeInSeconds > 0.0f && deltaTimeInSeconds < m_maxDeltaTimeInSeconds; - - if (!shouldThrottle) - { - bool expectedValue = false; - if (m_processingLoadScreen.compare_exchange_strong(expectedValue, true)) - { - m_previousCallTimeForUpdateAndRender = callTimeForUpdateAndRender; - - const float updateDeltaTime = (m_fixedDeltaTimeInSeconds == -1.0f) ? deltaTimeInSeconds : m_fixedDeltaTimeInSeconds; - - EBUS_EVENT(LoadScreenUpdateNotificationBus, UpdateAndRender, updateDeltaTime); - - // Some platforms (iOS, OSX) require system events to be pumped in order to update the screen - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty); - - m_processingLoadScreen.store(false); - } - } - } -} - -void LoadScreenComponent::GameStart() -{ - if (m_loadScreenState == LoadScreenState::None) - { - LoadConfigSettings(s_gameFixedFpsCvarName, s_gameMaxFpsCvarName, s_gameMinimumLoadTimeCvarName); - - const bool usingLoadingThread = IsLoadingThreadEnabled(); - - AZ::EBusLogicalResult> anyHandled(false); - EBUS_EVENT_RESULT(anyHandled, LoadScreenNotificationBus, NotifyGameLoadStart, usingLoadingThread); - - if (anyHandled.value) - { - if (usingLoadingThread) - { - m_loadScreenState = LoadScreenState::ShowingMultiThreaded; - - GetGlobalEnv()->pRenderer->StartLoadtimePlayback(this); - } - else - { - m_loadScreenState = LoadScreenState::Showing; - - // Kick-start the first frame. - UpdateAndRender(); - } - - if (ITimer* timer = GetGlobalEnv()->pTimer) - { - m_lastStartTime = timer->GetAsyncTime(); - } - } - } -} - -void LoadScreenComponent::LevelStart() -{ - if (m_loadScreenState == LoadScreenState::None) - { - LoadConfigSettings(s_levelFixedFpsCvarName, s_levelMaxFpsCvarName, s_levelMinimumLoadTimeCvarName); - - const bool usingLoadingThread = IsLoadingThreadEnabled(); - - AZ::EBusLogicalResult> anyHandled(false); - EBUS_EVENT_RESULT(anyHandled, LoadScreenNotificationBus, NotifyLevelLoadStart, usingLoadingThread); - - if (anyHandled.value) - { - if (usingLoadingThread) - { - m_loadScreenState = LoadScreenState::ShowingMultiThreaded; - - GetGlobalEnv()->pRenderer->StartLoadtimePlayback(this); - } - else - { - m_loadScreenState = LoadScreenState::Showing; - - // Kick-start the first frame. - UpdateAndRender(); - } - - if (ITimer* timer = GetGlobalEnv()->pTimer) - { - m_lastStartTime = timer->GetAsyncTime(); - } - } - } -} - -void LoadScreenComponent::Pause() -{ - if (m_loadScreenState == LoadScreenState::Showing) - { - m_loadScreenState = LoadScreenState::Paused; - } - else if (m_loadScreenState == LoadScreenState::ShowingMultiThreaded) - { - m_loadScreenState = LoadScreenState::PausedMultithreaded; - } -} - -void LoadScreenComponent::Resume() -{ - if (m_loadScreenState == LoadScreenState::Paused) - { - m_loadScreenState = LoadScreenState::Showing; - } - else if (m_loadScreenState == LoadScreenState::PausedMultithreaded) - { - m_loadScreenState = LoadScreenState::ShowingMultiThreaded; - } -} - -void LoadScreenComponent::Stop() -{ - // If we were actually in a load screen, check if we need to wait longer. - if (m_loadScreenState != LoadScreenState::None && m_minimumLoadTimeInSeconds > 0.0f) - { - if (ITimer* timer = GetGlobalEnv()->pTimer) - { - CTimeValue currentTime = timer->GetAsyncTime(); - float timeSinceStart = currentTime.GetDifferenceInSeconds(m_lastStartTime); - - while (timeSinceStart < m_minimumLoadTimeInSeconds) - { - // Simple loop that makes sure the loading screens update but also doesn't consume the whole core. - - if (m_loadScreenState == LoadScreenState::Showing) - { - EBUS_EVENT(LoadScreenBus, UpdateAndRender); - } - - CrySleep(0); - - currentTime = timer->GetAsyncTime(); - timeSinceStart = currentTime.GetDifferenceInSeconds(m_lastStartTime); - } - } - } - - if (m_loadScreenState == LoadScreenState::ShowingMultiThreaded) - { - // This will block until the other thread completes. - GetGlobalEnv()->pRenderer->StopLoadtimePlayback(); - } - - if (m_loadScreenState != LoadScreenState::None) - { - EBUS_EVENT(LoadScreenNotificationBus, NotifyLoadEnd); - } - - Reset(); - - m_loadScreenState = LoadScreenState::None; -} - -bool LoadScreenComponent::IsPlaying() -{ - return m_loadScreenState != LoadScreenState::None; -} - -void LoadScreenComponent::LoadtimeUpdate(float deltaTime) -{ - if (m_loadScreenState == LoadScreenState::ShowingMultiThreaded) - { - EBUS_EVENT(LoadScreenUpdateNotificationBus, LoadThreadUpdate, deltaTime); - } -} - -void LoadScreenComponent::LoadtimeRender() -{ - if (m_loadScreenState == LoadScreenState::ShowingMultiThreaded) - { - EBUS_EVENT(LoadScreenUpdateNotificationBus, LoadThreadRender); - } -} - -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED diff --git a/Code/CryEngine/CryCommon/LoadScreenComponent.h b/Code/CryEngine/CryCommon/LoadScreenComponent.h deleted file mode 100644 index 71ed6287f1..0000000000 --- a/Code/CryEngine/CryCommon/LoadScreenComponent.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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. - * - */ -#pragma once - -#include -#include -#include - -#include -#include -#include - -#if AZ_LOADSCREENCOMPONENT_ENABLED - -/* -* This component is responsible for managing the load screen. -*/ -class LoadScreenComponent - : public AZ::Component - , public CrySystemEventBus::Handler - , public LoadScreenBus::Handler - , public ILoadtimeCallback -{ -public: - AZ_COMPONENT(LoadScreenComponent, "{97CDBD6C-C621-4427-87C8-10E1B8F947FF}"); - - LoadScreenComponent() = default; - ~LoadScreenComponent() = default; - - ////////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - void Init() override; - void Activate() override; - void Deactivate() override; - ////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // CrySystemEvents - void OnCrySystemInitialized(ISystem&, const SSystemInitParams& params) override; - void OnCrySystemShutdown(ISystem&) override; - //////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // LoadScreenBus interface implementation - void UpdateAndRender() override; - void GameStart() override; - void LevelStart() override; - void Pause() override; - void Resume() override; - void Stop() override; - bool IsPlaying() override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ILoadtimeCallback interface implementation - void LoadtimeUpdate(float deltaTime) override; - void LoadtimeRender() override; - ////////////////////////////////////////////////////////////////////////// - - inline bool IsLoadingThreadEnabled() const - { - return m_loadingThreadEnabled != 0; - } - -protected: - static void Reflect(AZ::ReflectContext* context); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - -private: - void Reset(); - void LoadConfigSettings(const char* fixedFpsVarName, const char* maxFpsVarName, const char* minimumLoadTimeVarName); - - ////////////////////////////////////////////////////////////////////////// - enum class LoadScreenState - { - None, - Showing, - ShowingMultiThreaded, - Paused, - PausedMultithreaded, - }; - LoadScreenState m_loadScreenState{ LoadScreenState::None }; - - float m_fixedDeltaTimeInSeconds{ -1.0f }; - float m_maxDeltaTimeInSeconds{ -1.0f }; - float m_minimumLoadTimeInSeconds{ 0.0f }; - - CTimeValue m_lastStartTime; - CTimeValue m_previousCallTimeForUpdateAndRender; - AZStd::atomic_bool m_processingLoadScreen{ false }; - - int32_t m_loadingThreadEnabled{ 0 }; - ////////////////////////////////////////////////////////////////////////// -}; - -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED diff --git a/Code/CryEngine/CryCommon/LyShine/IDraw2d.h b/Code/CryEngine/CryCommon/LyShine/IDraw2d.h index 16fdfceca3..76a71c9e24 100644 --- a/Code/CryEngine/CryCommon/LyShine/IDraw2d.h +++ b/Code/CryEngine/CryCommon/LyShine/IDraw2d.h @@ -11,7 +11,6 @@ */ #pragma once -#include #include #include #include @@ -84,7 +83,7 @@ public: // types //! If this is not passed then the defaults below are used struct TextOptions { - IFFont* font; //!< default is "default" + AZStd::string fontName; //!< default is "default" unsigned int effectIndex; //!< default is 0 AZ::Vector3 color; //!< default is (1,1,1) HAlign horizontalAlignment; //!< default is HAlign::Left diff --git a/Code/CryEngine/CryCommon/LyShine/ISprite.h b/Code/CryEngine/CryCommon/LyShine/ISprite.h index d2e9a6e039..b9adda6901 100644 --- a/Code/CryEngine/CryCommon/LyShine/ISprite.h +++ b/Code/CryEngine/CryCommon/LyShine/ISprite.h @@ -16,9 +16,6 @@ #include #include -// forward declarations -class ITexture; - //////////////////////////////////////////////////////////////////////////////////////////////////// //! A sprite is a texture with extra information about how it behaves for 2D drawing //! Currently a sprite exists on disk as a side car file next to the texture file. @@ -80,9 +77,6 @@ public: // member functions //! Set the borders of a given cell within the sprite-sheet. virtual void SetCellBorders(int cellIndex, Borders borders) = 0; - //! Get the texture for this sprite - virtual ITexture* GetTexture() = 0; - //! Serialize this object for save/load virtual void Serialize(TSerialize ser) = 0; diff --git a/Code/CryEngine/CryCommon/MaterialUtils.h b/Code/CryEngine/CryCommon/MaterialUtils.h deleted file mode 100644 index 60752de8c5..0000000000 --- a/Code/CryEngine/CryCommon/MaterialUtils.h +++ /dev/null @@ -1,134 +0,0 @@ -/* -* 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. -* -*/ -#pragma once -#ifndef CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H -#define CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H - -#include -#include // for max path len -#include -#include -#include - -#include - -namespace MaterialUtils -{ - //! UnifyMaterialName - given a non-unified material name, remove the extension, unify the slashes - //! and fix up any legacy naming issues so that the material name can be used in a hash map - //! and will work each lookup. - inline void UnifyMaterialName(char* inputOutputBuffer) - { - if (!inputOutputBuffer) - { - return; - } - - // convert slashes and remove extensions: - size_t inputLength = strlen(inputOutputBuffer); - if (inputLength == 0) - { - return; - } - // this must be done first, so that the extension cutting function below does not mistakenly destroy this when it finds the . - if ((azstrnicmp(inputOutputBuffer, "./", 2) == 0) || (azstrnicmp(inputOutputBuffer, ".\\", 2) == 0)) - { - memmove(inputOutputBuffer, inputOutputBuffer + 2, inputLength - 2); - inputOutputBuffer[inputLength - 2] = 0; - inputLength -= 2; - } - - for (size_t pos = 0; pos < inputLength; ++pos) - { - if (inputOutputBuffer[pos] == '\\') - { - inputOutputBuffer[pos] = '/'; // unify slashes - } - else - { - inputOutputBuffer[pos] = tolower(inputOutputBuffer[pos]); - } - } - AZStd::string tempString(inputOutputBuffer); - AzFramework::StringFunc::Path::StripExtension(tempString); - - AZ_Assert(tempString.length() <= inputLength, "Extension stripped string has to be smaller than/same size as original string!"); - // real size of inputOutputBuffer is inputLength + 1 with Null character - azstrcpy(inputOutputBuffer, inputLength + 1, tempString.c_str()); -#if defined(SUPPORT_LEGACY_MATERIAL_NAMES) - - // LEGACY support Some files may start with ./ in front of them. This is not required anymore. - static const char* removals[2] = { - "engine/", - nullptr // reserved for game name - }; - static size_t removalSize = sizeof(removals) / sizeof(removals[0]); - - // LEGACY support. Some files may start with gamename in front of them. This is not required anymore. - static char cachedGameName[AZ_MAX_PATH_LEN] = { 0 }; - if (!removals[removalSize - 1]) - { - auto projectName = AZ::Utils::GetProjectName(); - if (!projectName.empty()) - { - azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, projectName.c_str()); - azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/"); - } - - if (cachedGameName[0] == 0) - { - // at least substitute something so that unit tests can make this assumption: - azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, "AutomatedTesting/"); - } - - removals[removalSize - 1] = cachedGameName; - } - - for (size_t pos = 0; pos < removalSize; ++pos) - { - if (removals[pos]) - { - size_t removalLength = strlen(removals[pos]); - if (removalLength >= inputLength) - { - continue; - } - - if (azstrnicmp(inputOutputBuffer, removals[pos], removalLength) == 0) - { - memmove(inputOutputBuffer, inputOutputBuffer + removalLength, inputLength - removalLength); - inputOutputBuffer[inputLength - removalLength] = 0; - inputLength -= removalLength; - } - } - } - - // legacy: Files were saved into a mtl with many leading forward or back slashes, we eat them all here. We want it to start with a rel path. - const char* actualFileName = inputOutputBuffer; - size_t finalLength = inputLength; - while ((actualFileName[0]) && ((actualFileName[0] == '\\') || (actualFileName[0] == '/'))) - { - ++actualFileName; - --finalLength; - } - if (finalLength != inputLength) - { - memmove(inputOutputBuffer, actualFileName, finalLength); - inputOutputBuffer[finalLength] = 0; - inputLength = finalLength; - } - -#endif - } -} - -#endif // CRYINCLUDE_CRYCOMMON_MATERIALUTILS_H diff --git a/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h b/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h index 31509ca6ba..3d4327116e 100644 --- a/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h +++ b/Code/CryEngine/CryCommon/Mocks/IConsoleMock.h @@ -13,7 +13,6 @@ #define CRYINCLUDE_CRYCOMMON_ICONSOLEMOCK_H #pragma once -#include #include #include diff --git a/Code/CryEngine/CryCommon/Mocks/IMemoryManagerMock.h b/Code/CryEngine/CryCommon/Mocks/IMemoryManagerMock.h deleted file mode 100644 index 3f458d7f52..0000000000 --- a/Code/CryEngine/CryCommon/Mocks/IMemoryManagerMock.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* 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. -* -*/ -#pragma once -#include - -class MemoryManagerMock - : public IMemoryManager -{ -public: - MOCK_METHOD1(GetProcessMemInfo, - bool(SProcessMemInfo& minfo)); - MOCK_METHOD3(TraceDefineHeap, - HeapHandle(const char* heapName, size_t size, const void* pBase)); - MOCK_METHOD6(TraceHeapAlloc, - void(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint)); - MOCK_METHOD3(TraceHeapFree, - void(HeapHandle heap, void* mem, size_t blockSize)); - MOCK_METHOD1(TraceHeapSetColor, - void(uint32 color)); - MOCK_METHOD0(TraceHeapGetColor, - uint32()); - MOCK_METHOD1(TraceHeapSetLabel, - void(const char* sLabel)); - MOCK_METHOD1(CreateCustomMemoryHeapInstance, - ICustomMemoryHeap* const (EAllocPolicy const eAllocPolicy)); - MOCK_METHOD3(CreateGeneralExpandingMemoryHeap, - IGeneralMemoryHeap* (size_t upperLimit, size_t reserveSize, const char* sUsage)); - MOCK_METHOD3(CreateGeneralMemoryHeap, - IGeneralMemoryHeap* (void* base, size_t sz, const char* sUsage)); - MOCK_METHOD2(ReserveAddressRange, - IMemoryAddressRange* (size_t capacity, const char* sName)); - MOCK_METHOD2(CreatePageMappingHeap, - IPageMappingHeap* (size_t addressSpace, const char* sName)); - MOCK_METHOD0(CreateDefragAllocator, - IDefragAllocator*()); -}; diff --git a/Code/CryEngine/CryCommon/Mocks/INetworkMock.h b/Code/CryEngine/CryCommon/Mocks/INetworkMock.h deleted file mode 100644 index b627f927bc..0000000000 --- a/Code/CryEngine/CryCommon/Mocks/INetworkMock.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -struct NetworkMock : public INetwork -{ - NetworkMock() : m_gridMate(nullptr) - { - } - GridMate::IGridMate* m_gridMate; - - void Release() override {} - void GetMemoryStatistics([[maybe_unused]] ICrySizer* pSizer) override {} - void GetBandwidthStatistics([[maybe_unused]] SBandwidthStats* const pStats) override {} - void GetPerformanceStatistics([[maybe_unused]] SNetworkPerformance* pSizer) override {} - void GetProfilingStatistics([[maybe_unused]] SNetworkProfilingStats* const pStats) override {} - void SyncWithGame([[maybe_unused]] ENetworkGameSync syncType) override {} - const char* GetHostName() override { return "testhostname"; } - GridMate::IGridMate* GetGridMate() override - { - return m_gridMate; - } - ChannelId GetChannelIdForSessionMember([[maybe_unused]] GridMate::GridMember* member) const override { return ChannelId(); } - ChannelId GetServerChannelId() const override { return ChannelId(); } - ChannelId GetLocalChannelId() const override { return ChannelId(); } - CTimeValue GetSessionTime() override { return CTimeValue(); } - void ChangedAspects([[maybe_unused]] EntityId id, [[maybe_unused]] NetworkAspectType aspectBits) override {} - void SetDelegatableAspectMask([[maybe_unused]] NetworkAspectType aspectBits) override {} - void SetObjectDelegatedAspectMask([[maybe_unused]] EntityId entityId, [[maybe_unused]] NetworkAspectType aspects, [[maybe_unused]] bool set) override {} - void DelegateAuthorityToClient([[maybe_unused]] EntityId entityId, [[maybe_unused]] ChannelId clientChannelId) override {} - void InvokeActorRMI([[maybe_unused]] EntityId entityId, [[maybe_unused]] uint8 actorExtensionId, [[maybe_unused]] ChannelId targetChannelFilter, [[maybe_unused]] IActorRMIRep& rep) override {} - void InvokeScriptRMI([[maybe_unused]] ISerializable* serializable, [[maybe_unused]] bool isServerRMI, [[maybe_unused]] ChannelId toChannelId = kInvalidChannelId, [[maybe_unused]] ChannelId avoidChannelId = kInvalidChannelId) override {} - void RegisterActorRMI([[maybe_unused]] IActorRMIRep* rep) override {} - void UnregisterActorRMI([[maybe_unused]] IActorRMIRep* rep) override {} - EntityId LocalEntityIdToServerEntityId([[maybe_unused]] EntityId localId) const override { return EntityId(); } - EntityId ServerEntityIdToLocalEntityId([[maybe_unused]] EntityId serverId, [[maybe_unused]] bool allowForcedEstablishment = false) const override { return EntityId(); } -}; diff --git a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h index 757c586261..2594b1cd35 100644 --- a/Code/CryEngine/CryCommon/Mocks/IRendererMock.h +++ b/Code/CryEngine/CryCommon/Mocks/IRendererMock.h @@ -12,8 +12,6 @@ #pragma once #include -#include -#include #include struct SRendItemSorter {}; @@ -286,8 +284,6 @@ public: CRenderObject * (SShaderItem & si, CRenderObject * obj, const SRenderingPassInfo& passInfo, int numPts, int ninds, SVF_P3F_C4B_T2F * &verts, SPipTangents * &tangs, uint16 * &inds, int nAW, const SRendItemSorter& rendItemSorter)); MOCK_METHOD0(ForceUpdateGlobalShaderParameters, void()); - MOCK_METHOD1(EF_SetShaderMissCallback, - void(ShaderCacheMissCallback callback)); MOCK_METHOD0(EF_GetShaderMissLogPath, const char*()); MOCK_METHOD1(EF_GetShaderNames, @@ -296,8 +292,6 @@ public: bool(const char* szFileName)); MOCK_METHOD1(EF_ReloadFile_Request, bool(const char* szFileName)); - MOCK_METHOD2(EF_LoadImage, - _smart_ptr(const char* szFileName, uint32 nFlags)); MOCK_METHOD3(EF_GetRemapedShaderMaskGen, uint64(const char*, uint64, bool)); MOCK_METHOD3(EF_GetShaderGlobalMaskGenFromString, @@ -332,10 +326,6 @@ public: ITexture * (const char* nameTex)); MOCK_METHOD1(EF_LoadLightmap, int(const char* name)); - MOCK_METHOD3(EF_RenderEnvironmentCubeHDR, - bool(int size, Vec3 & Pos, TArray&vecData)); - MOCK_METHOD1(EF_CreateRE, - IRenderElement * (EDataType edt)); MOCK_METHOD1(EF_StartEf, void(const SRenderingPassInfo& passInfo)); MOCK_METHOD3(EF_GetObjData, @@ -364,8 +354,6 @@ public: uint32(eDeferredLightType)); MOCK_METHOD0(EF_ClearDeferredLightsList, void()); - MOCK_METHOD2(EF_GetDeferredLights, - TArray*(const SRenderingPassInfo&, const eDeferredLightType)); MOCK_METHOD1(EF_AddDeferredClipVolume, uint8(const IClipVolume * pClipVolume)); MOCK_METHOD2(EF_SetDeferredClipVolumeBlendData, @@ -541,8 +529,6 @@ public: void(unsigned int TextureId)); MOCK_METHOD1(DeleteFont, void(IFFont * font)); - MOCK_METHOD2(BakeMesh, - bool(const SMeshBakingInputParams * pInputParams, SMeshBakingOutput * pReturnValues)); MOCK_METHOD3(CaptureFrameBufferFast, bool(unsigned char* pDstRGBA8, int destinationWidth, int destinationHeight)); MOCK_METHOD3(CopyFrameBufferFast, @@ -589,8 +575,6 @@ public: SDepthTexture * (int, int, bool)); MOCK_METHOD1(DestroyDepthSurface, void(SDepthTexture * pDepthSurf)); - MOCK_CONST_METHOD1(CreateOptics, - IOpticsElementBase * (EFlareType type)); MOCK_METHOD1(PauseTimer, void(bool bPause)); MOCK_METHOD0(CreateShaderPublicParams, @@ -867,13 +851,6 @@ public: MOCK_METHOD1(AddProfilerLabel, void(const char*)); - MOCK_METHOD1(InitializeVideoRenderer, - void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer)); - MOCK_METHOD1(CleanupVideoRenderer, - void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer)); - MOCK_METHOD2(DrawVideoRenderer, - void(AZ::VideoRenderer::IVideoRenderer* pVideoRenderer, const AZ::VideoRenderer::DrawArguments& drawArguments)); - MOCK_METHOD5(EF_QueryImpl, void(ERenderQueryTypes eQuery, void* pInOut0, uint32 nInOutSize0, void* pInOut1, uint32 nInOutSize1)); }; diff --git a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h index 4d2e80a2f3..8c9c98b3ee 100644 --- a/Code/CryEngine/CryCommon/Mocks/ISystemMock.h +++ b/Code/CryEngine/CryCommon/Mocks/ISystemMock.h @@ -23,8 +23,6 @@ class SystemMock public: MOCK_METHOD0(Release, void()); - MOCK_CONST_METHOD0(GetCVarsWhiteListConfigSink, - ILoadConfigurationEntrySink * ()); MOCK_METHOD0(GetGlobalEnvironment, SSystemGlobalEnvironment * ()); MOCK_METHOD2(UpdatePreTickBus, @@ -37,38 +35,22 @@ public: void()); MOCK_METHOD0(NeedDoWorkDuringOcclusionChecks, bool()); - MOCK_METHOD2(SynchronousLoadingTick, - void(const char* pFunc, int line)); MOCK_METHOD0(RenderStatistics, void()); - MOCK_METHOD0(GetUsedMemory, - uint32()); MOCK_METHOD0(GetUserName, const char*()); - MOCK_METHOD0(GetCPUFlags, - int()); - MOCK_METHOD0(GetLogicalCPUCount, - int()); - MOCK_CONST_METHOD0(GetRenderingDriverName, - const char*()); - MOCK_METHOD1(DumpMemoryUsageStatistics, - void(bool)); MOCK_METHOD0(Quit, void()); MOCK_METHOD1(Relaunch, void(bool bRelaunch)); MOCK_CONST_METHOD0(IsQuitting, bool()); - MOCK_CONST_METHOD0(IsShaderCacheGenMode, - bool()); MOCK_METHOD1(SerializingFile, void(int mode)); MOCK_CONST_METHOD0(IsSerializingFile, int()); MOCK_CONST_METHOD0(IsRelaunch, bool()); - MOCK_METHOD4(DisplayErrorMessage, - void(const char*, float, const float*, bool)); void FatalError([[maybe_unused]] const char* sFormat, ...) override {} void ReportBug([[maybe_unused]] const char* sFormat, ...) override {} @@ -82,28 +64,12 @@ public: int(const char* text, const char* caption, unsigned int uType)); MOCK_METHOD1(CheckLogVerbosity, bool(int verbosity)); - MOCK_METHOD0(GetIZLibCompressor, - IZLibCompressor * ()); - MOCK_METHOD0(GetIZLibDecompressor, - IZLibDecompressor * ()); - MOCK_METHOD0(GetLZ4Decompressor, - ILZ4Decompressor * ()); - MOCK_METHOD0(GetZStdDecompressor, - IZStdDecompressor * ()); - MOCK_METHOD0(GetPerfHUD, - ICryPerfHUD * ()); - MOCK_METHOD0(GetINotificationNetwork, - INotificationNetwork * ()); MOCK_METHOD0(GetIViewSystem, IViewSystem * ()); MOCK_METHOD0(GetILevelSystem, ILevelSystem * ()); MOCK_METHOD0(GetINameTable, INameTable * ()); - MOCK_METHOD0(GetIValidator, - IValidator * ()); - MOCK_METHOD0(GetStreamEngine, - IStreamEngine * ()); MOCK_METHOD0(GetICmdLine, ICmdLine * ()); MOCK_METHOD0(GetILog, @@ -112,8 +78,6 @@ public: AZ::IO::IArchive * ()); MOCK_METHOD0(GetICryFont, ICryFont * ()); - MOCK_METHOD0(GetIMemoryManager, - IMemoryManager * ()); MOCK_METHOD0(GetIMovieSystem, IMovieSystem * ()); MOCK_METHOD0(GetIAudioSystem, @@ -122,44 +86,12 @@ public: ::IConsole * ()); MOCK_METHOD0(GetIRemoteConsole, IRemoteConsole * ()); - MOCK_METHOD0(GetIResourceManager, - IResourceManager * ()); - MOCK_METHOD0(GetIThreadTaskManager, - IThreadTaskManager * ()); MOCK_METHOD0(GetIProfilingSystem, IProfilingSystem * ()); MOCK_METHOD0(GetISystemEventDispatcher, ISystemEventDispatcher * ()); - MOCK_METHOD0(GetIVisualLog, - IVisualLog * ()); - MOCK_METHOD0(GetIFileChangeMonitor, - IFileChangeMonitor * ()); - MOCK_METHOD0(GetHWND, - WIN_HWND()); - MOCK_METHOD0(GetIRenderer, - IRenderer * ()); MOCK_METHOD0(GetITimer, ITimer * ()); - MOCK_METHOD0(GetIThreadManager, - IThreadManager * ()); - MOCK_METHOD1(SetLoadingProgressListener, - void(ILoadingProgressListener * pListener)); - MOCK_CONST_METHOD0(GetLoadingProgressListener, - ISystem::ILoadingProgressListener * ()); - MOCK_METHOD1(SetIMaterialEffects, - void(IMaterialEffects * pMaterialEffects)); - MOCK_METHOD1(SetIOpticsManager, - void(IOpticsManager * pOpticsManager)); - MOCK_METHOD1(SetIFileChangeMonitor, - void(IFileChangeMonitor * pFileChangeMonitor)); - MOCK_METHOD1(SetIVisualLog, - void(IVisualLog * pVisualLog)); - MOCK_METHOD2(DebugStats, - void(bool checkpoint, bool leaks)); - MOCK_METHOD0(DumpWinHeaps, - void()); - MOCK_METHOD1(DumpMMStats, - int(bool log)); MOCK_METHOD1(SetForceNonDevMode, void(bool bValue)); MOCK_CONST_METHOD0(GetForceNonDevMode, @@ -168,10 +100,6 @@ public: bool()); MOCK_CONST_METHOD0(IsDevMode, bool()); - MOCK_CONST_METHOD1(IsMODValid, - bool(const char* szMODName)); - MOCK_CONST_METHOD0(IsMinimalMode, - bool()); MOCK_METHOD3(CreateXmlNode, XmlNodeRef(const char*, bool, bool)); MOCK_METHOD4(LoadXmlFromBuffer, @@ -180,8 +108,6 @@ public: XmlNodeRef(const char*, bool)); MOCK_METHOD0(GetXmlUtils, IXmlUtils * ()); - MOCK_CONST_METHOD0(GetArchiveHost, - Serialization::IArchiveHost * ()); MOCK_METHOD1(SetViewCamera, void(CCamera & Camera)); MOCK_METHOD0(GetViewCamera, @@ -203,11 +129,6 @@ public: MOCK_METHOD0(GetBuildVersion, const SFileVersion&()); - MOCK_METHOD5(CompressDataBlock, - bool(const void*, size_t, void*, size_t &, int)); - - MOCK_METHOD4(DecompressDataBlock, - bool(const void* input, size_t inputSize, void* output, size_t & outputSize)); MOCK_METHOD1(AddCVarGroupDirectory, void(const string&)); MOCK_METHOD0(SaveConfiguration, @@ -215,34 +136,20 @@ public: MOCK_METHOD3(LoadConfiguration, void(const char*, ILoadConfigurationEntrySink*, bool)); - MOCK_METHOD1(GetConfigSpec, - ESystemConfigSpec(bool)); MOCK_CONST_METHOD0(GetMaxConfigSpec, ESystemConfigSpec()); - MOCK_METHOD3(SetConfigSpec, - void(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient)); MOCK_CONST_METHOD0(GetConfigPlatform, ESystemConfigPlatform()); MOCK_METHOD1(SetConfigPlatform, void(ESystemConfigPlatform platform)); - MOCK_METHOD1(AutoDetectSpec, - void(bool detectResolution)); - MOCK_METHOD2(SetThreadState, - int(ESubsystem subsys, bool bActive)); - MOCK_METHOD0(CreateSizer, - ICrySizer * ()); MOCK_CONST_METHOD0(IsPaused, bool()); MOCK_METHOD0(GetLocalizationManager, ILocalizationManager * ()); - MOCK_METHOD0(GetITextModeConsole, - ITextModeConsole * ()); MOCK_METHOD0(GetNoiseGen, CPNoise3 * ()); MOCK_METHOD0(GetUpdateCounter, uint64()); - MOCK_CONST_METHOD0(GetCryFactoryRegistry, - ICryFactoryRegistry * ()); MOCK_METHOD1(RegisterErrorObserver, bool(IErrorObserver * errorObserver)); MOCK_METHOD1(UnregisterErrorObserver, @@ -261,10 +168,6 @@ public: int()); MOCK_METHOD1(GetApplicationLogInstance, int(const char* logFilePath)); - MOCK_METHOD0(GetCurrentUpdateTimeStats, - sUpdateTimes & ()); - MOCK_METHOD2(GetUpdateTimeStats, - const sUpdateTimes * (uint32 &, uint32 &)); MOCK_METHOD0(ClearErrorMessages, void()); MOCK_METHOD2(debug_GetCallStack, @@ -275,42 +178,16 @@ public: void(bool)); MOCK_METHOD1(GetUpdateStats, void(SSystemUpdateStats & stats)); - MOCK_METHOD0(DumpMemoryCoverage, - void()); MOCK_METHOD0(GetSystemGlobalState, ESystemGlobalState(void)); MOCK_METHOD1(SetSystemGlobalState, void(ESystemGlobalState systemGlobalState)); - MOCK_METHOD5(AsyncMemcpy, - void(void* dst, const void* src, size_t size, int nFlags, volatile int* sync)); - -#if defined(CVARS_WHITELIST) - MOCK_CONST_METHOD0(GetCVarsWhiteList, - ICVarsWhitelist * ()); -#endif - -#ifndef _RELEASE - MOCK_METHOD1(GetCheckpointData, - void(ICheckpointData & data)); - MOCK_METHOD0(IncreaseCheckpointLoadCount, - void()); - MOCK_METHOD1(SetLoadOrigin, - void(LevelLoadOrigin origin)); -#endif #if !defined(_RELEASE) MOCK_CONST_METHOD0(IsSavingResourceList, bool()); #endif - MOCK_METHOD0(SteamInit, - bool()); - MOCK_CONST_METHOD0(GetImageHandler, - const IImageHandler * ()); - MOCK_METHOD3(InitializeEngineModule, - bool(const char* dllName, const char* moduleClassName, const SSystemInitParams&initParams)); - MOCK_METHOD2(UnloadEngineModule, - bool(const char* dllName, const char* moduleClassName)); MOCK_METHOD0(GetRootWindowMessageHandler, void*()); MOCK_METHOD1(RegisterWindowMessageHandler, diff --git a/Code/CryEngine/CryCommon/Mocks/MockCGFContent.h b/Code/CryEngine/CryCommon/Mocks/MockCGFContent.h deleted file mode 100644 index 8047a863f6..0000000000 --- a/Code/CryEngine/CryCommon/Mocks/MockCGFContent.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* 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. -* -*/ -#pragma once - -#include - -#include - -class MockIAssetWriter - : public IAssetWriter -{ -public: - ~MockIAssetWriter() override = default; - MOCK_METHOD1(WriteCGF, - bool(CContentCGF* content)); - MOCK_METHOD2(WriteCHR, - bool(CContentCGF* content, IConvertContext* convertContext)); - MOCK_METHOD3(WriteSKIN, - bool(CContentCGF* content, IConvertContext* convertContext, bool exportMorphTargets)); -}; diff --git a/Code/CryEngine/CryCommon/Name_TypeInfo.h b/Code/CryEngine/CryCommon/Name_TypeInfo.h deleted file mode 100644 index bfb4d3b09c..0000000000 --- a/Code/CryEngine/CryCommon/Name_TypeInfo.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H -#define CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H -#pragma once - -#include "CryName.h" - -// CCryName TypeInfo - -TYPE_INFO_BASIC(CCryName) - -string ToString(CCryName const& val) -{ - return string(val.c_str()); -} -bool FromString(CCryName& val, const char* s) -{ - val = s; - return true; -} - -#endif // CRYINCLUDE_CRYCOMMON_NAME_TYPEINFO_H diff --git a/Code/CryEngine/CryCommon/OceanConstants.h b/Code/CryEngine/CryCommon/OceanConstants.h deleted file mode 100644 index 446a7e284a..0000000000 --- a/Code/CryEngine/CryCommon/OceanConstants.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -* 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. -* -*/ -#pragma once -#include -#include - -// Water level unknown. -#define WATER_LEVEL_UNKNOWN -1000000.f -#define BOTTOM_LEVEL_UNKNOWN -1000000.f - -namespace AZ -{ - /** - * Numeric constants that the editors should use for the ocean properties - */ - namespace OceanConstants - { - // Ocean Height consts are maintained for backwards compatibility - // @TODO: Remove height / depth related consts when feature toggle is removed. - static const float s_HeightMin = -AZ::Constants::MaxFloatBeforePrecisionLoss; - static const float s_HeightMax = AZ::Constants::MaxFloatBeforePrecisionLoss; - static const float s_HeightUnknown = WATER_LEVEL_UNKNOWN; - static const float s_BottomUnknown = BOTTOM_LEVEL_UNKNOWN; - static const float s_DefaultHeight = 16.0f; - - static const float s_CausticsDistanceAttenMin = 0.0f; - static const float s_CausticsDistanceAttenDefault = 10.0f; - static const float s_CausticsDistanceAttenMax = 100.0f; - static const float s_CausticsDepthMin = 0.0f; - static const float s_CausticsDepthDefault = 8.0f; - static const float s_CausticsDepthMax = 100.0f; - static const float s_CausticsIntensityMin = 0.0f; - static const float s_CausticsIntensityDefault = 1.0f; - static const float s_CausticsIntensityMax = 10.0f; - static const float s_CausticsTilingMin = 0.10f; - static const float s_CausticsTilingDefault = 2.0f; - static const float s_CausticsTilingMax = 10.0f; - - static const float s_animationWavesAmountMin = 0.2f; - static const float s_animationWavesAmountMax = 5.0f; - static const float s_animationWavesAmountDefault = 0.75f; - static const float s_animationWavesSizeMin = 0.0f; - static const float s_animationWavesSizeMax = 3.0f; - static const float s_animationWavesSizeDefault = 1.25f; - static const float s_animationWavesSpeedMin = 0.0f; - static const float s_animationWavesSpeedMax = 5.0f; - static const float s_animationWavesSpeedDefault = 1.0f; - static const float s_animationWindDirectionMin = 0.0f; - static const float s_animationWindDirectionMax = 6.2832f; - static const float s_animationWindDirectionDefault = 1; - static const float s_animationWindSpeedMin = 0.0f; - static const float s_animationWindSpeedMax = 1000.0f; - static const float s_animationWindSpeedDefault = 40.0f; - - static const AZ::Color s_oceanFogColorDefault((AZ::u8)5, (AZ::u8)36, (AZ::u8)32, (AZ::u8)255); - static const AZ::Color s_oceanNearFogColorDefault((AZ::u8)1, (AZ::u8)7, (AZ::u8)5, (AZ::u8)255); - static const float s_oceanFogColorMultiplierDefault = 0.15f; - static const float s_oceanFogDensityDefault = 0.07f; - static const float s_OceanFogColorMultiplierMin = 0.0f; - static const float s_OceanFogColorMultiplierMax = 1.0f; - static const float s_OceanFogDensityMin = 0.0f; - static const float s_OceanFogDensityMax = 1.0f; - - static const int s_waterTessellationAmountMin = 10; - static const int s_waterTessellationAmountMax = 500; - static const int s_waterTessellationDefault = 85; - - static const bool s_UseOceanBottom = true; - - static const bool s_GodRaysEnabled = true; - static const float s_UnderwaterDistortion = 1.0f; - - static const float s_oceanIsVeryFarAway = 1000000.f; - }; - -} diff --git a/Code/CryEngine/CryCommon/Pak/CryPakUtils.h b/Code/CryEngine/CryCommon/Pak/CryPakUtils.h deleted file mode 100644 index 3a888c0279..0000000000 --- a/Code/CryEngine/CryCommon/Pak/CryPakUtils.h +++ /dev/null @@ -1,363 +0,0 @@ -/* -* 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. -* -*/ -#pragma once - -#include - -//! Everybody should use fxopen instead of fopen so it opens on all platforms -inline AZ::IO::HandleType fxopen(const char* file, const char* mode, bool bGameRelativePath = false) -{ - if (gEnv && gEnv->pCryPak) - { - gEnv->pCryPak->CheckFileAccessDisabled(file, mode); -} - bool bWriteAccess = false; - for (const char* s = mode; *s; s++) - { - if (*s == 'w' || *s == 'W' || *s == 'a' || *s == 'A' || *s == '+') - { - bWriteAccess = true; - break; - } - ; - } - - if (gEnv && gEnv->pCryPak) - { - int nAdjustFlags = 0; - if (!bGameRelativePath) - { - nAdjustFlags |= AZ::IO::IArchive::FLAGS_PATH_REAL; - } - if (bWriteAccess) - { - nAdjustFlags |= AZ::IO::IArchive::FLAGS_FOR_WRITING; - } - char path[_MAX_PATH]; - const char* szAdjustedPath = gEnv->pCryPak->AdjustFileName(file, path, AZ_ARRAY_SIZE(path), nAdjustFlags); - -#if !AZ_TRAIT_LEGACY_CRYPAK_UNIX_LIKE_FILE_SYSTEM - if (bWriteAccess) - { - // Make sure folder is created. - gEnv->pCryPak->MakeDir(szAdjustedPath); - } -#endif - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - AZ::IO::FileIOBase::GetInstance()->Open(szAdjustedPath, AZ::IO::GetOpenModeFromStringMode(mode), fileHandle); - return fileHandle; - } - else - { - return AZ::IO::InvalidHandle; - } -} - -class CDebugAllowFileAccess -{ -public: -#if defined(_RELEASE) - ILINE CDebugAllowFileAccess() { } - ILINE void End() { } -#else - CDebugAllowFileAccess() - { - m_threadId = AZStd::this_thread::get_id(); - m_oldDisable = gEnv->pCryPak ? gEnv->pCryPak->DisableRuntimeFileAccess(false, m_threadId) : false; - m_active = true; - } - ~CDebugAllowFileAccess() - { - End(); - } - void End() - { - if (m_active) - { - if (gEnv && gEnv->pCryPak) - { - gEnv->pCryPak->DisableRuntimeFileAccess(m_oldDisable, m_threadId); - } - m_active = false; - } - } -protected: - AZStd::thread_id m_threadId; - bool m_oldDisable; - bool m_active; -#endif -}; - -////////////////////////////////////////////////////////////////////////// - - -class CInMemoryFileLoader -{ -public: - CInMemoryFileLoader(AZ::IO::IArchive* pCryPak) - : m_pPak(pCryPak) - , m_fileHandle(AZ::IO::InvalidHandle) - , m_pBuffer(0) - , m_pCursor(0) - , m_nFileSize(0) {} - ~CInMemoryFileLoader() - { - Close(); - } - - bool IsFileExists() const - { - return m_fileHandle != AZ::IO::InvalidHandle; - } - - AZ::IO::HandleType GetFileHandle() const - { - return m_fileHandle; - } - - bool FOpen(const char* name, const char* mode, bool bImmediateCloseFile = false) - { - if (m_pPak) - { - assert(m_fileHandle == AZ::IO::InvalidHandle); - m_fileHandle = m_pPak->FOpen(name, mode); - if (m_fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - m_nFileSize = m_pPak->FGetSize(m_fileHandle); - if (m_nFileSize == 0) - { - Close(); - return false; - } - - m_pCursor = m_pBuffer = (char*)m_pPak->PoolMalloc(m_nFileSize); - - size_t nReaded = m_pPak->FReadRawAll(m_pBuffer, m_nFileSize, m_fileHandle); - if (nReaded != m_nFileSize) - { - Close(); - return false; - } - - if (bImmediateCloseFile) - { - m_pPak->FClose(m_fileHandle); - m_fileHandle = AZ::IO::InvalidHandle; - } - - return true; - } - - return false; - } - - void FClose() - { - Close(); - } - - size_t FReadRaw(void* data, size_t length, size_t elems) - { - ptrdiff_t dist = m_pCursor - m_pBuffer; - - size_t count = length; - if (dist + count * elems > m_nFileSize) - { - count = (m_nFileSize - dist) / elems; - } - - memmove(data, m_pCursor, count * elems); - m_pCursor += count * elems; - - return count; - } - - template - size_t FRead(T* data, size_t elems, bool bSwapEndian = eLittleEndian) - { - ptrdiff_t dist = m_pCursor - m_pBuffer; - - size_t count = elems; - if (dist + count * sizeof(T) > m_nFileSize) - { - count = (m_nFileSize - dist) / sizeof(T); - } - - memmove(data, m_pCursor, count * sizeof(T)); - m_pCursor += count * sizeof(T); - - SwapEndian(data, count, bSwapEndian); - return count; - } - - size_t FTell() - { - ptrdiff_t dist = m_pCursor - m_pBuffer; - return dist; - } - - int FSeek(int64_t origin, int command) - { - int retCode = -1; - int64_t newPos; - char* newPosBuf; - switch (command) - { - case SEEK_SET: - newPos = origin; - if (newPos <= (int64_t)m_nFileSize) - { - m_pCursor = m_pBuffer + newPos; - retCode = 0; - } - break; - case SEEK_CUR: - newPosBuf = m_pCursor + origin; - if (newPosBuf <= m_pBuffer + m_nFileSize) - { - m_pCursor = newPosBuf; - retCode = 0; - } - break; - case SEEK_END: - newPos = m_nFileSize - origin; - if (newPos <= (int64_t)m_nFileSize) - { - m_pCursor = m_pBuffer + newPos; - retCode = 0; - } - break; - default: - // Not valid disk operation! - AZ_Assert(false, "Invalid disk operation"); - } - return retCode; - } - - -private: - - void Close() - { - if (m_fileHandle != AZ::IO::InvalidHandle) - { - m_pPak->FClose(m_fileHandle); - } - - if (m_pBuffer) - { - m_pPak->PoolFree(m_pBuffer); - } - - m_pBuffer = m_pCursor = 0; - m_nFileSize = 0; - m_fileHandle = AZ::IO::InvalidHandle; - } - -private: - AZ::IO::HandleType m_fileHandle; - char* m_pBuffer; - AZ::IO::IArchive* m_pPak; - char* m_pCursor; - size_t m_nFileSize; -}; - - -////////////////////////////////////////////////////////////////////////// -// Helper class that can be used to recursively scan the directory. -////////////////////////////////////////////////////////////////////////// -struct SDirectoryEnumeratorHelper -{ -public: - void ScanDirectoryRecursive(AZ::IO::IArchive* pIPak, const AZStd::string& root, const AZStd::string& pathIn, const AZStd::string& fileSpec, AZStd::vector& files) - { - auto AddSlash = [](AZStd::string_view path) -> AZStd::string - { - if (path.ends_with(AZ_CORRECT_DATABASE_SEPARATOR)) - { - return path; - } - else if (path.ends_with(AZ_WRONG_DATABASE_SEPARATOR)) - { - return AZStd::string{ path.substr(0, path.size() - 1) } + AZ_CORRECT_DATABASE_SEPARATOR; - } - return path.empty() ? AZStd::string(path) : AZStd::string(path) + AZ_CORRECT_DATABASE_SEPARATOR; - }; - AZStd::string dir; - AZ::StringFunc::Path::Join(root.c_str(), pathIn.c_str(), dir); - dir = AddSlash(dir); - - ScanDirectoryFiles(pIPak, "", dir, fileSpec, files); - - AZStd::string findFilter; - AZ::StringFunc::Path::Join(dir.c_str(), "*", findFilter); - - // Add all directories. - - AZ::IO::ArchiveFileIterator pakFileIterator = pIPak->FindFirst(findFilter.c_str()); - if (pakFileIterator) - { - do - { - // Skip back folders. - if (pakFileIterator.m_filename[0] == '.') - { - continue; - } - if (pakFileIterator.m_filename.empty()) - { - AZ_Fatal("Archive", "IArchive FindFirst/FindNext returned empty name while looking for '%s'", findFilter.c_str()); - continue; - } - if ((pakFileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) // skip sub directories. - { - AZStd::string scanDir = AZStd::string::format("%s%.*s/", AddSlash(pathIn).c_str(), aznumeric_cast(pakFileIterator.m_filename.size()), pakFileIterator.m_filename.data()); - scanDir += AZ_CORRECT_DATABASE_SEPARATOR; - ScanDirectoryRecursive(pIPak, root, scanDir, fileSpec, files); - continue; - } - } while (pakFileIterator = pIPak->FindNext(pakFileIterator)); - pIPak->FindClose(pakFileIterator); - } - } -private: - void ScanDirectoryFiles(AZ::IO::IArchive* pIPak, const AZStd::string& root, const AZStd::string& path, const AZStd::string& fileSpec, AZStd::vector& files) - { - AZStd::string dir; - AZ::StringFunc::Path::Join(root.c_str(), path.c_str(), dir); - - AZStd::string findFilter; - AZ::StringFunc::Path::Join(dir.c_str(), fileSpec.c_str(), findFilter); - - AZ::IO::ArchiveFileIterator pakFileIterator = pIPak->FindFirst(findFilter.c_str()); - if (pakFileIterator) - { - do - { - // Skip back folders and subdirectories. - if (pakFileIterator.m_filename[0] == '.' || (pakFileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory) - { - continue; - } - AZStd::string fullPath; - AZ::StringFunc::Path::Join(path.c_str(), AZStd::string(pakFileIterator.m_filename).c_str(), fullPath); - files.push_back(fullPath); - } while (pakFileIterator = pIPak->FindNext(pakFileIterator)); - pIPak->FindClose(pakFileIterator); - } - } - - -}; diff --git a/Code/CryEngine/CryCommon/PakLoadDataUtils.cpp b/Code/CryEngine/CryCommon/PakLoadDataUtils.cpp deleted file mode 100644 index cf0fe2598d..0000000000 --- a/Code/CryEngine/CryCommon/PakLoadDataUtils.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* -* 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. -* -*/ - -#include - -namespace PakLoadDataUtils -{ - bool LoadDataFromFile_Seek(size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, [[maybe_unused]] EEndian eEndian) - { - GetISystem()->GetIPak()->FSeek(fileHandle, elems, SEEK_CUR); - nDataSize -= elems; - AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0"); - return (nDataSize >= 0); - } - - bool LoadDataFromFile_Seek(size_t elems, uint8*& f, int& nDataSize, [[maybe_unused]] EEndian eEndian) - { - nDataSize -= elems; - f += elems; - AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0"); - return true; - } - - void LoadDataFromFile_FixAlignment(AZ::IO::HandleType& fileHandle, int& nDataSize) - { - while (nDataSize & 3) - { - [[maybe_unused]] size_t nRes = GetISystem()->GetIPak()->FSeek(fileHandle, 1, SEEK_CUR); - AZ_Assert(nRes == 0, "FSeek failed for 1 byte"); - AZ_Assert(nDataSize, "nDataSize reached zero" ); - nDataSize--; - } - AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0"); - } - - void LoadDataFromFile_FixAlignment(uint8*& f, int& nDataSize) - { - while (nDataSize & 3) - { - AZ_Assert(*f == 222, "Found invalid data in buffer."); - f++; - AZ_Assert(nDataSize, "nDataSize reached zero"); - nDataSize--; - } - AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0"); - } - -} //namespace PakLoadDataUtils diff --git a/Code/CryEngine/CryCommon/PakLoadDataUtils.h b/Code/CryEngine/CryCommon/PakLoadDataUtils.h deleted file mode 100644 index 6f2868f8f6..0000000000 --- a/Code/CryEngine/CryCommon/PakLoadDataUtils.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* 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. -* -*/ -#pragma once - -#include -#include - -namespace PakLoadDataUtils -{ - template - static bool LoadDataFromFile(T* data, size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, EEndian eEndian, int* pSeek = 0) - { - auto ipak = GetISystem()->GetIPak(); - if (pSeek) - { - *pSeek = aznumeric_cast(ipak->FTell(fileHandle)); - } - - if (ipak->FRead(data, elems, fileHandle, eEndian) != elems) - { - AZ_Assert(false, "Failed to read %zu elements", elems); - return false; - } - nDataSize -= sizeof(T) * elems; - AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0"); - return true; - } - - bool LoadDataFromFile_Seek(size_t elems, AZ::IO::HandleType& fileHandle, int& nDataSize, [[maybe_unused]] EEndian eEndian); - - template - static bool LoadDataFromFile(T* data, size_t elems, uint8*& f, int& nDataSize, EEndian eEndian, [[maybe_unused]] int* pSeek = 0) - { - StepDataCopy(data, f, elems, eEndian); - nDataSize -= elems * sizeof(T); - AZ_Assert(nDataSize >= 0, "nDataSize must be equal or greater than 0"); - return (nDataSize >= 0); - } - - bool LoadDataFromFile_Seek(size_t elems, uint8*& f, int& nDataSize, [[maybe_unused]] EEndian eEndian); - - void LoadDataFromFile_FixAlignment(AZ::IO::HandleType& fileHandle, int& nDataSize); - - void LoadDataFromFile_FixAlignment(uint8*& f, int& nDataSize); - -} //namespace PakLoadDataUtils diff --git a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android.cmake b/Code/CryEngine/CryCommon/Platform/Android/crycommon_android.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android_files.cmake b/Code/CryEngine/CryCommon/Platform/Android/crycommon_android_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Android/crycommon_android_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/Platform/Android/crycommon_enginesettings_android_files.cmake b/Code/CryEngine/CryCommon/Platform/Android/crycommon_enginesettings_android_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Android/crycommon_enginesettings_android_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/AppleTV/crycommon_appletv.cmake b/Code/CryEngine/CryCommon/Platform/AppleTV/crycommon_appletv.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/AppleTV/crycommon_appletv.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_enginesettings_linux_files.cmake b/Code/CryEngine/CryCommon/Platform/Linux/crycommon_enginesettings_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_enginesettings_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux.cmake b/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux_files.cmake b/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Linux/crycommon_linux_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_enginesettings_mac_files.cmake b/Code/CryEngine/CryCommon/Platform/Mac/crycommon_enginesettings_mac_files.cmake deleted file mode 100644 index f862be24f6..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_enginesettings_mac_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../EngineSettingsBackendApple.cpp - ../../EngineSettingsBackendApple.h -) diff --git a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac.cmake b/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac_files.cmake b/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Mac/crycommon_mac_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_enginesettings_windows_files.cmake b/Code/CryEngine/CryCommon/Platform/Windows/crycommon_enginesettings_windows_files.cmake deleted file mode 100644 index db9fd5b464..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_enginesettings_windows_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../EngineSettingsBackendWin32.cpp - ../../EngineSettingsBackendWin32.h -) diff --git a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows.cmake b/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - diff --git a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows_files.cmake b/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/Windows/crycommon_windows_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_enginesettings_ios_files.cmake b/Code/CryEngine/CryCommon/Platform/iOS/crycommon_enginesettings_ios_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_enginesettings_ios_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios.cmake b/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios.cmake deleted file mode 100644 index f5b9ea77a2..0000000000 --- a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios.cmake +++ /dev/null @@ -1,11 +0,0 @@ -# -# 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. -# - diff --git a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios_files.cmake b/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios_files.cmake deleted file mode 100644 index 7b9245ae92..0000000000 --- a/Code/CryEngine/CryCommon/Platform/iOS/crycommon_ios_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../WinBase.cpp -) diff --git a/Code/CryEngine/CryCommon/PoolAllocator.h b/Code/CryEngine/CryCommon/PoolAllocator.h index d6037289a7..110d25153e 100644 --- a/Code/CryEngine/CryCommon/PoolAllocator.h +++ b/Code/CryEngine/CryCommon/PoolAllocator.h @@ -36,9 +36,6 @@ // require a pointer to the bucket be stored, whereas now no memory is used // while the block is allocated. // -// This allocator is suitable for use with STL lists - see STLPoolAllocator -// for an STL-compatible interface. -// // The class can optionally support multi-threading, using the second // template parameter. By default it is multithread-safe. // See Synchronization.h. diff --git a/Code/CryEngine/CryCommon/ProfileLog.h b/Code/CryEngine/CryCommon/ProfileLog.h deleted file mode 100644 index fbde619166..0000000000 --- a/Code/CryEngine/CryCommon/ProfileLog.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_PROFILELOG_H -#define CRYINCLUDE_CRYCOMMON_PROFILELOG_H -#pragma once - - -#include // <> required for Interfuscator -#include // <> required for Interfuscator - -struct ILogElement -{ - virtual ~ILogElement(){} - virtual ILogElement* Log (const char* name, const char* message) = 0; - virtual ILogElement* SetTime (float time) = 0; - virtual void Flush (stack_string& indent) = 0; -}; - -struct IProfileLogSystem -{ - virtual ~IProfileLogSystem(){} - virtual ILogElement* Log (const char* name, const char* msg) = 0; - virtual void SetTime (ILogElement* pElement, float time) = 0; - virtual void Release () = 0; -}; - -struct SHierProfileLogItem -{ - SHierProfileLogItem(const char* name, const char* msg, int inbDoLog) - : m_pLogElement(NULL) - , m_bDoLog(inbDoLog) - { - if (m_bDoLog) - { - m_pLogElement = gEnv->pProfileLogSystem->Log(name, msg); - m_startTime = gEnv->pTimer->GetAsyncTime(); - } - } - ~SHierProfileLogItem() - { - if (m_bDoLog) - { - CTimeValue endTime = gEnv->pTimer->GetAsyncTime(); - gEnv->pProfileLogSystem->SetTime(m_pLogElement, (endTime - m_startTime).GetMilliSeconds()); - } - } - -private: - int m_bDoLog; - CTimeValue m_startTime; - ILogElement* m_pLogElement; -}; - -#define HPROFILE_BEGIN(msg1, msg2, doLog) { SHierProfileLogItem __hier_profile_uniq_var_in_this_scope__(msg1, msg2, doLog); -#define HPROFILE_END() } - -#define HPROFILE(msg1, msg2, doLog) SHierProfileLogItem __hier_profile_uniq_var_in_this_scope__(msg1, msg2, doLog); - -#endif // CRYINCLUDE_CRYCOMMON_PROFILELOG_H diff --git a/Code/CryEngine/CryCommon/ProjectDefines.h b/Code/CryEngine/CryCommon/ProjectDefines.h index 9308412c15..d8cc4aa6c7 100644 --- a/Code/CryEngine/CryCommon/ProjectDefines.h +++ b/Code/CryEngine/CryCommon/ProjectDefines.h @@ -40,8 +40,6 @@ #endif #endif -#define USE_STEAM 0 // Enable this to start using Steam - // The following definitions are used by Sandbox and RC to determine which platform support is needed #define TOOLS_SUPPORT_POWERVR #define TOOLS_SUPPORT_ETC2COMP @@ -78,9 +76,6 @@ typedef uint32 vtx_idx; #if defined(WIN32) || defined(WIN64) || LOG_CONST_CVAR_ACCESS #define RELEASE_LOGGING -//#if defined(_RELEASE) -//#define CVARS_WHITELIST -//#endif // defined(_RELEASE) #endif #if defined(_RELEASE) && !defined(RELEASE_LOGGING) @@ -162,10 +157,6 @@ typedef uint32 vtx_idx; #endif #endif -#if defined(ENABLE_PROFILING_CODE) - #define USE_PERFHUD -#endif - #if defined(ENABLE_PROFILING_CODE) #define ENABLE_ART_RT_TIME_ESTIMATE #endif @@ -185,32 +176,6 @@ typedef uint32 vtx_idx; #define SHADER_REFLECT_TEXTURE_SLOTS 0 #endif -#if (defined(WIN32) || defined(WIN64) || defined(AZ_PLATFORM_MAC)) && (!defined(AZ_MONOLITHIC_BUILD) || defined(RESOURCE_COMPILER)) -#define CRY_ENABLE_RC_HELPER 1 -#endif - -#if !defined(_RELEASE) && PROJECTDEFINES_H_TRAIT_ENABLE_SOFTCODE_SYSTEM - #define SOFTCODE_SYSTEM_ENABLED -#endif - -// Is SoftCoding enabled for this module? Usually set by the SoftCode AddIn in conjunction with a SoftCode.props file. -#ifdef SOFTCODE_ENABLED - -// Is this current compilation unit part of a SOFTCODE build? - #ifdef SOFTCODE -// Import any SC functions from the host module - #define SC_API __declspec(dllimport) - #else -// Export any SC functions from the host module - #define SC_API __declspec(dllexport) - #endif - -#else // SoftCode disabled - - #define SC_API - -#endif - // these enable and disable certain net features to give compatibility between PCs and consoles / profile and performance builds #define PC_CONSOLE_NET_COMPATIBLE 0 #define PROFILE_PERFORMANCE_NET_COMPATIBLE 0 @@ -277,9 +242,6 @@ typedef uint32 vtx_idx; #endif // TESSELLATION #endif // !defined(MOBILE) - -#define USE_GEOM_CACHES - //------------------------------------------------------ // SVO GI //------------------------------------------------------ @@ -296,10 +258,6 @@ typedef uint32 vtx_idx; # define ENABLE_LOADING_PROFILER // requires AZ_PROFILE_TELEMETRY to also be defined #endif -#if defined(SOFTCODE_ENABLED) - #error "SoftCode currently relies on CryMemoryManager being enabled. Either build without SoftCode support, or enable CryMemoryManager." -#endif - #if PROJECTDEFINES_H_TRAIT_USE_GPU_PARTICLES && !defined(NULL_RENDERER) #define GPU_PARTICLES 1 #else diff --git a/Code/CryEngine/CryCommon/QTangent.h b/Code/CryEngine/CryCommon/QTangent.h deleted file mode 100644 index f40e9cff99..0000000000 --- a/Code/CryEngine/CryCommon/QTangent.h +++ /dev/null @@ -1,157 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_QTANGENT_H -#define CRYINCLUDE_CRYCOMMON_QTANGENT_H -#pragma once - -namespace QTangent { - // Computes a QTangent from a frame and reflection scalar representing the - // tangent space. - // Will also ensure the resulting QTangent is suitable for 16bit quantization. - ILINE Quat FromFrameReflection(Quat frame, const float reflection) - { - frame.v = -frame.v; - if (frame.w < 0.0f) - { - frame = -frame; - } - - // Make sure w is never 0 by applying the smallest possible bias. - // This is needed in order to have sign() never return 0 in the shaders. - static const float BIAS_16BIT = 1.0f / 32767.0f; - static const float BIAS_SCALE_16BIT = sqrtf(1.0f - BIAS_16BIT * BIAS_16BIT); - if (frame.w < BIAS_16BIT && frame.w > -BIAS_16BIT) - { - frame *= BIAS_SCALE_16BIT; - frame.w = BIAS_16BIT; - } - - if (reflection < 0.0f) - { - frame = -frame; - } - - return frame; - } - - ILINE Quat FromFrameReflection(const Matrix33& frame, const float reflection) - { - Quat quat(frame); - quat.Normalize(); - return FromFrameReflection(quat, reflection); - } - - ILINE Quat FromFrameReflection16Safe(Matrix33 frame, const float reflection) - { - frame.OrthonormalizeFast(); - if (!frame.IsOrthonormalRH(0.1f)) - { - frame.SetIdentity(); - } - - return FromFrameReflection(frame, reflection); - } - - ILINE void ToTangentBitangentReflection(const Quat& qtangent, Vec3& tangent, Vec3& bitangent, float& reflection) - { - tangent = qtangent.GetColumn0(); - bitangent = qtangent.GetColumn1(); - reflection = qtangent.w < 0.0f ? -1.0f : +1.0f; - } -} // namespace QTangent - -// Auxiliary helper functions - -#include // <> required for Interfuscator - -ILINE Quat MeshTangentFrameToQTangent(const SMeshTangents& tangents) -{ - SMeshTangents tb = tangents; - Vec3 tangent32, bitangent32; - int16 reflection; - - tb.GetTB(tangent32, bitangent32); - tb.GetR(reflection); - - Matrix33 frame; - - frame.SetRow(0, tangent32); - frame.SetRow(1, bitangent32); - frame.SetRow(2, tangent32.Cross(bitangent32).GetNormalized()); - - return QTangent::FromFrameReflection16Safe(frame, reflection); -} - -ILINE Quat MeshTangentFrameToQTangent(const Vec4sf& tangent, const Vec4sf& bitangent) -{ - return MeshTangentFrameToQTangent(SMeshTangents(tangent, bitangent)); -} - -ILINE Quat MeshTangentFrameToQTangent(const SPipTangents& tangents) -{ - return MeshTangentFrameToQTangent(SMeshTangents(tangents)); -} - -ILINE bool MeshTangentsFrameToQTangents( - const Vec4sf* pTangent, const uint tangentStride, - const Vec4sf* pBitangent, const uint bitangentStride, const uint count, - SPipQTangents* pQTangents, const uint qtangentStride) -{ - Quat qtangent; - for (uint i = 0; i < count; ++i) - { - qtangent = MeshTangentFrameToQTangent(*pTangent, *pBitangent); - SMeshQTangents(qtangent).ExportTo(*pQTangents); - - pTangent = (const Vec4sf*)(((const uint8*)pTangent) + tangentStride); - pBitangent = (const Vec4sf*)(((const uint8*)pBitangent) + bitangentStride); - pQTangents = (SPipQTangents*)(((uint8*)pQTangents) + qtangentStride); - } - return true; -} - -ILINE bool MeshTangentsFrameToQTangents( - const SPipTangents* pTangents, const uint tangentStride, const uint count, - SPipQTangents* pQTangents, const uint qtangentStride) -{ - Quat qtangent; - for (uint i = 0; i < count; ++i) - { - qtangent = MeshTangentFrameToQTangent(*pTangents); - SMeshQTangents(qtangent).ExportTo(*pQTangents); - - pTangents = (const SPipTangents*)(((const uint8*)pTangents) + tangentStride); - pQTangents = (SPipQTangents*)(((uint8*)pQTangents) + qtangentStride); - } - return true; -} - -ILINE bool MeshTangentsFrameToQTangents( - const SMeshTangents* pTangents, const uint tangentStride, const uint count, - SMeshQTangents* pQTangents, const uint qtangentStride) -{ - Quat qtangent; - for (uint i = 0; i < count; ++i) - { - qtangent = MeshTangentFrameToQTangent(*pTangents); - *pQTangents = SMeshQTangents(qtangent); - - pTangents = (const SMeshTangents*)(((const uint8*)pTangents) + tangentStride); - pQTangents = (SMeshQTangents*)(((uint8*)pQTangents) + qtangentStride); - } - return true; -} - -#endif // CRYINCLUDE_CRYCOMMON_QTANGENT_H - diff --git a/Code/CryEngine/CryCommon/RendElement.h b/Code/CryEngine/CryCommon/RendElement.h deleted file mode 100644 index 41bcf2bf67..0000000000 --- a/Code/CryEngine/CryCommon/RendElement.h +++ /dev/null @@ -1,321 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_RENDELEMENT_H -#define CRYINCLUDE_CRYCOMMON_RENDELEMENT_H -#pragma once - - -//============================================================= - -#include "VertexFormats.h" - -class CRendElementBase; -struct CRenderChunk; -struct PrimitiveGroup; -class CShader; -struct SShaderTechnique; -class CParserBin; -struct SParserFrame; - -namespace AZ -{ - namespace Vertex - { - class Format; - } -} - -enum EDataType -{ - eDATA_Unknown = 0, - eDATA_Sky, - eDATA_Beam, - eDATA_ClientPoly, - eDATA_Flare, - eDATA_Terrain, - eDATA_SkyZone, - eDATA_Mesh, - eDATA_Imposter, - eDATA_LensOptics, - eDATA_FarTreeSprites_Deprecated, - eDATA_OcclusionQuery, - eDATA_Particle, - eDATA_GPUParticle, - eDATA_PostProcess, - eDATA_HDRProcess, - eDATA_Cloud, - eDATA_HDRSky, - eDATA_FogVolume, - eDATA_WaterVolume, - eDATA_WaterOcean, - eDATA_VolumeObject, - eDATA_PrismObject, // normally this would be #if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) but we keep it to get consistent numbers for serialization - eDATA_DeferredShading, - eDATA_GameEffect, - eDATA_BreakableGlass, - eDATA_GeomCache, - eDATA_Gem, -}; - -#include - -//======================================================= - -#define FCEF_TRANSFORM 1 -#define FCEF_DIRTY 2 -#define FCEF_NODEL 4 -#define FCEF_DELETED 8 - -#define FCEF_MODIF_TC 0x10 -#define FCEF_MODIF_VERT 0x20 -#define FCEF_MODIF_COL 0x40 -#define FCEF_MODIF_MASK 0xf0 - -#define FCEF_UPDATEALWAYS 0x100 -#define FCEF_ALLOC_CUST_FLOAT_DATA 0x200 -#define FCEF_MERGABLE 0x400 - -#define FCEF_SKINNED 0x800 -#define FCEF_PRE_DRAW_DONE 0x1000 - -#define FGP_NOCALC 1 -#define FGP_SRC 2 -#define FGP_REAL 4 -#define FGP_WAIT 8 - -#define FGP_STAGE_SHIFT 0x10 - -#define MAX_CUSTOM_TEX_BINDS_NUM 2 - -struct SGeometryInfo; -class CRendElement; - -struct IRenderElementDelegate -{ - virtual void mfPrepare(bool bCheckOverflow) = 0; - virtual bool mfDraw(CShader* shader, SShaderPass* pass) = 0; - virtual bool mfSetSampler([[maybe_unused]] int customId, [[maybe_unused]] int nTUnit, [[maybe_unused]] int nTState, [[maybe_unused]] int nTexMaterialSlot, [[maybe_unused]] int nSUnit) { return true; }; -}; - -struct IRenderElement -{ - virtual int mfGetMatId() = 0; - virtual uint16 mfGetFlags() = 0; - virtual void mfSetFlags(uint16 fl) = 0; - virtual void mfUpdateFlags(uint16 fl) = 0; - virtual void mfClearFlags(uint16 fl) = 0; - virtual void mfPrepare(bool bCheckOverflow) = 0; - virtual void mfCenter(Vec3& centr, CRenderObject* pObj) = 0; - virtual void mfGetBBox(Vec3& vMins, Vec3& vMaxs) = 0; - virtual void mfReset() = 0; - virtual void mfGetPlane(Plane_tpl& pl) = 0; - virtual void mfExport(struct SShaderSerializeContext& SC) = 0; - virtual void mfImport(struct SShaderSerializeContext& SC, uint32& offset) = 0; - virtual void mfPrecache(const SShaderItem& SH) = 0; - virtual bool mfIsHWSkinned() = 0; - virtual bool mfCheckUpdate(int Flags, uint16 nFrame, bool bTessellation = false) = 0; - virtual bool mfUpdate(int Flags, bool bTessellation = false) = 0; - virtual bool mfCompile(CParserBin& Parser, SParserFrame& Frame) = 0; - virtual bool mfDraw(CShader* ef, SShaderPass* sfm) = 0; - virtual bool mfPreDraw(SShaderPass* sl) = 0; - virtual bool mfSetSampler(int customId, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit) = 0; - virtual void mfSetDelegate(IRenderElementDelegate* pDelegate) = 0; - virtual IRenderElementDelegate* mfGetDelegate() = 0; - virtual CRenderChunk* mfGetMatInfo() = 0; - virtual TRenderChunkArray* mfGetMatInfoList() = 0; - virtual void* mfGetPointer(ESrcPointer ePT, int* Stride, EParamType Type, ESrcPointer Dst, int Flags) = 0; - virtual AZ::Vertex::Format GetVertexFormat() const = 0; - virtual void* GetCustomData() const = 0; - virtual int GetCustomTexBind(int i) const = 0; - virtual CRendElementBase* mfCopyConstruct() = 0; - virtual EDataType mfGetType() = 0; - virtual int Size() = 0; - virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0; - -}; - -class CRendElement -{ -public: - static CRendElement m_RootGlobal; - static CRendElement m_RootRelease[]; - CRendElement* m_NextGlobal; - CRendElement* m_PrevGlobal; - - EDataType m_Type; - -protected: - virtual void UnlinkGlobal() - { - if (!m_NextGlobal || !m_PrevGlobal) - { - return; - } - m_NextGlobal->m_PrevGlobal = m_PrevGlobal; - m_PrevGlobal->m_NextGlobal = m_NextGlobal; - m_NextGlobal = m_PrevGlobal = NULL; - } - - virtual void LinkGlobal(CRendElement* Before) - { - if (m_NextGlobal || m_PrevGlobal) - { - return; - } - m_NextGlobal = Before->m_NextGlobal; - Before->m_NextGlobal->m_PrevGlobal = this; - Before->m_NextGlobal = this; - m_PrevGlobal = Before; - } - -public: - CRendElement(); - virtual ~CRendElement(); - virtual void Release(bool bForce = false); - virtual const char* mfTypeString(); - virtual void mfSetType(EDataType t) { m_Type = t; } - virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {} - virtual int Size() { return 0; } - - static void ShutDown(); - static void Tick(); - static void Cleanup(); -}; - -class CRendElementBase - : public CRendElement - , public IRenderElement -{ -public: - uint16 m_Flags; - uint16 m_nFrameUpdated; - -public: - void* m_CustomData; - int m_CustomTexBind[MAX_CUSTOM_TEX_BINDS_NUM]; - - struct SGeometryStreamInfo - { - const void* pStream; - int nOffset; - int nStride; - }; - struct SGeometryInfo - { - uint32 bonesRemapGUID; // Input paremeter to fetch correct skinning stream. - - int primitiveType; //!< \see eRenderPrimitiveType - AZ::Vertex::Format vertexFormat; - uint32 streamMask; - - int32 nFirstIndex; - int32 nNumIndices; - uint32 nFirstVertex; - uint32 nNumVertices; - - uint32 nMaxVertexStreams; - - SGeometryStreamInfo indexStream; - SGeometryStreamInfo vertexStream[VSF_NUM]; - - void* pTessellationAdjacencyBuffer; - void* pSkinningExtraBonesBuffer; - }; - -public: - CRendElementBase(); - virtual ~CRendElementBase(); - - - virtual void mfPrepare(bool bCheckOverflow) override - { - if (m_delegate) - { - m_delegate->mfPrepare(bCheckOverflow); - } - } - bool mfDraw(CShader* ef, SShaderPass* sfm) override { return m_delegate ? m_delegate->mfDraw(ef, sfm) : true; } - bool mfSetSampler(int customId, int nTUnit, int nTState, int nTexMaterialSlot, int nSUnit) override { return m_delegate ? m_delegate->mfSetSampler(customId, nTUnit, nTState, nTexMaterialSlot, nSUnit) : false; } - void mfSetDelegate(IRenderElementDelegate* pDelegate) override { m_delegate = pDelegate; } - IRenderElementDelegate* mfGetDelegate() { return m_delegate; } - - EDataType mfGetType() override { return m_Type; }; - - CRenderChunk* mfGetMatInfo() override { return nullptr; } - TRenderChunkArray* mfGetMatInfoList() override { return nullptr; } - int mfGetMatId() override { return -1; } - void mfReset() override {}; - CRendElementBase* mfCopyConstruct() override; - void mfCenter(Vec3& centr, CRenderObject* pObj) override; - - bool mfCompile([[maybe_unused]] CParserBin& Parser, [[maybe_unused]] SParserFrame& Frame) override { return false; } - bool mfPreDraw([[maybe_unused]] SShaderPass* sl) override { return true; } - bool mfUpdate([[maybe_unused]] int Flags, [[maybe_unused]] bool bTessellation = false) override { return true; } - void mfPrecache([[maybe_unused]] const SShaderItem& SH) override {} - void mfExport([[maybe_unused]] struct SShaderSerializeContext& SC) override { CryFatalError("mfExport has not been implemented for this render element type"); } - void mfImport([[maybe_unused]] struct SShaderSerializeContext& SC, [[maybe_unused]] uint32& offset) override { CryFatalError("mfImport has not been implemented for this render element type"); } - void mfGetPlane(Plane_tpl& pl) override; - void* mfGetPointer([[maybe_unused]] ESrcPointer ePT, [[maybe_unused]] int* Stride, [[maybe_unused]] EParamType Type, [[maybe_unused]] ESrcPointer Dst, [[maybe_unused]] int Flags) override { return nullptr; } - - uint16 mfGetFlags() override { return m_Flags; } - void mfSetFlags(uint16 fl) override { m_Flags = fl; } - void mfUpdateFlags(uint16 fl) override { m_Flags |= fl; } - void mfClearFlags(uint16 fl) override { m_Flags &= ~fl; } - bool mfCheckUpdate(int Flags, uint16 nFrame, bool bTessellation = false) override - { - if (nFrame != m_nFrameUpdated || (m_Flags & (FCEF_DIRTY | FCEF_SKINNED | FCEF_UPDATEALWAYS))) - { - m_nFrameUpdated = nFrame; - return mfUpdate(Flags, bTessellation); - } - return true; - } - void mfGetBBox(Vec3& vMins, Vec3& vMaxs) override - { - vMins.Set(0, 0, 0); - vMaxs.Set(0, 0, 0); - } - bool mfIsHWSkinned() override { return false; } - int Size() override { return 0; } - void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const override {} - AZ::Vertex::Format GetVertexFormat() const override { return AZ::Vertex::Format(eVF_Unknown); }; - virtual bool GetGeometryInfo([[maybe_unused]] SGeometryInfo& streams) { return false; } - void Draw([[maybe_unused]] CRenderObject* pObj, [[maybe_unused]] const struct SGraphicsPiplinePassContext& ctx) {}; - void* GetCustomData() const { return m_CustomData; } - int GetCustomTexBind(int index) const { return m_CustomTexBind[index]; } - -protected: - IRenderElementDelegate * m_delegate = nullptr; -}; - -#include "CREMesh.h" -#include "CRESky.h" -#include "CREOcclusionQuery.h" -#include "CREImposter.h" -#include "CREBaseCloud.h" -#include "CREPostProcess.h" -#include "CREFogVolume.h" -#include "CREWaterVolume.h" -#include "CREWaterOcean.h" -#include "CREVolumeObject.h" -#include "CREGameEffect.h" -#include "CREGeomCache.h" - -#if !defined(EXCLUDE_DOCUMENTATION_PURPOSE) -#include "CREPrismObject.h" -#endif // EXCLUDE_DOCUMENTATION_PURPOSE - -//========================================================== - -#endif // CRYINCLUDE_CRYCOMMON_RENDELEMENT_H diff --git a/Code/CryEngine/CryCommon/RenderBus.h b/Code/CryEngine/CryCommon/RenderBus.h index efd004219a..21c56f607c 100644 --- a/Code/CryEngine/CryCommon/RenderBus.h +++ b/Code/CryEngine/CryCommon/RenderBus.h @@ -33,14 +33,6 @@ namespace AZ static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; ////////////////////////////////////////////////////////////////////////// - /** - * This event gets posted at the end of CD3D9Renderer's EF_Scene3D method. - * CSystem (in SystemRenderer.cpp) uses this to render the console, aux geom and UI - * in a manner that will make sure the render calls end up as part of the scene's render. - * This is important or else those render calls won't show up properly in VR. - */ - virtual void OnScene3DEnd() {}; - /** * This event gets posted at the beginning of CD3D9Renderer's FreeResources method, before the resources have been freed. */ diff --git a/Code/CryEngine/CryCommon/RenderContextConfig.h b/Code/CryEngine/CryCommon/RenderContextConfig.h deleted file mode 100644 index 3d5899d3f6..0000000000 --- a/Code/CryEngine/CryCommon/RenderContextConfig.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include -#include - -namespace AZ -{ - class ReflectContext; -} - -namespace AzRTT -{ - typedef AZ::Uuid RenderContextId; - - // various post screen effects will fail if we attempt to render the scene to very - // small render target sizes so provide a reasonable minimum (tile/icon size) - constexpr uint32_t MinRenderTargetWidth = 32; - constexpr uint32_t MinRenderTargetHeight = 32; - - // this maximum recommended texture size applies to width and height - // using sizes larger than this can lead to performance issues and instability - constexpr uint32_t MaxRecommendedRenderTargetSize = 2048; - - enum class AlphaMode { - ALPHA_DISABLED = 0, - ALPHA_OPAQUE, - ALPHA_DEPTH_BASED - }; - - // RenderContextConfig stores the render settings to use when rendering to texture. - // It also provides a more developer-friendly interface to deal with by exposing - // the most commonly used properties in one place. - struct RenderContextConfig - { - AZ_CLASS_ALLOCATOR(RenderContextConfig, AZ::SystemAllocator, 0); - AZ_RTTI(RenderContextConfig, "{6114F930-CBE4-4373-AF9D-3B5319471C8F}"); - virtual ~RenderContextConfig() = default; - static void Reflect(AZ::ReflectContext* context); - - //! render target width - uint32_t m_width = 256; - - //! render target height - uint32_t m_height = 256; - - //! write srgb or linear output - bool m_sRGBWrite = false; - - //! alpha mode to use for the render target - AlphaMode m_alphaMode = AlphaMode::ALPHA_OPAQUE; - - //! scene settings - bool m_oceanEnabled = true; - bool m_terrainEnabled = true; - bool m_vegetationEnabled = true; - - //! shadow settings - bool m_shadowsEnabled = true; - int32_t m_shadowsNumCascades = -1; - float m_shadowsGSMRange = -1.f; - float m_shadowsGSMRangeStep = -1.f; - - //! post-effects settings - bool m_depthOfFieldEnabled = false; - bool m_motionBlurEnabled = false; - int m_aaMode = 0; - - //! visiblity for shadow settings - AZ::Crc32 GetShadowSettingsVisible(); - - //! confirm if user wants to use texture size larger than MaxRecommendedRenderTargetSize - bool ValidateTextureSize(void* newValue, const AZ::Uuid& valueType); - }; -} diff --git a/Code/CryEngine/CryCommon/ResourceCompilerHelper.cpp b/Code/CryEngine/CryCommon/ResourceCompilerHelper.cpp deleted file mode 100644 index 33373f7460..0000000000 --- a/Code/CryEngine/CryCommon/ResourceCompilerHelper.cpp +++ /dev/null @@ -1,639 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#include "ProjectDefines.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "ResourceCompilerHelper.h" -#include "EngineSettingsManager.h" - -// When complining CryTiffPlugin the mayaAssert.h is included that defined -// Assert as _Assert. This wreaks havoc with AZ_Assert since under the covers -// it calls AzCore::Debug::Trace::Assert, which gets transformed bo -// Trace::_Assert, which does not exist. Gotta love macros. Undefine Assert -// before we include semaphore so that it can compile correctly -#if defined(Assert) -#undef Assert -#endif - -#include -#include -#include -#include -#include - -#if defined(AZ_PLATFORM_WINDOWS) -#include -#include // ShellExecuteW() -#endif - -#if AZ_TRAIT_OS_PLATFORM_APPLE -#include "AppleSpecific.h" -#include -#else -#undef RC_EXECUTABLE -#define RC_EXECUTABLE "rc.exe" -#endif - -#include -#include // lawsonn - we use std::string internally -#include - -namespace -{ - class LineStreamBuffer - { - public: - template - LineStreamBuffer(T* object, void (T::* method)(const char* line)) - : m_charCount(0) - , m_bTruncated(false) - { - m_target = new Target(object, method); - } - - ~LineStreamBuffer() - { - Flush(); - delete m_target; - } - - void HandleText(const char* text, int length) - { - const char* pos = text; - while (pos - text < length) - { - const char* start = pos; - - while (pos - text < length && *pos != '\n' && *pos != '\r') - { - ++pos; - } - - size_t n = pos - start; - if (m_charCount + n > kMaxCharCount) - { - n = kMaxCharCount - m_charCount; - m_bTruncated = true; - } - memcpy(&m_buffer[m_charCount], start, n); - m_charCount += n; - - if (pos - text < length) - { - Flush(); - while (pos - text < length && (*pos == '\n' || *pos == '\r')) - { - ++pos; - } - } - } - } - - void Flush() - { - if (m_charCount > 0) - { - m_buffer[m_charCount] = 0; - m_target->Call(m_buffer); - m_charCount = 0; - } - } - - bool IsTruncated() const - { - return m_bTruncated; - } - - private: - struct ITarget - { - virtual ~ITarget() {} - virtual void Call(const char* line) = 0; - }; - template - struct Target - : public ITarget - { - public: - Target(T* object, void (T::* method)(const char* line)) - : object(object) - , method(method) {} - virtual void Call(const char* line) - { - (object->*method)(line); - } - private: - T* object; - void (T::* method)(const char* line); - }; - - ITarget* m_target; - size_t m_charCount; - static const size_t kMaxCharCount = 2047; - char m_buffer[kMaxCharCount + 1]; - bool m_bTruncated; - }; - -#if !defined(AZ_PLATFORM_WINDOWS) - void MessageBoxW(int, const wchar_t* header, const wchar_t* message, unsigned long) - { -#if AZ_TRAIT_OS_PLATFORM_APPLE - CFStringEncoding encoding = (CFByteOrderLittleEndian == CFByteOrderGetCurrent()) ? - kCFStringEncodingUTF32LE : kCFStringEncodingUTF32BE; - CFStringRef header_ref = CFStringCreateWithBytes(nullptr, reinterpret_cast(header), wcslen(header) * sizeof(wchar_t), encoding, false); - CFStringRef message_ref = CFStringCreateWithBytes(nullptr, reinterpret_cast(message), wcslen(message) * sizeof(wchar_t), encoding, false); - - CFOptionFlags result; //result code from the message box - - CFUserNotificationDisplayAlert(0, kCFUserNotificationStopAlertLevel, 0, 0, 0, header_ref, message_ref, 0, 0, 0, &result); - - CFRelease(header_ref); - CFRelease(message_ref); -#endif - } -#endif -} - -namespace -{ - class RcLock - { - public: - RcLock() - : m_cs(0u, 1u) - { - m_cs.release(); - } - ~RcLock() - { - } - - void Lock() - { - m_cs.acquire(); - } - void Unlock() - { - m_cs.release(); - } - - private: - AZStd::semaphore m_cs; - }; - - - template - class RcAutoLock - { - public: - RcAutoLock(LockClass& lock) - : m_lock(lock) - { - m_lock.Lock(); - } - ~RcAutoLock() - { - m_lock.Unlock(); - } - - private: - RcAutoLock(); - RcAutoLock(const RcAutoLock&); - RcAutoLock& operator =(const RcAutoLock&); - - private: - LockClass& m_lock; - }; - - - HANDLE s_rcProcessHandle = 0; - RcLock s_rcProcessHandleLock; -} - -////////////////////////////////////////////////////////////////////////// -static void ShowMessageBoxRcNotFound([[maybe_unused]] const wchar_t* const szCmdLine, [[maybe_unused]] const wchar_t* const szDir) -{ - SettingsManagerHelpers::CFixedString tmp; - - tmp.append(L"The resource compiler (RC.EXE) was not found."); - MessageBoxW(0, tmp.c_str(), L"Error", MB_ICONERROR | MB_OK); -} - - -////////////////////////////////////////////////////////////////////////// -namespace -{ - class ResourceCompilerLineHandler - { - public: - ResourceCompilerLineHandler(IResourceCompilerListener* listener) - : m_listener(listener) - { - } - - void HandleLine(const char* line) - { - if (!m_listener || !line) - { - return; - } - - // check the first three characters to see if it's a warning or error. - bool bHasPrefix; - IResourceCompilerListener::MessageSeverity severity; - if ((line[0] == 'E') && (line[1] == ':') && (line[2] == ' ')) - { - bHasPrefix = true; - severity = IResourceCompilerListener::MessageSeverity_Error; - line += 3; // skip the prefix - } - else if ((line[0] == 'W') && (line[1] == ':') && (line[2] == ' ')) - { - bHasPrefix = true; - severity = IResourceCompilerListener::MessageSeverity_Warning; - line += 3; // skip the prefix - } - else if ((line[0] == ' ') && (line[1] == ' ') && (line[2] == ' ')) - { - bHasPrefix = true; - severity = IResourceCompilerListener::MessageSeverity_Info; - line += 3; // skip the prefix - } - else - { - bHasPrefix = false; - severity = IResourceCompilerListener::MessageSeverity_Info; - } - - if (bHasPrefix) - { - // skip thread info "%d>", if present - { - const char* p = line; - while (*p == ' ') - { - ++p; - } - if (isdigit(*p)) - { - while (isdigit(*p)) - { - ++p; - } - if (*p == '>') - { - line = p + 1; - } - } - } - - // skip time info "%d:%d", if present - { - const char* p = line; - while (*p == ' ') - { - ++p; - } - if (isdigit(*p)) - { - while (isdigit(*p)) - { - ++p; - } - if (*p == ':') - { - ++p; - if (isdigit(*p)) - { - while (isdigit(*p)) - { - ++p; - } - while (*p == ' ') - { - ++p; - } - line = p; - } - } - } - } - } - - m_listener->OnRCMessage(severity, line); - } - - private: - IResourceCompilerListener* m_listener; - }; - - // we now support macros like #ENGINEROOT# in the string: - void replaceAllInStringInPlace(std::string& inOut, const char* findValue, const char* replaceValue) - { - if (!findValue) - { - return; - } - - if (!replaceValue) - { - return; - } - - std::string::size_type pos = std::string::npos; - std::string::size_type replaceLen = strlen(findValue); - - while ((pos = inOut.find(findValue)) != std::string::npos) - { - inOut.replace(pos, replaceLen, replaceValue); - } - } - - // given a string that contains macros (like #ENGINEROOT#), eliminate the macros and replace them with the real data. - // note that in the 'remote' implementation, these macros are sent to the remote RC. It can then expand them for its own environment - // but in a local RC, these macros are expanded by the local environment. - void expandMacros(const char* inputString, char* outputString, std::size_t bufferSize) - { - if (!inputString) - { - return; - } - - if (!outputString) - { - return; - } - - AZStd::string_view rootFolder; - AZ::ComponentApplicationBus::BroadcastResult(rootFolder, &AZ::ComponentApplicationRequests::GetAppRoot); - - std::string finalString(inputString); - const AZStd::string rootFolderStr = rootFolder.data(); - replaceAllInStringInPlace(finalString, "#ENGINEROOT#", rootFolderStr.c_str()); - // put additional replacements here. - - azstrcpy(outputString, bufferSize, finalString.c_str()); - } -} - -////////////////////////////////////////////////////////////////////////// -IResourceCompilerHelper::ERcCallResult CResourceCompilerHelper::CallResourceCompiler( - const char* szFileName, - const char* szAdditionalSettings, - IResourceCompilerListener* listener, - bool bMayShowWindow, - bool bSilent, - bool bNoUserDialog, - const wchar_t* szWorkingDirectory, - [[maybe_unused]] const wchar_t* szRootPath) -{ -#if defined(AZ_PLATFORM_WINDOWS) - HANDLE hChildStdOutRd = INVALID_HANDLE_VALUE, hChildStdOutWr = INVALID_HANDLE_VALUE; - HANDLE hChildStdInRd = INVALID_HANDLE_VALUE, hChildStdInWr = INVALID_HANDLE_VALUE; - PROCESS_INFORMATION pi; -#else - FILE* hChildStdOutRd; -#endif - - { - RcAutoLock lock(s_rcProcessHandleLock); - - // make command for execution - SettingsManagerHelpers::CFixedString wRemoteCmdLine; - - - if (!szAdditionalSettings) - { - szAdditionalSettings = ""; - } - - // expand the additioanl settings. - char szActualFileName[512] = {0}; - char szActualAdditionalSettings[512] = {0}; - - expandMacros(szFileName, szActualFileName, 512); - expandMacros(szAdditionalSettings, szActualAdditionalSettings, 512); - - CSettingsManagerTools smTools = CSettingsManagerTools(); // moved this line to after macro expansion to avoid multiple of these existing at once. - - AZStd::string_view exeFolderName; - AZ::ComponentApplicationBus::BroadcastResult(exeFolderName, &AZ::ComponentApplicationRequests::GetExecutableFolder); - - wchar_t szRegSettingsBuffer[1024]; - smTools.GetEngineSettingsManager()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(szRegSettingsBuffer, sizeof(szRegSettingsBuffer))); - bool enableSourceControl = true; - smTools.GetEngineSettingsManager()->GetValueByRef("RC_EnableSourceControl", enableSourceControl); - - wRemoteCmdLine.appendAscii("\""); - wRemoteCmdLine.appendAscii(exeFolderName.data(), exeFolderName.size()); - wRemoteCmdLine.appendAscii("/"); - wRemoteCmdLine.appendAscii(RC_EXECUTABLE); - wRemoteCmdLine.appendAscii("\""); - - if (!enableSourceControl) - { - wRemoteCmdLine.appendAscii(" -nosourcecontrol "); - } - - if (!szFileName) - { - wRemoteCmdLine.appendAscii(" -userdialog=0 "); - wRemoteCmdLine.appendAscii(szActualAdditionalSettings); - wRemoteCmdLine.appendAscii(" "); - wRemoteCmdLine.append(szRegSettingsBuffer); - } - else - { - wRemoteCmdLine.appendAscii(" \""); - wRemoteCmdLine.appendAscii(szActualFileName); - wRemoteCmdLine.appendAscii("\""); - wRemoteCmdLine.appendAscii(bNoUserDialog ? " -userdialog=0 " : " -userdialog=1 "); - wRemoteCmdLine.appendAscii(szActualAdditionalSettings); - wRemoteCmdLine.appendAscii(" "); - wRemoteCmdLine.append(szRegSettingsBuffer); - } - - // Create a pipe to read the stdout of the RC. - SECURITY_ATTRIBUTES saAttr; - if (listener) - { -#if defined(AZ_PLATFORM_WINDOWS) - ZeroMemory(&saAttr, sizeof(saAttr)); - saAttr.bInheritHandle = TRUE; - saAttr.lpSecurityDescriptor = 0; - CreatePipe(&hChildStdOutRd, &hChildStdOutWr, &saAttr, 0); - SetHandleInformation(hChildStdOutRd, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN - CreatePipe(&hChildStdInRd, &hChildStdInWr, &saAttr, 0); - SetHandleInformation(hChildStdInWr, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN -#endif - } - -#if defined(AZ_PLATFORM_WINDOWS) - STARTUPINFOW si; - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - si.dwX = 100; - si.dwY = 100; - if (listener) - { - si.hStdError = hChildStdOutWr; - si.hStdOutput = hChildStdOutWr; - si.hStdInput = hChildStdInRd; - si.dwFlags = STARTF_USEPOSITION | STARTF_USESTDHANDLES; - } - else - { - si.dwFlags = STARTF_USEPOSITION; - } - - ZeroMemory(&pi, sizeof(pi)); -#endif - - bool bShowWindow; - if (bMayShowWindow) - { - wchar_t buffer[20]; - smTools.GetEngineSettingsManager()->GetValueByRef("ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))); - bShowWindow = (wcscmp(buffer, L"true") == 0); - } - else - { - bShowWindow = false; - } - -#if defined(AZ_PLATFORM_WINDOWS) - const wchar_t* szStartingDirectory = szWorkingDirectory; - if (!szStartingDirectory) - { - char currentDirectory[MAX_PATH]; - AZ::Utils::GetExecutableDirectory(currentDirectory, MAX_PATH); - SettingsManagerHelpers::CFixedString wCurrentDirectory; - wCurrentDirectory.appendAscii(currentDirectory); - szStartingDirectory = wCurrentDirectory.c_str(); - } - - - if (!CreateProcessW( - NULL, // No module name (use command line). - const_cast(wRemoteCmdLine.c_str()), // Command line. - NULL, // Process handle not inheritable. - NULL, // Thread handle not inheritable. - TRUE, // Set handle inheritance to TRUE. - bShowWindow ? 0 : CREATE_NO_WINDOW, // creation flags. - NULL, // Use parent's environment block. - szStartingDirectory, // Set starting directory. - &si, // Pointer to STARTUPINFO structure. - &pi)) // Pointer to PROCESS_INFORMATION structure. - { - // The following code block is commented out instead of being deleted - // because it's good to have at hand for a debugging session. - #if 0 - const size_t charsInMessageBuffer = 32768; // msdn about FormatMessage(): "The output buffer cannot be larger than 64K bytes." - wchar_t szMessageBuffer[charsInMessageBuffer] = L""; - FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, szMessageBuffer, charsInMessageBuffer, NULL); - GetCurrentDirectoryW(charsInMessageBuffer, szMessageBuffer); - #endif - - if (!bSilent) - { - ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szStartingDirectory); - } - - return eRcCallResult_notFound; - } - - s_rcProcessHandle = pi.hProcess; -#else - int fd = open(".", O_RDONLY); - char remoteCmdLineUtf8[MAX_PATH * 8]; - char workingDirectory[MAX_PATH * 8]; - ConvertUtf16ToUtf8(wRemoteCmdLine.c_str(), SettingsManagerHelpers::CCharBuffer(remoteCmdLineUtf8, MAX_PATH * 8)); - if (szWorkingDirectory) - { - ConvertUtf16ToUtf8(szWorkingDirectory, SettingsManagerHelpers::CCharBuffer(workingDirectory, MAX_PATH * 8)); - chdir(workingDirectory); - } - hChildStdOutRd = popen(remoteCmdLineUtf8, "r"); - fchdir(fd); - if (hChildStdOutRd == nullptr) - { - if (!bSilent) - { - ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szWorkingDirectory); - } - return eRcCallResult_notFound; - } -#endif - } - - bool bFailedToReadOutput = false; - - if (listener) - { -#if defined(AZ_PLATFORM_WINDOWS) - // Close the pipe that writes to the child process, since we don't actually have any input for it. - CloseHandle(hChildStdInWr); - - // Read all the output from the child process. - CloseHandle(hChildStdOutWr); -#endif - ResourceCompilerLineHandler lineHandler(listener); - LineStreamBuffer lineBuffer(&lineHandler, &ResourceCompilerLineHandler::HandleLine); - for (;; ) - { - char buffer[2048]; - DWORD bytesRead; -#if defined(AZ_PLATFORM_WINDOWS) - if (!ReadFile(hChildStdOutRd, buffer, sizeof(buffer), &bytesRead, NULL) || (bytesRead == 0)) -#else - if (fgets(buffer, sizeof(buffer), hChildStdOutRd) == nullptr || (bytesRead = strlen(buffer) == 0)) -#endif - { - break; - } - lineBuffer.HandleText(buffer, bytesRead); - } - - bFailedToReadOutput = lineBuffer.IsTruncated(); - } - -#if defined(AZ_PLATFORM_WINDOWS) - // Wait until child process exits. - WaitForSingleObject(pi.hProcess, INFINITE); -#else - DWORD exitCode = pclose(hChildStdOutRd); -#endif - -#if defined(AZ_PLATFORM_WINDOWS) - RcAutoLock lock(s_rcProcessHandleLock); - s_rcProcessHandle = 0; - - DWORD exitCode = eRcExitCode_Error; - if (bFailedToReadOutput || GetExitCodeProcess(pi.hProcess, &exitCode) == 0) - { - exitCode = eRcExitCode_Error; - } - - // Close process and thread handles. - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); -#endif - - return ConvertResourceCompilerExitCodeToResultCode(exitCode); -} - - -#endif //(CRY_ENABLE_RC_HELPER) diff --git a/Code/CryEngine/CryCommon/ResourceCompilerHelper.h b/Code/CryEngine/CryCommon/ResourceCompilerHelper.h deleted file mode 100644 index 913d72f642..0000000000 --- a/Code/CryEngine/CryCommon/ResourceCompilerHelper.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H -#define CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H - -#pragma once - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "IResourceCompilerHelper.h" - -////////////////////////////////////////////////////////////////////////// -// Provides settings and functions to make calls to RC. -// calls RC locally. only works on windows, does not exist on other platforms -// note: You shouldn't be calling this directly -// instead, you should be calling it via the IResourceCompilerHelper interface. -// since it may be replaced with a custom RC for your platform or a remote invocation -class CResourceCompilerHelper - : public IResourceCompilerHelper -{ -public: - virtual ERcCallResult CallResourceCompiler( - const char* szFileName = 0, - const char* szAdditionalSettings = 0, - IResourceCompilerListener* listener = 0, - bool bMayShowWindow = true, - bool bSilent = false, - bool bNoUserDialog = false, - const wchar_t* szWorkingDirectory = 0, - const wchar_t* szRootPath = 0) override; -}; - -#endif // CRY_ENABLE_RC_HELPER - -#endif // CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H diff --git a/Code/CryEngine/CryCommon/RingBuffer.h b/Code/CryEngine/CryCommon/RingBuffer.h deleted file mode 100644 index e163a076cf..0000000000 --- a/Code/CryEngine/CryCommon/RingBuffer.h +++ /dev/null @@ -1,273 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright (C), Crytek, 1999-2015. -#pragma once - -// A fixed-size type-safe ring buffer (ie, fixed-size double-ended queue). -// Note: It's possible to add support for iterators, indexing if needed. -template -class CRingBuffer -{ - static_assert(std::is_integral::value && std::is_unsigned::value, "I is not unsigned integral type"); - static_assert(N != 0 && N <= I(-1), "N is not a valid value (or I is too small)"); - enum : I - { - kPowerOf2 = (N & (N - 1)) == 0, - kMaxSize = static_cast(N), - }; - -public: - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; - typedef I size_type; - - // Constructs an empty ring buffer. - CRingBuffer() - : m_begin(0) - , m_count(0) - {} - - // Destroy a ring buffer. - ~CRingBuffer() - { - clear(); - } - - // Retrieve the size of the collection. - size_type size() const - { - return m_count; - } - - // Retrieve the maximum size of the collection. - size_type max_size() const - { - return kMaxSize; - } - - // Test if the collection is empty. - bool empty() const - { - return m_count == 0; - } - - // Test if the collection is full. - bool full() const - { - return m_count == kMaxSize; - } - - // Get the front-most item of the collection. - // If the collection is empty, the behavior is undefined. - reference front() - { - CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty"); - return *ptr(m_begin); - } - - // Get the front-most item of the collection. - // If the collection is empty, the behavior is undefined. - const_reference front() const - { - CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty"); - return *ptr(m_begin); - } - - // Get the back-most item of the collection. - // If the collection is empty, the behavior is undefined. - reference back() - { - CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty"); - return *ptr(wrap(m_begin + m_count - 1)); - } - - // Get the back-most item of the collection. - // If the collection is empty, the behavior is undefined. - const_reference back() const - { - CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty"); - return *ptr(wrap(m_begin + m_count - 1)); - } - - // Adds an item to the front of the collection. - // In case the collection is full, the function returns false and the collection remains unmodified. - template - bool push_front(X&& value) - { - static_assert(std::is_constructible::value, "T cannot be constructed from the given type"); - if (full()) - { - return false; - } - const I index = decrement(m_begin); - ::new(static_cast(ptr(index)))T(std::forward(value)); - m_begin = index; - ++m_count; - return true; - } - - // Adds an item to the front of the collection. - // In case the collection is full, the function overwrites the last item in the collection. - template - void push_front_overwrite(X&& value) - { - static_assert(std::is_constructible::value, "T cannot be constructed from the given type"); - const I index = decrement(m_begin); - if (full()) - { - ptr(index)->~T(); - --m_count; - } - ::new(static_cast(ptr(index)))T(std::forward(value)); - m_begin = index; - ++m_count; - } - - // Removes an item from the front of the collection. - // If the collection is empty, the behavior is undefined. - void pop_front() - { - CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty"); - ptr(m_begin)->~T(); - m_begin = increment(m_begin); - --m_count; - } - - // Attempts to remove an item from the front of the collection, and assigns it to 'value'. - // Returns true if an item was removed, false if the collection was empty (and 'value' remains unmodified). - bool try_pop_front(T& value) - { - if (m_count != 0) - { - T* const pItem = ptr(m_begin); - value = std::move(*pItem); - pItem->~T(); - m_begin = increment(m_begin); - --m_count; - return true; - } - return false; - } - - // Adds an item to the back of the collection. - // In case the collection is full, the function returns false and the collection remains unmodified. - template - bool push_back(X&& value) - { - static_assert(std::is_constructible::value, "T cannot be constructed from the given type"); - if (full()) - { - return false; - } - const I index = wrap(m_begin + m_count); - ::new(static_cast(ptr(index)))T(std::forward(value)); - ++m_count; - return true; - } - - // Adds an item to the back of the collection. - // In case the collection is full, the function overwrites the first item in the collection. - template - void push_back_overwrite(X&& value) - { - static_assert(std::is_constructible::value, "T cannot be constructed from the given type"); - const I index = wrap(m_begin + m_count); - if (full()) - { - ptr(index)->~T(); - m_begin = increment(index); - --m_count; - } - ::new(static_cast(ptr(index)))T(std::forward(value)); - ++m_count; - } - - // Removes an item from the back of the collection. - // If the collection is empty, the behavior is undefined. - void pop_back() - { - CRY_ASSERT_MESSAGE(m_count != 0, "Container is empty"); - const I index = wrap(m_begin + m_count - 1); - ptr(index)->~T(); - --m_count; - } - - // Attempts to remove an item from the back of the collection, and assigns it to 'value'. - // Returns true if an item was removed, false if the collection was empty (and 'value' remains unmodified). - bool try_pop_back(T& value) - { - if (m_count != 0) - { - const I index = wrap(m_begin + m_count - 1); - T* const pItem = ptr(index); - value = std::move(*pItem); - pItem->~T(); - --m_count; - return true; - } - return false; - } - - // Destroy all items in a ring buffer. - void clear() - { - size_type index = m_begin; - for (size_type i = 0; i < m_count; ++i, index = increment(index)) - { - ptr(index)->~T(); - } - m_begin = 0; - m_count = 0; - } - -private: - // Decrements a given index, wrapping it around N. - static size_type decrement(size_type index) - { - return kPowerOf2 ? ((index - 1) & (kMaxSize - 1)) : index ? index - 1 : kMaxSize - 1; - } - - // Increments a given index, wrapping it around N. - static size_type increment(size_type index) - { - ++index; - return kPowerOf2 ? index & (kMaxSize - 1) : index == kMaxSize ? 0 : index; - } - - // Wraps an index, which has a maximum value of 2N-1. - static size_type wrap(size_type index) - { - return kPowerOf2 ? index & (kMaxSize - 1) : index >= kMaxSize ? index - kMaxSize : index; - } - - // Obtain pointer to raw storage at given index. - pointer ptr(size_type index) - { - return reinterpret_cast(&m_storage) + index; - } - - // Obtain pointer to raw storage at given index. - const_pointer ptr(size_type index) const - { - return reinterpret_cast(&m_storage) + index; - } - - // No copy/assign supported. - CRingBuffer(const CRingBuffer&); - void operator=(const CRingBuffer&); - - size_type m_begin, m_count; - typename std::aligned_storage::value>::type m_storage; -}; diff --git a/Code/CryEngine/CryCommon/STLGlobalAllocator.h b/Code/CryEngine/CryCommon/STLGlobalAllocator.h deleted file mode 100644 index 2067c9b2e9..0000000000 --- a/Code/CryEngine/CryCommon/STLGlobalAllocator.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for an std::allocator using the global heap. -//--------------------------------------------------------------------------- - -#include -#include - -#include "CryMemoryManager.h" - -#include -#include -#include - -struct CryLegacySTLAllocatorDescriptor - : public AZ::HphaSchema::Descriptor -{ - CryLegacySTLAllocatorDescriptor() - { - m_systemChunkSize = 4 * 1024 * 1024; // Ask the OS for 4MB at a time - } -}; - -class CryLegacySTLAllocator - : public AZ::SimpleSchemaAllocator -{ -public: - AZ_TYPE_INFO(CryLegacySTLAllocator, "{87EE21F1-8215-4979-B493-AF13D8D91DAD}"); - using Descriptor = CryLegacySTLAllocatorDescriptor; - using Base = AZ::SimpleSchemaAllocator; - CryLegacySTLAllocator() - : Base("CryLegacySTLAllocator", "Allocator used to dodge limits on static init time allocations") - { - } -}; - -// Specialize for the CryLegacySTLAllocator to provide one per module that does not use the -// environment for its storage, since this thing is designed to get around the lack -// of static allocators -namespace AZ -{ - template <> - class AllocatorInstance : public Internal::AllocatorInstanceBase> - { - }; -} - - -class ICrySizer; -namespace stl -{ - template - class STLGlobalAllocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef STLGlobalAllocator other; - }; - - STLGlobalAllocator() throw() - { - } - - STLGlobalAllocator(const STLGlobalAllocator&) throw() - { - } - - template - STLGlobalAllocator(const STLGlobalAllocator&) throw() - { - } - - ~STLGlobalAllocator() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate(size_type n = 1, const void* hint = 0) - { - (void)hint; - pointer ret = static_cast(AZ::AllocatorInstance::Get().Allocate(n * sizeof(T), 0)); - return ret; - } - - void deallocate(pointer p, [[maybe_unused]] size_type n = 1) - { - AZ::AllocatorInstance::Get().DeAllocate(p); - } - - size_type max_size() const throw() - { - return INT_MAX; - } -#if !defined(_LIBCPP_VERSION) - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } -#endif // !_LIBCPP_VERSION - void destroy(pointer p) - { - p->~T(); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const STLGlobalAllocator&) const { return true; } - bool operator!=(const STLGlobalAllocator&) const { return false; } - - static void GetMemoryUsage(ICrySizer* pSizer) - { - } - }; - - template <> - class STLGlobalAllocator - { - public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template - struct rebind - { - typedef STLGlobalAllocator other; - }; - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/STLPoolAllocator.h b/Code/CryEngine/CryCommon/STLPoolAllocator.h deleted file mode 100644 index 564720bc02..0000000000 --- a/Code/CryEngine/CryCommon/STLPoolAllocator.h +++ /dev/null @@ -1,208 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H -#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for the pool allocator (see PoolAllocator.h). -// -// This class is suitable for use as an allocator for STL lists. Note it will -// not work with vectors, since it allocates fixed-size blocks, while vectors -// allocate elements in variable-sized contiguous chunks. -// -// To create a list of type UserDataType using this allocator, use the -// following syntax: -// -// std::list > myList; -//--------------------------------------------------------------------------- - -#include "PoolAllocator.h" -#include "MetaUtils.h" -#include -#include - -namespace stl -{ - namespace STLPoolAllocatorHelper - { - inline void destruct(char*) {} - inline void destruct(wchar_t*) {} - template - inline void destruct(T* t) {t->~T(); } - } - - template - struct STLPoolAllocatorStatic - { - // Non-freeing stl pool allocators should just go on the global heap - only if they've been explicitly - // set to cleanup should they go on the default heap. - typedef SizePoolAllocator< - HeapAllocator< - L, - typename metautils::select::type> - > AllocatorType; - - static AllocatorType* GetOrCreateAllocator() - { - if (allocator) - { - return allocator; - } - - allocator = new AllocatorType(S, A, FHeap().FreeWhenEmpty(FreeWhenEmpty)); - return allocator; - } - - static AllocatorType* allocator; - }; - - template - struct STLPoolAllocatorKungFu - : public STLPoolAllocatorStatic - { - }; - - template - class STLPoolAllocator - { - public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template - struct rebind - { - typedef STLPoolAllocator other; - }; - - STLPoolAllocator() throw() - { - } - - STLPoolAllocator(const STLPoolAllocator&) throw() - { - } - - template - STLPoolAllocator(const STLPoolAllocator&) throw() - { - } - - ~STLPoolAllocator() throw() - { - } - - pointer address(reference x) const - { - return &x; - } - - const_pointer address(const_reference x) const - { - return &x; - } - - pointer allocate([[maybe_unused]] size_type n = 1, [[maybe_unused]] const void* hint = 0) - { - assert(n == 1); - typename STLPoolAllocatorKungFu::AllocatorType * allocator = STLPoolAllocatorKungFu::GetOrCreateAllocator(); - return static_cast(allocator->Allocate()); - } - - void deallocate(pointer p, [[maybe_unused]] size_type n = 1) - { - assert(n == 1); - typename STLPoolAllocatorKungFu::AllocatorType * allocator = STLPoolAllocatorKungFu::allocator; - allocator->Deallocate(p); - } - - size_type max_size() const throw() - { - return INT_MAX; - } -#ifndef _LIBCPP_VERSION - void construct(pointer p, const T& val) - { - new(static_cast(p))T(val); - } - - void construct(pointer p) - { - new(static_cast(p))T(); - } -#endif // !(_LIBCPP_VERSION) - void destroy(pointer p) - { - STLPoolAllocatorHelper::destruct(p); - } - - pointer new_pointer() - { - return new(allocate())T(); - } - - pointer new_pointer(const T& val) - { - return new(allocate())T(val); - } - - void delete_pointer(pointer p) - { - p->~T(); - deallocate(p); - } - - bool operator==(const STLPoolAllocator&) {return true; } - bool operator!=(const STLPoolAllocator&) {return false; } - - static void GetMemoryUsage(ICrySizer* pSizer) - { - pSizer->AddObject(STLPoolAllocatorKungFu::allocator); - } - }; - - template - class STLPoolAllocatorNoMT - : public STLPoolAllocator - { - }; - - template <> - class STLPoolAllocator - { - public: - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - template - struct rebind - { - typedef STLPoolAllocator other; - }; - }; - - template - typename STLPoolAllocatorStatic::AllocatorType * STLPoolAllocatorStatic::allocator; -} - - - -#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H diff --git a/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h b/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h deleted file mode 100644 index 28fff38917..0000000000 --- a/Code/CryEngine/CryCommon/STLPoolAllocator_ManyElems.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H -#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H -#pragma once - - -//--------------------------------------------------------------------------- -// STL-compatible interface for the pool allocator (see PoolAllocator.h). -// -// this class acts like STLPoolAllocator, but it is also usable for vectors -// which means that it can be used as a more efficient allocator for many -// implementations of hash_map (typically this uses internally a vector and -// a list with the same allocator) -//--------------------------------------------------------------------------- - -#include "STLPoolAllocator.h" - -namespace stl -{ - template - struct STLPoolAllocator_ManyElemsStatic - { - static PoolAllocator* allocator; - }; - - template - class STLPoolAllocator_ManyElems - : public STLPoolAllocator - { - typedef STLPoolAllocator Super; - typedef PoolAllocator LargeAllocator; - - public: - typedef typename Super::pointer pointer; - typedef typename Super::pointer pointer_type; - typedef typename Super::size_type size_type; - typedef AZStd::false_type allow_memory_leaks; - - template - struct rebind - { - typedef STLPoolAllocator_ManyElems other; - }; - - STLPoolAllocator_ManyElems() throw() - { - } - - template - STLPoolAllocator_ManyElems(const STLPoolAllocator_ManyElems&) throw() - { - } - - pointer allocate(size_type n = 1, const void* hint = 0) - { - if (n == 1) - { - return Super::allocate(n, hint); - } - else if (n * sizeof(T) <= LargeAllocationSizeThreshold) - { - if (!STLPoolAllocator_ManyElemsStatic::allocator) - { - STLPoolAllocator_ManyElemsStatic::allocator = new LargeAllocator(); - } - return static_cast(STLPoolAllocator_ManyElemsStatic::allocator->Allocate()); - } - else - { - return static_cast(CryModuleMalloc(n * sizeof(T))); - } - } - - void deallocate(pointer p, size_type n = 1) - { - if (n == 1) - { - Super::deallocate(p); - } - else if (n * sizeof(T) <= LargeAllocationSizeThreshold) - { - STLPoolAllocator_ManyElemsStatic::allocator->Deallocate(p); - } - else - { - CryModuleFree(p); - } - } - }; - - template - PoolAllocator* STLPoolAllocator_ManyElemsStatic::allocator; -} - -#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H diff --git a/Code/CryEngine/CryCommon/ScopeGuard.h b/Code/CryEngine/CryCommon/ScopeGuard.h deleted file mode 100644 index c56c49fd18..0000000000 --- a/Code/CryEngine/CryCommon/ScopeGuard.h +++ /dev/null @@ -1,188 +0,0 @@ -/* -* 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. -* -*/ -#pragma once - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define SCOPEGUARD_H_SECTION_1 1 -#define SCOPEGUARD_H_SECTION_2 2 -#endif - -/** -This is from the c++17 working draft paper N3949 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3949.pdf -It is a new library addition targeted for c++17. I didn't feel like waiting. Only modification is as required to get the -code compiling in the yet to be c++11 compliant visual studio. It is similar to boost scope exit, but in a modern and -more feature rich form. scope_guard just executes a lambda when it goes out of scope. unique_resource is a more complete -RAII wrapper. Its stands in for a resource (i.e. overloads cast operator to the wrapped resource) and frees it when it -goes out of scope. see the paper for more examples and a better description. Get rid of this once c++17 is available. -*/ -namespace std17 -{ - template - struct scope_guard_t - { - // construction - explicit scope_guard_t(D&& f) - : deleter(std::move(f)) - , execute_on_destruction(true) - { - } - // move - scope_guard_t(scope_guard_t&& rhs) - : deleter(std::move(rhs.deleter)) - , execute_on_destruction(rhs.execute_on_destruction) - { - rhs.release(); - } - // release - ~scope_guard_t() - { - if (execute_on_destruction) - { - deleter(); - } - } - void release() { execute_on_destruction = false; } - private: -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION SCOPEGUARD_H_SECTION_1 - #include AZ_RESTRICTED_FILE(ScopeGuard_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - scope_guard_t(scope_guard_t const&) = delete; - void operator=(scope_guard_t const&) = delete; - scope_guard_t& operator=(scope_guard_t&&) = delete; -#endif - D deleter; - bool execute_on_destruction; - // exposition only - }; - - template - scope_guard_t scope_guard(D&& deleter) - { - return scope_guard_t(std::move(deleter)); - // fails with curlies - } - - enum class invoke_it - { - once, again - }; - template - class unique_resource_t - { - R resource; - D deleter; - bool execute_on_destruction; - // exposition only -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION SCOPEGUARD_H_SECTION_2 - #include AZ_RESTRICTED_FILE(ScopeGuard_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - unique_resource_t& operator=(unique_resource_t const&) = delete; - unique_resource_t(unique_resource_t const&) = delete; -#endif - // no copies! - public: - // construction - explicit unique_resource_t(R&& _resource, D&& _deleter, bool _shouldrun = true) - : resource(std::move(_resource)) - , deleter(std::move(_deleter)) - , execute_on_destruction(_shouldrun) - { - } - // move - unique_resource_t(unique_resource_t&& other) - : resource(std::move(other.resource)) - , deleter(std::move(other.deleter)) - , execute_on_destruction(other.execute_on_destruction) - { - other.release(); - } - unique_resource_t& operator=(unique_resource_t&& other) - { - this->invoke(invoke_it::once); - deleter = std::move(other.deleter); - resource = std::move(other.resource); - execute_on_destruction = other.execute_on_destruction; - other.release(); - return *this; - } - // resource release - ~unique_resource_t() - { - this->invoke(invoke_it::once); - } - void invoke(invoke_it const strategy = invoke_it::once) - { - if (execute_on_destruction) - { - get_deleter()(resource); - } - execute_on_destruction = strategy == invoke_it::again; - } - R const& release() - { - execute_on_destruction = false; - return this->get(); - } - void reset(R&& newresource) - { - invoke(invoke_it::again); - resource = std::move(newresource); - } - // resource access - R const& get() const - { - return resource; - } - operator R const& () const - { - return resource; - } - R operator->() const - { - return resource; - } - typename std::add_lvalue_reference::type>::type operator*() const - { - return *resource; - } - // deleter access - const D& get_deleter() const - { - return deleter; - } - }; - - template - unique_resource_t unique_resource(R&& r, D t) - { - return unique_resource_t(std::move(r), std::move(t), true); - } - - template - unique_resource_t unique_resource_checked(R r, R invalid, D t) - { - bool shouldrun = (r != invalid); - return unique_resource_t(std::move(r), std::move(t), shouldrun); - } -} - diff --git a/Code/CryEngine/CryCommon/Serialization/Assert.h b/Code/CryEngine/CryCommon/Serialization/Assert.h deleted file mode 100644 index a1ce890dc8..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Assert.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H -#pragma once - -#ifdef SERIALIZATION_STANDALONE -#include -#else -#include -#endif - -#ifdef YASLI_ASSERT -# undef YASLI_ASSERT -#endif - -#ifdef YASLI_VERIFY -# undef YASLI_VERIFY -#endif - -#ifdef YASLI_ESCAPE -# undef YASLI_ESCAPE -#endif - -#ifdef SERIALIZATION_STANDALONE -#define YASLI_ASSERT(x) assert(x) -#define YASLI_ASSERT_STR(x, str) assert(x && str) -#define YASLI_ESCAPE(x, action) if (!(x)) { YASLI_ASSERT(0 && #x); action; }; -#else -#define YASLI_ASSERT(x) CRY_ASSERT(x) -#define YASLI_ASSERT_STR(x, str) CRY_ASSERT_MESSAGE(x, str) -#define YASLI_ESCAPE(x, action) if (!(x)) { YASLI_ASSERT(0 && #x); action; }; -#endif // SERIALIZATION_STANDALONE - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H diff --git a/Code/CryEngine/CryCommon/Serialization/BitVector.h b/Code/CryEngine/CryCommon/Serialization/BitVector.h deleted file mode 100644 index 06cb3b956a..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BitVector.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2012 Crytek GmbH -// Authors: Evgeny Andreeshchev, Alexander Kotliar -// Based on: Yasli - the serialization library. -// Modifications copyright Amazon.com, Inc. or its affiliates - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H -#pragma once - - -namespace Serialization{ - -class IArchive; -template -class BitVector -{ -public: - BitVector(int value = 0) : value_(value) {} - - operator int&() { return value_; } - operator int() const { return value_; } - - BitVector& operator|= (Enum value) { value_ |= value; return *this; } - BitVector& operator|= (int value) { value_ |= value; return *this; } - BitVector& operator&= (int value) { value_ &= value; return *this; } - - void Serialize(IArchive& ar); -private: - int value_; -}; - -template -bool Serialize(Serialization::IArchive& ar, Serialization::BitVector& value, const char* name, const char* label); - -} - -#include "BitVectorImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H diff --git a/Code/CryEngine/CryCommon/Serialization/BitVectorImpl.h b/Code/CryEngine/CryCommon/Serialization/BitVectorImpl.h deleted file mode 100644 index 1d5c02342c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BitVectorImpl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H -#pragma once - -#include "Serialization/BitVector.h" -#include "Serialization/IArchive.h" -#include "Serialization/Enum.h" - -namespace Serialization { - struct BitVectorWrapper - { - int* valuePointer; - int value; - const CEnumDescription* description; - - explicit BitVectorWrapper(int* _value = 0, const CEnumDescription* _description = 0) - : valuePointer(_value) - , description(_description) - { - if (valuePointer) - { - value = *valuePointer; - } - } - BitVectorWrapper(const BitVectorWrapper& _rhs) - : value(_rhs.value) - , description(0) - , valuePointer(0) - { - } - - ~BitVectorWrapper() - { - if (valuePointer) - { - * valuePointer = value; - } - } - BitVectorWrapper& operator=(const BitVectorWrapper& rhs) - { - value = rhs.value; - return *this; - } - - - void Serialize(IArchive& ar) - { - ar(value, "value", "Value"); - } - }; - - template - void BitVector::Serialize(IArchive& ar) - { - ar(value_, "value", "Value"); - } -} - -template -bool Serialize(Serialization::IArchive& ar, Serialization::BitVector& value, const char* name, const char* label) -{ - using namespace Serialization; - CEnumDescription& desc = getEnumDescription(); - if (ar.IsEdit()) - { - return ar(BitVectorWrapper(&static_cast(value), &desc), name, label); - } - else - { - return desc.serializeBitVector(ar, static_cast(value), name, label); - } -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/BlackBox.h b/Code/CryEngine/CryCommon/Serialization/BlackBox.h deleted file mode 100644 index 7efbbf7ece..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BlackBox.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H -#pragma once - -#include // for malloc and free - -namespace Serialization -{ - // Black box is used to store opaque data blobs in a format internal to - // specific Archive. For example it can be used to store sections of the JSON - // or binary archive. - // - // This is useful for the Editor to store portions of files with unfamiliar - // structure. - // - // We store deallocation function here so we can safely pass the blob - // across DLLs with different memory allocators. - struct SBlackBox - { - const char* format; - void* data; - size_t size; - typedef void(* FreeFunction)(void*); - FreeFunction freeFunction; - - SBlackBox() - : format("") - , data(0) - , size(0) - , freeFunction(0) - { - } - - SBlackBox(const SBlackBox& rhs) - : format("") - , data(0) - , size(0) - , freeFunction(0) - { - *this = rhs; - } - - void set(const char* _format, const void* _data, size_t _size) - { - if (_data && freeFunction) - { - freeFunction(this->data); - this->data = 0; - this->size = 0; - freeFunction = 0; - } - this->format = _format; - if (_data && _size) - { - this->data = CryModuleMalloc(_size); - memcpy(this->data, _data, _size); - this->size = _size; - freeFunction = &Free; - } - } - - SBlackBox& operator=(const SBlackBox& rhs) - { - set(rhs.format, rhs.data, rhs.size); - return *this; - } - - ~SBlackBox() - { - set("", 0, 0); - } - - static void Free(void* ptr) - { - CryModuleFree(ptr); - } - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H diff --git a/Code/CryEngine/CryCommon/Serialization/BoostSharedPtr.h b/Code/CryEngine/CryCommon/Serialization/BoostSharedPtr.h deleted file mode 100644 index 7d1d8591d0..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/BoostSharedPtr.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -#include "ClassFactory.h" - -template -class BoostSharedPtrSerializer - : public Serialization::IPointer -{ -public: - BoostSharedPtrSerializer(AZStd::shared_ptr& ptr) - : m_ptr(ptr) - { - } - - const char* registeredTypeName() const override - { - if (m_ptr) - { - return factoryOverride().getRegisteredTypeName(m_ptr.get()); - } - else - { - return ""; - } - } - - void create(const char* registeredTypeName) const override - { - CRY_ASSERT(!m_ptr || m_ptr.use_count() == 1); - if (registeredTypeName && registeredTypeName[0] != '\0') - { - m_ptr.reset(factoryOverride().create(registeredTypeName)); - } - else - { - m_ptr.reset(); - } - } - - Serialization::TypeID baseType() const override - { - return Serialization::TypeID::get(); - } - - virtual Serialization::SStruct serializer() const override - { - return Serialization::SStruct(*m_ptr); - } - - void* get() const - { - return reinterpret_cast(m_ptr.get()); - } - - const void* handle() const - { - return &m_ptr; - } - - Serialization::TypeID pointerType() const override - { - return Serialization::TypeID::get >(); - } - - Serialization::ClassFactory* factory() const override - { - return &factoryOverride(); - } - - virtual Serialization::ClassFactory& factoryOverride() const - { - return Serialization::ClassFactory::the(); - } - -protected: - AZStd::shared_ptr& m_ptr; -}; - -namespace AZStd -{ - template - bool Serialize(Serialization::IArchive& ar, AZStd::shared_ptr& ptr, const char* name, const char* label) - { - BoostSharedPtrSerializer serializer(ptr); - return ar(static_cast(serializer), name, label); - } -} diff --git a/Code/CryEngine/CryCommon/Serialization/CRCRef.h b/Code/CryEngine/CryCommon/Serialization/CRCRef.h deleted file mode 100644 index b26195dd99..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CRCRef.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H -#pragma once - -template -struct SCRCRef; - -namespace Serialization -{ - class IArchive; -} - -template -bool Serialize(Serialization::IArchive& ar, SCRCRef& crcRef, const char* name, const char* label); - -#include "CRCRefImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H diff --git a/Code/CryEngine/CryCommon/Serialization/CRCRefImpl.h b/Code/CryEngine/CryCommon/Serialization/CRCRefImpl.h deleted file mode 100644 index 28b0f4305b..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CRCRefImpl.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H -#pragma once - -#include "IArchive.h" -#include "Serializer.h" - -template -class CRCRefSerializer - : public Serialization::IString -{ -public: - CRCRefSerializer(TCRCRef& crcRef) - : m_crcRef(crcRef) - { - } - - virtual void set(const char* value) - { - m_crcRef.SetByString(value); - } - - virtual const char* get() const - { - return m_crcRef.c_str(); - } - - const void* handle() const - { - return &m_crcRef; - } - - Serialization::TypeID type() const - { - return Serialization::TypeID::get(); - } - - - TCRCRef& m_crcRef; -}; - - -template -class CCRCRefSerializerNoStrings -{ -public: - CCRCRefSerializerNoStrings(struct SCRCRef& crcRef) - : crc(crcRef.crc) - { - } - - bool Serialize(Serialization::IArchive& ar) - { - return ar(crc, "CRC", "CRC"); - } - - typedef typename THash::TInt TInt; - TInt& crc; -}; - - - -template -bool Serialize(Serialization::IArchive& ar, struct SCRCRef& crcRef, const char* name, const char* label) -{ - if (StoreStrings == 0) - { - if (ar.IsInput()) - { - SCRCRef crcCopy; - ar(CCRCRefSerializerNoStrings(crcCopy), name, label); - if (crcCopy.crc != THash::INVALID) - { - crcRef = crcCopy; - return true; - } - } - else if (ar.IsOutput()) - { - return ar(CCRCRefSerializerNoStrings(crcRef), name, label); - } - } - - CRCRefSerializer > crcRefSerializer(crcRef); - return ar(static_cast(crcRefSerializer), name, label); -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Callback.h b/Code/CryEngine/CryCommon/Serialization/Callback.h deleted file mode 100644 index 0a0ce2b7f8..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Callback.h +++ /dev/null @@ -1,184 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H -#pragma once - -#include - -namespace Serialization -{ - struct ICallback - { - virtual bool SerializeValue(IArchive& ar, const char* name, const char* value) = 0; - virtual ICallback* Clone() = 0; - virtual void Release() = 0; - virtual TypeID Type() const = 0; - - typedef AZStd::function ApplyFunction; - virtual void Call(const ApplyFunction&) = 0; - }; - - template - struct CallbackSimple - : ICallback - { - typedef AZStd::function CallbackFunction; - T* value; - T oldValue; - CallbackFunction callback; - - CallbackSimple(T* value, const T& oldValue, const AZStd::function& callback) - : value(value) - , oldValue(oldValue) - , callback(callback) - { - } - - ICallback* Clone() { return new CallbackSimple(0, oldValue, callback); } - void Release() { delete this; } - bool SerializeValue(IArchive& ar, const char* name, const char* label) { return ar(*value, name, label); } - TypeID Type() const{ return TypeID::get(); } - - void Call(const ApplyFunction& applyFunction) - { - T newValue; - applyFunction((void*)&newValue, TypeID::get()); - if (oldValue != newValue) - { - callback(newValue); - oldValue = newValue; - } - } - }; - - template - struct CallbackWithDecorator - : ICallback - { - typedef AZStd::function CallbackFunction; - typedef AZStd::function DecoratorFunction; - - T oldValue; - T* value; - CallbackFunction callback; - DecoratorFunction decorator; - - CallbackWithDecorator(T* value, - const T& oldValue, - const CallbackFunction& callback, - const DecoratorFunction& decorator) - : value(value) - , oldValue(oldValue) - , callback(callback) - , decorator(decorator) - { - } - - ICallback* Clone() { return new CallbackWithDecorator(0, oldValue, callback, decorator); } - void Release() { delete this; } - bool SerializeValue(IArchive& ar, const char* name, const char* label) { return ar(decorator(*value), name, label); } - TypeID Type() const{ return TypeID::get(); } - - void Call(const ApplyFunction& applyFunction) - { - T newValue; - Decorator dec = decorator(newValue); - applyFunction((void*)&dec, TypeID::get()); - if (oldValue != newValue) - { - callback(newValue); - oldValue = newValue; - } - } - }; - - - - namespace Detail - { - template - struct MethodReturnType - { - typedef void type; - }; - - template - struct MethodReturnType - { - typedef ReturnType type; - }; - - template - struct OperatorBracketsReturnType - { - typedef typename MethodReturnType::type Type; - }; - } - - template - CallbackSimple - Callback(T& value, const CallbackFunc& callback) - { - return CallbackSimple(&value, value, AZStd::function(callback)); - } - - - template - CallbackWithDecorator::Type> - Callback(T& value, const CallbackFunc& callback, const DecoratorFunc& decorator) - { - typedef typename Detail::OperatorBracketsReturnType::Type Decorator; - return CallbackWithDecorator(&value, value, - AZStd::function(callback), - AZStd::function(decorator)); - } - - - template - bool Serialize(IArchive& ar, CallbackSimple& callback, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(static_cast(callback), name, label); - } - else - { - if (!ar(*callback.value, name, label)) - { - return false; - } - return true; - } - } - - template - bool Serialize(IArchive& ar, CallbackWithDecorator& callback, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(static_cast(callback), name, label); - } - else - { - if (!ar(*callback.value, name, label)) - { - return false; - } - return true; - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H diff --git a/Code/CryEngine/CryCommon/Serialization/ClassFactory.h b/Code/CryEngine/CryCommon/Serialization/ClassFactory.h deleted file mode 100644 index 4734a566eb..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ClassFactory.h +++ /dev/null @@ -1,376 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H -#pragma once - -#include -#include - -#include "Serialization/Assert.h" -#include "Serialization/IClassFactory.h" -#include "Serialization/TypeID.h" - -namespace Serialization { - class IArchive; - - class ClassFactoryManager - { - public: - static ClassFactoryManager& the() - { - static ClassFactoryManager factoryManager; - return factoryManager; - } - - const IClassFactory* find(TypeID baseType) const - { - lazyRegisterFactories(); - Factories::const_iterator it = factories_.find(baseType); - if (it == factories_.end()) - { - return 0; - } - else - { - return it->second; - } - } - - void registerFactory([[maybe_unused]] TypeID type, IClassFactory* factory) - { - factory->m_next = m_head; - m_head = factory; - } - protected: - void lazyRegisterFactories() const - { - if (m_head) - { - IClassFactory* factory = m_head; - while (factory) - { - const_cast(this)->factories_[factory->baseType_] = factory; - factory = factory->m_next; - } - const_cast(this)->m_head = nullptr; - } - } - - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> Factories; - Factories factories_; - IClassFactory* m_head = nullptr; - }; - - template - class ClassFactory - : public IClassFactory - { - public: - static ClassFactory& the() - { - static AZStd::aligned_storage_for_t storage; - if (s_instance != (decltype(s_instance))&storage) - { - s_instance = new(&storage) ClassFactory(); - } - return *s_instance; - } - - static void destroy() - { - if (s_instance) - { - s_instance->~ClassFactory(); - s_instance = nullptr; - } - } - - class CreatorBase - { - public: - virtual ~CreatorBase() {} - virtual BaseType* create() const = 0; - virtual const TypeDescription& description() const{ return *description_; } - virtual void* vptr() const { return vptr_; } - virtual TypeID typeID() const = 0; - protected: - const TypeDescription* description_ = nullptr; - void* vptr_ = nullptr; - public: - CreatorBase* next; - }; - - static void* extractVPtr(BaseType* ptr) - { - return *((void**)ptr); - } - - template - struct Annotation - { - Annotation(IClassFactory* factory, const char* name, const char* value) { static_cast*>(factory)->addAnnotation(name, value); } - }; - - template - class Creator - : public CreatorBase - { - public: - Creator(const TypeDescription* description, ClassFactory* factory = nullptr) - { - this->description_ = description; - - if (!factory) - { - factory = &ClassFactory::the(); - } - - factory->registerCreator(this); - } - - void* vptr() const override - { - if (!this->vptr_) - { - Derived vptrProbe; - const_cast(this)->vptr_ = extractVPtr(&vptrProbe); - } - return this->vptr_; - } - - BaseType* create() const override { return new Derived(); } - TypeID typeID() const override { return Serialization::TypeID::get(); } - }; - - ClassFactory() - : IClassFactory(TypeID::get()) - { - ClassFactoryManager::the().registerFactory(baseType_, this); - } - - ~ClassFactory() - { - m_data->~Data(); - m_data = nullptr; - } - - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> TypeToCreatorMap; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> VPtrToCreatorMap; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> RegisteredNameToTypeID; - typedef AZStd::unordered_map >, AZStd::hash, AZStd::equal_to, AZ::StdLegacyAllocator> AnnotationMap; - - virtual BaseType* create(const char* registeredName) const - { - lazyRegisterCreators(); - if (!registeredName) - { - return 0; - } - if (registeredName[0] == '\0') - { - return 0; - } - typename TypeToCreatorMap::const_iterator it = m_data->typeToCreatorMap_.find(registeredName); - if (it != m_data->typeToCreatorMap_.end()) - { - return it->second->create(); - } - else - { - return 0; - } - } - - virtual const char* getRegisteredTypeName(BaseType* ptr) const - { - lazyRegisterCreators(); - if (ptr == 0) - { - return ""; - } - void* vptr = extractVPtr(ptr); - typename VPtrToCreatorMap::const_iterator it = m_data->vptrToCreatorMap_.find(vptr); - if (it == m_data->vptrToCreatorMap_.end()) - { - return ""; - } - return it->second->description().name(); - } - - BaseType* createByIndex(int index) const - { - lazyRegisterCreators(); - YASLI_ASSERT(size_t(index) < m_data->creators_.size()); - return m_data->creators_[index]->create(); - } - - void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label) - { - lazyRegisterCreators(); - YASLI_ESCAPE(size_t(index) < m_data->creators_.size(), return ); - BaseType* ptr = m_data->creators_[index]->create(); - ar(*ptr, name, label); - delete ptr; - } - // from ClassFactoryInterface: - size_t size() const{ return m_data->creators_.size(); } - const TypeDescription* descriptionByIndex(int index) const override - { - lazyRegisterCreators(); - if (size_t(index) >= int(m_data->creators_.size())) - { - return 0; - } - return &m_data->creators_[index]->description(); - } - - const TypeDescription* descriptionByRegisteredName(const char* name) const override - { - lazyRegisterCreators(); - const size_t numCreators = m_data->creators_.size(); - for (size_t i = 0; i < numCreators; ++i) - { - if (strcmp(m_data->creators_[i]->description().name(), name) == 0) - { - return &m_data->creators_[i]->description(); - } - } - return 0; - } - // ^^^ - - TypeID typeIDByRegisteredName(const char* registeredTypeName) const - { - lazyRegisterCreators(); - RegisteredNameToTypeID::const_iterator it = m_data->registeredNameToTypeID_.find(registeredTypeName); - if (it == m_data->registeredNameToTypeID_.end()) - { - return TypeID(); - } - return it->second; - } - - const char* findAnnotation(const char* registeredTypeName, const char* name) const - { - lazyRegisterCreators(); - TypeID typeID = typeIDByRegisteredName(registeredTypeName); - AnnotationMap::const_iterator it = m_data->annotations_.find(typeID); - if (it == m_data->annotations_.end()) - { - return ""; - } - for (size_t i = 0; i < it->second.size(); ++i) - { - if (strcmp(it->second[i].first, name) == 0) - { - return it->second[i].second; - } - } - return ""; - } - void unregisterCreator(const TypeDescription& typeDescription) - { - auto creator = m_data->typeToCreatorMap_.find(typeDescription.name()); - if (creator != m_data->typeToCreatorMap_.end()) - { - m_data->creators_.erase(std::find(m_data->creators_.begin(), m_data->creators_.end(), m_data->creator->second)); - m_data->vptrToCreatorMap_.erase(m_data->vptrToCreatorMap_.find(creator->second->vptr())); - m_data->typeToCreatorMap_.erase(creator); - } - } - - protected: - virtual void registerCreator(CreatorBase* creator) - { - creator->next = creatorsList; - creatorsList = creator; - } - - void lazyRegisterCreators() const - { - if (!m_data) - { - const_cast(this)->m_data = ::new((void*)&m_dataStorage) Data(); - for (CreatorBase* creator = creatorsList; creator; creator = creator->next) - { - if (!const_cast(this)->m_data->typeToCreatorMap_.insert(AZStd::make_pair(creator->description().name(), creator)).second) - { - YASLI_ASSERT(0 && "Type registered twice in the same factory. Was SERIALIZATION_CLASS_NAME put into header file by mistake?"); - } - const_cast(this)->m_data->creators_.push_back(creator); - const_cast(this)->m_data->registeredNameToTypeID_[creator->description().name()] = creator->typeID(); - const_cast(this)->m_data->vptrToCreatorMap_[creator->vptr()] = creator; - } - } - } - - template - void addAnnotation(const char* name, const char* value) - { - addAnnotation(Serialization::TypeID::get(), name, value); - } - - virtual void addAnnotation(const Serialization::TypeID& id, const char* name, const char* value) - { - lazyRegisterCreators(); - m_data->annotations_[id].push_back(std::make_pair(name, value)); - } - - CreatorBase* creatorsList = nullptr; - static ClassFactory* s_instance; - - struct Data - { - TypeToCreatorMap typeToCreatorMap_; - AZStd::vector creators_; - VPtrToCreatorMap vptrToCreatorMap_; - RegisteredNameToTypeID registeredNameToTypeID_; - AnnotationMap annotations_; - }; - Data* m_data = nullptr; - AZStd::aligned_storage_for_t m_dataStorage; - }; - - template - ClassFactory* ClassFactory::s_instance = nullptr; -} - -#define SERIALIZATION_CLASS_NULL(BaseType, name) \ - namespace { \ - bool BaseType##_NullRegistered = Serialization::ClassFactory::the().setNullLabel(name); \ - } - -#define SERIALIZATION_CLASS_NAME(BaseType, Type, name, label) \ - static const Serialization::TypeDescription Type##BaseType##_DerivedDescription(name, label); \ - static Serialization::ClassFactory::Creator Type##BaseType##_Creator(&Type##BaseType##_DerivedDescription); \ - int dummyForType_##Type##BaseType; - -#define SERIALIZATION_CLASS_NAME_FOR_FACTORY(Factory, BaseType, Type, name, label) \ - static const Serialization::TypeDescription Type##BaseType##_DerivedDescription(name, label); \ - static Serialization::ClassFactory::Creator Type##BaseType##_Creator(&Type##BaseType##_DerivedDescription, &(Factory)); - -#define SERIALIZATION_CLASS_ANNOTATION(BaseType, Type, attributeName, attributeValue) \ - static Serialization::ClassFactory::Annotation Type##BaseType##_Annotation(&Serialization::ClassFactory::the(), attributeName, attributeValue); - -#define SERIALIZATION_CLASS_ANNOTATION_FOR_FACTORY(factory, BaseType, Type, attributeName, attributeValue) \ - static Serialization::ClassFactory::Annotation Type##BaseType##_Annotation(&factory, attributeName, attributeValue); - -#define SERIALIZATION_FORCE_CLASS(BaseType, Type) \ - extern int dummyForType_##Type##BaseType; \ - int* dummyForTypePtr_##Type##BaseType = &dummyForType_##Type##BaseType + 1; - -#include "ClassFactoryImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H diff --git a/Code/CryEngine/CryCommon/Serialization/ClassFactoryImpl.h b/Code/CryEngine/CryCommon/Serialization/ClassFactoryImpl.h deleted file mode 100644 index f3d034fb51..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ClassFactoryImpl.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H -#pragma once - -#include "IArchive.h" -#include "IClassFactory.h" -#include "STL.h" -#include "ClassFactory.h" -#include "Strings.h" - -namespace Serialization { - inline bool Serialize(Serialization::IArchive& ar, Serialization::TypeNameWithFactory& value, const char* name, [[maybe_unused]] const char* label) - { - if (!ar(value.registeredName, name)) - { - return false; - } - - if (ar.IsInput()) - { - const TypeDescription* desc = value.factory->descriptionByRegisteredName(value.registeredName.c_str()); - if (!desc) - { - ar.Error(value, "Unable to read TypeID: unregistered type name: \'%s\'", value.registeredName.c_str()); - value.registeredName.clear(); - return false; - } - } - return true; - } -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Color.h b/Code/CryEngine/CryCommon/Serialization/Color.h deleted file mode 100644 index 1b4f612bcd..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Color.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H -#pragma once - -#include -#include - -template -inline bool Serialize(Serialization::IArchive& ar, Color_tpl& c, const char* name, const char* label); - -namespace Serialization -{ - struct Vec3AsColor - { - Vec3& v; - Vec3AsColor(Vec3& v) - : v(v) {} - - void Serialize(Serialization::IArchive& ar) - { - ar(Range(v.x, 0.0f, 1.0f), "r", "^"); - ar(Range(v.y, 0.0f, 1.0f), "g", "^"); - ar(Range(v.z, 0.0f, 1.0f), "b", "^"); - } - }; - - inline bool Serialize(Serialization::IArchive& ar, Vec3AsColor& c, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct(c), name, label); - } - else - { - typedef float (* Array)[3]; - return ar(*((Array) & c.v.x), name, label); - } - } -} - -#include "ColorImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H diff --git a/Code/CryEngine/CryCommon/Serialization/ColorImpl.h b/Code/CryEngine/CryCommon/Serialization/ColorImpl.h deleted file mode 100644 index cf7f5886d7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ColorImpl.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H -#pragma once - -#include "Color.h" - -////////////////////////////////////////////////////////////////////////// -template -struct SerializableColor_tpl - : Color_tpl -{ - static float ColorRangeMin(float) { return 0.0f; } - static float ColorRangeMax(float) { return 1.0f; } - static unsigned char ColorRangeMin(unsigned char) { return 0; } - static unsigned char ColorRangeMax(unsigned char) { return 255; } - - void Serialize(Serialization::IArchive& ar) - { - ar(Serialization::Range(Color_tpl::r, ColorRangeMin(Color_tpl::r), ColorRangeMax(Color_tpl::r)), "r", "^"); - ar(Serialization::Range(Color_tpl::g, ColorRangeMin(Color_tpl::g), ColorRangeMax(Color_tpl::g)), "g", "^"); - ar(Serialization::Range(Color_tpl::b, ColorRangeMin(Color_tpl::b), ColorRangeMax(Color_tpl::b)), "b", "^"); - ar(Serialization::Range(Color_tpl::a, ColorRangeMin(Color_tpl::a), ColorRangeMax(Color_tpl::a)), "a", "^"); - } -}; - -template -bool Serialize(Serialization::IArchive& ar, Color_tpl& c, const char* name, const char* label) -{ - if (ar.IsEdit()) - { - return Serialize(ar, static_cast&>(c), name, label); - } - else - { - typedef T (& Array)[4]; - return ar((Array)c, name, label); - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryExtension.h b/Code/CryEngine/CryCommon/Serialization/CryExtension.h deleted file mode 100644 index ed4e99fba1..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryExtension.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H -#pragma once - -#ifdef GetClassName -#undef GetClassName -#endif -#include - -namespace Serialization -{ - // Allows to have AZStd::shared_ptr but serialize it by - // interface-casting to TSerializable, i.e. implementing Serialization through - // separate interface. - template - struct CryExtensionPointer - { - AZStd::shared_ptr& ptr; - - CryExtensionPointer(AZStd::shared_ptr& _ptr) - : ptr(_ptr) {} - void Serialize(Serialization::IArchive& ar); - }; -} - -// This function treats T as a type derived from CryUnknown type. -template -bool Serialize(Serialization::IArchive& ar, AZStd::shared_ptr& ptr, const char* name, const char* label); - -#include "CryExtensionImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryExtensionImpl.h b/Code/CryEngine/CryCommon/Serialization/CryExtensionImpl.h deleted file mode 100644 index e976163d55..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryExtensionImpl.h +++ /dev/null @@ -1,281 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H -#pragma once - -#include -#include -#include -#include - -namespace Serialization { - // Generate user-friendly class name, e.g. convert - // "AnimationPoseModifier_FootStore" -> "Foot Store" - inline string MakePrettyClassName(const char* className) - { - const char* firstSep = strchr(className, '_'); - if (!firstSep) - { - // name doesn't follow expected convention, return as is - return className; - } - - const char* start = firstSep + 1; - string result; - result.reserve(strlen(start) + 4); - - const char* p = start; - while (*p != '\0') - { - if (*p >= 'A' && *p <= 'Z' && - *(p - 1) >= 'a' && *(p - 1) <= 'z') - { - result += ' '; - } - if (*p == '_') - { - result += ' '; - } - else - { - result += *p; - } - ++p; - } - - return result; - } - - // Provides Serialization::IClassFactory interface for classes - // registered with CryExtension to IArchive. - // - // TSerializable can be used to expose Serialize method through - // a separate interface, rathern than TBase. Safe to missing - // as QueryInterface is used to check its presence. - template - class CryExtensionClassFactory - : public Serialization::IClassFactory - { - public: - size_t size() const override - { - return m_types.size(); - } - - static CryExtensionClassFactory& the() - { - static CryExtensionClassFactory instance; - return instance; - } - - CryExtensionClassFactory() - : IClassFactory(Serialization::TypeID::get()) - { - setNullLabel("[ None ]"); - ICryFactoryRegistry* factoryRegistry = gEnv->pSystem->GetCryFactoryRegistry(); - - size_t factoryCount = 0; - factoryRegistry->IterateFactories(cryiidof(), 0, factoryCount); - - if (factoryCount) - { - string sharedPrefix; - bool hasSharedPrefix = true; - AZStd::unique_ptr factories(new ICryFactory*[factoryCount]); - factoryRegistry->IterateFactories(cryiidof(), factories.get(), factoryCount); - - for (size_t i = 0; i < factoryCount; ++i) - { - ICryFactory* factory = factories[i]; - if (factory->ClassSupports(cryiidof())) - { - m_factories.push_back(factory); - if (hasSharedPrefix) - { - // make sure that shared prefix is the same for all the names - const char* name = factory->GetName(); - const char* lastPrefixCharacter = strchr(name, '_'); - if (lastPrefixCharacter == 0) - { - hasSharedPrefix = false; - } - else - { - if (!sharedPrefix.empty()) - { - if (strncmp(name, sharedPrefix.c_str(), sharedPrefix.size()) != 0) - { - hasSharedPrefix = false; - } - } - else - { - sharedPrefix.assign(name, lastPrefixCharacter + 1); - } - } - } - } - } - - size_t usableFactoriesCount = m_factories.size(); - m_types.reserve(usableFactoriesCount); - m_labels.reserve(usableFactoriesCount); - - for (size_t i = 0; i < usableFactoriesCount; ++i) - { - ICryFactory* factory = m_factories[i]; - m_classIds.push_back(factory->GetClassID()); - const char* name = factory->GetName(); - m_labels.push_back(MakePrettyClassName(name)); - if (hasSharedPrefix) - { - name += sharedPrefix.size(); - } - m_types.push_back(Serialization::TypeDescription(name, m_labels.back().c_str())); - } - } - } - - const Serialization::TypeDescription* descriptionByIndex(int index) const override - { - if (size_t(index) >= m_types.size()) - { - return 0; - } - return &m_types[index]; - } - - const Serialization::TypeDescription* descriptionByRegisteredName(const char* registeredName) const override - { - size_t count = m_types.size(); - for (size_t i = 0; i < m_types.size(); ++i) - { - if (strcmp(m_types[i].name(), registeredName) == 0) - { - return &m_types[i]; - } - } - return 0; - } - - const char* findAnnotation(const char* typeName, const char* name) const override { return ""; } - - void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label) override - { - if (size_t(index) >= m_types.size()) - { - return; - } - AZStd::shared_ptr ptr(create(m_types[index].name())); - if (TSerializable* ser = cryinterface_cast(ptr.get())) - { - ar(*ser, name, label); - } - } - - AZStd::shared_ptr create(const char* registeredName) - { - size_t count = m_types.size(); - for (size_t i = 0; i < count; ++i) - { - if (strcmp(m_types[i].name(), registeredName) == 0) - { - return AZStd::static_pointer_cast(m_factories[i]->CreateClassInstance()); - } - } - return AZStd::shared_ptr(); - } - - const char* getRegisteredTypeName(const AZStd::shared_ptr& ptr) const - { - if (!ptr.get()) - { - return ""; - } - CryInterfaceID id = AZStd::static_pointer_cast(ptr)->GetFactory()->GetClassID(); - size_t count = m_classIds.size(); - for (size_t i = 0; i < count; ++i) - { - if (m_classIds[i] == id) - { - return m_types[i].name(); - } - } - return ""; - } - - private: - std::vector m_types; - std::vector m_labels; - std::vector m_factories; - std::vector m_classIds; - }; - - // Exposes CryExtension shared_ptr<> as serializeable type for Serialization::IArchive - template - class CryExtensionSharedPtr - : public Serialization::IPointer - { - public: - CryExtensionSharedPtr(AZStd::shared_ptr& ptr) - : m_ptr(ptr) - {} - - const char* registeredTypeName() const override - { - if (m_ptr) - { - return factory()->getRegisteredTypeName(m_ptr); - } - else - { - return ""; - } - } - - void create(const char* registeredTypeName) const override - { - if (registeredTypeName[0] != '\0') - { - m_ptr = factory()->create(registeredTypeName); - } - else - { - m_ptr.reset((T*)0); - } - } - - Serialization::TypeID baseType() const{ return Serialization::TypeID::get(); } - virtual Serialization::SStruct serializer() const override - { - if (TSerializable* ser = cryinterface_cast(m_ptr.get())) - { - return Serialization::SStruct(*ser); - } - else - { - return Serialization::SStruct(); - } - } - void* get() const override { return reinterpret_cast(m_ptr.get()); } - const void* handle() const override { return &m_ptr; } - Serialization::TypeID pointerType() const override { return Serialization::TypeID::get >(); } - CryExtensionClassFactory* factory() const override { return &CryExtensionClassFactory::the(); } - protected: - AZStd::shared_ptr& m_ptr; - }; -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryName.h b/Code/CryEngine/CryCommon/Serialization/CryName.h deleted file mode 100644 index 978af33379..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryName.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H -#pragma once - -namespace Serialization { - class IArchive; -} - -inline bool Serialize(Serialization::IArchive & ar, class CCryName & cryName, const char* name, const char* label); - -#include "CryNameImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryNameImpl.h b/Code/CryEngine/CryCommon/Serialization/CryNameImpl.h deleted file mode 100644 index e307892fd3..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryNameImpl.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H -#pragma once - -#include "CryName.h" -#include "IArchive.h" - -class CryNameSerializer - : public Serialization::IString -{ -public: - CryNameSerializer(CCryName& s) - : m_s(s) - { - } - - virtual void set(const char* value) - { - m_s = value; - } - - virtual const char* get() const - { - return m_s.c_str(); - } - - virtual const void* handle() const - { - return &m_s; - } - - virtual Serialization::TypeID type() const - { - return Serialization::TypeID::get(); - } - - CCryName& m_s; -}; - - -inline bool Serialize(Serialization::IArchive& ar, CCryName& cryName, const char* name, const char* label) -{ - CryNameSerializer serializer(cryName); - return ar(static_cast(serializer), name, label); -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/CryStrings.h b/Code/CryEngine/CryCommon/Serialization/CryStrings.h deleted file mode 100644 index 560f64c045..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryStrings.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "CryFixedString.h" - -#include "Serialization/Serializer.h" - -namespace Serialization -{ - class IArchive; -} - -// Note : if you are looking for the CryStringT serialization, it is handled in Serialization/STL.h - -template< size_t N > -bool Serialize(Serialization::IArchive& ar, CryFixedStringT< N >& value, const char* name, const char* label); - -template< size_t N > -bool Serialize(Serialization::IArchive& ar, CryStackStringT< char, N >& value, const char* name, const char* label); - -template< size_t N > -bool Serialize(Serialization::IArchive& ar, CryStackStringT< wchar_t, N >& value, const char* name, const char* label); - -#include "Serialization/CryStringsImpl.h" diff --git a/Code/CryEngine/CryCommon/Serialization/CryStringsImpl.h b/Code/CryEngine/CryCommon/Serialization/CryStringsImpl.h deleted file mode 100644 index 41de581b36..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/CryStringsImpl.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Serialization/IArchive.h" -#include "Serialization/CryStrings.h" - -namespace Serialization -{ - template< class TFixedStringClass > - class CFixedStringSerializer - : public IString - { - public: - CFixedStringSerializer(TFixedStringClass& str) - : str_(str) { } - - void set(const char* value) { str_ = value; } - const char* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - TFixedStringClass& str_; - }; - - template< class TFixedStringClass > - class CFixedWStringSerializer - : public IWString - { - public: - CFixedWStringSerializer(TFixedStringClass& str) - : str_(str) { } - - void set(const wchar_t* value) { str_ = value; } - const wchar_t* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - TFixedStringClass& str_; - }; -} - -template< size_t N > -inline bool Serialize(Serialization::IArchive& ar, CryFixedStringT< N >& value, const char* name, const char* label) -{ - Serialization::CFixedStringSerializer< CryFixedStringT< N > > str(value); - return ar(static_cast(str), name, label); -} - -template< size_t N > -inline bool Serialize(Serialization::IArchive& ar, CryStackStringT< char, N >& value, const char* name, const char* label) -{ - Serialization::CFixedStringSerializer< CryStackStringT< char, N > > str(value); - return ar(static_cast(str), name, label); -} - -template< size_t N > -inline bool Serialize(Serialization::IArchive& ar, CryStackStringT< wchar_t, N >& value, const char* name, const char* label) -{ - Serialization::CFixedWStringSerializer< CryStackStringT< wchar_t, N > > str(value); - return ar(static_cast(str), name, label); -} - diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ActionButton.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ActionButton.h deleted file mode 100644 index 2e8e07f597..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ActionButton.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include -#include - -namespace Serialization -{ - struct IActionButton; - - DECLARE_SMART_POINTERS(IActionButton) - - struct IActionButton - { - virtual ~IActionButton() {} - - virtual void Callback() const = 0; - virtual const char* Icon() const = 0; - virtual IActionButtonPtr Clone() const = 0; - }; - - typedef AZStd::function FunctorActionButtonCallback; - - struct FunctorActionButton - : public IActionButton - { - FunctorActionButtonCallback callback; - string icon; - - explicit FunctorActionButton(const FunctorActionButtonCallback& callback, const char* icon = "") - : callback(callback) - , icon(icon) - { - } - - // IActionButton - - virtual void Callback() const override - { - if (callback) - { - callback(); - } - } - - virtual const char* Icon() const override - { - return icon.c_str(); - } - - virtual IActionButtonPtr Clone() const override - { - return IActionButtonPtr(new FunctorActionButton(callback, icon.c_str())); - } - - // ~IActionButton - }; - - inline bool Serialize(Serialization::IArchive& ar, FunctorActionButton& button, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(button)), name, label); - } - else - { - return false; - } - } - - inline FunctorActionButton ActionButton(const FunctorActionButtonCallback& callback, const char* icon = "") - { - return FunctorActionButton(callback, icon); - } -} - diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlags.h b/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlags.h deleted file mode 100644 index 1e23ecee27..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlags.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H -#pragma once - -#include - -namespace Serialization { - class IArchive; - - struct BitFlagsWrapper - { - int* variable; - unsigned int visibleMask; - const CEnumDescription* description; - - void Serialize(IArchive& ar); - }; - - template - BitFlagsWrapper BitFlags(Enum& value) - { - BitFlagsWrapper wrapper; - wrapper.variable = (int*)&value; - wrapper.visibleMask = ~0U; - wrapper.description = &getEnumDescription(); - return wrapper; - } - - template - BitFlagsWrapper BitFlags(int& value, int visibleMask = ~0) - { - BitFlagsWrapper wrapper; - wrapper.variable = &value; - wrapper.visibleMask = visibleMask; - wrapper.description = &getEnumDescription(); - return wrapper; - } - - template - BitFlagsWrapper BitFlags(unsigned int& value, unsigned int visibleMask = ~0) - { - BitFlagsWrapper wrapper; - wrapper.variable = (int*)&value; - wrapper.visibleMask = visibleMask; - wrapper.description = &getEnumDescription(); - return wrapper; - } -} - -#include "BitFlagsImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlagsImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlagsImpl.h deleted file mode 100644 index 77b48fd1f0..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/BitFlagsImpl.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H -#pragma once - -#include "Serialization/IArchive.h" - -namespace Serialization { - inline void BitFlagsWrapper::Serialize(IArchive& ar) - { - const Serialization::CEnumDescription& desc = *description; - int count = desc.count(); - if (ar.IsInput()) - { - int previousValue = *variable; - for (int i = 0; i < count; ++i) - { - int flagValue = desc.valueByIndex(i); - if (!(flagValue & visibleMask)) - { - continue; - } - bool flag = (previousValue & flagValue) == flagValue; - bool previousFlag = flag; - ar(flag, desc.nameByIndex(i), desc.labelByIndex(i)); - if (flag != previousFlag) - { - if (flag) - { - *variable |= flagValue; - } - else - { - *variable &= ~flagValue; - } - } - } - } - else - { - for (int i = 0; i < count; ++i) - { - int flagValue = desc.valueByIndex(i); - if (!(flagValue & visibleMask)) - { - continue; - } - bool flag = (*variable & flagValue) == flagValue; - ar(flag, desc.nameByIndex(i), desc.labelByIndex(i)); - } - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPicker.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPicker.h deleted file mode 100644 index 146e7bf42f..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPicker.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H -#pragma once - -#include -#include - -#include - -namespace Serialization -{ - class IArchive; - - struct ColorPicker - { - ColorF* color; - - explicit ColorPicker(ColorF& color_) - : color(&color_) - { - } - - // the function should stay virtual to ensure cross-dll calls are using right heap - virtual void SetColor(const ColorF* color_){* color = *color_; } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::ColorPicker& value, const char* name, const char* label); -} // namespace Serialization - -#include "ColorPickerImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPickerImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPickerImpl.h deleted file mode 100644 index 6585f40a91..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ColorPickerImpl.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H -#pragma once - -#include "../Color.h" - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::ColorPicker& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.color, name, label); - } - } -} // namespace Serialization - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/JointName.h b/Code/CryEngine/CryCommon/Serialization/Decorators/JointName.h deleted file mode 100644 index 69195c20bf..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/JointName.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H -#pragma once - -#include -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/JointNameImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/JointNameImpl.h deleted file mode 100644 index ad168a92a3..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/JointNameImpl.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H -#pragma once - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrame.h b/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrame.h deleted file mode 100644 index 39841623f9..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrame.h +++ /dev/null @@ -1,117 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H -#pragma once - -#include -#include "Serialization/Math.h" - -namespace Serialization -{ - class IArchive; - - struct LocalPosition - { - Vec3* value; - int space; - const char* parentName; - const void* handle; - - LocalPosition(Vec3& _vec, int _space, const char* _parentName, const void* _handle) - : value(&_vec) - , space(_space) - , parentName(_parentName) - , handle(_handle) - { - } - - void Serialize(IArchive& ar); - }; - - struct LocalOrientation - { - Quat* value; - int space; - const char* parentName; - const void* handle; - - LocalOrientation(Quat& _vec, int _space, const char* _parentName, const void* _handle) - : value(&_vec) - , space(_space) - , parentName(_parentName) - , handle(_handle) - { - } - - void Serialize(IArchive& ar); - }; - - struct LocalFrame - { - Quat* rotation; - Vec3* position; - const char* parentName; - int rotationSpace; - int positionSpace; - const void* handle; - - LocalFrame(Quat* _rotation, int _rotationSpace, Vec3* _position, int _positionSpace, const char* _parentName, const void* _handle) - : rotation(_rotation) - , position(_position) - , parentName(_parentName) - , rotationSpace(_rotationSpace) - , positionSpace(_positionSpace) - , handle(_handle) - { - } - - void Serialize(IArchive& ar); - }; - - enum - { - SPACE_JOINT, - SPACE_ENTITY, - SPACE_JOINT_WITH_PARENT_ROTATION, - SPACE_JOINT_WITH_CHARACTER_ROTATION, - SPACE_SOCKET_RELATIVE_TO_JOINT, - SPACE_SOCKET_RELATIVE_TO_BINDPOSE - }; - - - - //position - inline LocalPosition LocalToEntity(Vec3& position, const void* handle = 0) - { - return LocalPosition(position, SPACE_ENTITY, "", handle ? handle : &position); - } - inline LocalPosition LocalToJoint(Vec3& position, const string& jointName, const void* handle = 0) - { - return LocalPosition(position, SPACE_JOINT, jointName.c_str(), handle ? handle : &position); - } - - inline LocalPosition LocalToJointCharacterRotation(Vec3& position, const string& jointName, const void* handle = 0) - { - return LocalPosition(position, SPACE_JOINT_WITH_CHARACTER_ROTATION, jointName.c_str(), handle ? handle : &position); - } - - bool Serialize(Serialization::IArchive& ar, Serialization::LocalPosition& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::LocalOrientation& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::LocalFrame& value, const char* name, const char* label); -} - -#include "LocalFrameImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrameImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrameImpl.h deleted file mode 100644 index 774cc06852..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/LocalFrameImpl.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAMEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAMEIMPL_H -#pragma once - -#include "LocalFrame.h" -#include "Serialization/IArchive.h" -#include "Serialization/MathImpl.h" - -namespace Serialization -{ - inline void LocalPosition::Serialize(Serialization::IArchive& ar) - { - ar(value->x, "x", "^"); - ar(value->y, "y", "^"); - ar(value->z, "z", "^"); - } - - inline void LocalOrientation::Serialize(Serialization::IArchive& ar) - { - ar(Serialization::AsAng3(*value), "q", "^"); - } - - inline void LocalFrame::Serialize(Serialization::IArchive& ar) - { - ar(*position, "t", "m_path = path; } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::OutputFilePath& value, const char* name, const char* label); -} - -#include "OutputFilePathImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePathImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePathImpl.h deleted file mode 100644 index 29d64fcff7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/OutputFilePathImpl.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H -#pragma once - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::OutputFilePath& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Range.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Range.h deleted file mode 100644 index 7966c579dd..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Range.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGE_H -#pragma once - -namespace Serialization -{ - template - struct RangeDecorator - { - T* value; - T softMin; - T softMax; - T hardMin; - T hardMax; - }; - - template - RangeDecorator Range(T& value, T hardMin, T hardMax) - { - RangeDecorator r; - r.value = &value; - r.softMin = hardMin; - r.softMax = hardMax; - r.hardMin = hardMin; - r.hardMax = hardMax; - return r; - } - - template - RangeDecorator Range(T& value, T softMin, T softMax, T hardMin, T hardMax) - { - RangeDecorator r; - r.value = &value; - r.softMin = softMin; - r.softMax = softMax; - r.hardMin = hardMin; - r.hardMax = hardMax; - return r; - } - - namespace Decorators - { - // Obsolete name, will be removed. Please use Serialization::Range instead. - using Serialization::Range; - } -} - -#include "RangeImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGE_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/RangeImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/RangeImpl.h deleted file mode 100644 index bc0508f3cb..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/RangeImpl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGEIMPL_H -#pragma once - -namespace Serialization -{ - template - bool Serialize(IArchive& ar, RangeDecorator& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - if (!ar(SStruct::ForEdit(value), name, label)) - { - return false; - } - } - else if (!ar(*value.value, name, label)) - { - return false; - } - - if (ar.IsInput()) - { - if (*value.value < value.hardMin) - { - *value.value = value.hardMin; - } - if (*value.value > value.hardMax) - { - *value.value = value.hardMax; - } - } - return true; - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RANGEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePath.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePath.h deleted file mode 100644 index 0f0c6dc34e..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePath.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATH_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATH_H -#pragma once - -#include "Serialization/Strings.h" - -namespace Serialization -{ - class IArchive; - - struct ResourceFilePath - { - enum - { - STRIP_EXTENSION = 1 << 0 - }; - - string* m_path; - string filter; - bool group; - int flags; - - // filters are defined in the following format: - // "All Images (bmp, jpg, tga)|*.bmp;*.jpg;*.tga|Targa (tga)|*.tga" - explicit ResourceFilePath(string& path, const char* filter = "", bool group = false, int flags = 0) - : m_path(&path) - , filter(filter) - , group(group) - , flags(flags) - { - } - - // the function should stay virtual to ensure cross-dll calls are using right heap - virtual void SetPath(const char* path) { *this->m_path = path; } - }; - - inline ResourceFilePath MaterialPath(string& path) - { - return ResourceFilePath(path, "Material", false, ResourceFilePath::STRIP_EXTENSION); - } - - bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFilePath& value, const char* name, const char* label); -} - -#include "ResourceFilePathImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePathImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePathImpl.h deleted file mode 100644 index 66c9140236..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFilePathImpl.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATHIMPL_H -#pragma once - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFilePath& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFILEPATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPath.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPath.h deleted file mode 100644 index 327f668e43..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPath.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATH_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATH_H -#pragma once - -#include "Serialization/Strings.h" - -namespace Serialization -{ - class IArchive; - - struct ResourceFolderPath - { - string* m_path; - string startFolder; - - explicit ResourceFolderPath(string& path, const char* startFolder = "") - : m_path(&path) - , startFolder(startFolder) - { - } - - // the function should stay virtual to ensure cross-dll calls are using right heap - virtual void SetPath(const char* path) { *this->m_path = path; } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFolderPath& value, const char* name, const char* label); -} - -#include "ResourceFolderPathImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPathImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPathImpl.h deleted file mode 100644 index 33ceacbe10..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceFolderPathImpl.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATHIMPL_H -#pragma once - -#include "Serialization/IArchive.h" - -namespace Serialization -{ - inline bool Serialize(Serialization::IArchive& ar, Serialization::ResourceFolderPath& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCEFOLDERPATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceSelector.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceSelector.h deleted file mode 100644 index 3b9920be6c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourceSelector.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace Serialization -{ - struct IResourceSelector - { - const char* resourceType; - - virtual ~IResourceSelector() {} - virtual const char* GetValue() const = 0; - virtual void SetValue(const char* s) = 0; - virtual int GetId() const{ return -1; } - virtual const void* GetHandle() const = 0; - virtual Serialization::TypeID GetType() const = 0; - }; - - // Provides a way to annotate resource reference so different UI can be used - // for them. See IResourceSelector.h to see how selectors for specific types - // are registered. - // - // TString could be SCRCRef or CCryName as well. - // - // Do not use this class directly, instead use function that wraps it for - // specific type, see Resources.h for example. - template - struct ResourceSelector - : IResourceSelector - { - TString& value; - - const char* GetValue() const { return value.c_str(); } - void SetValue(const char* s) { value = s; } - const void* GetHandle() const { return &value; } - Serialization::TypeID GetType() const { return Serialization::TypeID::get(); } - - ResourceSelector(TString& _value, const char* _resourceType) - : value(_value) - { - this->resourceType = _resourceType; - } - }; - - struct ResourceSelectorWithId - : IResourceSelector - { - string& value; - int id; - - const char* GetValue() const { return value.c_str(); } - void SetValue(const char* s) { value = s; } - int GetId() const { return id; } - const void* GetHandle() const { return &value; } - Serialization::TypeID GetType() const { return Serialization::TypeID::get(); } - - ResourceSelectorWithId(string& _value, const char* _resourceType, int _id) - : value(_value) - , id(_id) - { - this->resourceType = _resourceType; - } - }; - - template - bool Serialize(IArchive& ar, ResourceSelector& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } - - inline bool Serialize(IArchive& ar, ResourceSelectorWithId& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } -} diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Resources.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Resources.h deleted file mode 100644 index 637fc937ed..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Resources.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCES_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCES_H -#pragma once -#include "ResourceSelector.h" - -namespace Serialization -{ - // animation resources - template - ResourceSelector AnimationAlias(T& s) { return ResourceSelector(s, "AnimationAlias"); } // "name" from animation set - template - ResourceSelector AnimationPath(T& s) { return ResourceSelector(s, "Animation"); } - inline ResourceSelectorWithId AnimationPathWithId(string& s, int id) { return ResourceSelectorWithId(s, "Animation", id); } - template - ResourceSelector CharacterPath(T& s) { return ResourceSelector(s, "Character"); } - template - ResourceSelector CharacterPhysicsPath(T& s) { return ResourceSelector(s, "CharacterPhysics"); } - template - ResourceSelector CharacterRigPath(T& s) { return ResourceSelector(s, "CharacterRig"); } - template - ResourceSelector SkeletonPath(T& s) { return ResourceSelector(s, "Skeleton"); } - template - ResourceSelector SkeletonParamsPath(T& s) { return ResourceSelector(s, "SkeletonParams"); } // CHRParams - template - ResourceSelector JointName(T& s) { return ResourceSelector(s, "Joint"); } - template - ResourceSelector AttachmentName(T& s) { return ResourceSelector(s, "Attachment"); } - - // miscelaneous resources - template - ResourceSelector SoundName(T& s) { return ResourceSelector(s, "Sound"); } - template - ResourceSelector DialogName(T& s) { return ResourceSelector(s, "Dialog"); } - template - ResourceSelector ForceFeedbackIdName(T& s) { return ResourceSelector(s, "ForceFeedbackId"); } - template - ResourceSelector ModelFilename(T& s) { return ResourceSelector(s, "Model"); } - template - ResourceSelector ParticleName(T& s) { return ResourceSelector(s, "Particle"); } - - namespace Decorators - { - // Decorators namespace is obsolete now, SHOULD NOT BE USED. - template - ResourceSelector AnimationName(T& s) { return ResourceSelector(s, "Animation"); } - using Serialization::SoundName; - using Serialization::AttachmentName; - template - ResourceSelector ObjectFilename(T& s) { return ResourceSelector(s, "Model"); } - using Serialization::JointName; - using Serialization::ForceFeedbackIdName; - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCES_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesAudio.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesAudio.h deleted file mode 100644 index 9e10be6c3b..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesAudio.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -#include "ResourceSelector.h" - -namespace Serialization -{ - template - ResourceSelector AudioTrigger(T& s) { return ResourceSelector(s, "AudioTrigger"); } - template - ResourceSelector AudioSwitch(T& s) { return ResourceSelector(s, "AudioSwitch"); } - template - ResourceSelector AudioSwitchState(T& s) { return ResourceSelector(s, "AudioSwitchState"); } - template - ResourceSelector AudioRTPC(T& s) { return ResourceSelector(s, "AudioRTPC"); } - template - ResourceSelector AudioEnvironment(T& s) { return ResourceSelector(s, "AudioEnvironment"); } - template - ResourceSelector AudioPreloadRequest(T& s) { return ResourceSelector(s, "AudioPreloadRequest"); } -}; diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesImpl.h deleted file mode 100644 index dde4e1ae0c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/ResourcesImpl.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCESIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCESIMPL_H -#pragma once - -namespace Serialization -{ - template - bool Serialize(IArchive& ar, ResourceSelector& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } - - inline bool Serialize(IArchive& ar, ResourceSelectorWithId& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(Serialization::SStruct::ForEdit(static_cast(value)), name, label); - } - else - { - return ar(value.value, name, label); - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_RESOURCESIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Slider.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Slider.h deleted file mode 100644 index 8be5086660..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Slider.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDER_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDER_H -#pragma once - -namespace Serialization -{ - class IArchive; - - struct SSliderF - { - SSliderF(float* value, float _minLimit, float _maxLimit) - : valuePointer(value) - , minLimit(_minLimit) - , maxLimit(_maxLimit) - { - } - - SSliderF() - : valuePointer(0) - , minLimit(0.0f) - , maxLimit(1.0f) - { - } - - - float* valuePointer; - float minLimit; - float maxLimit; - }; - - struct SSliderI - { - SSliderI(int* value, int minLimit, int maxLimit) - : valuePointer(value) - , minLimit(minLimit) - , maxLimit(maxLimit) - { - } - - SSliderI() - : valuePointer(0) - , minLimit(0) - , maxLimit(1) - { - } - - int* valuePointer; - int minLimit; - int maxLimit; - }; - - - inline SSliderF Slider(float& value, float minLimit, float maxLimit) - { - return SSliderF(&value, minLimit, maxLimit); - } - - inline SSliderI Slider(int& value, int minLimit, int maxLimit) - { - return SSliderI(&value, minLimit, maxLimit); - } - - bool Serialize(IArchive& ar, SSliderF& slider, const char* name, const char* label); - bool Serialize(IArchive& ar, SSliderI& slider, const char* name, const char* label); - - namespace Decorators - { - // OBSOLETE NAME, please use Serialization::Slider instead (without Decorators namespace) - using Serialization::Slider; - } -} - -#include "SliderImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDER_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/SliderImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/SliderImpl.h deleted file mode 100644 index c9e0dfc891..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/SliderImpl.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDERIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDERIMPL_H -#pragma once - -#include "Slider.h" -#include "Serialization/IArchive.h" - -namespace Serialization -{ - inline bool Serialize(IArchive& ar, SSliderF& slider, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(SStruct::ForEdit(slider), name, label); - } - else - { - return ar(*slider.valuePointer, name, label); - } - } - - inline bool Serialize(IArchive& ar, SSliderI& slider, const char* name, const char* label) - { - if (ar.IsEdit()) - { - return ar(SStruct::ForEdit(slider), name, label); - } - else - { - return ar(*slider.valuePointer, name, label); - } - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SLIDERIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/Sprite.h b/Code/CryEngine/CryCommon/Serialization/Decorators/Sprite.h deleted file mode 100644 index 0eeefd7536..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/Sprite.h +++ /dev/null @@ -1,44 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITE_H -#pragma once - -namespace Serialization -{ -class IArchive; - -struct Sprite -{ - string* m_path; - string m_filter; - string m_startFolder; - - // filters are defined in the following format: - // "All Images (bmp, jpg, tga)|*.bmp;*.jpg;*.tga|Targa (tga)|*.tga" - explicit Sprite(string& path, const char* filter = "All files|*.*", const char* startFolder = "") - : m_path(&path) - , m_filter(filter) - , m_startFolder(startFolder) - { - } -}; - -bool Serialize(IArchive& ar, Sprite& value, const char* name, const char* label); - -} // namespace Serialization - -#include "SpriteImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITE_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/SpriteImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/SpriteImpl.h deleted file mode 100644 index 6d0075fafc..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/SpriteImpl.h +++ /dev/null @@ -1,35 +0,0 @@ -//------------------------------------------------------------------------------- -// Copyright (C) Amazon.com, Inc. or its affiliates. -// All Rights Reserved. -// -// Licensed under the terms set out in the LICENSE.HTML file included at the -// root of the distribution; you may not use this file except in compliance -// with the License. -// -// Do not remove or modify this notice or the LICENSE.HTML file. This file -// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, -// either express or implied. See the License for the specific language -// governing permissions and limitations under the License. -//------------------------------------------------------------------------------- -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITEIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITEIMPL_H -#pragma once - -namespace Serialization -{ - -inline bool Serialize(IArchive& ar, Sprite& value, const char* name, const char* label) -{ - if (ar.IsEdit()) - { - return ar(SStruct::ForEdit(value), name, label); - } - else - { - return ar(*value.m_path, name, label); - } -} - -} // namespace Serialization - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_SPRITEIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/TagList.h b/Code/CryEngine/CryCommon/Serialization/Decorators/TagList.h deleted file mode 100644 index 4c4ad81ebf..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/TagList.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLIST_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLIST_H -#pragma once - -#include -#include "Serialization/Strings.h" - -namespace Serialization { - class IArchive; -} - -struct ITagSource -{ - virtual void AddRef() = 0; - virtual void Release() = 0; - virtual unsigned int TagCount(unsigned int group) const = 0; - virtual const char* TagValue(unsigned int group, unsigned int index) const = 0; - virtual const char* TagDescription(unsigned int group, unsigned int index) const = 0; - virtual const char* GroupName(unsigned int group) const = 0; - virtual unsigned int GroupCount() const = 0; -}; - -struct TagList -{ - std::vector* tags; - - TagList(std::vector& tags) - : tags(&tags) - { - } -}; - -bool Serialize(Serialization::IArchive& ar, TagList& tagList, const char* name, const char* label); - -#include "TagListImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLIST_H diff --git a/Code/CryEngine/CryCommon/Serialization/Decorators/TagListImpl.h b/Code/CryEngine/CryCommon/Serialization/Decorators/TagListImpl.h deleted file mode 100644 index 2ee6e1769b..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Decorators/TagListImpl.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLISTIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLISTIMPL_H -#pragma once - -#include -#include "Serialization/IArchive.h" -#include "Serialization/Strings.h" -#include "Serialization/STL.h" - -struct TagListContainer - : Serialization::ContainerSTL, Serialization::string> -{ - TagListContainer(TagList& tagList) - : ContainerSTL(tagList.tags) - { - } - - Serialization::TypeID containerType() const override { return Serialization::TypeID::get(); }; -}; - -inline bool Serialize(Serialization::IArchive& ar, TagList& tagList, const char* name, const char* label) -{ - TagListContainer container(tagList); - return ar(static_cast(container), name, label); -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_TAGLISTIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/DynArray.h b/Code/CryEngine/CryCommon/Serialization/DynArray.h deleted file mode 100644 index 1904cf4ac3..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/DynArray.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAY_H -#pragma once - -namespace Serialization { - class IArchive; -} - -template -bool Serialize(Serialization::IArchive& ar, DynArray& container, const char* name, const char* label); - -#include "DynArrayImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAY_H diff --git a/Code/CryEngine/CryCommon/Serialization/DynArrayImpl.h b/Code/CryEngine/CryCommon/Serialization/DynArrayImpl.h deleted file mode 100644 index c437604f67..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/DynArrayImpl.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAYIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAYIMPL_H -#pragma once - -#include "IArchive.h" -#include "STLImpl.h" - -template -bool Serialize(Serialization::IArchive& ar, DynArray& container, const char* name, const char* label) -{ - Serialization::ContainerSTL, T> ser(&container); - return ar(static_cast(ser), name, label); -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DYNARRAYIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Enum.h b/Code/CryEngine/CryCommon/Serialization/Enum.h deleted file mode 100644 index e377269013..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Enum.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUM_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUM_H -#pragma once - - -#include -#include - -#include "StringList.h" -#include "Serialization/TypeID.h" - -namespace Serialization { - class IArchive; - - struct LessStrCmp - { - bool operator()(const char* l, const char* r) const - { - return strcmp(l, r) < 0; - } - }; - - class CEnumDescription - { - public: - struct NameValue - { - NameValue* m_next; - const char* m_name; - const int m_value; - const char* m_label; - - NameValue(CEnumDescription& desc, const char* name, int value, const char* label="") - : m_next(desc.m_regListHead) - , m_name(name) - , m_value(value) - , m_label(label) - { - desc.m_regListHead = this; - } - }; - - NameValue* m_regListHead = nullptr; - - CEnumDescription(const Serialization::TypeID& type) - : type_(type) {} - inline int value(const char* name) const; - inline int valueByIndex(int index) const; - inline int valueByLabel(const char* label) const; - inline const char* name(int value) const; - inline const char* nameByIndex(int index) const; - inline const char* labelByIndex(int index) const; - inline const char* label(int value) const; - inline const char* indexByName(const char* name) const; - inline int indexByValue(int value) const; - - inline bool Serialize(IArchive& ar, int& value, const char* name, const char* label) const; - inline bool serializeBitVector(IArchive& ar, int& value, const char* name, const char* label) const; - - void add(int value, const char* name, const char* label = ""); - int count() const{ return int(values_.size()); } - const StringListStatic& names() const{ return names_; } - const StringListStatic& labels() const{ return labels_; } - inline StringListStatic nameCombination(int bitVector) const; - inline StringListStatic labelCombination(int bitVector) const; - bool registered() const { return !names_.empty(); } - TypeID type() const{ return type_; } - private: - void lazyRegister() const; - - StringListStatic names_; - StringListStatic labels_; - - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> NameToValue; - NameToValue nameToValue_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> LabelToValue; - LabelToValue labelToValue_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> ValueToIndex; - ValueToIndex valueToIndex_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> ValueToName; - ValueToName valueToName_; - typedef AZStd::unordered_map, AZStd::equal_to, AZ::StdLegacyAllocator> ValueToLabel; - ValueToName valueToLabel_; - AZStd::vector values_; - TypeID type_; - }; - - template - class EnumDescriptionImpl - : public CEnumDescription - { - EnumDescriptionImpl() - : CEnumDescription(Serialization::TypeID::get()) {} - public: - static CEnumDescription& the() - { - static EnumDescriptionImpl description; - return description; - } - }; - - template - CEnumDescription& getEnumDescription() - { - return EnumDescriptionImpl::the(); - } - - inline bool serializeEnum(const CEnumDescription& desc, IArchive& ar, int& value, const char* name, const char* label) - { - return desc.Serialize(ar, value, name, label); - } -} - -#define SERIALIZATION_ENUM_BEGIN(Type, label) \ - namespace { \ - bool registerEnum_##Type(); \ - bool Type##_enum_registered = registerEnum_##Type(); \ - bool registerEnum_##Type(){ \ - Serialization::CEnumDescription& description = Serialization::EnumDescriptionImpl::the(); - -#define SERIALIZATION_ENUM_BEGIN_NESTED(Class, Enum, label) \ - namespace { \ - bool registerEnum_##Class##_##Enum(); \ - bool Class##_##Enum##_enum_registered = registerEnum_##Class##_##Enum(); \ - bool registerEnum_##Class##_##Enum(){ \ - Serialization::CEnumDescription& description = Serialization::EnumDescriptionImpl::the(); - -#define SERIALIZATION_ENUM_BEGIN_NESTED2(Class, Class1, Enum, label) \ - namespace { \ - bool registerEnum_##Class##Class1##_##Enum(); \ - bool Class##Class1##_##Enum##_enum_registered = registerEnum_##Class##Class1##_##Enum(); \ - bool registerEnum_##Class##Class1##_##Enum(){ \ - Serialization::CEnumDescription& description = Serialization::EnumDescriptionImpl::the(); - - -#define SERIALIZATION_ENUM_VALUE(value, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, label, (int)value); - -#define SERIALIZATION_ENUM(value, name, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, name, (int)value, label); - -#define SERIALIZATION_ENUM_VALUE_NESTED(Class, value, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, #value, (int)Class::value, label); - -#define SERIALIZATION_ENUM_VALUE_NESTED2(Class, Class1, value, label) \ - static Serialization::CEnumDescription::NameValue AZ_JOIN(enumValue, __LINE__)(description, #value, (int)Class::Class1::value, label); - - -#define SERIALIZATION_ENUM_END() \ - return true; \ - }; \ - }; - -#include "EnumImpl.h" -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUM_H diff --git a/Code/CryEngine/CryCommon/Serialization/EnumImpl.h b/Code/CryEngine/CryCommon/Serialization/EnumImpl.h deleted file mode 100644 index e5af93e43c..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/EnumImpl.h +++ /dev/null @@ -1,248 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H -#pragma once - -#pragma once -#include "IArchive.h" -#include "STL.h" -#include "Enum.h" -#include "StringList.h" -#ifndef SERIALIZATION_STANDALONE -#include -#endif - -namespace Serialization { - inline void CEnumDescription::add(int value, const char* name, const char* label) - { - YASLI_ESCAPE(name && label, return ); - // Filter for dupes in case enum description included in a shared header - NameToValue::iterator nameIt = nameToValue_.find(name); - if (nameIt != nameToValue_.end() && nameIt->second == value) - { LabelToValue::iterator labelIt = labelToValue_.find(label); - if (labelIt != labelToValue_.end() && labelIt->second == value) - { - return; - } - } - nameToValue_[name] = value; - labelToValue_[label] = value; - valueToName_[value] = name; - valueToLabel_[value] = label; - valueToIndex_[value] = int(names_.size()); - names_.push_back(name); - labels_.push_back(label); - values_.push_back(value); - } - - inline bool CEnumDescription::Serialize(IArchive& ar, int& value, const char* name, const char* label) const - { - lazyRegister(); - if (!ar.IsInPlace()) - { - if (count() == 0) - { -#ifdef SERIALIZATION_STANDALONE - assert(0 && "Attempt to serialize enum type that is not registered with SERIALIZATION_ENUM macro"); -#else - CryFatalError("Attempt to serialize enum type that is not registered with SERIALIZATION_ENUM macro: %s", type().name()); -#endif - return false; - } - - int index = StringListStatic::npos; - if (ar.IsOutput()) - { - index = indexByValue(value); - } - StringListStaticValue stringListValue(ar.IsEdit() ? labels() : names(), index, &value, type()); - ar(stringListValue, name, label); - if (ar.IsInput()) - { - if (stringListValue.index() == StringListStatic::npos) - { - return false; - } - value = ar.IsEdit() ? valueByLabel(stringListValue.c_str()) : this->value(stringListValue.c_str()); - } - else if (index == StringListStatic::npos) - { - ar.Error(&value, type(), "Unregistered or uninitialized enumeration value."); - } - } - else - { - return ar(value, name, label); - } - return true; - } - - inline bool CEnumDescription::serializeBitVector(IArchive& ar, int& value, const char* name, const char* label) const - { - lazyRegister(); - if (ar.IsOutput()) - { - StringListStatic names = nameCombination(value); - string str; - joinStringList(&str, names, '|'); - return ar(str, name, label); - } - else - { - string str; - if (!ar(str, name, label)) - { - return false; - } - StringList values; - splitStringList(&values, str.c_str(), '|'); - StringList::iterator it; - value = 0; - for (it = values.begin(); it != values.end(); ++it) - { - if (!it->empty()) - { - value |= this->value(it->c_str()); - } - } - return true; - } - } - - - inline const char* CEnumDescription::name(int value) const - { - lazyRegister(); - ValueToName::const_iterator it = valueToName_.find(value); - YASLI_ESCAPE(it != valueToName_.end(), return ""); - return it->second; - } - inline const char* CEnumDescription::label(int value) const - { - lazyRegister(); - ValueToLabel::const_iterator it = valueToLabel_.find(value); - YASLI_ESCAPE(it != valueToLabel_.end(), return ""); - return it->second; - } - - inline StringListStatic CEnumDescription::nameCombination(int bitVector) const - { - lazyRegister(); - StringListStatic strings; - for (ValueToName::const_iterator i = valueToName_.begin(); i != valueToName_.end(); ++i) - { - if ((bitVector & i->first) == i->first) - { - bitVector &= ~i->first; - strings.push_back(i->second); - } - } - YASLI_ASSERT(!bitVector && "Unregistered enum value"); - return strings; - } - - inline StringListStatic CEnumDescription::labelCombination(int bitVector) const - { - lazyRegister(); - StringListStatic strings; - for (ValueToLabel::const_iterator i = valueToLabel_.begin(); i != valueToLabel_.end(); ++i) - { - if (i->second && (bitVector & i->first) == i->first) - { - bitVector &= ~i->first; - strings.push_back(i->second); - } - } - YASLI_ASSERT(!bitVector && "Unregistered enum value"); - return strings; - } - - - inline int CEnumDescription::indexByValue(int value) const - { - lazyRegister(); - ValueToIndex::const_iterator it = valueToIndex_.find(value); - if (it == valueToIndex_.end()) - { - return -1; - } - else - { - return it->second; - } - } - - inline int CEnumDescription::valueByIndex(int index) const - { - lazyRegister(); - if (size_t(index) < values_.size()) - { - return values_[index]; - } - return 0; - } - - inline const char* CEnumDescription::nameByIndex(int index) const - { - lazyRegister(); - if (size_t(index) < size_t(names_.size())) - { - return names_[size_t(index)]; - } - return 0; - } - - inline const char* CEnumDescription::labelByIndex(int index) const - { - lazyRegister(); - if (size_t(index) < size_t(labels_.size())) - { - return labels_[size_t(index)]; - } - return 0; - } - - inline int CEnumDescription::value(const char* name) const - { - lazyRegister(); - NameToValue::const_iterator it = nameToValue_.find(name); - YASLI_ESCAPE(it != nameToValue_.end(), return 0); - return it->second; - } - inline int CEnumDescription::valueByLabel(const char* label) const - { - lazyRegister(); - LabelToValue::const_iterator it = labelToValue_.find(label); - YASLI_ESCAPE(it != labelToValue_.end(), return 0); - return it->second; - } - - inline void CEnumDescription::lazyRegister() const - { - if (m_regListHead) - { - NameValue* val = m_regListHead; - while (val) - { - const_cast(this)->add(val->m_value, val->m_name, val->m_label); - val = val->m_next; - } - const_cast(this)->m_regListHead = nullptr; - } - } -} -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ENUMIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/IArchive.h b/Code/CryEngine/CryCommon/Serialization/IArchive.h deleted file mode 100644 index 30de83ccc1..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IArchive.h +++ /dev/null @@ -1,446 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_IARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_IARCHIVE_H -#pragma once - - -#include -#include - -#include "Serializer.h" -#include "KeyValue.h" -#include "TypeID.h" - -namespace Serialization { - class IArchive; - - template - bool Serialize(Serialization::IArchive& ar, T& object, const char* name, const char* label); - - class CEnumDescription; - template - CEnumDescription& getEnumDescription(); - bool serializeEnum(const CEnumDescription& desc, IArchive& ar, int& value, const char* name, const char* label); - - // SContextLink should not be used directly. See SContext<> below. - struct SContextLink - { - SContextLink* outer; - TypeID type; - void* contextObject; - - SContextLink() - : outer() - , contextObject() - { - } - }; - - struct SBlackBox; - struct ICallback; - - class IArchive - { - public: - enum ArchiveCaps - { - INPUT = 1 << 0, - OUTPUT = 1 << 1, - TEXT = 1 << 2, - BINARY = 1 << 3, - EDIT = 1 << 4, - INPLACE = 1 << 5, - NO_EMPTY_NAMES = 1 << 6, - VALIDATION = 1 << 7, - DOCUMENTATION = 1 << 8 - }; - - IArchive(int caps) - : caps_(caps) - , filter_(0) - , innerContext_(0) - { - } - virtual ~IArchive() {} - - bool IsInput() const{ return caps_ & INPUT ? true : false; } - bool IsOutput() const{ return caps_ & OUTPUT ? true : false; } - bool IsEdit() const - { -#if !defined(CONSOLE) && !defined(RELEASE) - return (caps_ & EDIT) != 0; -#else - return false; -#endif - } - bool IsInPlace() const{ return caps_ & INPLACE ? true : false; } - bool GetCaps(int caps) const { return (caps_ & caps) == caps; } - - void SetFilter(int filter) - { - filter_ = filter; - } - int GetFilter() const{ return filter_; } - bool Filter(int flags) const - { - YASLI_ASSERT(flags != 0 && "flags is supposed to be a bit mask"); - YASLI_ASSERT(filter_ && "Filter is not set!"); - return (filter_ & flags) != 0; - } - - virtual bool operator()([[maybe_unused]] bool& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] char& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint8& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int8& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int16& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint16& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int32& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint32& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] int64& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] uint64& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] float& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] double& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - - virtual bool operator()([[maybe_unused]] IString& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] IWString& value, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] const SStruct& ser, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { notImplemented(); return false; } - virtual bool operator()([[maybe_unused]] IContainer& ser, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { return false; } - virtual bool operator()(IPointer& ptr, const char* name = "", const char* label = 0); - virtual bool operator()(IKeyValue& keyValue, const char* name = "", const char* label = 0) { return operator()(SStruct(keyValue), name, label); } - virtual bool operator()([[maybe_unused]] const SBlackBox& blackBox, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { return false; } - virtual bool operator()([[maybe_unused]] ICallback& callback, [[maybe_unused]] const char* name = "", [[maybe_unused]] const char* label = 0) { return false; } - - template - bool operator()(const T& value, const char* name = "", const char* label = 0); - - // Error and Warning calls are used for diagnostics and validation of the - // values. Output depends on the specific implementation of IArchive, - // for example PropertyTree uses it to show bubbles with errors in UI - // next to the mentioned property. - template - void Error(T& value, const char* format, ...); - template - void Warning(T& value, const char* format, ...); - - void Error(const void* value, const Serialization::TypeID& type, const char* format, ...); - // Used to add tooltips in PropertyTree - void Doc(const char* docString); - - virtual bool OpenBlock([[maybe_unused]] const char* name, [[maybe_unused]] const char* label) { return true; } - virtual void CloseBlock() {} - - // long, unsigned long and long double are intentionally omitted - - template - T* FindContext() const { return (T*)FindContextByType(TypeID::get()); } - - void* FindContextByType(const TypeID& type) const - { - SContextLink* context = innerContext_; - while (context) - { - if (context->type == type) - { - return context->contextObject; - } - context = context->outer; - } - return 0; - } - - SContextLink* SetInnerContext(SContextLink* context) - { - SContextLink* result = innerContext_; - innerContext_ = context; - return result; - } - SContextLink* GetInnerContext() const{ return innerContext_; } - protected: - virtual void ValidatorMessage([[maybe_unused]] bool error, [[maybe_unused]] const void* handle, [[maybe_unused]] const TypeID& type, [[maybe_unused]] const char* message) {} - virtual void DocumentLastField([[maybe_unused]] const char* text) {} - - void notImplemented() { YASLI_ASSERT(0 && "Not implemented!"); } - - int caps_; - int filter_; - - SContextLink* innerContext_; - }; - - - // IArchive::SContext can be used to establish access to outer objects in serialization stack. - // - // Example: - // void Scene::Serialize(...) { - // IArchive::SContext context(ar, this); - // ar(rootNode, ...); - // } - // - // void Node::Serialize(...) { - // Scene* scene = ar.FindContext(); - // } - template - struct SContext - : SContextLink - { - SContext(IArchive& ar, T* context) - : ar_(&ar) - { - outer = ar_->SetInnerContext(this); - type = TypeID::get(); - contextObject = (void*)context; - } - SContext(T* context) - : ar_(0) - { - outer = 0; - type = TypeID::get(); - contextObject = (void*)context; - } - ~SContext() - { - if (ar_) - { - ar_->SetInnerContext(outer); - } - } - private: - IArchive* ar_; - }; - - namespace detail { - template - struct Selector{}; - - template - struct Selector - { - typedef T2 type; - }; - - template - struct Selector - { - typedef T1 type; - }; - - template - struct Select - { - typedef typename Selector::type selected_type; - typedef typename selected_type::type type; - }; - - template - struct Identity - { - typedef T type; - }; - - - template - struct IsArray - { - enum - { - value = false - }; - }; - - template - struct IsArray< T[Size] > - { - enum - { - value = true - }; - }; - - template - struct ArraySize - { - enum - { - value = true - }; - }; - - template - struct SerializeStruct - { - static bool invoke(IArchive& ar, T& value, const char* name, const char* label) - { - SStruct ser(value); - return ar(ser, name, label); - }; - }; - - template - struct SerializeEnum - { - static bool invoke(IArchive& ar, Enum& value, const char* name, const char* label) - { - const CEnumDescription& enumDescription = getEnumDescription(); - return serializeEnum(enumDescription, ar, reinterpret_cast(value), name, label); - }; - }; - - template - struct SerializeArray{}; - - template - struct SerializeArray - { - static bool invoke(IArchive& ar, T value[Size], const char* name, const char* label) - { - ContainerArray ser(value, Size); - return ar(static_cast(ser), name, label); - } - }; - - - template - struct IsClass - { - private: - struct NoType - { - char dummy; - }; - struct YesType - { - char dummy[100]; - }; - - template - static YesType function_helper(void(U::*)(void)); - - template - static NoType function_helper(...); - public: - enum - { - value = (sizeof(function_helper(0)) == sizeof(YesType)) - }; - }; - } - - template - bool IArchive::operator()(const T& value, const char* name, const char* label) - { - return Serialize(*this, const_cast(value), name, label); - } - - inline bool IArchive::operator()(IPointer& ptr, const char* name, const char* label) - { - return (*this)(SStruct(const_cast(ptr)), name, label); - } - - inline void IArchive::Doc([[maybe_unused]] const char* docString) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if (caps_ & DOCUMENTATION) - { - DocumentLastField(docString); - } -#endif - } - - template - void IArchive::Error([[maybe_unused]] T& value, [[maybe_unused]] const char* format, ...) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if ((caps_ & VALIDATION) == 0) - { - return; - } - va_list args; - va_start(args, format); - char buf[1024]; - azvsnprintf(buf, sizeof(buf), format, args); - va_end(args); - ValidatorMessage(true, &value, TypeID::get(), buf); -#endif - } - - inline void IArchive::Error([[maybe_unused]] const void* handle, [[maybe_unused]] const Serialization::TypeID& type, [[maybe_unused]] const char* format, ...) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if ((caps_ & VALIDATION) == 0) - { - return; - } - va_list args; - va_start(args, format); - char buf[1024]; - azvsnprintf(buf, sizeof(buf), format, args); - va_end(args); - ValidatorMessage(true, handle, type, buf); -#endif - } - - template - void IArchive::Warning([[maybe_unused]] T& value, [[maybe_unused]] const char* format, ...) - { -#if !defined(CONSOLE) && !defined(RELEASE) - if ((caps_ & VALIDATION) == 0) - { - return; - } - va_list args; - va_start(args, format); - char buf[1024]; - azvsnprintf(buf, sizeof(buf), format, args); - va_end(args); - ValidatorMessage(false, &value, TypeID::get(), buf); -#endif - } - - template - bool Serialize(Serialization::IArchive& ar, T object[Size], const char* name, const char* label) - { - YASLI_ASSERT(0); - return false; - } - - template - bool Serialize(Serialization::IArchive& ar, const T& object, const char* name, const char* label) - { - T::unable_to_serialize_CONST_object(); - YASLI_ASSERT(0); - return false; - } - - template - bool Serialize(Serialization::IArchive& ar, T& object, const char* name, const char* label) - { - using namespace Serialization::detail; - - return - Select< IsClass, - Identity< SerializeStruct >, - Select< IsArray, - Identity< SerializeArray >, - Identity< SerializeEnum > - > - >::type::invoke(ar, object, name, label); - } -} - -#include "Serialization/SerializerImpl.h" - -// vim: ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_IARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/IArchiveHost.h b/Code/CryEngine/CryCommon/Serialization/IArchiveHost.h deleted file mode 100644 index c2afc1778f..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IArchiveHost.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once -// IArchiveHost serves a purpose of sharing IArchive implementations among -// diffferent modules. -// -// Example of usage: -// -// struct SType -// { -// void Serialize(Serialization::IArchive& ar); -// }; -// -// SType instanceToSave; -// bool saved = Serialization::SaveJsonFile("Scripts/instance.json", instanceToSave); -// -// SType instanceToLoad; -// bool loaded = Serialization::LoadJsonFile(instanceToLoad, "Scripts/instance.json"); -// -#include -#include - -namespace Serialization -{ - struct IArchiveHost - { - virtual ~IArchiveHost() {} - virtual bool LoadJsonFile(const SStruct& outObj, const char* filename) = 0; - virtual bool SaveJsonFile(const char* filename, const SStruct& obj) = 0; - virtual bool LoadJsonBuffer(const SStruct& outObj, const char* buffer, size_t bufferLength) = 0; - virtual bool SaveJsonBuffer(DynArray& outBuffer, const SStruct& obj) = 0; - - virtual bool LoadBinaryFile(const SStruct& outObj, const char* filename) = 0; - virtual bool SaveBinaryFile(const char* filename, const SStruct& obj) = 0; - virtual bool LoadBinaryBuffer(const SStruct& outObj, const char* buffer, size_t bufferLength) = 0; - virtual bool SaveBinaryBuffer(DynArray& outBuffer, const SStruct& obj) = 0; - virtual bool CloneBinary(const SStruct& dest, const SStruct& source) = 0; - // Compares two instances in serialized form through binary archive - virtual bool CompareBinary(const SStruct& lhs, const SStruct& rhs) = 0; - - virtual bool LoadXmlFile(const SStruct& outObj, const char* filename) = 0; - virtual bool SaveXmlFile(const char* filename, const SStruct& obj, const char* rootNodeName) = 0; - virtual bool LoadXmlNode(const SStruct& outObj, const XmlNodeRef& node) = 0; - virtual XmlNodeRef SaveXmlNode(const SStruct& obj, const char* nodeName) = 0; - virtual bool SaveXmlNode(XmlNodeRef& node, const SStruct& obj) = 0; - }; - - // Syntactic sugar - template - bool LoadJsonFile(T& instance, const char* filename) - { - return gEnv->pSystem->GetArchiveHost()->LoadJsonFile(Serialization::SStruct(instance), filename); - } - - template - bool SaveJsonFile(const char* filename, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveJsonFile(filename, Serialization::SStruct(instance)); - } - - template - bool LoadJsonBuffer(T& instance, const char* buffer, size_t bufferLength) - { - return gEnv->pSystem->GetArchiveHost()->LoadJsonBuffer(Serialization::SStruct(instance), buffer, bufferLength); - } - - template - bool SaveJsonBuffer(DynArray& outBuffer, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveJsonBuffer(outBuffer, Serialization::SStruct(instance)); - } - - // --------------------------------------------------------------------------- - - template - bool LoadBinaryFile(T& outInstance, const char* filename) - { - return gEnv->pSystem->GetArchiveHost()->LoadBinaryFile(Serialization::SStruct(outInstance), filename); - } - - template - bool SaveBinaryFile(const char* filename, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveBinaryFile(filename, Serialization::SStruct(instance)); - } - - template - bool LoadBinaryBuffer(T& outInstance, const char* buffer, size_t bufferLength) - { - return gEnv->pSystem->GetArchiveHost()->LoadBinaryBuffer(Serialization::SStruct(outInstance), buffer, bufferLength); - } - - template - bool SaveBinaryBuffer(DynArray& outBuffer, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveBinaryBuffer(outBuffer, Serialization::SStruct(instance)); - } - - template - bool CloneBinary(T& outInstance, const T& inInstance) - { - return gEnv->pSystem->GetArchiveHost()->CloneBinary(Serialization::SStruct(outInstance), Serialization::SStruct(inInstance)); - } - - template - bool CompareBinary(const T& lhs, const T& rhs) - { - return gEnv->pSystem->GetArchiveHost()->CompareBinary(Serialization::SStruct(lhs), Serialization::SStruct(rhs)); - } - - // --------------------------------------------------------------------------- - - template - bool LoadXmlFile(T& outInstance, const char* filename) - { - return gEnv->pSystem->GetArchiveHost()->LoadXmlFile(Serialization::SStruct(outInstance), filename); - } - - template - bool SaveXmlFile(const char* filename, const T& instance, const char* rootNodeName) - { - return gEnv->pSystem->GetArchiveHost()->SaveXmlFile(filename, Serialization::SStruct(instance), rootNodeName); - } - - template - bool LoadXmlNode(T& outInstance, const XmlNodeRef& node) - { - return gEnv->pSystem->GetArchiveHost()->LoadXmlNode(Serialization::SStruct(outInstance), node); - } - - template - XmlNodeRef SaveXmlNode(const T& instance, const char* nodeName) - { - return gEnv->pSystem->GetArchiveHost()->SaveXmlNode(Serialization::SStruct(instance), nodeName); - } - - template - bool SaveXmlNode(XmlNodeRef& node, const T& instance) - { - return gEnv->pSystem->GetArchiveHost()->SaveXmlNode(node, Serialization::SStruct(instance)); - } -} diff --git a/Code/CryEngine/CryCommon/Serialization/IClassFactory.h b/Code/CryEngine/CryCommon/Serialization/IClassFactory.h deleted file mode 100644 index bf50b17acd..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IClassFactory.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ICLASSFACTORY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ICLASSFACTORY_H -#pragma once - -#include - -#include "Serialization/Assert.h" -#include "Serialization/TypeID.h" - -namespace Serialization { - class IArchive; - class TypeDescription - { - public: - TypeDescription(const char* name, const char* label) - : name_(name) - , label_(label) - { - } - const char* name() const{ return name_; } - const char* label() const{ return label_; } - - protected: - const char* name_; - const char* label_; - }; - - class IClassFactory - { - friend class ClassFactoryManager; - public: - IClassFactory(TypeID baseType) - : baseType_(baseType) - , nullLabel_(0) - { - } - - virtual ~IClassFactory() { } - - virtual size_t size() const = 0; - virtual const TypeDescription* descriptionByIndex(int index) const = 0; - virtual const TypeDescription* descriptionByRegisteredName(const char* typeName) const = 0; - virtual const char* findAnnotation(const char* registeredTypeName, const char* annotationName) const = 0; - virtual void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label) = 0; - - bool setNullLabel(const char* label){ nullLabel_ = label ? label : ""; return true; } - const char* nullLabel() const{ return nullLabel_; } - protected: - TypeID baseType_; - const char* nullLabel_; - IClassFactory* m_next = nullptr; - }; - - - struct TypeNameWithFactory - { - string registeredName; - IClassFactory* factory; - - TypeNameWithFactory(const char* _registeredName, IClassFactory* _factory = 0) - : registeredName(_registeredName) - , factory(_factory) - { - } - }; - - bool Serialize(Serialization::IArchive& ar, Serialization::TypeNameWithFactory& value, const char* name, const char* label); -} - -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ICLASSFACTORY_H diff --git a/Code/CryEngine/CryCommon/Serialization/ITextInputArchive.h b/Code/CryEngine/CryCommon/Serialization/ITextInputArchive.h deleted file mode 100644 index c9f268d9a4..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ITextInputArchive.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTINPUTARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTINPUTARCHIVE_H -#pragma once -#include "Serialization/IArchive.h" -#include "CryExtension/ICryUnknown.h" -#include "CryExtension/CryCreateClassInstance.h" - -namespace Serialization { - class ITextInputArchive - : public ICryUnknown - , public IArchive - { - public: - CRYINTERFACE_DECLARE(ITextInputArchive, 0x1845738b1dcc4168, 0xb440dba776b460c9) - - using IArchive::operator(); - - virtual bool LoadFileUsingCRT(const char* filename) = 0; - virtual bool AttachMemory(const char* buffer, size_t size) = 0; - - protected: - ITextInputArchive(int caps) - : IArchive(caps) {} - }; - - inline AZStd::shared_ptr CreateTextInputArchive() - { - AZStd::shared_ptr pArchive; - CryCreateClassInstance(MAKE_CRYGUID(0x7a83a1c890054608, 0x9f8447a4b0ad6c3b), pArchive); - return pArchive; - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTINPUTARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/ITextOutputArchive.h b/Code/CryEngine/CryCommon/Serialization/ITextOutputArchive.h deleted file mode 100644 index e87b819404..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/ITextOutputArchive.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTOUTPUTARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTOUTPUTARCHIVE_H -#pragma once -#include "Serialization/IArchive.h" -#include "CryExtension/ICryUnknown.h" -#include "CryExtension/CryCreateClassInstance.h" - -namespace Serialization { - class ITextOutputArchive - : public ICryUnknown - , public IArchive - { - CRYINTERFACE_DECLARE(ITextOutputArchive, 0xa273d6157a8b4f0d, 0x80ad6c8031bbfbf3) - public: - virtual bool SaveFileUsingCRT(const char* filename) = 0; - - // use precise but less readable way to write float/double types - virtual void SetExponentFloatRepresentation(bool) = 0; - - // buffer is a null-terminated string - virtual const char* GetBuffer() const = 0; - virtual size_t GetBufferLength() const = 0; - - // by default nested structres are put in one line, unless the line length is - // longer than 'textWidth' - virtual void SetTextWidth(int textWidth) = 0; - - using IArchive::operator(); - protected: - ITextOutputArchive(int caps) - : IArchive(caps) {} - }; - - inline AZStd::shared_ptr CreateTextOutputArchive() - { - AZStd::shared_ptr pArchive; - CryCreateClassInstance(MAKE_CRYGUID(0xd1f14adbc4e74e49, 0x9cea55d80a55cbdb), pArchive); - return pArchive; - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ITEXTOUTPUTARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/IXmlArchive.h b/Code/CryEngine/CryCommon/Serialization/IXmlArchive.h deleted file mode 100644 index 07d4438d92..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IXmlArchive.h +++ /dev/null @@ -1,175 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_IXMLARCHIVE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_IXMLARCHIVE_H -#pragma once - - -#include "Serialization/IArchive.h" -#include "CryExtension/ICryUnknown.h" -#include "CryExtension/CryCreateClassInstance.h" - -namespace Serialization -{ - struct IXmlArchive - : public ICryUnknown - , public IArchive - { - public: - CRYINTERFACE_DECLARE(IXmlArchive, 0x1386c94ded174f96, 0xab14d20e1b616588); - - using IArchive::operator(); - - virtual void SetXmlNode(XmlNodeRef pRootNode) = 0; - virtual XmlNodeRef GetXmlNode() const = 0; - - protected: - IXmlArchive(int caps) - : IArchive(caps | IArchive::NO_EMPTY_NAMES) {} - }; - - - typedef AZStd::shared_ptr< IXmlArchive > IXmlArchivePtr; - - - inline IXmlArchivePtr CreateXmlInputArchive() - { - IXmlArchivePtr pArchive; - CryCreateClassInstance("CXmlIArchive", pArchive); - return pArchive; - } - - - inline IXmlArchivePtr CreateXmlInputArchive(XmlNodeRef pXmlNode) - { - if (pXmlNode) - { - IXmlArchivePtr pArchive = CreateXmlInputArchive(); - if (pArchive) - { - pArchive->SetXmlNode(pXmlNode); - } - return pArchive; - } - return IXmlArchivePtr(); - } - - - inline IXmlArchivePtr CreateXmlInputArchive(const char* const filename) - { - XmlNodeRef pXmlNode = gEnv->pSystem->LoadXmlFromFile(filename); - return CreateXmlInputArchive(pXmlNode); - } - - - inline IXmlArchivePtr CreateXmlOutputArchive() - { - IXmlArchivePtr pArchive; - CryCreateClassInstance("CXmlOArchive", pArchive); - return pArchive; - } - - - inline IXmlArchivePtr CreateXmlOutputArchive(XmlNodeRef pXmlNode) - { - if (pXmlNode) - { - IXmlArchivePtr pArchive = CreateXmlOutputArchive(); - if (pArchive) - { - pArchive->SetXmlNode(pXmlNode); - } - return pArchive; - } - return IXmlArchivePtr(); - } - - - inline IXmlArchivePtr CreateXmlOutputArchive(const char* const xmlRootElementName) - { - XmlNodeRef pXmlNode = gEnv->pSystem->CreateXmlNode(xmlRootElementName); - return CreateXmlOutputArchive(pXmlNode); - } - - - template< typename T > - bool StructFromXml(const char* const filename, T& dataOut) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlInputArchive(filename); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(dataOut); - const bool success = serializer(*pXmlArchive); - return success; - } - return false; - } - - - template< typename T > - bool StructFromXml(XmlNodeRef pXmlNode, T& dataOut) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlInputArchive(pXmlNode); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(dataOut); - const bool success = serializer(*pXmlArchive); - return success; - } - return false; - } - - - template< typename T > - XmlNodeRef StructToXml(const char* const xmlRootElementName, const T& dataIn) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlOutputArchive(xmlRootElementName); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(const_cast< T& >(dataIn)); - const bool success = serializer(*pXmlArchive); - if (success) - { - return pXmlArchive->GetXmlNode(); - } - } - return XmlNodeRef(); - } - - - template< typename T > - bool StructToXml(XmlNodeRef pXmlNode, const T& dataIn) - { - Serialization::IXmlArchivePtr pXmlArchive = Serialization::CreateXmlOutputArchive(pXmlNode); - if (pXmlArchive) - { - Serialization::SStruct serializer = Serialization::SStruct(const_cast< T& >(dataIn)); - const bool success = serializer(*pXmlArchive); - return success; - } - return false; - } - - - template< typename T > - bool StructToXml(const char* const filename, const char* const xmlRootElementName, const T& dataIn) - { - XmlNodeRef pXmlNode = Serialization::StructToXml(xmlRootElementName, dataIn); - if (pXmlNode) - { - return pXmlNode->saveToFile(filename); - } - return false; - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_IXMLARCHIVE_H diff --git a/Code/CryEngine/CryCommon/Serialization/IntrusiveFactory.h b/Code/CryEngine/CryCommon/Serialization/IntrusiveFactory.h deleted file mode 100644 index dcd92d51a9..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/IntrusiveFactory.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_INTRUSIVEFACTORY_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_INTRUSIVEFACTORY_H -#pragma once - -#include - -template -class CIntrusiveFactory -{ -private: - struct ICreator - { - virtual TBase* Create() const = 0; - }; - -public: - template - struct SCreator - : ICreator - { - SCreator() { CIntrusiveFactory::Instance().RegisterType(this); } - - TBase* Create() const override { return new TDerived(); } - }; - - static CIntrusiveFactory& Instance() { static CIntrusiveFactory instance; return instance; } - - TBase* Create(const char* keyType) const - { - TCreatorByType::const_iterator it = m_creators.find(keyType); - if (it == m_creators.end() || it->second == 0) - { - return 0; - } - else - { - return it->second->Create(); - } - } - - struct SSerializer - { - _smart_ptr& pointer; - - SSerializer(_smart_ptr& pointer) - : pointer(pointer) {} - - void Serialize(Serialization::IArchive& ar); - }; - -private: - template - void RegisterType(ICreator* creator) - { - const char* type = TDerived::GetType(); - m_creators[type] = creator; - } - - typedef std::map > TCreatorByType; - TCreatorByType m_creators; -}; - -template -void CIntrusiveFactory::SSerializer::Serialize(Serialization::IArchive & ar) -{ - string type = pointer.get() ? pointer->GetInstanceType() : ""; - string oldType = type; - ar(type, "type", "Type"); - if (ar.IsInput()) - { - if (oldType != type) - { - pointer.reset(CIntrusiveFactory::Instance().Create(type.c_str())); - } - } - if (pointer) - { - pointer->Serialize(ar); - } -} - - - -#define REGISTER_IN_INTRUSIVE_FACTORY(BaseType, DerivedType) namespace { CIntrusiveFactory::SCreator baseType##DerivedType##_Creator; } - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_INTRUSIVEFACTORY_H diff --git a/Code/CryEngine/CryCommon/Serialization/KeyValue.h b/Code/CryEngine/CryCommon/Serialization/KeyValue.h deleted file mode 100644 index afe74927df..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/KeyValue.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_KEYVALUE_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_KEYVALUE_H -#pragma once -namespace Serialization { - class IArchive; - - class IKeyValue - : IString - { - public: - virtual const char* get() const = 0; - virtual void set(const char* key) = 0; - virtual bool serializeValue(IArchive& ar, const char* name, const char* label) = 0; - template - void Serialize(TArchive& ar) - { - ar(*(IString*)this, "", "^"); - serializeValue(ar, "", "^"); - } - }; -} - - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_KEYVALUE_H diff --git a/Code/CryEngine/CryCommon/Serialization/Math.h b/Code/CryEngine/CryCommon/Serialization/Math.h deleted file mode 100644 index c7d86935e0..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Math.h +++ /dev/null @@ -1,166 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// This header extends serialization to support common geometrical types. -// It allows serialization of mentioned below types simple passing them to archive. -// For example: -// -// #include -// #include -// -// Serialization::IArchive& ar; -// -// Vec3 v; -// ar(v, "v"); -// -// QuatT q; -// ar(q, "q"); -// - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATH_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATH_H -#pragma once -namespace Serialization { - class IArchive; -} - -template -bool Serialize(Serialization::IArchive& ar, struct Vec2_tpl& v, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Vec3_tpl& v, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Vec4_tpl& v, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Quat_tpl& q, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct QuatT_tpl& qt, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Ang3_tpl& a, const char* name, const char* label); - -template -bool Serialize(Serialization::IArchive& ar, struct Matrix34_tpl& value, const char* name, const char* label); - -bool Serialize(Serialization::IArchive& ar, struct AABB& aabb, const char* name, const char* label); - -// --------------------------------------------------------------------------- -// RadiansAsDeg allows to present radian values as degrees to the user in the -// editor. -// -// Example: -// ... -// float radians; -// ar(RadiansAsDeg(radians), "degrees", "Degrees"); -// -// Ang3 euler; -// ar(RadiansAsDeg(euler), "eulerDegrees", "Euler Degrees"); -// -namespace Serialization -{ - template - struct SRadianAng3AsDeg - { - Ang3_tpl* ang3; - SRadianAng3AsDeg(Ang3_tpl* _ang3) - : ang3(_ang3) {} - }; - - template - SRadianAng3AsDeg RadiansAsDeg(Ang3_tpl& radians) - { - return SRadianAng3AsDeg(&radians); - } - - template - struct SRadiansAsDeg - { - T* radians; - SRadiansAsDeg(T* _radians) - : radians(_radians) {} - }; - - template - SRadiansAsDeg RadiansAsDeg(T& radians) - { - return SRadiansAsDeg(&radians); - } - - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadiansAsDeg& value, const char* name, const char* label); - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadianAng3AsDeg& value, const char* name, const char* label); - - // --------------------------------------------------------------------------- - // QuatAsAng3 provides a wrapper that allows editing of quaternions as Ang3 (in degrees). - // - // Example: - // ... - // Quat q; - // ar(QuatAsAng3(q), "orientation", "Orientation"); - // - - template - struct QuatAsAng3 - { - Quat_tpl* quat; - QuatAsAng3(Quat_tpl& _quat) - : quat(&_quat) {} - }; - - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatAsAng3& value, const char* name, const char* label); - - // --------------------------------------------------------------------------- - // QuatTAsVec3Ang3 provides a wrapper that allows editing of transforms as Vec3 and Ang3 (in degrees). - // - // Example: - // ... - // QuatT trans; - // ar(QuatTAsVec3Ang3(trans), "transform", "Transform"); - // - - template - struct QuatTAsVec3Ang3 - { - QuatT_tpl* trans; - QuatTAsVec3Ang3(QuatT_tpl& _trans) - : trans(&_trans) {} - }; - - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatTAsVec3Ang3& value, const char* name, const char* label); - - // --------------------------------------------------------------------------- - // Helper functions for Ang3 - // - // Example: - // ... - // Quat q; - // QuatT trans; - // ar(AsAng3(q),"orientation","Orientation"); - // ar(AsAnge(trans),"transform", "Transform"); - // - - template - inline QuatAsAng3 AsAng3(Quat_tpl& q){ return QuatAsAng3(q); } - template - inline QuatTAsVec3Ang3 AsAng3(QuatT_tpl& trans){ return QuatTAsVec3Ang3(trans); } -} - -#include "MathImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATH_H diff --git a/Code/CryEngine/CryCommon/Serialization/MathImpl.h b/Code/CryEngine/CryCommon/Serialization/MathImpl.h deleted file mode 100644 index 95ff63e179..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/MathImpl.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATHIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATHIMPL_H -#pragma once - -#include "Serialization/IArchive.h" - -#include "Cry_Vector2.h" -#include "Cry_Vector3.h" -#include "Cry_Vector4.h" -#include "Cry_Quat.h" -#include "Cry_Matrix34.h" -#include "Cry_Geo.h" - - -template -bool Serialize(Serialization::IArchive& ar, Vec2_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[2]; - return ar((Array)value, name, label); -} - -template -bool Serialize(Serialization::IArchive& ar, Vec3_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[3]; - return ar((Array)value, name, label); -} - -template -inline bool Serialize(Serialization::IArchive& ar, struct Vec4_tpl& v, const char* name, const char* label) -{ - typedef T (& Array)[4]; - return ar((Array)v, name, label); -} - - -template -bool Serialize(Serialization::IArchive& ar, struct Quat_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[4]; - return ar((Array)value, name, label); -} - -template -struct SerializableQuatT - : QuatT_tpl -{ - void Serialize(Serialization::IArchive& ar) - { - ar(this->q, "q", "Quaternion"); - ar(this->t, "t", "Translation"); - } -}; - -template -bool Serialize(Serialization::IArchive& ar, struct QuatT_tpl& value, const char* name, const char* label) -{ - return Serialize(ar, static_cast&>(value), name, label); -} - -struct SerializableAABB - : AABB -{ - void Serialize(Serialization::IArchive& ar) - { - ar(this->min, "min", "Min"); - ar(this->max, "max", "Max"); - } -}; - -inline bool Serialize(Serialization::IArchive& ar, struct AABB& value, const char* name, const char* label) -{ - return Serialize(ar, static_cast(value), name, label); -} - -template -bool Serialize(Serialization::IArchive& ar, Matrix34_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[3][4]; - return ar((Array)value, name, label); -} - -////////////////////////////////////////////////////////////////////////// - - -namespace Serialization -{ - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadiansAsDeg& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - float degrees = RAD2DEG(*value.radians); - float oldDegrees = degrees; - if (!ar(degrees, name, label)) - { - return false; - } - if (oldDegrees != degrees) - { - *value.radians = DEG2RAD(degrees); - } - return true; - } - else - { - return ar(*value.radians, name, label); - } - } - - template - bool Serialize(Serialization::IArchive& ar, Serialization::SRadianAng3AsDeg& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - Ang3 degrees(RAD2DEG(value.ang3->x), RAD2DEG(value.ang3->y), RAD2DEG(value.ang3->z)); - Ang3 oldDegrees = degrees; - if (!ar(degrees, name, label)) - { - return false; - } - if (oldDegrees != degrees) - { - *value.ang3 = Ang3(DEG2RAD(degrees.x), DEG2RAD(degrees.y), DEG2RAD(degrees.z)); - } - return true; - } - else - { - return ar(*value.ang3, name, label); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -template -bool Serialize(Serialization::IArchive& ar, Ang3_tpl& value, const char* name, const char* label) -{ - typedef T (& Array)[3]; - return ar((Array)value, name, label); -} - -////////////////////////////////////////////////////////////////////////// - -namespace Serialization -{ - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatAsAng3& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - Ang3 ang3(*value.quat); - Ang3 oldAng3 = ang3; - if (!ar(Serialization::RadiansAsDeg(ang3), name, label)) - { - return false; - } - if (ang3 != oldAng3) - { - *value.quat = Quat(ang3); - } - return true; - } - else - { - return ar(*value.quat, name, label); - } - } - - template - bool Serialize(Serialization::IArchive& ar, Serialization::QuatTAsVec3Ang3& value, const char* name, const char* label) - { - if (ar.IsEdit()) - { - if (!ar.OpenBlock(name, label)) - { - return false; - } - - ar(QuatAsAng3((value.trans)->q), "rot", "Rotation"); - ar.Doc("Euler Angles in degrees"); - ar((value.trans)->t, "t", "Translation"); - ar.CloseBlock(); - return true; - } - else - { - return ar(*(value.trans), name, label); - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_MATHIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/NetScriptSerialize.h b/Code/CryEngine/CryCommon/Serialization/NetScriptSerialize.h deleted file mode 100644 index 8c66452419..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/NetScriptSerialize.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* 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. -* -*/ -#ifndef CRYINCLUDE_CRYCOMMON_CRYSCRIPTSYSTEM_NETSCRIPTSERIALIZE_H -#define CRYINCLUDE_CRYCOMMON_CRYSCRIPTSYSTEM_NETSCRIPTSERIALIZE_H - -namespace Serialization -{ - class INetScriptMarshaler - { - public: - virtual TSerialize FindSerializer(const char* name) = 0; - virtual bool CommitSerializer(const char* name, TSerialize serializer) = 0; - - virtual int GetMaxServerProperties() const = 0; - }; -} - -#endif diff --git a/Code/CryEngine/CryCommon/Serialization/Object.h b/Code/CryEngine/CryCommon/Serialization/Object.h deleted file mode 100644 index d304883452..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Object.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_OBJECT_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_OBJECT_H -#pragma once - -#include "Serializer.h" - -// --------------------------------------------------------------------------- - -namespace Serialization { - typedef int(* AddRefFunc)(void*); - typedef int(* DecRefFunc)(void*); - - // represents a reference to the persistent object - class Object - { - public: - Object() - : address_(0) - , addRefFunc_(0) - , decRefFunc_(0) - , serializeFunc_(0) - { - } - - Object(const Object& o) - : address_(o.address_) - , type_(o.type_) - , addRefFunc_(o.addRefFunc_) - , decRefFunc_(o.decRefFunc_) - , serializeFunc_(o.serializeFunc_) - { - addRef(); - } - - Object(const SStruct& ser) - : address_(ser.pointer()) - , type_(ser.type()) - , addRefFunc_(0) - , decRefFunc_(0) - , serializeFunc_(ser.serializeFunc()) - { - } - - Object(void* address, const TypeID& type, AddRefFunc addRefFunc, DecRefFunc decRefFunc, SerializeStructFunc serializeFunc) - : address_(address) - , type_(type) - , addRefFunc_(addRefFunc) - , decRefFunc_(decRefFunc) - , serializeFunc_(serializeFunc) - { - addRef(); - } - - ~Object() - { - if (address_) - { - decRef(); - address_ = 0; - } - } - - void* address() const{ return address_; } - const TypeID& type() const{ return type_; } - bool isSet() { return serializeFunc_ != 0; } - - int addRef() - { - if (!addRefFunc_) - { - return 1; - } - if (!address_) - { - return -1; - } - return addRefFunc_(address_); - } - - int decRef() - { - if (!decRefFunc_) - { - return 1; - } - if (!address_) - { - return -1; - } - return decRefFunc_(address_); - } - - bool operator()(IArchive& ar) const - { - if (!serializeFunc_ || !address_) - { - return false; - } - return serializeFunc_(address_, ar); - } - - SStruct serializer() const - { - return SStruct(type_, address_, 0, serializeFunc_); - } - - Object& operator=(const Object& o) - { - if (this == &o) - { - return *this; - } - - if (address_) - { - decRef(); - } - - address_ = o.address_; - type_ = o.type_; - addRefFunc_ = o.addRefFunc_; - decRefFunc_ = o.decRefFunc_; - serializeFunc_ = o.serializeFunc_; - - addRef(); - return *this; - } - - private: - void* address_; - TypeID type_; - AddRefFunc addRefFunc_; - DecRefFunc decRefFunc_; - SerializeStructFunc serializeFunc_; - }; -} - -// --------------------------------------------------------------------------- - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_OBJECT_H diff --git a/Code/CryEngine/CryCommon/Serialization/STL.h b/Code/CryEngine/CryCommon/Serialization/STL.h deleted file mode 100644 index 357a8937a4..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/STL.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STL_H -#pragma once - - -#include -#include -#include - -#include "Serialization/Serializer.h" - -namespace Serialization { - class IArchive; -} - -namespace std -{ - template - bool Serialize(Serialization::IArchive& ar, std::pair& pair, const char* name, const char* label); - - template - bool Serialize(Serialization::IArchive& ar, std::vector& container, const char* name, const char* label); - - template - bool Serialize(Serialization::IArchive& ar, std::list& container, const char* name, const char* label); - - template - bool Serialize(Serialization::IArchive& ar, std::map& container, const char* name, const char* label); -} - -namespace Serialization -{ - bool Serialize(Serialization::IArchive& ar, Serialization::string& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::wstring& value, const char* name, const char* label); -} - -#include "STLImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STL_H diff --git a/Code/CryEngine/CryCommon/Serialization/STLImpl.h b/Code/CryEngine/CryCommon/Serialization/STLImpl.h deleted file mode 100644 index b03d877b55..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/STLImpl.h +++ /dev/null @@ -1,251 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STLIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STLIMPL_H -#pragma once - - -#include "Serialization/IArchive.h" -#include "Serialization/Serializer.h" - -namespace Serialization { - template - class ContainerSTL - : public IContainer /*{{{*/ - { - public: - explicit ContainerSTL(Container* container = 0) - : container_(container) - , it_(container->begin()) - , size_(container->size()) - { - YASLI_ASSERT(container_ != 0); - } - - template - void resizeHelper(size_t _size, std::vector* _v) const - { - _v->resize(_size); - } - - void resizeHelper(size_t _size, ...) const - { - while (size_t(container_->size()) > _size) - { - typename Container::iterator it = container_->end(); - --it; - container_->erase(it); - } - while (size_t(container_->size()) < _size) - { - container_->insert(container_->end(), Element()); - } - } - - // from ContainerSerializationInterface - size_t size() const - { - YASLI_ESCAPE(container_ != 0, return 0); - return container_->size(); - } - size_t resize(size_t size) - { - YASLI_ESCAPE(container_ != 0, return 0); - resizeHelper(size, container_); - it_ = container_->begin(); - size_ = size; - return size; - } - - void* pointer() const{ return reinterpret_cast(container_); } - TypeID elementType() const{ return TypeID::get(); } - TypeID containerType() const{ return TypeID::get(); } - - - bool next() - { - YASLI_ESCAPE(container_ && it_ != container_->end(), return false); - ++it_; - return it_ != container_->end(); - } - - void* elementPointer() const { return &*it_; } - size_t elementSize() const { return sizeof(typename Container::value_type); } - - bool operator()(IArchive& ar, const char* name, const char* label) - { - YASLI_ESCAPE(container_, return false); - if (it_ == container_->end()) - { - it_ = container_->insert(container_->end(), Element()); - return ar(*it_, name, label); - } - else - { - return ar(*it_, name, label); - } - } - operator bool() const{ - return container_ != 0; - } - void serializeNewElement(IArchive& ar, const char* name = "", const char* label = 0) const - { - Element element; - ar(element, name, label); - } - // ^^^ - protected: - Container* container_; - typename Container::iterator it_; - size_t size_; - };/*}}}*/ -} - -namespace std -{ - template - bool Serialize(Serialization::IArchive& ar, std::vector& container, const char* name, const char* label) - { - Serialization::ContainerSTL, T> ser(&container); - return ar(static_cast(ser), name, label); - } - - template - bool Serialize(Serialization::IArchive& ar, std::list& container, const char* name, const char* label) - { - Serialization::ContainerSTL, T> ser(&container); - return ar(static_cast(ser), name, label); - } - - template - bool Serialize(Serialization::IArchive& ar, std::map& container, const char* name, const char* label) - { - std::vector > temp; - if (ar.IsOutput()) - { - temp.assign(container.begin(), container.end()); - } - if (!ar(temp, name, label)) - { - return false; - } - if (ar.IsInput()) - { - container.clear(); - container.insert(temp.begin(), temp.end()); - } - return true; - } -} - -// --------------------------------------------------------------------------- -namespace Serialization { - class StringSTL - : public IString - { - public: - StringSTL(string& str) - : str_(str) { } - - void set(const char* value) { str_ = value; } - const char* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - string& str_; - }; - - inline bool Serialize(Serialization::IArchive& ar, Serialization::string& value, const char* name, const char* label) - { - Serialization::StringSTL str(value); - return ar(static_cast(str), name, label); - } - - // --------------------------------------------------------------------------- - - class WStringSTL - : public IWString - { - public: - WStringSTL(Serialization::wstring& str) - : str_(str) { } - - void set(const wchar_t* value) { str_ = value; } - const wchar_t* get() const { return str_.c_str(); } - const void* handle() const { return &str_; } - TypeID type() const { return TypeID::get(); } - private: - wstring& str_; - }; - - inline bool Serialize(Serialization::IArchive& ar, Serialization::wstring& value, const char* name, const char* label) - { - Serialization::WStringSTL str(value); - return ar(static_cast(str), name, label); - } - - // --------------------------------------------------------------------------- - - template - struct StdPair - { - StdPair(std::pair& pair) - : pair_(pair) {} - void Serialize(Serialization::IArchive& ar) - { - ar(pair_.first, "key", "Key"); - ar(pair_.second, "value", "Value"); - } - std::pair& pair_; - }; - - template - struct StdStringPair - : Serialization::IKeyValue - { - const char* get() const { return pair_.first.c_str(); } - void set(const char* key) { pair_.first.assign(key); } - const void* handle() const { return &pair_; } - Serialization::TypeID type() const { return Serialization::TypeID::get(); } - bool serializeValue(Serialization::IArchive& ar, const char* name, const char* label) - { - return ar(pair_.second, name, label); - } - - StdStringPair(std::pair& pair) - : pair_(pair) - { - } - - std::pair& pair_; - }; -} - -namespace std -{ - template - bool Serialize(Serialization::IArchive& ar, std::pair& pair, const char* name, const char* label) - { - Serialization::StdPair keyValue(pair); - return ar(keyValue, name, label); - } - - template - bool Serialize(Serialization::IArchive& ar, std::pair& pair, const char* name, const char* label) - { - Serialization::StdStringPair keyValue(pair); - return ar(static_cast(keyValue), name, label); - } -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STLIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Serializer.h b/Code/CryEngine/CryCommon/Serialization/Serializer.h deleted file mode 100644 index 13acc57cec..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Serializer.h +++ /dev/null @@ -1,268 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZER_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZER_H -#pragma once - - -#include -#include "Assert.h" -#include "TypeID.h" - -namespace Serialization { - class IArchive; - class IClassFactory; - - typedef bool(* SerializeStructFunc)(void*, IArchive&); - - typedef bool(* SerializeContainerFunc)(void*, IArchive&, size_t index); - typedef size_t(* ContainerResizeFunc)(void*, size_t size); - typedef size_t(* ContainerSizeFunc)(void*); - - // Struct serializer. - // - // This type is used to pass needed struct/class type information through abstract interface. - // Most importantly it captures: - // - pointer to object - // - reference to serialize method (indirectly through pointer to static func.) - // - TypeID - struct SStruct/*{{{*/ - { - friend class IArchive; - public: - SStruct() - : object_(0) - , size_(0) - , serializeFunc_(0) - { - } - - SStruct(TypeID type, void* object, size_t size, SerializeStructFunc Serialize) - : type_(type) - , object_(object) - , size_(size) - , serializeFunc_(Serialize) - { - YASLI_ASSERT(object != 0); - } - - SStruct(const SStruct& _original) - : type_(_original.type_) - , object_(_original.object_) - , size_(_original.size_) - , serializeFunc_(_original.serializeFunc_) - { - } - - template - explicit SStruct(const T& object) - { - type_ = TypeID::get(); - object_ = (void*)(&object); - size_ = sizeof(T); - serializeFunc_ = &SStruct::serializeRaw; - } - - template - explicit SStruct(const T& object, TypeID type) - { - type_ = type; - object_ = (void*)(&object); - size_ = sizeof(T); - serializeFunc_ = &SStruct::serializeRaw; - } - - // This constructs SStruct from an object that doesn't have Serialize method. - // Such SStruct can not be serialized but conveys object reference and type - // information that is needed for Property-archives. Used for decorators. - template - static SStruct ForEdit(const T& object) - { - SStruct r; - r.type_ = TypeID::get(); - r.object_ = (void*)&object; - r.size_ = sizeof(T); - r.serializeFunc_ = 0; - return r; - } - - bool operator()(IArchive& ar, const char* name, const char* label) const; - bool operator()(IArchive& ar) const; - operator bool() const{ - return object_ != 0; - } - bool operator==(const SStruct& rhs) const{ return object_ == rhs.object_ && serializeFunc_ == rhs.serializeFunc_; } - bool operator!=(const SStruct& rhs) const{ return !operator==(rhs); } - void* pointer() const{ return object_; } - void setPointer(void* p) { object_ = p; } - TypeID type() const{ return type_; } - void setType(const TypeID& type) { type_ = type; } - size_t size() const{ return size_; } - SerializeStructFunc serializeFunc() const{ return serializeFunc_; } - - template - static bool serializeRaw(void* rawPointer, IArchive& ar) - { - YASLI_ESCAPE(rawPointer, return false); - // If you're getting compile error here, most likely, you have one of the following situations: - // - The type you're trying to serialize doesn't have Serialize _method_ implemented. - // - Type is supposed to be serialized with non-member Serialize function and this function is out of scope. - ((T*)(rawPointer))->Serialize(ar); - return true; - } - - template - T* cast() const - { - if (type_ == Serialization::TypeID::get()) - { - return (T*)object_; - } - else - { - return 0; - } - } - private: - - TypeID type_; - void* object_; - size_t size_; - SerializeStructFunc serializeFunc_; - };/*}}}*/ - typedef std::vector SStructs; - - // --------------------------------------------------------------------------- - - // This type is used to generalize access to specific container types. - // It is used by concrete IArchive implementations. - class IContainer - { - public: - virtual ~IContainer() { } - - virtual size_t size() const = 0; - virtual size_t resize(size_t size) = 0; - virtual bool isFixedSize() const{ return false; } - - virtual void* pointer() const = 0; - virtual bool next() = 0; - virtual TypeID containerType() const = 0; - - virtual TypeID elementType() const = 0; - virtual void* elementPointer() const = 0; - virtual size_t elementSize() const = 0; - - virtual bool operator()(IArchive& ar, const char* name, const char* label) = 0; - virtual operator bool() const = 0; - virtual void serializeNewElement(IArchive& ar, const char* name = "", const char* label = 0) const = 0; - }; - - template - class ContainerArray - : public IContainer /*{{{*/ - { - friend class IArchive; - public: - explicit ContainerArray(T* array = 0, int size = 0) - : array_(array) - , index_(0) - , size_(size) - { - } - - // from ContainerSerializationInterface: - size_t size() const{ return size_; } - size_t resize([[maybe_unused]] size_t size) - { - index_ = 0; - return size_; - } - - void* pointer() const{ return reinterpret_cast(array_); } - TypeID containerType() const{ return TypeID::get(); } - TypeID elementType() const{ return TypeID::get(); } - void* elementPointer() const { return &array_[index_]; } - size_t elementSize() const { return sizeof(T); } - virtual bool isFixedSize() const{ return true; } - - bool operator()(IArchive& ar, const char* name, const char* label) - { - YASLI_ESCAPE(size_t(index_) < size_, return false); - return ar(array_[index_], name, label); - } - operator bool() const{ - return array_ != 0; - } - bool next() - { - ++index_; - return size_t(index_) < size_; - } - void serializeNewElement(IArchive& ar, const char* name, const char* label) const - { - T element; - ar(element, name, label); - } - // ^^^ - - private: - T* array_; - int index_; - size_t size_; - };/*}}}*/ - - // Generialized interface over owning polymorphic pointers. - // Used by concrete IArchive implementations. - class IPointer - { - public: - virtual ~IPointer() { } - - virtual const char* registeredTypeName() const = 0; - virtual void create(const char* registedTypeName) const = 0; - virtual TypeID baseType() const = 0; - virtual SStruct serializer() const = 0; - virtual void* get() const = 0; - virtual const void* handle() const = 0; - virtual TypeID pointerType() const = 0; - virtual IClassFactory* factory() const = 0; - - void Serialize(IArchive& ar) const; - }; - - class IString - { - public: - virtual ~IString() { } - - virtual void set(const char* value) = 0; - virtual const char* get() const = 0; - virtual const void* handle() const = 0; - virtual TypeID type() const = 0; - }; - class IWString - { - public: - virtual ~IWString() { } - - virtual void set(const wchar_t* value) = 0; - virtual const wchar_t* get() const = 0; - virtual const void* handle() const = 0; - virtual TypeID type() const = 0; - }; -} -// vim:ts=4 sw=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZER_H diff --git a/Code/CryEngine/CryCommon/Serialization/SerializerImpl.h b/Code/CryEngine/CryCommon/Serialization/SerializerImpl.h deleted file mode 100644 index f4e89c185d..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/SerializerImpl.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZERIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZERIMPL_H -#pragma once - -#include "Serializer.h" -#include "IClassFactory.h" -#include "ClassFactory.h" - -// IArchive.h is supposed to be pre-included - -namespace Serialization { - inline bool SStruct::operator()(IArchive& ar) const - { - YASLI_ESCAPE(serializeFunc_ && object_, return false); - return serializeFunc_(object_, ar); - } - - inline bool SStruct::operator()(IArchive& ar, const char* name, const char* label) const - { - return ar(*this, name, label); - } - - - inline void IPointer::Serialize(IArchive& ar) const - { - const bool noEmptyNames = ar.GetCaps(IArchive::NO_EMPTY_NAMES); - const char* const typePropertyName = noEmptyNames ? "type" : ""; - const char* const dataPropertyName = noEmptyNames ? "data" : ""; - - TypeID baseTypeID = baseType(); - const char* oldRegisteredName = registeredTypeName(); - if (!oldRegisteredName) - { - oldRegisteredName = ""; - } - IClassFactory* factory = this->factory(); - - if (ar.IsOutput()) - { - if (oldRegisteredName[0] != '\0') - { - TypeNameWithFactory pair(oldRegisteredName, factory); - if (ar(pair, typePropertyName)) - { - ar(serializer(), dataPropertyName); - } - else - { - ar.Warning(pair, "Unable to write typeID!"); - } - } - } - else - { - TypeNameWithFactory pair("", factory); - if (!ar(pair, typePropertyName)) - { - if (oldRegisteredName[0] != '\0') - { - create(""); // 0 - } - return; - } - - if (oldRegisteredName[0] != '\0' && (pair.registeredName.empty() || (pair.registeredName != oldRegisteredName))) - { - create(""); // 0 - } - if (!pair.registeredName.empty()) - { - if (!get()) - { - create(pair.registeredName.c_str()); - } - ar(serializer(), dataPropertyName); - } - } - } -} -// vim:sw=4 ts=4: - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SERIALIZERIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/SmartPtr.h b/Code/CryEngine/CryCommon/Serialization/SmartPtr.h deleted file mode 100644 index 8c109887b7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/SmartPtr.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTR_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTR_H -#pragma once - -template -class _smart_ptr; - -namespace Serialization -{ - class IArchive; -}; - -template -bool Serialize(Serialization::IArchive& ar, _smart_ptr& ptr, const char* name, const char* label); - -#include "SmartPtrImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTR_H diff --git a/Code/CryEngine/CryCommon/Serialization/SmartPtrImpl.h b/Code/CryEngine/CryCommon/Serialization/SmartPtrImpl.h deleted file mode 100644 index 64cd7f65c1..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/SmartPtrImpl.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTRIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTRIMPL_H -#pragma once - -#include "SmartPtr.h" -#include -#include "ClassFactory.h" - -// Exposes _smart_ptr<> as serializeable type for Serialization::IArchive -template -class SmartPtrSerializer - : public Serialization::IPointer -{ -public: - SmartPtrSerializer(_smart_ptr& ptr) - : m_ptr(ptr) - {} - - const char* registeredTypeName() const override - { - if (m_ptr) - { - return Serialization::ClassFactory::the().getRegisteredTypeName(m_ptr.get()); - } - else - { - return ""; - } - } - - void create(const char* registeredTypeName) const override - { - CRY_ASSERT(!m_ptr || m_ptr->NumRefs() == 1); - if (registeredTypeName && registeredTypeName[0] != '\0') - { - m_ptr.reset(Serialization::ClassFactory::the().create(registeredTypeName)); - } - else - { - m_ptr.reset((T*)0); - } - } - Serialization::TypeID baseType() const{ return Serialization::TypeID::get(); } - virtual Serialization::SStruct serializer() const{ return Serialization::SStruct(*m_ptr); } - void* get() const{ return reinterpret_cast(m_ptr.get()); } - const void* handle() const { return &m_ptr; } - Serialization::TypeID pointerType() const { return Serialization::TypeID::get<_smart_ptr >(); } - Serialization::IClassFactory* factory() const{ return &Serialization::ClassFactory::the(); } -protected: - _smart_ptr& m_ptr; -}; - -template -bool Serialize(Serialization::IArchive& ar, _smart_ptr& ptr, const char* name, const char* label) -{ - SmartPtrSerializer serializer(ptr); - return ar(static_cast(serializer), name, label); -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_SMARTPTRIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/StringList.h b/Code/CryEngine/CryCommon/Serialization/StringList.h deleted file mode 100644 index 4b2ca96278..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/StringList.h +++ /dev/null @@ -1,301 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLIST_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLIST_H -#pragma once - - -#include -#include "Serialization/Strings.h" -#include "Serialization/DynArray.h" -#include -#include "Serialization/Assert.h" -#ifndef SERIALIZATION_STANDALONE -#include -#endif - -#include - -namespace Serialization { - class IArchive; - class StringListStatic -#ifdef SERIALIZATION_STANDALONE - : public std::vector - { -#else - : public AZStd::fixed_vector { -#endif - public: - enum - { - npos = -1 - }; - int find(const char* value) const - { - int numItems = int(size()); - for (int i = 0; i < numItems; ++i) - { - if (strcmp((*this)[i], value) == 0) - { - return i; - } - } - return npos; - } - }; - - class StringListStaticValue - { - public: - StringListStaticValue(const StringListStaticValue& original) - : stringList_(original.stringList_) - , index_(original.index_) - { - handle_ = this; - } - StringListStaticValue() - : stringList_(0) - , index_(StringListStatic::npos) - { - handle_ = this; - } - StringListStaticValue(const StringListStatic& stringList, int value) - : stringList_(&stringList) - , index_(value) - { - handle_ = this; - } - StringListStaticValue(const StringListStatic& stringList, int value, const void* handle, const Serialization::TypeID& type) - : stringList_(&stringList) - , index_(value) - , handle_(handle) - , type_(type) - { - } - StringListStaticValue(const StringListStatic& stringList, const char* value, const void* handle, const Serialization::TypeID& type) - : stringList_(&stringList) - , index_(stringList.find(value)) - , handle_(handle) - , type_(type) - { - YASLI_ASSERT(index_ != StringListStatic::npos); - } - StringListStaticValue& operator=(const char* value) - { - index_ = stringList_->find(value); - return *this; - } - StringListStaticValue& operator=(int value) - { - YASLI_ASSERT(value >= 0 && size_t(value) < size_t(stringList_->size())); - YASLI_ASSERT(this != 0); - index_ = value; - return *this; - } - StringListStaticValue& operator=(const StringListStaticValue& rhs) - { - stringList_ = rhs.stringList_; - index_ = rhs.index_; - return *this; - } - const char* c_str() const - { - if (index_ >= 0 && size_t(index_) < size_t(stringList_->size())) - { - return (*stringList_)[index_]; - } - else - { - return ""; - } - } - int index() const{ return index_; } - const void* handle() const{ return handle_; } - Serialization::TypeID type() const { return type_; } - const StringListStatic& stringList() const{ return *stringList_; } - template - void Serialize(IArchive& ar) - { - ar(index_, "index"); - } - protected: - const StringListStatic* stringList_; - int index_; - const void* handle_; - Serialization::TypeID type_; - }; - - class StringList -#ifdef SERIALIZATION_STANDALONE - : public std::vector - { -#else - : public DynArray{ -#endif - public: - StringList() {} - StringList(const StringList& rhs) - { - *this = rhs; - } - StringList& operator=(const StringList& rhs) - { - // As StringList crosses dll boundaries it is important to copy strings - // rather than reference count them to be sure that stored CryString uses - // proper allocator. - resize(rhs.size()); - for (size_t i = 0; i < size_t(size()); ++i) - { - (*this)[i] = rhs[i].c_str(); - } - return *this; - } - StringList(const StringListStatic& rhs) - { - const int size = int(rhs.size()); - resize(size); - for (int i = 0; i < int(size); ++i) - { - (*this)[i] = rhs[i]; - } - } - enum - { - npos = -1 - }; - int find(const char* value) const - { - const int numItems = int(size()); - for (int i = 0; i < numItems; ++i) - { - if ((*this)[i] == value) - { - return i; - } - } - return npos; - } - }; - - class StringListValue - { - public: - explicit StringListValue(const StringListStaticValue& value) - { - stringList_.resize(value.stringList().size()); - for (size_t i = 0; i < size_t(stringList_.size()); ++i) - { - stringList_[i] = value.stringList()[i]; - } - index_ = value.index(); - } - StringListValue(const StringListValue& value) - { - stringList_ = value.stringList_; - index_ = value.index_; - } - StringListValue() - : index_(StringList::npos) - { - handle_ = this; - } - StringListValue(const StringList& stringList, int value) - : stringList_(stringList) - , index_(value) - { - handle_ = this; - } - StringListValue(const StringList& stringList, int value, const void* handle, const Serialization::TypeID& typeId) - : stringList_(stringList) - , index_(value) - , handle_(handle) - , type_(typeId) - { - } - StringListValue(const StringList& stringList, const char* value) - : stringList_(stringList) - , index_(stringList.find(value)) - { - handle_ = this; - YASLI_ASSERT(index_ != StringList::npos); - } - StringListValue(const StringList& stringList, const char* value, const void* handle, const Serialization::TypeID& typeId) - : stringList_(stringList) - , index_(stringList.find(value)) - , handle_(handle) - , type_(typeId) - { - YASLI_ASSERT(index_ != StringList::npos); - } - StringListValue(const StringListStatic& stringList, const char* value) - : stringList_(stringList) - , index_(stringList.find(value)) - { - handle_ = this; - YASLI_ASSERT(index_ != StringList::npos); - } - StringListValue& operator=(const char* value) - { - index_ = stringList_.find(value); - return *this; - } - StringListValue& operator=(int value) - { - YASLI_ASSERT(value >= 0 && size_t(value) < size_t(stringList_.size())); - YASLI_ASSERT(this != 0); - index_ = value; - return *this; - } - const char* c_str() const - { - if (index_ >= 0 && size_t(index_) < size_t(stringList_.size())) - { - return stringList_[index_].c_str(); - } - else - { - return ""; - } - } - int index() const{ return index_; } - const void* handle() const { return handle_; } - Serialization::TypeID type() const { return type_; } - const StringList& stringList() const{ return stringList_; } - template - void Serialize(IArchive& ar) - { - ar(index_, "index"); - ar(stringList_, "stringList"); - } - protected: - StringList stringList_; - int index_; - const void* handle_; - Serialization::TypeID type_; - }; - - class IArchive; - - void splitStringList(StringList* result, const char* str, char sep); - void joinStringList(string* result, const StringList& stringList, char sep); - void joinStringList(string* result, const StringListStatic& stringList, char sep); - - bool Serialize(Serialization::IArchive& ar, Serialization::StringList& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::StringListValue& value, const char* name, const char* label); - bool Serialize(Serialization::IArchive& ar, Serialization::StringListStaticValue& value, const char* name, const char* label); -} - -#include "StringListImpl.h" - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLIST_H diff --git a/Code/CryEngine/CryCommon/Serialization/StringListImpl.h b/Code/CryEngine/CryCommon/Serialization/StringListImpl.h deleted file mode 100644 index 4f7b573623..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/StringListImpl.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLISTIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLISTIMPL_H -#pragma once - -#include "StringList.h" -#include "IArchive.h" -#include "DynArray.h" -#include "STL.h" - -namespace Serialization { - // --------------------------------------------------------------------------- - inline void splitStringList(StringList* result, const char* str, char delimeter) - { - result->clear(); - - const char* ptr = str; - for (; *ptr; ++ptr) - { - if (*ptr == delimeter) - { - result->push_back(string(str, ptr)); - str = ptr + 1; - } - } - result->push_back(string(str, ptr)); - } - - inline void joinStringList(string* result, const StringList& stringList, char sep) - { - YASLI_ESCAPE(result != 0, return ); - result->clear(); - for (StringList::const_iterator it = stringList.begin(); it != stringList.end(); ++it) - { - if (!result->empty()) - { - result += sep; - } - result->append(*it); - } - } - - inline void joinStringList(string* result, const StringListStatic& stringList, char sep) - { - YASLI_ESCAPE(result != 0, return ); - result->clear(); - for (StringListStatic::const_iterator it = stringList.begin(); it != stringList.end(); ++it) - { - if (!result->empty()) - { - (*result) += sep; - } - YASLI_ESCAPE(*it != 0, continue); - result->append(*it); - } - } - - inline bool Serialize(Serialization::IArchive& ar, Serialization::StringList& value, const char* name, const char* label) - { -#ifdef SERIALIZATION_STANDALONE - return ar(static_cast&>(value), name, label); -#else - return ar(static_cast&>(value), name, label); -#endif - } - - inline bool Serialize(Serialization::IArchive& ar, Serialization::StringListValue& value, const char* name, const char* label) - { - using Serialization::string; - if (ar.IsEdit()) - { - return ar(Serialization::SStruct(value), name, label); - } - else - { - string str; - if (ar.IsOutput()) - { - str = value.c_str(); - } - if (ar(str, name, label) && ar.IsInput()) - { - value = str.c_str(); - return true; - } - return false; - } - } - - inline bool Serialize(Serialization::IArchive& ar, Serialization::StringListStaticValue& value, const char* name, const char* label) - { - using Serialization::string; - if (ar.IsEdit()) - { - return ar(Serialization::SStruct(value), name, label); - } - else - { - string str; - if (ar.IsOutput()) - { - str = value.c_str(); - } - if (ar(str, name, label) && ar.IsInput()) - { - value = str.c_str(); - return true; - } - return true; - } - } -} - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGLISTIMPL_H diff --git a/Code/CryEngine/CryCommon/Serialization/Strings.h b/Code/CryEngine/CryCommon/Serialization/Strings.h deleted file mode 100644 index db8be9c3b8..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/Strings.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGS_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGS_H -#pragma once - -#ifdef SERIALIZATION_STANDALONE -#include -namespace Serialization { - using std::string; - using std::wstring; -} -#else -#include - -namespace Serialization { - typedef CryStringT string; - typedef CryStringT wstring; -} -#endif // SERIALIZATION_STANDALONE -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_STRINGS_H diff --git a/Code/CryEngine/CryCommon/Serialization/TypeID.h b/Code/CryEngine/CryCommon/Serialization/TypeID.h deleted file mode 100644 index 067813d9fc..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/TypeID.h +++ /dev/null @@ -1,290 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEID_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEID_H -#pragma once - - -#include "Serialization/Assert.h" -#include "Serialization/Strings.h" -#include - -namespace Serialization { - class IArchive; - struct TypeInfo; - class TypeID - { - public: - TypeID() - : typeInfo_(0) - , module_(0) {} - - TypeID(const TypeID& original) - : typeInfo_(original.typeInfo_) - , module_(original.module_) - { - } - - operator bool() const{ - return *this != TypeID(); - } - - template - static TypeID get(); - std::size_t sizeOf() const; - const char* name() const; - - bool operator==(const TypeID& rhs) const; - bool operator!=(const TypeID& rhs) const; - bool operator<(const TypeID& rhs) const; - private: - TypeInfo* typeInfo_; - void* module_; - friend struct TypeInfo; - friend class TypeDescription; - }; - - struct TypeInfo - { - TypeID id; - size_t size; - char name[128]; - - // We are trying to minimize type names here. Stripping namespaces, - // whitespaces and S/C/E/I prefixes. Why namespaces? Type names are usually - // used in two contexts: for unique name within factory context, where - // collision is unlikely, or for filtering in PropertyTree where concise - // name is much more useful. - static void cleanTypeName(char*& d, const char* dend, const char*& s, const char* send) - { - if (strncmp(s, "class ", 6) == 0) - { - s += 6; - } - else if (strncmp(s, "struct ", 7) == 0) - { - s += 7; - } - - while (*s == ' ' && s != send) - { - ++s; - } - - // strip C/S/I/E prefixes - if ((*s == 'C' || *s == 'S' || *s == 'I' || *s == 'E') && s[1] >= 'A' && s[1] <= 'Z') - { - ++s; - } - - if (s >= send) - { - return; - } - - char* startd = d; - while (d != dend && s != send) - { - while (*s == ' ' && s != send) - { - ++s; - } - if (s == send) - { - break; - } - if (*s == ':' && s[1] == ':') - { - // strip namespaces - s += 2; - d = startd; - - if ((*s == 'C' || *s == 'S' || *s == 'I' || *s == 'E') && s[1] >= 'A' && s[1] <= 'Z') - { - ++s; - } - } - if (s >= send) - { - break; - } - if (*s == '<') - { - * d = '<'; - ++d; - ++s; - cleanTypeName(d, dend, s, send); - } - else if (*s == '>') - { - * d = '\0'; - return; - } - * d = *s; - ++s; - ++d; - } - } - - template - static void extractTypeName(char (&name)[nameLen], const char* funcName) - { -#ifdef __clang__ - // "static yasli::TypeID yasli::TypeID::get() [T = ActualTypeName]" - const char* s = strstr(funcName, "[T = "); - if (s) - { - s += 5; - } - const char* send = strrchr(funcName, ']'); -#elif __GNUC__ >= 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) - // "static yasli::TypeID yasli::TypeID::get() [with T = ActualTypeName]" - const char* s = strstr(funcName, "[with T = "); - if (s) - { - s += 9; - } - const char* send = strrchr(funcName, ']'); -#else - // "static yasli::TypeID yasli::TypeID::get()" - const char* s = strchr(funcName, '<'); - const char* send = strrchr(funcName, '>'); - YASLI_ASSERT(s != 0 && send != 0); - if (s != send) - { - ++s; - } -#endif - YASLI_ASSERT(s != 0 && send != 0); - - char* d = name; - const char* dend = name + sizeof(name) - 1; - cleanTypeName(d, dend, s, send); - * d = '\0'; - - // This assertion is not critical, but may result in collision as - // stripped name wil be used, e.g. for lookup in factory. - YASLI_ASSERT(s == send && "Type name does not fit into the buffer"); - } - - TypeInfo(size_t _size, const char* templatedFunctionName) - : size(_size) - { - extractTypeName(name, templatedFunctionName); - id.typeInfo_ = this; - static int moduleSpecificSymbol; - id.module_ = &moduleSpecificSymbol; - } - - bool operator==(const TypeInfo& rhs) const - { - return size == rhs.size && strcmp(name, rhs.name) == 0; - } - - bool operator<(const TypeInfo& rhs) const - { - if (size == rhs.size) - { - return strcmp(name, rhs.name) < 0; - } - else - { - return size < rhs.size; - } - } - }; - - template - TypeID TypeID::get() - { -#ifdef _MSC_VER - static TypeInfo typeInfo(sizeof(T), __FUNCSIG__); -#else - static TypeInfo typeInfo(sizeof(T), __PRETTY_FUNCTION__); -#endif - return typeInfo.id; - } - - inline const char* TypeID::name() const - { - if (typeInfo_) - { - return typeInfo_->name; - } - else - { - return ""; - } - } - - inline size_t TypeID::sizeOf() const - { - if (typeInfo_) - { - return typeInfo_->size; - } - else - { - return 0; - } - } - - inline bool TypeID::operator==(const TypeID& rhs) const - { - if (typeInfo_ == rhs.typeInfo_) - { - return true; - } - else if (!typeInfo_ || !rhs.typeInfo_) - { - return false; - } - else if (module_ == rhs.module_) - { - return false; - } - else - { - return *typeInfo_ == *rhs.typeInfo_; - } - } - - inline bool TypeID::operator!=(const TypeID& rhs) const - { - return !operator==(rhs); - } - - inline bool TypeID::operator<(const TypeID& rhs) const - { - if (!typeInfo_) - { - return rhs.typeInfo_ != 0; - } - else if (!rhs.typeInfo_) - { - return false; - } - else - { - return *typeInfo_ < *rhs.typeInfo_; - } - } - - template - T* createDerivedClass(TypeID typeID); -} - -//bool Serialize(Serialization::IArchive& ar, Serialization::TypeID& typeID, const char* name, const char* label); - -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEID_H diff --git a/Code/CryEngine/CryCommon/Serialization/TypeInfo.h b/Code/CryEngine/CryCommon/Serialization/TypeInfo.h deleted file mode 100644 index eafd959d51..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/TypeInfo.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFO_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFO_H -#pragma once - - -namespace Serialization { - class IArchive; -} - -struct STypeInfoInstance -{ - template - STypeInfoInstance(T& obj) - : m_pTypeInfo(&TypeInfo(&obj)) - , m_pObject(&obj) - { - } - - STypeInfoInstance(const CTypeInfo* typeInfo, void* object) - : m_pTypeInfo(typeInfo) - , m_pObject(object) - { - } - - inline void Serialize(Serialization::IArchive& ar); - - const CTypeInfo* m_pTypeInfo; - void* m_pObject; - std::set m_persistentStrings; -}; - -#include "TypeInfoImpl.h" -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFO_H diff --git a/Code/CryEngine/CryCommon/Serialization/TypeInfoImpl.h b/Code/CryEngine/CryCommon/Serialization/TypeInfoImpl.h deleted file mode 100644 index 7f94e8bec7..0000000000 --- a/Code/CryEngine/CryCommon/Serialization/TypeInfoImpl.h +++ /dev/null @@ -1,245 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFOIMPL_H -#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFOIMPL_H -#pragma once - - - -#include "CryTypeInfo.h" -#include "Serialization/Decorators/Range.h" -#include "Serialization/Enum.h" -#include "ISplines.h" -#include -#include "Serialization/Color.h" -#include "Cry_Color.h" -#include "Decorators/Resources.h" - -struct SPrivateTypeInfoInstanceLevel -{ - SPrivateTypeInfoInstanceLevel(const CTypeInfo* typeInfo, void* object, STypeInfoInstance* instance) - : m_pTypeInfo(typeInfo) - , m_pObject(object) - , m_instance(instance) - { - } - - void Serialize(Serialization::IArchive& ar) - { - for AllSubVars(pVar, *m_pTypeInfo) - { - string group; - if (pVar->GetAttr("Group", group)) - { - if (!m_sCurrentGroup.empty()) - { - ar.CloseBlock(); - } - const char* name = m_instance->m_persistentStrings.insert(group).first->c_str(); - ar.OpenBlock(name, name); - m_sCurrentGroup = name; - } - else - { - const char* name = pVar->GetName(); - if (!*name) - { - name = pVar->Type.Name; - } - - const char* label = pVar->GetName(); - if (!*label) - { - string n = "^"; - n += pVar->GetName(); - label = m_instance->m_persistentStrings.insert(n).first->c_str(); - } - - SerializeVariable(pVar, m_pObject, ar, name, label); - } - } - - if (!m_sCurrentGroup.empty()) - { - ar.CloseBlock(); - m_sCurrentGroup.clear(); - } - } - - template - void SerializeT(const CTypeInfo::CVarInfo* pVar, void* pParentAddress, Serialization::IArchive& ar, const char* name, const char* label) - { - T value; - const CTypeInfo& type = pVar->Type; - type.ToValue(pVar->GetAddress(pParentAddress), value); - ar(value, name, label); - if (ar.IsInput()) - { - type.FromValue(pVar->GetAddress(pParentAddress), value); - } - } - - template - void SerializeNumericalT(const CTypeInfo::CVarInfo* pVar, void* pParentAddress, Serialization::IArchive& ar, const char* name, const char* label) - { - T value; - const CTypeInfo& type = pVar->Type; - type.ToValue(pVar->GetAddress(pParentAddress), value); - - float limMin, limMax; - if (pVar->GetLimit(eLimit_Min, limMin) && pVar->GetLimit(eLimit_Max, limMax)) - { - ar(Serialization::Range(value, limMin, limMax), name, label); - } - else - { - ar(value, name, label); - } - if (ar.IsInput()) - { - type.FromValue(pVar->GetAddress(pParentAddress), value); - } - } - - void SerializeVariable(const CTypeInfo::CVarInfo* pVar, void* pParentAddress, Serialization::IArchive& ar, const char* name, const char* label) - { - const CTypeInfo& type = pVar->Type; - - if (type.HasSubVars()) - { - if (strcmp(name, "Color") == 0) - { - Color3F value; - const CTypeInfo& type = pVar->Type; - type.ToValue(pVar->GetAddress(pParentAddress), value); - ColorF colour = value; - ar(colour, name, label); - if (ar.IsInput()) - { - value = Color3F(colour.r, colour.g, colour.b); - type.FromValue(pVar->GetAddress(pParentAddress), value); - } - } - else - { - // load params of sub-variables (variable is a struct or vector) - SPrivateTypeInfoInstanceLevel instance(&type, pVar->GetAddress(pParentAddress), m_instance); - ar(instance, name, label); - } - } - else - { - if (type.IsType()) - { - SerializeT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.IsType()) - { - SerializeNumericalT(pVar, pParentAddress, ar, name, label); - } - else if (type.EnumElem(0)) - { - Serialization::StringList stringList; - const char* enumType = type.EnumElem(0); - for (int i = 1; enumType; ++i) - { - stringList.push_back(enumType); - enumType = type.EnumElem(i); - } - - string enumValue = pVar->ToString(pParentAddress); - int index = std::max(stringList.find(enumValue.c_str()), 0); - - Serialization::StringListValue stringListValue(stringList, index); - ar(stringListValue, name, label); - if (ar.IsInput()) - { - pVar->FromString(pParentAddress, stringListValue.c_str()); - } - } - else - { - ISplineInterpolator* pSpline = 0; - if (type.ToValue(pVar->GetAddress(pParentAddress), pSpline)) - { - // TODO: Curve field - } - else - { - string value; - value = pVar->ToString(pParentAddress); - - if (strcmp(name, "Texture") == 0) - { - // TODO: Texture field - } - else if (strcmp(name, "Material") == 0) - { - // TODO: Material field - } - else if (strcmp(name, "Geometry") == 0) - { - ar(Serialization::ModelFilename(value), name, label); - } - else if (strcmp(name, "Sound") == 0) - { - ar(Serialization::SoundName(value), name, label); - } - else if (strcmp(name, "GeomCache") == 0) - { - // TODO: Geom cache field - } - else - { - ar(value, name, label); - } - if (ar.IsInput()) - { - pVar->FromString(pParentAddress, value.c_str()); - } - } - } - } - } - -private: - const CTypeInfo* m_pTypeInfo; - void* m_pObject; - string m_sCurrentGroup; - STypeInfoInstance* m_instance; -}; - -//------------------------------ -inline void STypeInfoInstance::Serialize(Serialization::IArchive& ar) -{ - SPrivateTypeInfoInstanceLevel instance(m_pTypeInfo, m_pObject, this); - instance.Serialize(ar); -} -#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_TYPEINFOIMPL_H diff --git a/Code/CryEngine/CryCommon/SettingsManagerHelpers.cpp b/Code/CryEngine/CryCommon/SettingsManagerHelpers.cpp deleted file mode 100644 index 9746b00574..0000000000 --- a/Code/CryEngine/CryCommon/SettingsManagerHelpers.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "ProjectDefines.h" - -#if defined(CRY_ENABLE_RC_HELPER) - -#include "SettingsManagerHelpers.h" -#include "EngineSettingsManager.h" - -#include -#include -#include - -#include -#include - -#if defined(AZ_PLATFORM_WINDOWS) -#include -#include //ShellExecuteW() -#pragma comment(lib, "Shell32.lib") -#endif -#if AZ_TRAIT_OS_PLATFORM_APPLE -#include "AppleSpecific.h" -#endif - -bool SettingsManagerHelpers::Utf16ContainsAsciiOnly(const wchar_t* wstr) -{ - while (*wstr) - { - if (*wstr > 127 || *wstr < 0) - { - return false; - } - ++wstr; - } - return true; -} - - -void SettingsManagerHelpers::ConvertUtf16ToUtf8(const wchar_t* src, CCharBuffer dst) -{ - if (dst.getSizeInElements() <= 0) - { - return; - } - - if (src[0] == 0) - { - dst[0] = 0; - } - else - { - const std::codecvt& utf8Utf16Facet = std::use_facet>(std::locale()); - std::mbstate_t mb{}; - const wchar_t* from_next; - char* to_next; - std::codecvt_base::result result = utf8Utf16Facet.out(mb, src, src + wcslen(src), from_next, dst.getPtr(), dst.getPtr() + dst.getSizeInElements(), to_next); - if (result != std::codecvt_base::ok) - { - dst[0] = 0; - } - else - { - to_next = 0; - } - } -} - - -void SettingsManagerHelpers::ConvertUtf8ToUtf16(const char* src, CWCharBuffer dst) -{ - if (dst.getSizeInElements() <= 0) - { - return; - } - - if (src[0] == 0) - { - dst[0] = 0; - } - else - { - const std::codecvt& utf8Utf16Facet = std::use_facet>(std::locale()); - std::mbstate_t mb{}; - const char* from_next; - wchar_t* to_next; - std::codecvt_base::result result = utf8Utf16Facet.in(mb, src, src + strlen(src), from_next, dst.getPtr(), dst.getPtr() + dst.getSizeInElements(), to_next); - if (result != std::codecvt_base::ok) - { - dst[0] = 0; - } - else - { - to_next = 0; - } - } -} - - -void SettingsManagerHelpers::GetAsciiFilename(const wchar_t* wfilename, CCharBuffer buffer) -{ - if (buffer.getSizeInElements() <= 0) - { - return; - } - - if (wfilename[0] == 0) - { - buffer[0] = 0; - return; - } - - if (Utf16ContainsAsciiOnly(wfilename)) - { - ConvertUtf16ToUtf8(wfilename, buffer); - return; - } - -#if defined(AZ_PLATFORM_WINDOWS) - // The path is non-ASCII unicode, so let's resort to short filenames (they are always ASCII-only, I hope) - wchar_t shortW[MAX_PATH]; - const int bufferCharCount = sizeof(shortW) / sizeof(shortW[0]); - const int charCount = GetShortPathNameW(wfilename, shortW, bufferCharCount); - if (charCount <= 0 || charCount >= bufferCharCount) - { - buffer[0] = 0; - return; - } - - shortW[charCount] = 0; - if (!Utf16ContainsAsciiOnly(shortW)) - { - buffer[0] = 0; - return; - } - - ConvertUtf16ToUtf8(shortW, buffer); -#else - buffer[0] = 0; -#endif -} - - -////////////////////////////////////////////////////////////////////////// -CSettingsManagerTools::CSettingsManagerTools(const wchar_t* szModuleName) -{ - m_pSettingsManager = new CEngineSettingsManager(szModuleName); -} - -////////////////////////////////////////////////////////////////////////// -CSettingsManagerTools::~CSettingsManagerTools() -{ - delete m_pSettingsManager; -} - -////////////////////////////////////////////////////////////////////////// -bool CSettingsManagerTools::GetInstalledBuildPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) -{ - return m_pSettingsManager->GetInstalledBuildRootPathUtf16(index, name, path); -} - - -bool CSettingsManagerTools::GetInstalledBuildPathAscii(const int index, SettingsManagerHelpers::CCharBuffer name, SettingsManagerHelpers::CCharBuffer path) -{ - wchar_t wName[MAX_PATH]; - wchar_t wPath[MAX_PATH]; - if (GetInstalledBuildPathUtf16(index, SettingsManagerHelpers::CWCharBuffer(wName, sizeof(wName)), SettingsManagerHelpers::CWCharBuffer(wPath, sizeof(wPath)))) - { - SettingsManagerHelpers::GetAsciiFilename(wName, name); - SettingsManagerHelpers::GetAsciiFilename(wPath, path); - return true; - } - return false; -} - - - -////////////////////////////////////////////////////////////////////////// -static bool FileExists(const wchar_t* filename) -{ -#if defined(AZ_PLATFORM_WINDOWS) - const DWORD dwAttrib = GetFileAttributesW(filename); - return dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY); -#else - char utf8Filename[MAX_PATH]; - SettingsManagerHelpers::ConvertUtf16ToUtf8(filename, SettingsManagerHelpers::CCharBuffer(utf8Filename, sizeof(utf8Filename))); - struct stat buffer; - return (stat(utf8Filename, &buffer) == 0); -#endif -} - - -////////////////////////////////////////////////////////////////////////// -void CSettingsManagerTools::GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer wbuffer) -{ - if (wbuffer.getSizeInElements() <= 0) - { - return; - } - - AZStd::string_view exePath; - AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder); - - SettingsManagerHelpers::CFixedString editorExe; - editorExe = wbuffer.getPtr(); - editorExe.appendAscii(exePath.data(), exePath.size()); - - if (editorExe.length() <= 0) - { - wbuffer[0] = 0; - return; - } - - bool bFound = false; - if (Is64bitWindows()) - { - const size_t len = editorExe.length(); - editorExe.appendAscii("/Editor.exe"); - bFound = FileExists(editorExe.c_str()); - if (!bFound) - { - editorExe.setLength(len); - } - } - - const size_t sizeToCopy = (editorExe.length() + 1) * sizeof(wbuffer[0]); - if (!bFound || sizeToCopy > wbuffer.getSizeInBytes()) - { - wbuffer[0] = 0; - } - else - { - memcpy(wbuffer.getPtr(), editorExe.c_str(), sizeToCopy); - } -} - - -////////////////////////////////////////////////////////////////////////// -bool CSettingsManagerTools::CallEditor(void** pEditorWindow, [[maybe_unused]] void* hParent, const char* pWindowName, const char* pFlag) -{ -#if !defined(AZ_PLATFORM_WINDOWS) - AZ_Assert(false, "CSettingsManagerTools::CallEditor is not supported on this platform!"); - return false; -#else - HWND window = ::FindWindowA(NULL, pWindowName); - if (window) - { - *pEditorWindow = window; - return true; - } - else - { - *pEditorWindow = 0; - - wchar_t buffer[512] = { L'\0' }; - GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))); - - SettingsManagerHelpers::CFixedString wFlags; - SettingsManagerHelpers::ConvertUtf8ToUtf16(pFlag, wFlags.getBuffer()); - wFlags.setLength(wcslen(wFlags.c_str())); - - if (buffer[0] != '\0') - { - INT_PTR hIns = (INT_PTR)ShellExecuteW(NULL, L"open", buffer, wFlags.c_str(), NULL, SW_SHOWNORMAL); - if (hIns > 32) - { - return true; - } - else - { - MessageBoxA(0, "Editor.exe was not found.\n\nPlease verify CryENGINE root path.", "Error", MB_ICONERROR | MB_OK); - } - } - } - - return false; -#endif -} - -////////////////////////////////////////////////////////////////////////// -// Modified version of -// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139(v=vs.85).aspx -bool CSettingsManagerTools::Is64bitWindows() -{ -#if defined(_WIN64) - // 64-bit programs run only on 64-bit Windows - return true; -#elif !defined(AZ_PLATFORM_WINDOWS) - return false; -#else - // 32-bit programs run on both 32-bit and 64-bit Windows - static bool bWin64 = false; - static bool bOnce = true; - if (bOnce) - { - typedef BOOL (WINAPI * LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); - LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process"); - if (fnIsWow64Process != NULL) - { - BOOL itIsWow64Process = FALSE; - if (fnIsWow64Process(GetCurrentProcess(), &itIsWow64Process)) - { - bWin64 = (itIsWow64Process == TRUE); - } - } - bOnce = false; - } - return bWin64; -#endif -} - -#endif // #if defined(CRY_ENABLE_RC_HELPER) - -// eof diff --git a/Code/CryEngine/CryCommon/SettingsManagerHelpers.h b/Code/CryEngine/CryCommon/SettingsManagerHelpers.h deleted file mode 100644 index e05d2b97aa..0000000000 --- a/Code/CryEngine/CryCommon/SettingsManagerHelpers.h +++ /dev/null @@ -1,491 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H -#define CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H -#pragma once - -#include "ProjectDefines.h" -#include // memcpy -#include // std::min - - -namespace SettingsManagerHelpers -{ - namespace Utils - { - inline size_t strlen(const char* p) - { - return p ? ::strlen(p) : 0; - } - - inline size_t strcmp(const char* p0, const char* p1) - { - return ::strcmp(p0, p1); - } - - - inline size_t strlen(const wchar_t* p) - { - return p ? ::wcslen(p) : 0; - } - - inline size_t strcmp(const wchar_t* p0, const wchar_t* p1) - { - return ::wcscmp(p0, p1); - } - } - - // The function copies characters from src to dst one by one until any of - // the following conditions is met: - // 1) the end of the destination buffer (minus one character) is reached - // 2) the end of the source buffer is reached - // 3) zero character is found in the source buffer - // - // When any of 1), 2), 3) happens, the function writes the terminating zero - // character to the destination buffer and return. - // - // The function guarantees writing the terminating zero character to the - // destination buffer (if the buffer can fit at least one character). - // - // The function returns false when a null pointer is passed or when - // clamping happened (i.e. when the end of the destination buffer is - // reached but the source has some characters left). - inline bool strcpy_with_clamp(char* const dst, size_t const dst_size_in_bytes, const char* const src, size_t const src_size_in_bytes = (size_t)-1) - { - if (!dst || dst_size_in_bytes < sizeof(char)) - { - return false; - } - - if (!src || src_size_in_bytes < sizeof(char)) - { - dst[0] = 0; - return src != 0; // we return true for non-null src without characters - } - - const size_t src_n = src_size_in_bytes; - const size_t n = (std::min)(dst_size_in_bytes - 1, src_n); - - for (size_t i = 0; i < n; ++i) - { - dst[i] = src[i]; - if (!src[i]) - { - return true; - } - } - - dst[n] = 0; - return n >= src_n || src[n] == 0; - } - - - template - class CBuffer - { - public: - typedef T element_type; - - private: - element_type* m_ptr; - size_t m_sizeInBytes; - - public: - CBuffer(element_type* ptr, size_t sizeInBytes) - : m_ptr(ptr) - , m_sizeInBytes(ptr ? sizeInBytes : 0) - { - } - - const element_type* getPtr() const - { - return m_ptr; - } - - element_type* getPtr() - { - return m_ptr; - } - - size_t getSizeInElements() const - { - return m_sizeInBytes / sizeof(element_type); - } - - size_t getSizeInBytes() const - { - return m_sizeInBytes; - } - - const element_type& operator[](size_t pos) const - { - return m_ptr[pos]; - } - - element_type& operator[](size_t pos) - { - return m_ptr[pos]; - } - }; - - typedef CBuffer CCharBuffer; - typedef CBuffer CWCharBuffer; - - - template - class CFixedString - { - public: - typedef T char_type; - static const size_t npos = ~size_t(0); - private: - size_t m_count; // # chars (not counting trailing zero) - char_type m_buffer[CAPACITY + 1]; // '+ 1' is for trailing zero - - public: - CFixedString() - { - clear(); - } - - CFixedString(const char_type* p) - { - set(p); - } - - CFixedString& operator=(const char_type* p) - { - set(p); - return *this; - } - - CFixedString& operator=(const CFixedString& s) - { - if (&s != this) - { - set(s.m_buffer, s.m_count); - } - return *this; - } - - CBuffer getBuffer() - { - return CBuffer(m_buffer, (CAPACITY + 1) * sizeof(char_type)); - } - - char_type operator[](const size_t i) const - { - return m_buffer[i]; - } - - const char_type* c_str() const - { - return &m_buffer[0]; - } - - const size_t length() const - { - return m_count; - } - - void clear() - { - m_count = 0; - m_buffer[m_count] = 0; - } - - void setLength(size_t n) - { - m_count = (n <= CAPACITY) ? n : CAPACITY; - m_buffer[m_count] = 0; - } - - char_type* ptr() - { - return &m_buffer[0]; - } - - CFixedString substr(size_t pos = 0, size_t n = npos) const - { - CFixedString s; - if (pos < m_count && n > 0) - { - if (n > m_count || pos + n > m_count) - { - n = m_count - pos; - } - s.set(&m_buffer[pos], n); - } - return s; - } - - void set(const char_type* p, size_t n) - { - if (p == 0 || n <= 0) - { - m_count = 0; - } - else - { - m_count = (n > CAPACITY) ? CAPACITY : n; - // memmove() is used because p may point to m_buffer - memmove(m_buffer, p, m_count * sizeof(*p)); - } - m_buffer[m_count] = 0; - } - - void set(const char_type* p) - { - if (p && p[0]) - { - set(p, Utils::strlen(p)); - } - else - { - clear(); - } - } - - void append(const char_type* p, size_t n) - { - if (p && n > 0) - { - if (n > CAPACITY || m_count + n > CAPACITY) - { - // assert(0); - n = CAPACITY - m_count; - } - if (n > 0) - { - memcpy(&m_buffer[m_count], p, n * sizeof(*p)); - m_count += n; - m_buffer[m_count] = 0; - } - } - } - - void append(const char_type* p) - { - if (p && p[0]) - { - append(p, Utils::strlen(p)); - } - } - - void appendAscii(const char* p, size_t n) - { - if (p && n > 0) - { - if (n > CAPACITY || m_count + n > CAPACITY) - { - // assert(0); - n = CAPACITY - m_count; - } - if (n > 0) - { - for (size_t i = 0; i < n; ++i) - { - m_buffer[m_count + i] = p[i]; - } - m_count += n; - m_buffer[m_count] = 0; - } - } - } - - void appendAscii(const char* p) - { - if (p && p[0]) - { - appendAscii(p, Utils::strlen(p)); - } - } - - bool equals(const char_type* p) const - { - return (p == 0 || p[0] == 0) - ? (m_count == 0) - : (Utils::strcmp(m_buffer, p) == 0); - } - - void trim() - { - size_t begin = 0; - while (begin < m_count && (m_buffer[begin] == ' ' || m_buffer[begin] == '\r' || m_buffer[begin] == '\t' || m_buffer[begin] == '\n')) - { - ++begin; - } - - if (begin >= m_count) - { - clear(); - return; - } - - size_t end = m_count - 1; - while (end > begin && (m_buffer[begin] == ' ' || m_buffer[begin] == '\r' || m_buffer[begin] == '\t' || m_buffer[begin] == '\n')) - { - --end; - } - - m_count = end + 1; - m_buffer[m_count] = 0; - - if (begin > 0) - { - set(&m_buffer[begin], m_count - begin); - } - } - }; - - - struct SKeyValue - { - CFixedString key; - CFixedString value; - }; - - - template - class CKeyValueArray - { - private: - size_t count; - SKeyValue data[CAPACITY]; - - public: - CKeyValueArray() - : count(0) - { - } - - size_t size() const - { - return count; - } - - const SKeyValue& operator[](size_t i) const - { - return data[i]; - } - - void clear() - { - count = 0; - } - - const SKeyValue* find(const char* key) const - { - for (size_t i = 0; i < count; ++i) - { - if (data[i].key.equals(key)) - { - return &data[i]; - } - } - return 0; - } - - SKeyValue* find(const char* key) - { - for (size_t i = 0; i < count; ++i) - { - if (data[i].key.equals(key)) - { - return &data[i]; - } - } - return 0; - } - - SKeyValue* set(const char* key, const wchar_t* value) - { - SKeyValue* p = find(key); - if (!p) - { - if (count >= CAPACITY) - { - return 0; - } - p = &data[count++]; - p->key = key; - } - p->value = value; - return p; - } - }; - - -#if defined(CRY_ENABLE_RC_HELPER) - - bool Utf16ContainsAsciiOnly(const wchar_t* wstr); - - void ConvertUtf16ToUtf8(const wchar_t* src, CCharBuffer dst); - - void ConvertUtf8ToUtf16(const char* src, CWCharBuffer dst); - - template - void AddPathSeparator(CFixedString& wstr) - { - if (wstr.length() <= 0) - { - return; - } - - if (wstr[wstr.length() - 1] == L'/' || wstr[wstr.length() - 1] == L'\\') - { - return; - } - - wstr.appendAscii("/"); - } - - void GetAsciiFilename(const wchar_t* wfilename, CCharBuffer buffer); - -#endif // #if defined(CRY_ENABLE_RC_HELPER) -} // namespace SettingsManagerHelpers - - -#if defined(CRY_ENABLE_RC_HELPER) - -////////////////////////////////////////////////////////////////////////// -// Provides settings and functions to make calls to RC. -class CEngineSettingsManager; -class CSettingsManagerTools -{ -public: - CSettingsManagerTools(const wchar_t* szModuleName = 0); - ~CSettingsManagerTools(); - -private: - CEngineSettingsManager* m_pSettingsManager; - -public: - CEngineSettingsManager* GetEngineSettingsManager() - { - return m_pSettingsManager; - } - - bool GetInstalledBuildPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path); - bool GetInstalledBuildPathAscii(const int index, SettingsManagerHelpers::CCharBuffer name, SettingsManagerHelpers::CCharBuffer path); - - void GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer wbuffer); - bool CallEditor(void** pEditorWindow, void* hParent, const char* pWndName, const char* pFlag); - - static bool Is64bitWindows(); -}; - -#endif // #if defined(CRY_ENABLE_RC_HELPER) - -#endif // CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H diff --git a/Code/CryEngine/CryCommon/SmartPointersHelpers.h b/Code/CryEngine/CryCommon/SmartPointersHelpers.h deleted file mode 100644 index 41d60bc119..0000000000 --- a/Code/CryEngine/CryCommon/SmartPointersHelpers.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// This header is provided for backwards compatibility. Avoid including this header, instead -// include the needed smart ptr headers - -#pragma once - -#include -#include -#include - -#define DECLARE_SMART_POINTERS(name) \ - typedef AZStd::shared_ptr name##Ptr; \ - typedef AZStd::shared_ptr name##ConstPtr; \ - typedef AZStd::weak_ptr name##WeakPtr; \ - typedef AZStd::weak_ptr name##ConstWeakPtr; diff --git a/Code/CryEngine/CryCommon/StackContainer.h b/Code/CryEngine/CryCommon/StackContainer.h deleted file mode 100644 index 5af9a60e2e..0000000000 --- a/Code/CryEngine/CryCommon/StackContainer.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Helper to enable inplace construction and destruction of objects - -#ifndef CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H -#define CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H -#pragma once - -#include - -// Class that contains a non-pod data type allocated on the stack via placement -// new. Constructor parameters up to an arity of 5 are forwarded over an -// inplace factory expression. -template -class CStackContainer -{ - // The backing storage - uint8 m_Storage[ sizeof (T) ]; - - // Constructs the object via an inplace factory - template - void construct (const Factory& factory) - { - factory.template apply(m_Storage); - } - - // Destructs the object. The destructor of the contained object is called - void destruct () - { - reinterpret_cast(m_Storage)->~T(); - } - - // Prevent the object to be placed on the heap - // (.... it simply wouldn't make much sense) - void* operator new(size_t); - void operator delete(void*); - -public: - - // Constructs inside the object - template - CStackContainer (const Expr& expr) - { construct(expr); } - - // Destructs the object contained - ~CStackContainer() { destruct(); } - - // Accessor methods - T* get() { return reinterpret_cast(m_Storage); } - const T* get() const { return reinterpret_cast(m_Storage); } -}; - -#endif // CRYINCLUDE_CRYCOMMON_STACKCONTAINER_H diff --git a/Code/CryEngine/CryCommon/StlUtils.h b/Code/CryEngine/CryCommon/StlUtils.h index df88a14196..9d6090502f 100644 --- a/Code/CryEngine/CryCommon/StlUtils.h +++ b/Code/CryEngine/CryCommon/StlUtils.h @@ -27,7 +27,6 @@ #endif #define STATIC_ASSERT(condition, errMessage) static_assert(condition, errMessage) -#include "STLGlobalAllocator.h" #include #include diff --git a/Code/CryEngine/CryCommon/StringUtils.h b/Code/CryEngine/CryCommon/StringUtils.h index 6c38315b40..4e3bed3b26 100644 --- a/Code/CryEngine/CryCommon/StringUtils.h +++ b/Code/CryEngine/CryCommon/StringUtils.h @@ -168,7 +168,6 @@ namespace CryStringUtils_Internal // Can be used for ASCII and Unicode (UTF-8/UTF-16/UTF-32), but not for ANSI. // ? will match exactly one code-point. // * will match zero or more code-points. - // Note: function moved here from CryCommonTools. template class CharComparator, class CharType> inline bool MatchesWildcards_Tpl(const CharType* pStr, const CharType* pWild) { diff --git a/Code/CryEngine/CryCommon/TPool.h b/Code/CryEngine/CryCommon/TPool.h deleted file mode 100644 index b7f1d19068..0000000000 --- a/Code/CryEngine/CryCommon/TPool.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -* 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. -* -*/ -#pragma once - -#include -#include - -template -class TPool -{ -public: - - TPool(int nPoolSize) - { - m_nPoolSize = nPoolSize; - m_pPool = new T[nPoolSize]; - m_lstFree.PreAllocate(nPoolSize, 0); - m_lstUsed.PreAllocate(nPoolSize, 0); - for (int i = 0; i < nPoolSize; i++) - { - m_lstFree.Add(&m_pPool[i]); - } - } - - ~TPool() - { - delete[] m_pPool; - } - - void ReleaseObject(T* pInst) - { - if (m_lstUsed.Delete(pInst)) - { - m_lstFree.Add(pInst); - } - } - - int GetUsedInstancesCount(int& nAll) - { - nAll = m_nPoolSize; - return m_lstUsed.Count(); - } - - T* GetObject() - { - T* pInst = NULL; - if (m_lstFree.Count()) - { - pInst = m_lstFree.Last(); - m_lstFree.DeleteLast(); - m_lstUsed.Add(pInst); - } - else - { - assert(!"TPool::GetObject: Out of free elements error"); - } - - return pInst; - } - - void GetMemoryUsage(class ICrySizer* pSizer) const - { - pSizer->AddObject(m_lstFree); - pSizer->AddObject(m_lstUsed); - - if (m_pPool) - { - for (int i = 0; i < m_nPoolSize; i++) - { - m_pPool[i].GetMemoryUsage(pSizer); - } - } - } - - PodArray m_lstFree; - PodArray m_lstUsed; - T* m_pPool; - int m_nPoolSize; -}; diff --git a/Code/CryEngine/CryCommon/Tarray.h b/Code/CryEngine/CryCommon/Tarray.h index 035a4b3e0e..32bb249f7c 100644 --- a/Code/CryEngine/CryCommon/Tarray.h +++ b/Code/CryEngine/CryCommon/Tarray.h @@ -19,7 +19,6 @@ #include #include #include -#include #ifndef CLAMP #define CLAMP(X, mn, mx) ((X) < (mn) ? (mn) : ((X) < (mx) ? (X) : (mx))) @@ -58,400 +57,4 @@ } #endif - -// General array class. -// Can refer to a general (unowned) region of memory (m_nAllocatedCount = 0). -// Can allocate, grow, and shrink an array. -// Does not deep copy. - -template -class TArray -{ -protected: - T* m_pElements; - unsigned int m_nCount; - unsigned int m_nAllocatedCount; - -public: - typedef T value_type; - - // Empty array. - TArray() - { - ClearArr(); - } - - // Create a new array, delete it on destruction. - TArray(int Count) - { - m_nCount = Count; - m_nAllocatedCount = Count; - m_pElements = NULL; - Realloc(0); - } - TArray(int Use, int Max) - { - m_nCount = Use; - m_nAllocatedCount = Max; - m_pElements = NULL; - Realloc(0); - } - - // Reference pre-existing memory. Does not delete it. - TArray(T* Elems, int Count) - { - m_pElements = Elems; - m_nCount = Count; - m_nAllocatedCount = 0; - } - ~TArray() - { - Free(); - } - - void Free() - { - m_nCount = 0; - if (m_nAllocatedCount && AZ::AllocatorInstance::IsReady()) - { - AZ::AllocatorInstance::Get().DeAllocate(m_pElements); - } - m_nAllocatedCount = 0; - m_pElements = NULL; - } - - void Create (int Count) - { - m_pElements = NULL; - m_nCount = Count; - m_nAllocatedCount = Count; - Realloc(0); - Clear(); - } - void Copy (const TArray& src) - { - m_pElements = NULL; - m_nCount = m_nAllocatedCount = src.Num(); - Realloc(0); - PREFAST_ASSUME(m_pElements); // realloc asserts if it fails - so this is safe - memcpy(m_pElements, src.m_pElements, src.Num() * sizeof(T)); - } - void Copy (const T* src, unsigned int numElems) - { - int nOffs = m_nCount; - Grow(numElems); - memcpy(&m_pElements[nOffs], src, numElems * sizeof(T)); - } - void Align4Copy (const T* src, unsigned int& numElems) - { - int nOffs = m_nCount; - Grow((numElems + 3) & ~3); - memcpy(&m_pElements[nOffs], src, numElems * sizeof(T)); - if (numElems & 3) - { - int nSet = 4 - (numElems & 3); - memset(&m_pElements[nOffs + numElems], 0, nSet); - numElems += nSet; - } - } - - void Realloc([[maybe_unused]] int nOldAllocatedCount) - { - if (!m_nAllocatedCount) - { - m_pElements = NULL; - } - else - { - m_pElements = static_cast(AZ::AllocatorInstance::Get().ReAllocate(m_pElements, m_nAllocatedCount * sizeof(T), alignof(T))); - assert (m_pElements); - } - } - - void Remove(unsigned int Index, unsigned int Count = 1) - { - if (Count) - { - memmove(m_pElements + Index, m_pElements + (Index + Count), sizeof(T) * (m_nCount - Index - Count)); - m_nCount -= Count; - } - } - - void Shrink() - { - if (m_nCount == 0 || m_nAllocatedCount == 0) - { - return; - } - assert(m_nAllocatedCount >= m_nCount); - if (m_nAllocatedCount != m_nCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount; - Realloc(nOldAllocatedCount); - } - } - - void _Remove(unsigned int Index, unsigned int Count) - { - assert (Index >= 0); - assert (Index <= m_nCount); - assert ((Index + Count) <= m_nCount); - - Remove(Index, Count); - } - - unsigned int Num(void) const { return m_nCount; } - unsigned int Capacity(void) const { return m_nAllocatedCount; } - unsigned int MemSize(void) const { return m_nCount * sizeof(T); } - void SetNum(unsigned int n) { m_nCount = m_nAllocatedCount = n; } - void SetUse(unsigned int n) { m_nCount = n; } - void Alloc(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; m_nAllocatedCount = n; Realloc(nOldAllocatedCount); } - void Reserve(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; SetNum(n); Realloc(nOldAllocatedCount); Clear(); } - void ReserveNoClear(unsigned int n) { int nOldAllocatedCount = m_nAllocatedCount; SetNum(n); Realloc(nOldAllocatedCount); } - void Expand(unsigned int n) - { - if (n > m_nAllocatedCount) - { - ReserveNew(n); - } - } - void ReserveNew(unsigned int n) - { - int num = m_nCount; - if (n > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = n * 2; - Realloc(nOldAllocatedCount); - } - m_nCount = n; - memset(&m_pElements[num], 0, sizeof(T) * (m_nCount - num)); - } - T* Grow(unsigned int n) - { - int nStart = m_nCount; - m_nCount += n; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount * 2; - Realloc(nOldAllocatedCount); - } - return &m_pElements[nStart]; - } - T* GrowReset(unsigned int n) - { - int num = m_nAllocatedCount; - T* Obj = AddIndex(n); - if (num != m_nAllocatedCount) - { - memset(&m_pElements[num], 0, sizeof(T) * (m_nAllocatedCount - num)); - } - return Obj; - } - - unsigned int* GetNumAddr(void) { return &m_nCount; } - T** GetDataAddr(void) { return &m_pElements; } - - T* Data(void) const { return m_pElements; } - T& Get(unsigned int id) const { return m_pElements[id]; } - - - void Assign(TArray& fa) - { - m_pElements = fa.m_pElements; - m_nCount = fa.m_nCount; - m_nAllocatedCount = fa.m_nAllocatedCount; - } - - - /*const TArray operator=(TArray fa) const - { - TArray t = TArray(fa.m_nCount,fa.m_nAllocatedCount); - for ( int i=0; i 0); return *m_pElements; } - - TArray operator()(unsigned int Start) - { - assert(Start < m_nCount); - return TArray(m_pElements + Start, m_nCount - Start); - } - TArray operator()(unsigned int Start, unsigned int Count) - { - assert(Start < m_nCount); - assert(Start + Count <= m_nCount); - return TArray(m_pElements + Start, Count); - } - - // For simple types only - TArray(const TArray& cTA) - { - m_pElements = NULL; - m_nCount = m_nAllocatedCount = cTA.Num(); - Realloc(0); - if (m_pElements) - { - memcpy(m_pElements, &cTA[0], m_nCount * sizeof(T)); - } - /*for (unsigned int i=0; i m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = nNewCount + (nNewCount >> 1) + 10; - Realloc(nOldAllocatedCount); - } - - m_nCount = nNewCount; - return &m_pElements[nIndex]; - } - - T& Insert(unsigned int nIndex, unsigned int inc = 1) - { - m_nCount += inc; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount + (m_nCount >> 1) + 32; - Realloc(nOldAllocatedCount); - } - memmove(&m_pElements[nIndex + inc], &m_pElements[nIndex], (m_nCount - inc - nIndex) * sizeof(T)); - - return m_pElements[nIndex]; - } - - void AddIndexNoCache(unsigned int inc) - { - m_nCount += inc; - if (m_nCount > m_nAllocatedCount) - { - int nOldAllocatedCount = m_nAllocatedCount; - m_nAllocatedCount = m_nCount; - Realloc(nOldAllocatedCount); - } - } - - void Add(const T& elem){AddElem(elem); } - void AddElem(const T& elem) - { - unsigned int m = m_nCount; - AddIndex(1); - m_pElements[m] = elem; - } - void AddElemNoCache(const T& elem) - { - unsigned int m = m_nCount; - AddIndexNoCache(1); - m_pElements[m] = elem; - } - - int Find(const T& p) - { - for (unsigned int i = 0; i < m_nCount; i++) - { - if (p == (*this)[i]) - { - return i; - } - } - return -1; - } - - void Delete(unsigned int n){DelElem(n); } - void DelElem(unsigned int n) - { - // memset(&m_pElements[n],0,sizeof(T)); - _Remove(n, 1); - } - - // Standard compliance interface - // - // This is for those who don't want to learn the non standard and - // thus not very convenient interface of TArray, but are unlucky - // enough not to be able to avoid using it. - void clear(){Free(); } - void resize(unsigned int nSize) { reserve(nSize); m_nCount = nSize; } - void reserve(unsigned int nSize) - { - if (nSize > m_nAllocatedCount) - { - Alloc(nSize); - } - } - unsigned size() const {return m_nCount; } - unsigned capacity() const {return m_nAllocatedCount; } - bool empty() const {return size() == 0; } - void push_back (const T& rSample) {Add(rSample); } - void pop_back () {m_nCount--; } - void erase (T* pElem) - { - int n = int(pElem - m_pElements); - assert(n >= 0 && n < m_nCount); - _Remove(n, 1); - } - T* begin() {return m_pElements; } - T* end() {return m_pElements + m_nCount; } - T last() {return m_pElements[m_nCount - 1]; } - const T* begin() const {return m_pElements; } - const T* end() const {return m_pElements + m_nCount; } - - int GetMemoryUsage() const { return (int)(m_nAllocatedCount * sizeof(T)); } -}; - -template -inline void Exchange(T& X, T& Y) -{ - const T Tmp = X; - X = Y; - Y = Tmp; -} - #endif // CRYINCLUDE_CRYCOMMON_TARRAY_H diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/HeightmapDataBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/HeightmapDataBus.h deleted file mode 100644 index 93065e1196..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/HeightmapDataBus.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include -#include - -namespace Terrain -{ - class Viewport2D - { - public: - int m_topLeftX = 0; - int m_topLeftY = 0; - int m_width = 0; - int m_height = 0; - - Viewport2D() = default; - Viewport2D(const Viewport2D&) = default; - Viewport2D& operator=(const Viewport2D&) = default; - - Viewport2D(int topLeftX, int topLeftY, int width, int height) - : m_topLeftX(topLeftX) - , m_topLeftY(topLeftY) - , m_width(width) - , m_height(height) - { - } - }; - - // External height map data requests - class HeightmapDataRequestInfo - { - public: - HeightmapDataRequestInfo() = default; - HeightmapDataRequestInfo(const HeightmapDataRequestInfo& rhs) = default; - HeightmapDataRequestInfo& operator=(const HeightmapDataRequestInfo& rhs) = default; - - HeightmapDataRequestInfo(int viewportTopLeftX, int viewportTopLeftY, int viewportWidth, int viewportHeight, float metersPerPixel, AZ::Vector2 worldMin, AZ::Vector2 worldMax) - : m_viewport(viewportTopLeftX, viewportTopLeftY, viewportWidth, viewportHeight) - , m_metersPerPixel(metersPerPixel) - , m_worldMin(worldMin) - , m_worldMax(worldMax) - { - } - - float GetMetersPerPixel() const - { - return m_metersPerPixel; - } - - AZ::Vector2 GetWorldMin() const - { - return m_worldMin; - } - - AZ::Vector2 GetWorldMax() const - { - return m_worldMax; - } - - AZ::Vector2 GetWorldWidth() const - { - return (m_worldMax - m_worldMin); - } - - Viewport2D GetViewport() const - { - return m_viewport; - } - - private: - Viewport2D m_viewport; - AZ::Vector2 m_worldMin = AZ::Vector2(0.0f, 0.0f); - AZ::Vector2 m_worldMax = AZ::Vector2(0.0f, 0.0f); - float m_metersPerPixel = 1.0f; - }; - - class HeightmapDataNotifications - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - virtual void OnTerrainHeightDataChanged(const AZ::Aabb& dirtyRegion) = 0; - }; - using HeightmapDataNotificationBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/TerrainBus.h deleted file mode 100644 index 2cfb5134c9..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainBus.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include -#include - -class CShader; - -namespace Terrain -{ - class TerrainDataRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - virtual float GetHeightSynchronous(float x, float y) = 0; - virtual AZ::Vector3 GetNormalSynchronous(float x, float y) = 0; - - virtual CShader* GetTerrainHeightGeneratorShader() const = 0; - virtual CShader* GetTerrainMaterialCompositingShader() const = 0; - }; - using TerrainDataRequestBus = AZ::EBus; - - class TerrainShaderRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - virtual void RefreshShader(const AZStd::string_view name, CShader* shader) = 0; - virtual void ReleaseShader(CShader* shader) const = 0; - }; - using TerrainShaderRequestBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainProviderBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/TerrainProviderBus.h deleted file mode 100644 index 6c1aca6ea7..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainProviderBus.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include -#include -#include - -#include - -#include "HeightmapDataBus.h" - -class CShader; - -namespace Terrain -{ - // This interface defines how the renderer can access the terrain system to set up state and gather information before rendering height maps - class TerrainProviderRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - // world properties - virtual AZ::Vector3 GetWorldSize() = 0; - virtual AZ::Vector3 GetRegionSize() = 0; - virtual AZ::Vector3 GetWorldOrigin() = 0; - virtual AZ::Vector2 GetHeightRange() = 0; - - // utility - virtual void GetRegionIndex(const AZ::Vector2& worldMin, const AZ::Vector2& worldMax, int& regionIndexX, int& regionIndexY) = 0; - - virtual float GetHeightAtIndexedPosition([[maybe_unused]] int ix, [[maybe_unused]] int iy) { return 64.0f; } - virtual float GetHeightAtWorldPosition([[maybe_unused]] float fx, [[maybe_unused]] float fy) { return 64.0f; } - virtual unsigned char GetSurfaceTypeAtIndexedPosition([[maybe_unused]] int ix, [[maybe_unused]] int iy) { return 0; } - }; - using TerrainProviderRequestBus = AZ::EBus; - - // This class exists for the terrain system to inject data into the renderer for generating the GPU-side terrain height map - struct CRETerrainContext - { - // Tract map - virtual void OnTractVersionUpdate() = 0; - - CShader* m_currentShader = nullptr; - }; - - class TerrainProviderNotifications - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - ////////////////////////////////////////////////////////////////////////// - - // interface to be implemented by the game, invoked by the terrain render element - - // pull settings from the world cache, so the next accessors are accurate - virtual void SynchronizeSettings(CRETerrainContext* context) = 0; - }; - using TerrainProviderNotificationBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainRendererBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/TerrainRendererBus.h deleted file mode 100644 index ea644f5653..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/TerrainRendererBus.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include - -namespace Terrain -{ - class TerrainRendererRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - - // Query state of the terrain renderer - // Returns true once the terrain renderer has fulfilled most data requests and is ready for rendering - virtual bool IsReady() = 0; - }; - using TerrainRendererRequestBus = AZ::EBus; -} diff --git a/Code/CryEngine/CryCommon/Terrain/Bus/WorldMaterialRequestsBus.h b/Code/CryEngine/CryCommon/Terrain/Bus/WorldMaterialRequestsBus.h deleted file mode 100644 index 3fb80f5f11..0000000000 --- a/Code/CryEngine/CryCommon/Terrain/Bus/WorldMaterialRequestsBus.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include -#include -#include - -struct IMaterial; -class ITexture; - -namespace Terrain -{ - struct MacroMaterial - { - // Textures - _smart_ptr m_macroColorMap = nullptr; - _smart_ptr m_macroGlossMap = nullptr; - _smart_ptr m_macroNormalMap = nullptr; - - // Material Params - AZ::Color m_macroColorMapColor; - float m_macroGlossMapScale = 1.0f; - float m_macroNormalMapScale = 1.0f; - float m_macroSpecReflectance = 0.03f; - - void Clear() - { - m_macroColorMap = nullptr; - m_macroGlossMap = nullptr; - m_macroNormalMap = nullptr; - - m_macroColorMapColor = AZ::Color(1.0f); - m_macroGlossMapScale = 1.0f; - m_macroNormalMapScale = 1.0f; - m_macroSpecReflectance = 0.03f; - } - }; - - struct TerrainMaterialLayer - { - _smart_ptr m_material = nullptr; - _smart_ptr m_splatTexture = nullptr; - - TerrainMaterialLayer(_smart_ptr material, _smart_ptr splatTexture) - : m_material(material) - , m_splatTexture(splatTexture) - { - } - }; - - struct RegionMaterials - { - MacroMaterial m_macroMaterial; - - AZStd::vector m_materialLayers; - _smart_ptr m_defaultMaterial = nullptr; - - RegionMaterials& operator=(const RegionMaterials& rhs) = default; - - void Clear() - { - m_materialLayers.clear(); - m_defaultMaterial = nullptr; - m_macroMaterial.Clear(); - } - }; - - const AZ::u32 kMaxRegionsPerTerrainMaterialRequest = 16; - typedef AZStd::pair RegionIndex; - typedef AZStd::fixed_vector RegionIndexVector; - typedef AZStd::fixed_vector RegionMaterialVector; - - enum class RequestResult - { - NoAssetsForRegion, - Loading, - Success - }; - - class WorldMaterialRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - //! allows multiple threads to call - using MutexType = AZStd::recursive_mutex; - - virtual void LoadWorld(const AZStd::string& worldName, int regionSize) = 0; - - virtual RequestResult RequestRegionMaterials(const RegionIndexVector& regions, RegionMaterialVector& outRegionMaterials) = 0; - - // Parameters: - // int tileX, tileY : Region tile indices - // Returns: - // bool : If true, region material data is loaded and exists. outMacroMaterial will be modified with the respective macro material data - // If false, no region material data has been loaded or exists for the given tile (may still have invalid material layers). - virtual RequestResult GetMacroMaterial(int tileX, int tileY, MacroMaterial& outMacroMaterial) = 0; - - virtual void GetTerrainPOMParameters(float& pomHeightBias, float& pomDisplacement, float& selfShadowStrength) = 0; - - //Get the surface type at a given position. If not loaded yet, returns "loadingMaterial". - virtual AZStd::string_view GetSurfaceTypeAtPosition(AZ::Vector2 position) = 0; - }; - using WorldMaterialRequestBus = AZ::EBus; -} // namespace Terrain - diff --git a/Code/CryEngine/CryCommon/TypeLibrary.h b/Code/CryEngine/CryCommon/TypeLibrary.h deleted file mode 100644 index 03d608a24e..0000000000 --- a/Code/CryEngine/CryCommon/TypeLibrary.h +++ /dev/null @@ -1,512 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_TYPELIBRARY_H -#define CRYINCLUDE_CRYCOMMON_TYPELIBRARY_H -#pragma once - -#include // <> required for Interfuscator - -#include -#include - -#ifdef SOFTCODE_ENABLED - -// Internal: Used by SC types to auto-remove themselves from their TypeRegistrar on destruction. -struct InstanceTracker -{ - InstanceTracker() - : m_pRegistrar() - {} - - ~InstanceTracker() - { - if (m_pRegistrar) - { - m_pRegistrar->RemoveInstance(this); - } - } - - void SetRegistrar(ITypeRegistrar* pRegistrar) - { - m_pRegistrar = pRegistrar; - } - - ITypeRegistrar* m_pRegistrar; // Valid if created by a registrar, otherwise NULL -}; - -#endif - - -#ifdef SOFTCODE_ENABLED - -// Include this for SEH support - #include - -/* - Used to declare the interface as having an associated TypeLibrary. - Usage: - struct IMyInterface - { - DECLARE_TYPELIB(IMyInterface); -*/ - #define DECLARE_TYPELIB(IName) \ - static void VisitMembers(IExchanger & ex) {} \ - typedef CTypeLibrary TLibrary - -/* - Exposes a class to a TypeLibrary for registration. - Usage: - class MyThing : public IThing - { - DECLARE_TYPE(MyThing, IThing); - ... -*/ - #define DECLARE_TYPE(TName, TSuperType) \ -public: \ - void VisitMembers(IExchanger & ex) { TSuperType::VisitMembers(ex); VisitMember<__START_MEMBERS>(ex); } \ -private: \ - friend class TypeRegistrar; \ - static const size_t __START_MEMBERS = __COUNTER__ + 1; \ - template \ - void VisitMember(IExchanger & exchanger) {} \ - InstanceTracker __instanceTracker - - #ifdef SOFTCODE - #define _EXPORT_TYPE_LIB(Interface) \ - extern "C" ITypeLibrary * GetTypeLibrary() { return CTypeLibrary::Instance(); } - #else - #define _EXPORT_TYPE_LIB(Interface) - #endif - -// Internal: Outputs the specialized method template for the member at index - #define _SOFT_MEMBER_VISITOR(member, index) \ - template <> \ - void VisitMember(IExchanger & ex) { ex.Visit(#member, member); VisitMember(ex); } - -/* - Used to expose a class member to SoftCoding (to allow run-time member exchange) - If SoftCode is disabled this does nothing and simple emits the member. - For array types, use SOFT_ARRAY() instead or use AZStd::array which allows assignment. - Usage: std::vector SOFT(m_myStrings); -*/ - #define SOFT(member) \ - member; \ - _SOFT_MEMBER_VISITOR(member, __COUNTER__) - -/* - Used to expose a primitive array type to SoftCoding. - Declare it directly after the member. - NOTE: It's cleaner to convert the member to AZStd::array as - this avoid having to use this special case while preserving semantics. - Usage: - ColorB m_colors[20]; - SOFT_ARRAY(m_colors); -*/ - #define SOFT_ARRAY(arrayMember) _SOFT_MEMBER_VISITOR(arrayMember, __COUNTER__) - -// Internal: Executes given lambda in an SEH try block. -template -void SoftCodeTry(TLambda& lambda) -{ - __try - { - lambda(); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - } -} - -// Internal: Used by TypeRegistry. Use SOFTCODE_RETRY() for user code. - #define SOFTCODE_TRY(exp) SoftCodeTry([&](){ exp; }) - #define SOFTCODE_TRY_BLOCK SoftCodeTry([&]() { - #define SOFTCODE_TRY_END }); - -/* - Internal: Attempt a given lambda functor. In the even on an exception execution will pause - to allow the user to provide a replacement implementation for the failing instance. - Usage: See SOFTCODE_RETRY & SOFTCODE_RETRY_BLOCK below. -*/ -template -void SoftCodeRetry(TPtr& pointer, TLambda& lambda) -{ - bool complete = false; - while (pointer && !complete) - { - __try - { - lambda(); - complete = true; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - if (gEnv->pSoftCodeMgr) - { - pointer = reinterpret_cast(gEnv->pSoftCodeMgr->WaitForUpdate(pointer)); - } - } - } - ; -} - -/* - Attempts to call an expression based the given pointer. - If a Structured Exception is raised the thread will wait for a replacement of - the pointer to be provided via the SoftCodeMgr. This will repeat until no exception is raised. - - Usage: SOFTCODE_RETRY(pThing, (pThing->Update(frameTime))); // Same as pThing->Update(frameTime); -*/ - #define SOFTCODE_RETRY(pointer, exp) SoftCodeRetry(pointer, [&](){ exp; }) - -/* - Attempts to call an expression based the given pointer. - If a Structured Exception is raised the thread will wait for a replacement of - the pointer to be provided via the SoftCodeMgr. This will repeat until no exception is raised. - - Usage: - SOFTCODE_RETRY_BLOCK(pThing) - { - pSomething = pThing->GetSomething(); - } - SOFTCODE_RETRY_END -*/ - #define SOFTCODE_RETRY_BLOCK(pointer) SoftCodeRetry(pointer, [&]() { - #define SOFTCODE_RETRY_END }); - -#else // !SOFTCODE_ENABLED ... - -// IMPORTANT: Docs for these macros are found above. - - #define DECLARE_TYPELIB(IName) \ - typedef CTypeLibrary TLibrary - - #define DECLARE_TYPE(TName, TSuperType) \ -private: \ - friend class TypeRegistrar; - - #define _EXPORT_TYPE_LIB(Interface) - - #define SOFT(member) member - #define SOFT_ARRAY(arrayMember) - - #define SOFTCODE_TRY(exp) (exp) - #define SOFTCODE_TRY_BLOCK { - #define SOFTCODE_TRY_END }; - - #define SOFTCODE_RETRY(pointer, exp) (exp) - #define SOFTCODE_RETRY_BLOCK(pointer) { - #define SOFTCODE_RETRY_END }; - -#endif // !SOFTCODE_ENABLED - -/* - Implements registration for a type to a TypeLibrary. - Usage: - // MyThing.cpp - DECLARE_TYPE(MyThing); -*/ -#define IMPLEMENT_TYPE(TName) \ - static TypeRegistrar s_register##TName(#TName) - -/* - Provides the singleton for the TypeLibrary implementation. - Also exports the accessors function for SoftCode builds. - Usage: - // ThingLibrary.cpp - IMPLEMENT_TYPELIB(IThing, "Things") -*/ -#define IMPLEMENT_TYPELIB(Interface, Name) \ - _EXPORT_TYPE_LIB(Interface) \ - template <> \ - CTypeLibrary* CTypeLibrary::Instance() \ - { \ - static CTypeLibrary s_instance(Name); \ - return &s_instance; \ - } - -/* - Internal: Used to register a type with a TypeLibrary. - Also provides instance construction (factory) access. - For SC builds it also provides copying and instance tracking. -*/ -template -class TypeRegistrar - : public ITypeRegistrar -{ -public: - TypeRegistrar(const char* name) - : m_name(name) - { - typedef typename T::TLibrary TLib; - TLib::Instance()->RegisterType(this); - } - - virtual const char* GetName() const { return m_name; } - - virtual void* CreateInstance() - { - T* pInstance = NULL; - - SOFTCODE_TRY_BLOCK - { - pInstance = ConstructInstance(); - } - SOFTCODE_TRY_END - - if (pInstance) - { - RegisterInstance(pInstance); - } - - return pInstance; - } - -#ifdef SOFTCODE_ENABLED - virtual size_t InstanceCount() const - { - return m_instances.size(); - } - - virtual void RemoveInstance(InstanceTracker* pTracker) - { - T* pInstance = GetInstanceFromTracker(pTracker); - TInstanceVec::iterator iter(std::find(m_instances.begin(), m_instances.end(), pInstance)); - std::swap(*iter, m_instances.back()); - m_instances.pop_back(); - } - - virtual bool ExchangeInstances(IExchanger& exchanger) - { - if (exchanger.IsLoading()) - { - const size_t instanceCount = exchanger.InstanceCount(); - - // Ensure we have the correct number of instances - if (m_instances.size() != instanceCount) - { - // TODO: Destroy any existing instances - for (size_t i = 0; i < instanceCount; ++i) - { - if (!CreateInstance()) - { - return false; - } - } - } - } - - bool complete = false; - SOFTCODE_TRY_BLOCK - { - for (std::vector::iterator iter(m_instances.begin()); iter != m_instances.end(); ++iter) - { - T* pInstance = *iter; - if (exchanger.BeginInstance(pInstance)) - { - // Exchanges the members of pInstance as defined in T - // Should also exchange members of parent types - pInstance->VisitMembers(exchanger); - } - } - complete = true; - } - SOFTCODE_TRY_END - - return complete; - } - - virtual bool DestroyInstances() - { - bool complete = false; - SOFTCODE_TRY_BLOCK - { - while (!m_instances.empty()) - { - delete m_instances.back(); - // NOTE: No need to pop_back() as already done by the InstanceTracker via RemoveInstance() - } - complete = true; - } - SOFTCODE_TRY_END - - return complete; - } - - - virtual bool HasInstance(void* pInstance) const - { - return std::find(m_instances.begin(), m_instances.end(), pInstance) != m_instances.end(); - } -#endif - -private: - void RegisterInstance(T* pInstance) - { -#ifdef SOFTCODE_ENABLED - pInstance->__instanceTracker.SetRegistrar(this); - m_instances.push_back(pInstance); -#endif - } - -#ifdef SOFTCODE_ENABLED - // Util: Avoids having to redundantly store the instance address in the tracker - T* GetInstanceFromTracker(InstanceTracker* pTracker) - { - ptrdiff_t trackerOffset = reinterpret_cast(&((static_cast(0))->__instanceTracker)); - return reinterpret_cast(reinterpret_cast(pTracker) - trackerOffset); - } -#endif - - // Needed to avoid C2712 due to lack of stack unwind within SEH try blocks - T* ConstructInstance() - { - return new T(); - } - -private: - const char* m_name; // Name of the type - -#ifdef SOFTCODE_ENABLED - typedef std::vector TInstanceVec; - TInstanceVec m_instances; // Tracks the active instances (SC only) -#endif -}; - -/* - Provides factory creation support for a set of types that - derive from a single interface T. Users need to provide a - specialization of the static CTypeLibrary* Instance() member - in a cpp file to provide the singleton instance. -*/ -template -class CTypeLibrary - #ifdef SOFTCODE_ENABLED - : public ITypeLibrary - #endif -{ -public: - CTypeLibrary(const char* name) - : m_name(name) -#ifdef SOFTCODE_ENABLED - , m_pOverrideLib() - , m_overrideActive() - , m_registered() -#endif - { - } - - // Implemented in the export cpp - static CTypeLibrary* Instance(); - - void RegisterType(ITypeRegistrar* pType) - { - m_typeMap[pType->GetName()] = pType; - } - - // The global identifier for this library module - /*virtual*/ const char* GetName() { return m_name; } - -#ifdef SOFTCODE_ENABLED - virtual void* CreateInstanceVoid(const char* typeName) - { - return CreateInstance(typeName); - } -#endif - - // Generic creation function - T* CreateInstance(const char* typeName) - { -#ifdef SOFTCODE_ENABLED - RegisterWithSoftCode(); - - // If override is enabled, use it - if (m_pOverrideLib) - { - return reinterpret_cast(m_pOverrideLib->CreateInstanceVoid(typeName)); - } -#endif - - TTypeMap::const_iterator typeIter(m_typeMap.find(typeName)); - if (typeIter != m_typeMap.end()) - { - ITypeRegistrar* pRegistrar = typeIter->second; - return reinterpret_cast(pRegistrar->CreateInstance()); - } - - return NULL; - } - -#ifdef SOFTCODE_ENABLED - // Indicates CreateInstance requests should be forwarded to the specified lib - virtual void SetOverride(ITypeLibrary* pOverrideLib) - { - m_pOverrideLib = pOverrideLib; - } - - virtual size_t GetTypes(ITypeRegistrar** ppTypes, size_t& count) const - { - size_t returnedCount = 0; - - if (ppTypes && count >= m_typeMap.size()) - { - for (TTypeMap::const_iterator iter(m_typeMap.begin()); iter != m_typeMap.end(); ++iter) - { - *ppTypes = iter->second; - ++ppTypes; - ++returnedCount; - } - } - - count = m_typeMap.size(); - return returnedCount; - } - - // Inform the Mgr of this Library and allow it to set an override - inline void RegisterWithSoftCode() - { - // Only register built-in types, SC types are handled directly by - // the SoftCodeMgr, so there's no need to auto-register. -#ifndef SOFTCODE - if (!m_registered) - { - if (ISoftCodeMgr* pSoftCodeMgr = gEnv->pSoftCodeMgr) - { - pSoftCodeMgr->RegisterLibrary(this); - } - - m_registered = true; - } -#endif - } -#endif - -private: - typedef AZStd::basic_string, AZ::AZStdAlloc> TypeString; - typedef AZStd::map, AZ::AZStdAlloc> TTypeMap; - TTypeMap m_typeMap; - - // The name for this TypeLibrary used during SC registration - const char* m_name; - -#ifdef SOFTCODE_ENABLED - // Used to patch in a new TypeLib at run-time - ITypeLibrary* m_pOverrideLib; - // True when the owning object system enables the override - bool m_overrideActive; - // True when registration with SoftCodeMgr has been attempted - bool m_registered; -#endif -}; - -#endif // CRYINCLUDE_CRYCOMMON_TYPELIBRARY_H diff --git a/Code/CryEngine/CryCommon/UnalignedBlit.h b/Code/CryEngine/CryCommon/UnalignedBlit.h deleted file mode 100644 index 4492ae6319..0000000000 --- a/Code/CryEngine/CryCommon/UnalignedBlit.h +++ /dev/null @@ -1,141 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Generic unaligned memory access helpers. -#pragma once -#include -#include - -namespace Detail -{ - template - struct Blitter - { - static_assert(std::is_trivial::value, "Blittable elements should be trivial (ie, integral types)"); - static_assert((std::alignment_of::value < std::alignment_of::value), "Blittable memory has sufficient alignment, do not use unaligned store or load"); - static_assert(sizeof(RealType) > sizeof(BlittedElement), "Blittable element is larger than real type"); - static_assert((sizeof(RealType) % sizeof(BlittedElement)) == 0, "Blitted element has the wrong size for the real type"); - typedef std::integral_constant NumElements; - - static void BlitLoad(const BlittedElement* pSource, RealType& target) - { - BlittedElement* pTarget = alias_cast(&target); - for (size_t i = 0; i < NumElements::value; ++i, ++pSource, ++pTarget) - { - * pTarget = *pSource; - } - } - - static void BlitStore(const RealType& source, BlittedElement* pTarget) - { - const BlittedElement* pSource = alias_cast(&source); - for (size_t i = 0; i < NumElements::value; ++i, ++pSource, ++pTarget) - { - * pTarget = *pSource; - } - } - }; -} - -// Load RealType from unaligned memory using some blittable type. -// The source memory must be suitably aligned for accessing BlittedElement. -// If no memory alignment can be guaranteed, use char for BlittedElement. -template -inline void LoadUnaligned(const BlittedElement* pMemory, RealType& value, - typename std::enable_if<(std::alignment_of::value > std::alignment_of::value)>::type* = nullptr) -{ - Detail::Blitter::BlitLoad(pMemory, value); -} - -// Load RealType from aligned memory (fallback overload). -// This is used if there is no reason to call the blitter, because sufficient alignment is guaranteed by BlittedElement. -template -inline void LoadUnaligned(const BlittedElement* pMemory, RealType& value, - typename std::enable_if<(std::alignment_of::value <= std::alignment_of::value)>::type* = nullptr) -{ - value = *alias_cast(pMemory); -} - -// Store to unaligned memory using some blittable type. -// The target memory must be suitably aligned for accessing BlittedElement. -// If no memory alignment can be guaranteed, use char for BlittedElement. -template -inline void StoreUnaligned(BlittedElement* pMemory, const RealType& value, - typename std::enable_if<(std::alignment_of::value > std::alignment_of::value)>::type* = nullptr) -{ - Detail::Blitter::BlitStore(value, pMemory); -} - -// Store to aligned memory (fallback overload). -// This is used if there is no reason to call the blitter, because sufficient alignment is guaranteed by BlittedElement. -template -inline void StoreUnaligned(BlittedElement* pMemory, const RealType& value, - typename std::enable_if<(std::alignment_of::value <= std::alignment_of::value)>::type* = nullptr) -{ - *alias_cast(pMemory) = value; -} - -// Pads the given pointer to the next possible aligned location for RealType -// Use this to ensure RealType can be referenced in some buffer of BlittedElement's, without using LoadUnaligned/StoreUnaligned -template -inline BlittedElement* AlignPointer(BlittedElement* pMemory, - typename std::enable_if<(std::alignment_of::value % std::alignment_of::value) == 0>::type* = nullptr) -{ - const size_t align = std::alignment_of::value; - const size_t mask = align - 1; - const size_t address = reinterpret_cast(pMemory); - const size_t offset = (align - (address & mask)) & mask; - return pMemory + (offset / sizeof(BlittedElement)); -} - -// Pads the given address to the next possible aligned location for RealType -// Use this to ensure RealType can be referenced inside memory, without using LoadUnaligned/StoreUnaligned -template -inline size_t AlignAddress(size_t address) -{ - return reinterpret_cast(AlignPointer(reinterpret_cast(address))); -} - -// Provides aligned storage for T, optionally aligned at a specific boundary (default being the native alignment of T) -// The specified T is not initialized automatically, use of placement new/delete is the user's responsibility -template::value> -struct SUninitialized -{ - typedef typename std::aligned_storage::type Storage; - Storage storage; - - void DefaultConstruct() - { - new(static_cast(&storage))T(); - } - - void CopyConstruct(const T& value) - { - new(static_cast(&storage))T(value); - } - - void MoveConstruct(T&& value) - { - new(static_cast(&storage))T(std::move(value)); - } - - void Destruct() - { - alias_cast(&storage)->~T(); - } - - operator T& () - { - return *alias_cast(&storage); - } -}; diff --git a/Code/CryEngine/CryCommon/WinBase.cpp b/Code/CryEngine/CryCommon/WinBase.cpp index d48a3327a7..47cb943240 100644 --- a/Code/CryEngine/CryCommon/WinBase.cpp +++ b/Code/CryEngine/CryCommon/WinBase.cpp @@ -12,6 +12,7 @@ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Linux/Mac port support for Win32API calls +#if !defined(WIN32) #include "platform.h" // Note: This should be first to get consistent debugging definitions @@ -77,7 +78,7 @@ unsigned int g_EnableMultipleAssert = 0;//set to something else than 0 if to ena #endif #if defined(APPLE) - #include "../CrySystem/SystemUtilsApple.h" + #include #endif #include "StringUtils.h" @@ -1667,3 +1668,5 @@ __finddata64_t::~__finddata64_t() } } #endif //defined(APPLE) || defined(LINUX) + +#endif // !defined(WIN32) diff --git a/Code/CryEngine/CryCommon/crycommon_enginesettings_files.cmake b/Code/CryEngine/CryCommon/crycommon_enginesettings_files.cmake deleted file mode 100644 index 0fbd223d21..0000000000 --- a/Code/CryEngine/CryCommon/crycommon_enginesettings_files.cmake +++ /dev/null @@ -1,27 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ProjectDefines.h - SettingsManagerHelpers.cpp - SettingsManagerHelpers.h - EngineSettingsManager.cpp - EngineSettingsManager.h - EngineSettingsBackend.cpp - EngineSettingsBackend.h - ResourceCompilerHelper.cpp - ResourceCompilerHelper.h -) - -# Remove files that cause #define collisions on Mac due to multiple inclusions of 'AppleSpecific.h' and include orders -set(SKIP_UNITY_BUILD_INCLUSION_FILES - SettingsManagerHelpers.cpp -) diff --git a/Code/CryEngine/CryCommon/crycommon_files.cmake b/Code/CryEngine/CryCommon/crycommon_files.cmake index 7d169c2643..660cf20276 100644 --- a/Code/CryEngine/CryCommon/crycommon_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_files.cmake @@ -10,32 +10,16 @@ # set(FILES - QTangent.h CryCommon.cpp - Allocator.h - FinalizingSpline.h IAudioInterfacesCommonData.h IAudioSystem.h - IChunkFile.h ICmdLine.h - IColorGradingController.h IConsole.h - ICryMiniGUI.h - IDeferredCollisionEvent.h - IDefragAllocator.h - IEngineModule.h IEntityRenderState.h IEntityRenderState_info.cpp - IFileChangeMonitor.h - IFlares.h IFont.h IFunctorBase.h - IFuncVariable.h IGem.h - IGeneralMemoryHeap.h - IGeomCache.h - IImage.h - IImageHandler.h IIndexedMesh.h IIndexedMesh_info.cpp ILevelSystem.h @@ -43,159 +27,94 @@ set(FILES LocalizationManagerBus.h LocalizationManagerBus.inl ILog.h - ILZ4Decompressor.h IMaterial.h - IMaterialEffects.h - IMemory.h - IMeshBaking.h IMiniLog.h IMovieSystem.h - INotificationNetwork.h - IOverloadSceneManager.h - IPerfHud.h IPhysics.h - IPhysicsDebugRenderer.h IPostEffectGroup.h IProcess.h IReadWriteXMLSink.h - IRemoteCommand.h IRenderAuxGeom.h IRenderer.h IRenderMesh.h - IResourceCollector.h - IResourceCompilerHelper.h - IResourceManager.h ISerialize.h - IServiceNetwork.h IShader.h - IShader_info.h - ISoftCodeMgr.h ISplines.h IStatObj.h StatObjBus.h IStereoRenderer.h - IStreamEngine.h - IStreamEngineDefs.h ISurfaceType.h ISystem.h - ISystemScheduler.h - ITextModeConsole.h ITexture.h - IThreadManager.h - IThreadTask.h ITimer.h IValidator.h - IVideoRenderer.h IViewSystem.h IWindowMessageHandler.h IXml.h - IZLibCompressor.h - IZlibDecompressor.h - IZStdDecompressor.h - IProximityTriggerSystem.h MicrophoneBus.h physinterface.h HMDBus.h VRCommon.h StereoRendererBus.h HeightmapUpdateNotificationBus.h - IObjManager.h INavigationSystem.h IMNM.h - AzDXGIFormat.h SFunctor.h FunctorBaseFunction.h - CustomMemoryHeap.h FunctorBaseMember.h stridedptr.h Options.h - CREGeomCache.h SerializationTypes.h CryEndian.h CryRandomInternal.h Random.h LCGRandom.h - MaterialUtils.h MTPseudoRandom.cpp CryTypeInfo.cpp - IResourceCompilerHelper.cpp BaseTypes.h CompileTimeAssert.h - CryThreadSafeWorkerContainer.h - CryThreadSafeRendererContainer.h - intrusive_list.hpp MemoryAccess.h - Algorithm.h AnimKey.h - AnimTime.h BitFiddling.h - CGFContent.h - CGFContent_info.cpp Common_TypeInfo.cpp - CountedValue.h - CrtDebugStats.h CryArray.h - CryArray2d.h CryAssert.h CryCrc32.h CryCustomTypes.h CryFile.h - CryFixedArray.h CryFixedString.h CryHeaders.h CryHeaders_info.cpp CryListenerSet.h - CryMemoryAllocator.h - CryMemoryManager.h CryLegacyAllocator.h CryName.h CryPath.h CryPodArray.h - CryPtrArray.h CrySizer.h CryString.h CrySystemBus.h CryThread.h CryThreadImpl.h CryTypeInfo.h - CryUtils.h CryVersion.h - CryZlib.h FrameProfiler.h - GeomCacheFileFormat.h - HashGrid.h HeapAllocator.h - HeapContainer.h - ImageExtensionHelper.cpp - ImageExtensionHelper.h - ImageExtensionHelper_info.h - InplaceFactory.h LegacyAllocator.h MetaUtils.h MiniQueue.h MTPseudoRandom.h MultiThread.h MultiThread_Containers.h - Name_TypeInfo.h NullAudioSystem.h PNoise3.h PoolAllocator.h primitives.h - primitives_info.h - ProfileLog.h ProjectDefines.h Range.h - RenderContextConfig.h - RingBuffer.h - ScopeGuard.h ScopedVariableSetter.h SerializeFwd.h SimpleSerialize.h - SmartPointersHelpers.h smartptr.h - StackContainer.h - STLGlobalAllocator.h - STLPoolAllocator.h StlUtils.h StringUtils.h Synchronization.h @@ -205,8 +124,6 @@ set(FILES TimeValue_info.h TypeInfo_decl.h TypeInfo_impl.h - TypeLibrary.h - UnalignedBlit.h UnicodeBinding.h UnicodeEncoding.h UnicodeFunctions.h @@ -215,31 +132,13 @@ set(FILES VectorSet.h VertexFormats.h XMLBinaryHeaders.h - Bezier.h RenderBus.h MainThreadRenderRequestBus.h - OceanConstants.h - PakLoadDataUtils.cpp - PakLoadDataUtils.h - TPool.h - CREBaseCloud.h - CREFogVolume.h - CREGameEffect.h - CREImposter.h - CREMesh.h - CREOcclusionQuery.h - CREPostProcess.h - CRESky.h - CREVolumeObject.h - CREWaterOcean.h - CREWaterVolume.h - RendElement.h Cry_Matrix33.h Cry_Matrix34.h Cry_Matrix44.h Cry_MatrixDiag.h Cry_Vector4.h - AABBSV.h Cry_Camera.h Cry_Color.h Cry_Geo.h @@ -253,14 +152,12 @@ set(FILES Cry_Vector3.h Cry_XOptimise.h CryHalf_info.h - GeomQuery.h CryHalf.inl MathConversion.h Cry_HWMatrix.h Cry_HWVector3.h AndroidSpecific.h AppleSpecific.h - Console_std.h CryAssert_Android.h CryAssert_impl.h CryAssert_iOS.h @@ -268,7 +165,6 @@ set(FILES CryAssert_Mac.h CryLibrary.cpp CryLibrary.h - CryMemoryManager_impl.h CryThread_dummy.h CryThread_pthreads.h CryThread_windows.h @@ -280,108 +176,11 @@ set(FILES Linux_Win32Wrapper.h LinuxSpecific.h LoadScreenBus.h - LoadScreenComponent.cpp - LoadScreenComponent.h MacSpecific.h platform.h platform_impl.cpp Win32specific.h Win64specific.h - CryExtension/CryCreateClassInstance.h - CryExtension/CryGUID.h - CryExtension/CryTypeID.h - CryExtension/ICryFactory.h - CryExtension/ICryFactoryRegistry.h - CryExtension/ICryUnknown.h - CryExtension/Impl/Conversion.h - CryExtension/Impl/ClassWeaver.h - CryExtension/Impl/CryGUIDHelper.h - CryExtension/Impl/ICryFactoryRegistryImpl.h - CryExtension/Impl/RegFactoryNode.h - CryExtension/Impl/TypeList.h - CryPool/Allocator.h - CryPool/Container.h - CryPool/Defrag.h - CryPool/example.h - CryPool/Fallback.h - CryPool/Inspector.h - CryPool/List.h - CryPool/Memory.h - CryPool/PoolAlloc.h - CryPool/STLWrapper.h - CryPool/ThreadSafe.h - stl/STLAlignedAlloc.h - Serialization/Assert.h - Serialization/BitVector.h - Serialization/BitVectorImpl.h - Serialization/BlackBox.h - Serialization/BoostSharedPtr.h - Serialization/Callback.h - Serialization/ClassFactory.h - Serialization/ClassFactoryImpl.h - Serialization/Color.h - Serialization/ColorImpl.h - Serialization/CRCRef.h - Serialization/CRCRefImpl.h - Serialization/CryExtension.h - Serialization/CryExtensionImpl.h - Serialization/CryName.h - Serialization/CryNameImpl.h - Serialization/CryStrings.h - Serialization/CryStringsImpl.h - Serialization/DynArray.h - Serialization/DynArrayImpl.h - Serialization/Enum.h - Serialization/EnumImpl.h - Serialization/IArchive.h - Serialization/IArchiveHost.h - Serialization/IClassFactory.h - Serialization/IntrusiveFactory.h - Serialization/ITextInputArchive.h - Serialization/ITextOutputArchive.h - Serialization/KeyValue.h - Serialization/Math.h - Serialization/MathImpl.h - Serialization/NetScriptSerialize.h - Serialization/Object.h - Serialization/Serializer.h - Serialization/SerializerImpl.h - Serialization/SmartPtr.h - Serialization/SmartPtrImpl.h - Serialization/STL.h - Serialization/STLImpl.h - Serialization/StringList.h - Serialization/StringListImpl.h - Serialization/Strings.h - Serialization/TypeID.h - Serialization/TypeInfo.h - Serialization/TypeInfoImpl.h - Serialization/Decorators/ActionButton.h - Serialization/Decorators/BitFlags.h - Serialization/Decorators/BitFlagsImpl.h - Serialization/Decorators/ColorPicker.h - Serialization/Decorators/ColorPickerImpl.h - Serialization/Decorators/JointName.h - Serialization/Decorators/JointNameImpl.h - Serialization/Decorators/LocalFrame.h - Serialization/Decorators/LocalFrameImpl.h - Serialization/Decorators/OutputFilePath.h - Serialization/Decorators/OutputFilePathImpl.h - Serialization/Decorators/Range.h - Serialization/Decorators/RangeImpl.h - Serialization/Decorators/ResourceFilePath.h - Serialization/Decorators/ResourceFilePathImpl.h - Serialization/Decorators/ResourceFolderPath.h - Serialization/Decorators/ResourceFolderPathImpl.h - Serialization/Decorators/Resources.h - Serialization/Decorators/ResourcesAudio.h - Serialization/Decorators/ResourceSelector.h - Serialization/Decorators/Slider.h - Serialization/Decorators/SliderImpl.h - Serialization/Decorators/Sprite.h - Serialization/Decorators/SpriteImpl.h - Serialization/Decorators/TagList.h - Serialization/Decorators/TagListImpl.h LyShine/IDraw2d.h LyShine/ILyShine.h LyShine/ISprite.h @@ -473,12 +272,6 @@ set(FILES Maestro/Types/AssetBlendKey.h Maestro/Types/AssetBlends.h Maestro/Types/SequenceType.h - Terrain/Bus/WorldMaterialRequestsBus.h - Terrain/Bus/TerrainBus.h - Terrain/Bus/TerrainRendererBus.h - Terrain/Bus/HeightmapDataBus.h - Terrain/Bus/TerrainProviderBus.h - CREPrismObject.h StaticInstance.h - Pak/CryPakUtils.h + WinBase.cpp ) diff --git a/Code/CryEngine/CryCommon/crycommon_linux_files.cmake b/Code/CryEngine/CryCommon/crycommon_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CryCommon/crycommon_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CryCommon/crycommon_testing_files.cmake b/Code/CryEngine/CryCommon/crycommon_testing_files.cmake index d20a33f791..b94be27c3b 100644 --- a/Code/CryEngine/CryCommon/crycommon_testing_files.cmake +++ b/Code/CryEngine/CryCommon/crycommon_testing_files.cmake @@ -14,12 +14,10 @@ set(FILES Mocks/IConsoleMock.h Mocks/ICryPakMock.h Mocks/ILogMock.h - Mocks/IMemoryManagerMock.h Mocks/ISystemMock.h Mocks/ITimerMock.h Mocks/ICVarMock.h Mocks/IRendererMock.h Mocks/ITextureMock.h Mocks/IRemoteConsoleMock.h - Mocks/MockCGFContent.h ) diff --git a/Code/CryEngine/CryCommon/intrusive_list.hpp b/Code/CryEngine/CryCommon/intrusive_list.hpp deleted file mode 100644 index 9a182b264d..0000000000 --- a/Code/CryEngine/CryCommon/intrusive_list.hpp +++ /dev/null @@ -1,180 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef _INTRUSIVE_LIST_HPP -#define _INTRUSIVE_LIST_HPP -#if !defined(WIN32) -#include -#endif //!defined(WIN32) - - -namespace util -{ - // Simple lightweight intrusive list utility - // - template - struct list - { - typedef Host value_type; - - list* next; - list* prev; - - // Default (initializing) constructor - list() - { - next = this; - prev = this; - } - - // Inserts this list into a given list item between - // prev and next (note: they need to be sequential!) - void insert(list* _prev, list* _next) - { - _next->prev = this; - this->next = _next; - this->prev = _prev; - _prev->next = this; - } - - // Should only be called on heads - void clear() { next = prev = this; } - - // Removes from a list, then inserts this list item into a given list between - // prev and next (note: they need to be sequential!) - void re_insert(list* _prev, list* _next) - { - erase(); - insert(_prev, _next); - } - - - // Remove this list instance from a list - // Safe to be called even if not attached to a list - void erase() - { - next->prev = prev; - prev->next = next; - next = prev = this; - } - - // Predicate to determine if a list structure is linked to a list - bool empty() const { return prev == this && next == this; } - bool linked() const { return !empty(); } - - // Get the host instance of the instrusive list - template - Host* item() - { - return ((Host*)((uintptr_t)(this) - (uintptr_t)(&(((Host*)0)->*member)))); - } - template - const Host* item() const - { - return ((Host*)((uintptr_t)(this) - (uintptr_t)(&(((Host*)0)->*member)))); - } - template - Host * item(int threadId) - { - uintptr_t value = (uintptr_t)this - (uintptr_t)&((((Host*)(NULL))->*Member)[threadId]); - return alias_cast(value); - } - - // Insert & relink functions - void insert_tail(list* _list) { insert(_list->prev, _list); } - void insert_tail(list& _list) { insert_tail(&_list); } - void insert_head(list* _list) { insert(_list, _list->next); } - void insert_head(list& _list) { insert_head(&_list); } - void relink_tail(list* _list) { erase(); insert_tail(_list); } - void relink_tail(list& _list) { relink_tail(&_list); } - void relink_head(list* _list) { erase(); insert_head(_list); } - void relink_head(list& _list) { relink_head(&_list); } - - static inline void splice(const list* _list, list* prev, list* next) - { - list* first = _list->next; - list* last = _list->prev; - - first->prev = prev; - prev->next = first; - - last->next = next; - next->prev = last; - } - - void splice_front(const list* _list) - { - if (!_list->empty()) - { - splice(_list, this, this->next); - _list->clear(); - } - } - - void splice_tail(list* _list) - { - if (!_list->empty()) - { - splice(_list, this->prev, this); - _list->clear(); - } - } - - // Accessors - list* tail() { return prev; } - const list* tail() const { return prev; } - list* head() { return head; } - const list* head() const { return head; } - }; - - // utility to extract the host type of an intrusive list at compile time - template - struct list_value_type - { - typedef typename List::value_type value_type; - }; - - // Loops over the list in forward manner, pos will be of type list* -# define list_for_each(pos, head) \ - for (typeof(head)pos = (head)->next; pos != (head); \ - pos = pos->next) - - // Loops over the list in backward manner, pos will be of type list* -# define list_for_each_backwards(pos, head) \ - for (typeof(head)pos = (head)->prev; pos != (head); \ - pos = pos->prev) - - // Loops over the list in forward manner while safeguarding - // against list removal during iteration. pos will be of type list* -# define list_for_each_safe(pos, head) \ - for (typeof(head)pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - - // Loops over the list in forward manner. pos will be of type list* -# define list_for_each_entry(pos, head, member) \ - for (util::list_value_type::value_type* pos = \ - (head)->next->item(); \ - &(pos->*(member)) != &list; \ - pos = ((pos->*(member)).next->item())) - - // Loops over the list in forward manner while safeguarding against list - // removal during iteratation. pos will be of type T* -# define list_for_each_entry_safe(pos, head, member) \ - for (util::list_value_type::value_type* pos = \ - (head)->next->item(), \ - * n = ((pos->*(member)).next->item()); \ - &(pos->*(member)) != &list; \ - pos = n, n = ((n->*(member)).next->item())) -} // end namespace util -#endif // ifndef _INTRUSIVE_LIST_HPP - diff --git a/Code/CryEngine/CryCommon/physinterface.h b/Code/CryEngine/CryCommon/physinterface.h index 036f7e29ab..dd787d48b7 100644 --- a/Code/CryEngine/CryCommon/physinterface.h +++ b/Code/CryEngine/CryCommon/physinterface.h @@ -3244,7 +3244,6 @@ struct PhysicsVars int nBodiesLargeGroup; int bBreakOnValidation; int bLogActiveObjects; - int bMultiplayer; int bProfileEntities; int bProfileFunx; int bProfileGroups; diff --git a/Code/CryEngine/CryCommon/platform.h b/Code/CryEngine/CryCommon/platform.h index f7361db11d..df8fb125b2 100644 --- a/Code/CryEngine/CryCommon/platform.h +++ b/Code/CryEngine/CryCommon/platform.h @@ -479,15 +479,7 @@ ILINE DestinationType alias_cast(SourceType pPtr) return conv_union.pDst; } -////////////////////////////////////////////////////////////////////////// - -#include "CryMemoryManager.h" - -// Memory manager breaks strdup -// Use something higher level, like CryString - #undef strdup - #define strdup dont_use_strdup - +#include "CryLegacyAllocator.h" ////////////////////////////////////////////////////////////////////////// #ifndef DEPRECATED diff --git a/Code/CryEngine/CryCommon/platform_impl.cpp b/Code/CryEngine/CryCommon/platform_impl.cpp index 6c261bb1f1..1d784ed8a0 100644 --- a/Code/CryEngine/CryCommon/platform_impl.cpp +++ b/Code/CryEngine/CryCommon/platform_impl.cpp @@ -14,13 +14,13 @@ #include #include #include -#include -#include +#include #include #include #include #include +#include #include // Section dictionary @@ -34,7 +34,7 @@ #define PLATFORM_IMPL_H_SECTION_VIRTUAL_ALLOCATORS 7 #endif -SC_API struct SSystemGlobalEnvironment* gEnv = nullptr; +struct SSystemGlobalEnvironment* gEnv = nullptr; // Traits #if defined(AZ_RESTRICTED_PLATFORM) @@ -42,9 +42,6 @@ SC_API struct SSystemGlobalEnvironment* gEnv = nullptr; #include AZ_RESTRICTED_FILE(platform_impl_h) #endif -//The reg factory is used for registering the different modules along the whole project -struct SRegFactoryNode* g_pHeadToRegFactories = 0; - ////////////////////////////////////////////////////////////////////////// // If not in static library. #include @@ -106,16 +103,6 @@ extern "C" AZ_DLL_EXPORT void ModuleInitISystem(ISystem* pSystem, [[maybe_unused AZ::AllocatorManager::Instance(); // Force the AllocatorManager to instantiate and register any allocators defined in data sections } AZ::Debug::ProfileModuleInit(); - -#if !defined(AZ_MONOLITHIC_BUILD) - ICryFactoryRegistryImpl* pCryFactoryImpl = static_cast(pSystem->GetCryFactoryRegistry()); - if (pCryFactoryImpl) - { - pCryFactoryImpl->RegisterFactories(g_pHeadToRegFactories); - } - - AZ_Error("System", pCryFactoryImpl, "Failed to successfully load factory for %s. You may have a missing or stale DLL that needs to be recompiled.", moduleName); -#endif } // if pSystem } @@ -161,7 +148,6 @@ void* GetDetachEnvironmentSymbol() #endif // !defined(SOFTCODE) bool g_bProfilerEnabled = false; -int g_iTraceAllocations = 0; ////////////////////////////////////////////////////////////////////////// // global random number generator used by cry_random functions @@ -209,11 +195,6 @@ void __stl_debug_message(const char* format_str, ...) #include #endif -// If we use cry memory manager this should be also included in every module. -#if defined(USING_CRY_MEMORY_MANAGER) -#include -#endif - #if defined(APPLE) || defined(LINUX) #include "CryAssert_impl.h" #endif diff --git a/Code/CryEngine/CryCommon/primitives_info.h b/Code/CryEngine/CryCommon/primitives_info.h deleted file mode 100644 index 052546c236..0000000000 --- a/Code/CryEngine/CryCommon/primitives_info.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H -#define CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H -#pragma once - -#include "primitives.h" - -STRUCT_INFO_TYPE_EMPTY(primitives::primitive) - -STRUCT_INFO_BEGIN(primitives::box) -STRUCT_BASE_INFO(primitives::primitive) -STRUCT_VAR_INFO(Basis, TYPE_INFO(Matrix33)) -STRUCT_VAR_INFO(bOriented, TYPE_INFO(int)) -STRUCT_VAR_INFO(center, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(size, TYPE_INFO(Vec3)) -STRUCT_INFO_END(primitives::box) - -STRUCT_INFO_BEGIN(primitives::sphere) -STRUCT_BASE_INFO(primitives::primitive) -STRUCT_VAR_INFO(center, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(r, TYPE_INFO(float)) -STRUCT_INFO_END(primitives::sphere) - -STRUCT_INFO_BEGIN(primitives::cylinder) -STRUCT_BASE_INFO(primitives::primitive) -STRUCT_VAR_INFO(center, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(axis, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(r, TYPE_INFO(float)) -STRUCT_VAR_INFO(hh, TYPE_INFO(float)) -STRUCT_INFO_END(primitives::cylinder) - -STRUCT_INFO_BEGIN(primitives::plane) -STRUCT_BASE_INFO(primitives::primitive) -STRUCT_VAR_INFO(n, TYPE_INFO(Vec3)) -STRUCT_VAR_INFO(origin, TYPE_INFO(Vec3)) -STRUCT_INFO_END(primitives::plane) - -#endif // CRYINCLUDE_CRYCOMMON_PRIMITIVES_INFO_H diff --git a/Code/CryEngine/CryCommon/stl/STLAlignedAlloc.h b/Code/CryEngine/CryCommon/stl/STLAlignedAlloc.h deleted file mode 100644 index dc21cead81..0000000000 --- a/Code/CryEngine/CryCommon/stl/STLAlignedAlloc.h +++ /dev/null @@ -1,115 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implements an aligned allocator for STL -// based on the Mallocator (http://blogs.msdn.com/b/vcblog/archive/2008/08/28/the-mallocator.aspx) - -#pragma once - -#include // Required for size_t and ptrdiff_t and NULL - -#include - -namespace stl -{ - template - class AlignedAllocator - : public AZ::SimpleSchemaAllocator> - { - public: - AZ_TYPE_INFO(AlignedAllocator, "{DF152D8A-36ED-4A2A-9FA6-734F212716C6}"); - using Base = AZ::SimpleSchemaAllocator>; - using Descriptor = Base::Descriptor; - using Schema = AZ::ChildAllocatorSchema; - - AlignedAllocator() - : Base("AlignedAllocator", "Legacy Cry Aligned Allocator") - { - } - - pointer_type Allocate(size_type byteSize, size_type /*alignment*/, int flags /* = 0 */, const char* name /* = 0 */, const char* fileName /* = 0 */, int lineNum /* = 0 */, unsigned int suppressStackRecord /* = 0 */) override - { - return Base::Allocate(byteSize, Alignment, flags, name, fileName, lineNum, suppressStackRecord); - } - - void DeAllocate(pointer_type ptr, size_type byteSize, [[maybe_unused]] size_type alignment) override - { - return Base::DeAllocate(ptr, byteSize, Alignment); - } - - pointer_type ReAllocate(pointer_type ptr, size_type newSize, size_type /*newAlignment*/) override - { - return Base::ReAllocate(ptr, newSize, Alignment); - } - }; - - template - using aligned_alloc = AZ::AZStdAlloc>; - - ////////////////////////////////////////////////////////////////////////// - // Defines aligned vector type - ////////////////////////////////////////////////////////////////////////// - template - class aligned_vector - : public AZStd::vector > - { - public: - typedef aligned_alloc MyAlloc; - typedef AZStd::vector MySuperClass; - typedef aligned_vector MySelf; - typedef size_t size_type; - - aligned_vector() {} - explicit aligned_vector(const MyAlloc& _Al) - : MySuperClass(_Al) {} - explicit aligned_vector(size_type _Count) - : MySuperClass(_Count) {}; - aligned_vector(size_type _Count, const T& _Val) - : MySuperClass(_Count, _Val) {} - aligned_vector(size_type _Count, const T& _Val, const MyAlloc& _Al) - : MySuperClass(_Count, _Val) {} - aligned_vector(const MySelf& _Right) - : MySuperClass(_Right) {}; - - - template - aligned_vector(_Iter _First, _Iter _Last) - : MySuperClass(_First, _Last) {}; - - template - aligned_vector(_Iter _First, _Iter _Last, const MyAlloc& _Al) - : MySuperClass(_First, _Last, _Al) {}; - }; - - template - inline size_t size_of_aligned_vector(const Vec& c) - { - if (!c.empty()) - { - // Not really correct as not taking alignment into the account - return c.capacity() * sizeof(typename Vec::value_type); - } - return 0; - } -} // namespace stl - -// Specialize for the AlignedAllocator to provide one per module that does not use the -// environment for its storage. Since this allocator just uses LegacyAllocator -// to do the real work, it's fine if there is one of these per cry module -namespace AZ -{ - template - class AllocatorInstance> : public Internal::AllocatorInstanceBase, AllocatorStorage::ModuleStoragePolicy>> - { - }; -} diff --git a/Code/CryEngine/CrySystem/AndroidConsole.cpp b/Code/CryEngine/CrySystem/AndroidConsole.cpp deleted file mode 100644 index 2716df3a22..0000000000 --- a/Code/CryEngine/CrySystem/AndroidConsole.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for Android, reports back to the main interface. - - -#include "CrySystem_precompiled.h" -#if defined(ANDROID) -#include "AndroidConsole.h" - -#include "android/log.h" -CAndroidConsole::CAndroidConsole() - : m_isInitialized(false) -{ -} - -CAndroidConsole::~CAndroidConsole() -{ -} - -// Interface IOutputPrintSink ///////////////////////////////////////////// -void CAndroidConsole::Print(const char* line) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "CryEngine", "MSG: %s\n", line); -} -// Interface ISystemUserCallback ////////////////////////////////////////// -bool CAndroidConsole::OnError(const char* errorString) -{ - __android_log_print(ANDROID_LOG_ERROR, "CryEngine", "ERR: %s\n", errorString); - return true; -} - -void CAndroidConsole::OnInitProgress(const char* sProgressMsg) -{ - (void) sProgressMsg; - // Do Nothing -} -void CAndroidConsole::OnInit(ISystem* pSystem) -{ - if (!m_isInitialized) - { - IConsole* pConsole = pSystem->GetIConsole(); - if (pConsole != 0) - { - pConsole->AddOutputPrintSink(this); - } - m_isInitialized = true; - } -} -void CAndroidConsole::OnShutdown() -{ - if (m_isInitialized) - { - // remove outputprintsink - m_isInitialized = false; - } -} -void CAndroidConsole::OnUpdate() -{ - // Do Nothing -} -void CAndroidConsole::GetMemoryUsage(ICrySizer* pSizer) -{ - size_t size = sizeof(*this); - - - - pSizer->AddObject(this, size); -} - -// Interface ITextModeConsole ///////////////////////////////////////////// -Vec2_tpl CAndroidConsole::BeginDraw() -{ - return Vec2_tpl(0, 0); -} -void CAndroidConsole::PutText(int x, int y, const char* msg) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "CryEngine", "PUT: %s\n", msg); -} -void CAndroidConsole::EndDraw() -{ - // Do Nothing -} -#endif // ANDROID diff --git a/Code/CryEngine/CrySystem/AndroidConsole.h b/Code/CryEngine/CrySystem/AndroidConsole.h deleted file mode 100644 index af45a68d5e..0000000000 --- a/Code/CryEngine/CrySystem/AndroidConsole.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for Android, reports back to the main interface. - - -#ifndef CRYINCLUDE_CRYSYSTEM_ANDROIDCONSOLE_H -#define CRYINCLUDE_CRYSYSTEM_ANDROIDCONSOLE_H -#pragma once - - -#include -#include - - - -class CAndroidConsole - : public ISystemUserCallback - , public IOutputPrintSink - , public ITextModeConsole -{ - CAndroidConsole(const CAndroidConsole&); - CAndroidConsole& operator = (const CAndroidConsole&); - - bool m_isInitialized; -public: - static CryCriticalSectionNonRecursive s_lock; -public: - CAndroidConsole(); - ~CAndroidConsole(); - - // Interface IOutputPrintSink ///////////////////////////////////////////// - DLL_EXPORT virtual void Print(const char* line); - - // Interface ISystemUserCallback ////////////////////////////////////////// - virtual bool OnError(const char* errorString); - virtual bool OnSaveDocument() { return false; } - virtual void OnProcessSwitch() { } - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem*); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - void SetRequireDedicatedServer(bool) {} - void SetHeader(const char*) {} - // Interface ITextModeConsole ///////////////////////////////////////////// - virtual Vec2_tpl BeginDraw(); - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw(); -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ANDROIDCONSOLE_H diff --git a/Code/CryEngine/CrySystem/AsyncPakManager.cpp b/Code/CryEngine/CrySystem/AsyncPakManager.cpp deleted file mode 100644 index 40928715d8..0000000000 --- a/Code/CryEngine/CrySystem/AsyncPakManager.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manage async pak files - - -#include "CrySystem_precompiled.h" -#include "AsyncPakManager.h" -#include "System.h" -#include "IStreamEngine.h" -#include -#include -#include "ResourceManager.h" - -#define MEGA_BYTE 1024* 1024 - -////////////////////////////////////////////////////////////////////////// - -string& CAsyncPakManager::SAsyncPak::GetStatus(string& status) const -{ - switch (eState) - { - case STATE_UNLOADED: - status = "Unloaded"; - break; - case STATE_REQUESTED: - status = "Requested"; - break; - case STATE_REQUESTUNLOAD: - status = "RequestUnload"; - break; - case STATE_LOADED: - status = "Loaded"; - break; - default: - status = "Unknown"; - break; - } - - return status; -} - -////////////////////////////////////////////////////////////////////////// - -CAsyncPakManager::CAsyncPakManager() -{ - m_nTotalOpenLayerPakSize = 0; - m_bRequestLayerUpdate = false; -} - -CAsyncPakManager::~CAsyncPakManager() -{ - Clear(); -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::Clear() -{ - //float startTime = gEnv->pTimer->GetAsyncCurTime(); - - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - if (layerPak.bStreaming) - { - // wait until finished - layerPak.pReadStream->Abort(); - } - - ReleaseData(&layerPak); - } - m_paks.clear(); - m_bRequestLayerUpdate = false; - - assert(m_nTotalOpenLayerPakSize == 0); - m_nTotalOpenLayerPakSize = 0; - - //printf("CAsyncPakManager::Clear() %0.4f secs\n", gEnv->pTimer->GetAsyncCurTime() - startTime); -} - -void CAsyncPakManager::UnloadLevelLoadPaks() -{ - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - - if (layerPak.eLifeTime == SAsyncPak::LIFETIME_LOAD_ONLY) - { - if (layerPak.bStreaming) - { - // wait until finished - layerPak.pReadStream->Abort(); - } - - ReleaseData(&layerPak); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::ParseLayerPaks(const string& levelCachePath) -{ - string layerPath = levelCachePath + "/"; // "/layers/"; - string search = layerPath + "*"; - auto pPak = gEnv->pCryPak; - - - // allow this find first to actually touch the file system - AZ::IO::ArchiveFileIterator fileIterator= pPak->FindFirst(search.c_str(), 0, true); - - if (fileIterator) - { - do - { - if ((fileIterator.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory || fileIterator.m_filename == "." || fileIterator.m_filename == "..") - { - continue; - } - - string pakName(fileIterator.m_filename.data(), fileIterator.m_filename.size()); - size_t findPos = pakName.find_last_of('.'); - if (findPos == string::npos) - { - continue; - } - - string extension = pakName.substr(findPos + 1, pakName.size()); - if (extension != "pak") - { - continue; - } - - SAsyncPak layerPak; - layerPak.layername = pakName.substr(0, findPos); - layerPak.filename = layerPath + pakName; - layerPak.nSize = pPak->FGetSize(layerPak.filename.c_str(), true); // allow to go to disc for this access - layerPak.bClosePakOnRelease = true; - - m_paks[layerPak.layername] = layerPak; - } while (fileIterator = pPak->FindNext(fileIterator)); - - pPak->FindClose(fileIterator); - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StartStreaming(SAsyncPak* pLayerPak) -{ - StreamReadParams params; - params.dwUserData = (DWORD_PTR) pLayerPak; - params.nSize = 0; - params.pBuffer = NULL; - params.nFlags = IStreamEngine::FLAGS_FILE_ON_DISK; - params.ePriority = estpIdle; - - pLayerPak->pReadStream = gEnv->pSystem->GetStreamEngine()->StartRead(eStreamTaskTypePak, pLayerPak->filename.c_str(), this, ¶ms); - - if (pLayerPak->pReadStream) - { - pLayerPak->bStreaming = true; - } - else - { - pLayerPak->eState = SAsyncPak::STATE_UNLOADED; - pLayerPak->pData.reset(); - } -} - -void CAsyncPakManager::ReleaseData(SAsyncPak* pLayerPak) -{ - if (pLayerPak->eState == SAsyncPak::STATE_LOADED) - { - if (pLayerPak->bClosePakOnRelease) - { - gEnv->pCryPak->ClosePack(pLayerPak->filename.c_str(), 0); - //printf("Unload pak from mem: %s\n", pLayerPak->filename.c_str()); - } - else - { - gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_Unload); - //printf("Close pak: %s\n", pLayerPak->filename.c_str()); - } - - m_nTotalOpenLayerPakSize -= pLayerPak->nSize; - } - - if (pLayerPak->pData) - { - assert(pLayerPak->pData->use_count() == 1); - } - - assert((!pLayerPak->pData) || (pLayerPak->pData && pLayerPak->pData->use_count() == 1)); - pLayerPak->pData.reset(); - pLayerPak->eState = SAsyncPak::STATE_UNLOADED; - - m_bRequestLayerUpdate = true; -} - -////////////////////////////////////////////////////////////////////////// - -bool CAsyncPakManager::LoadLayerPak(const char* sLayerName) -{ - // only load layer paks from valid files - TPakMap::iterator findResult = m_paks.find(sLayerName); - if (findResult != m_paks.end()) - { - return LoadPak(findResult->second); - } - - return false; -} - - -bool CAsyncPakManager::LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) -{ - //check if pak reference exists - TPakMap::iterator findResult = m_paks.find(pPath); - if (findResult != m_paks.end()) - { - return LoadPak(findResult->second); - } - else - { - char szFullPathBuf[AZ::IO::IArchive::MaxPath]; - const char* szFullPath = gEnv->pCryPak->AdjustFileName(pPath, szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), AZ::IO::IArchive::FOPEN_HINT_QUIET | AZ::IO::IArchive::FLAGS_PATH_REAL); - - // Check if the pak file actually exists before trying to load - if (!gEnv->pCryPak->IsFileExist(szFullPath, AZ::IO::IArchive::eFileLocation_Any)) - { - // Cached file does not exist - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Level cache pak file %s does not exist", szFullPath); - return false; - } - - SAsyncPak layerPak; - layerPak.layername = pPath; - layerPak.filename = szFullPathBuf; - layerPak.nSize = 0; - layerPak.eLifeTime = bLevelLoadOnly ? SAsyncPak::LIFETIME_LOAD_ONLY : SAsyncPak::LIFETIME_LEVEL_COMPLETE; - - m_paks[layerPak.layername] = layerPak; - - return LoadPak(m_paks[layerPak.layername]); - } - return false; -} - -bool CAsyncPakManager::LoadPak(SAsyncPak& layerPak) -{ - layerPak.nRequestCount++; - if (layerPak.eState == SAsyncPak::STATE_LOADED || layerPak.bStreaming || - layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - return true; - } - - layerPak.eState = SAsyncPak::STATE_REQUESTED; - - //printf("Streaming level pak: %s\n", layerPak.layername.c_str()); - - StartStreaming(&layerPak); - - return false; -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::UnloadLayerPak(const char* sLayerName) -{ - TPakMap::iterator findResult = m_paks.find(sLayerName); - if (findResult == m_paks.end()) - { - return; - } - - SAsyncPak& layerPak = findResult->second; - layerPak.nRequestCount--; - assert(layerPak.nRequestCount >= 0); - if (layerPak.nRequestCount > 0) - { - return; - } - - if (layerPak.bStreaming) - { - if (layerPak.pReadStream) - { - layerPak.pReadStream->Abort(); - } - layerPak.eState = SAsyncPak::STATE_REQUESTUNLOAD; - return; - } - - if (layerPak.eState == SAsyncPak::STATE_LOADED) - { - ReleaseData(&layerPak); - m_bRequestLayerUpdate = true; - } - - if (layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - layerPak.eState = SAsyncPak::STATE_UNLOADED; - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::GetLayerPakStats( - SLayerPakStats& stats, bool bCollectAllStats) const -{ - stats.m_MaxSize = (g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE); - stats.m_UsedSize = m_nTotalOpenLayerPakSize; - - for (TPakMap::const_iterator it = m_paks.begin(); it != m_paks.end(); ++it) - { - const SAsyncPak& layerPak = it->second; - if (bCollectAllStats || layerPak.eState != SAsyncPak::STATE_UNLOADED) - { - SLayerPakStats::SEntry entry; - entry.name = it->first; - entry.nSize = layerPak.nSize; - entry.bStreaming = layerPak.bStreaming; - layerPak.GetStatus(entry.status); - - stats.m_entries.push_back(entry); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StreamAsyncOnComplete( - IReadStream* pStream, unsigned nError) -{ - if (nError != 0) - { - return; - } - - SAsyncPak* pLayerPak = (SAsyncPak*) pStream->GetUserData(); - - //Check is pak is already open, if so, just assign mem - if (gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData)) - { - pLayerPak->bPakAlreadyOpen = true; - } - else - { - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, - &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (usePrefabSystemForLevels) - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL); - } - else - { - // - // ugly hack - depending on the pak file pak may need special root info / open flags - // - if (pLayerPak->layername.find("level.pak") != string::npos) - { - gEnv->pCryPak->OpenPack( - {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL); - } - else if (pLayerPak->layername.find("levelshadercache.pak") != string::npos) - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_PATH_REAL, NULL); - } - else - { - gEnv->pCryPak->OpenPack( - "@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, - NULL); - } - } - gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData); - } - - pLayerPak->eState = SAsyncPak::STATE_LOADED; - - //printf("Finished streaming level pak: %s\n", pLayerPak->layername.c_str()); -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::StreamOnComplete( - IReadStream* pStream, unsigned nError) -{ - SAsyncPak* pLayerPak = (SAsyncPak*) pStream->GetUserData(); - - if (nError != 0) - { - ReleaseData(pLayerPak); - } - - pLayerPak->bStreaming = false; - pLayerPak->pReadStream = NULL; - - m_bRequestLayerUpdate = true; -} - -void* CAsyncPakManager::StreamOnNeedStorage(IReadStream* pStream, unsigned nSize, bool& bAbortOnFailToAlloc) -{ - SAsyncPak* pAsyncPak = (SAsyncPak*)pStream->GetUserData(); - - pAsyncPak->nSize = nSize; - - if ((m_nTotalOpenLayerPakSize + nSize) > (size_t)(g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE)) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Not enough space to load in memory layer pak %s (Current: %" PRISIZE_T " Required: %d)", - pAsyncPak->filename.c_str(), m_nTotalOpenLayerPakSize, nSize); - - //printf("Not enough space to load in memory layer pak %s (Current: %d Required: %d)\n", pAsyncPak->filename.c_str(), m_nTotalOpenLayerPakSize, nSize); - - pAsyncPak->eState = SAsyncPak::STATE_UNLOADED; - pAsyncPak->bStreaming = false; - pAsyncPak->pReadStream = NULL; - - bAbortOnFailToAlloc = true; - - return NULL; - } - - if (nSize) - { - auto pCryPak = static_cast(gEnv->pCryPak); - - // allocate the data - const char* szUsage = "In Memory Zip File"; - pAsyncPak->pData = pCryPak->PoolAllocMemoryBlock(nSize, szUsage, alignof(uint8_t)); - - m_nTotalOpenLayerPakSize += nSize; - - return pAsyncPak->pData->m_address.get(); - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// - -void CAsyncPakManager::Update() -{ - if (!m_bRequestLayerUpdate) - { - return; - } - - m_bRequestLayerUpdate = false; - - for (TPakMap::iterator it = m_paks.begin(); - it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - if (!layerPak.bStreaming) - { - if (layerPak.eState == SAsyncPak::STATE_REQUESTUNLOAD) - { - // done streaming and not interested in it anymore, then release it again - ReleaseData(&layerPak); - } - else if (layerPak.eState == SAsyncPak::STATE_REQUESTED && - (m_nTotalOpenLayerPakSize + layerPak.nSize <= ((size_t)g_cvars.archiveVars.nTotalInMemoryPakSizeLimit * MEGA_BYTE))) - { - // do we have enough memory now to start streaming the pak - StartStreaming(&layerPak); - } - } - } -} - -// Abort streaming jobs and prevent any more requests -// Paks which are loaded remain, they will be cleaned up as usual -void CAsyncPakManager::CancelPendingJobs() -{ - for (TPakMap::iterator it = m_paks.begin(); it != m_paks.end(); ++it) - { - SAsyncPak& layerPak = it->second; - - if (layerPak.bStreaming) - { - layerPak.pReadStream->Abort(); - ReleaseData(&layerPak); - - //printf("Pak %s Aborted\n", layerPak.filename.c_str()); - } - else if (layerPak.eState == SAsyncPak::STATE_REQUESTED) - { - layerPak.eState = SAsyncPak::STATE_UNLOADED; - ReleaseData(&layerPak); - - //printf("Pak %s Cancelled\n", layerPak.filename.c_str()); - } - } -} - -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/AsyncPakManager.h b/Code/CryEngine/CrySystem/AsyncPakManager.h deleted file mode 100644 index 92a319c73c..0000000000 --- a/Code/CryEngine/CrySystem/AsyncPakManager.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manage async pak files - -#ifndef CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H -#pragma once - -#include -#include -#include - -namespace AZ::IO -{ - struct MemoryBlock; -} - -class CAsyncPakManager - : public IStreamCallback -{ -protected: - - struct SAsyncPak - { - enum EState - { - STATE_UNLOADED, - STATE_REQUESTED, - STATE_REQUESTUNLOAD, - STATE_LOADED, - }; - - enum ELifeTime - { - LIFETIME_LOAD_ONLY, - LIFETIME_LEVEL_COMPLETE, - LIFETIME_PERMANENT - }; - - SAsyncPak() - : nRequestCount(0) - , eState(STATE_UNLOADED) - , eLifeTime(LIFETIME_LOAD_ONLY) - , nSize(0) - , pData(0) - , bStreaming(false) - , bPakAlreadyOpen(false) - , bClosePakOnRelease(false) - , pReadStream(0) {} - - string& GetStatus(string&) const; - - string layername; - string filename; - size_t nSize; - AZStd::intrusive_ptr pData; - EState eState; - ELifeTime eLifeTime; - bool bStreaming; - bool bPakAlreadyOpen; - bool bClosePakOnRelease; - int nRequestCount; - IReadStreamPtr pReadStream; - }; - typedef std::map TPakMap; - -public: - - CAsyncPakManager(); - ~CAsyncPakManager(); - - void ParseLayerPaks(const string& levelCachePath); - - bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly); - void UnloadLevelLoadPaks(); - bool LoadLayerPak(const char* sLayerName); - void UnloadLayerPak(const char* sLayerName); - void CancelPendingJobs(); - - void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const; - - void Clear(); - void Update(); - -protected: - - bool LoadPak(SAsyncPak& layerPak); - - void StartStreaming(SAsyncPak* pLayerPak); - void ReleaseData(SAsyncPak* pLayerPak); - - ////////////////////////////////////////////////////////////////////////// - // IStreamCallback interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void StreamAsyncOnComplete (IReadStream* pStream, unsigned nError); - virtual void StreamOnComplete (IReadStream* pStream, unsigned nError); - virtual void* StreamOnNeedStorage(IReadStream* pStream, unsigned nSize, bool& bAbortOnFailToAlloc); - ////////////////////////////////////////////////////////////////////////// - - TPakMap m_paks; - size_t m_nTotalOpenLayerPakSize; - bool m_bRequestLayerUpdate; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ASYNCPAKMANAGER_H diff --git a/Code/CryEngine/CrySystem/AutoDetectSpec.cpp b/Code/CryEngine/CrySystem/AutoDetectSpec.cpp deleted file mode 100644 index dd7739bb79..0000000000 --- a/Code/CryEngine/CrySystem/AutoDetectSpec.cpp +++ /dev/null @@ -1,1145 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#if defined(WIN32) || defined(WIN64) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "System.h" -#include "AutoDetectSpec.h" - -// both function live in CPUDetect.cpp -bool IsAMD(); -bool IsIntel(); - - -static void TrimExcessiveWhiteSpaces(char* pStr) -{ - size_t len(strlen(pStr)); - bool remove(true); - for (size_t i(0); i < len; ++i) - { - if (pStr[i] == ' ' && remove) - { - size_t newlen(len - 1); - - size_t j(i + 1); - for (; j < len && pStr[j] == ' '; ++j) - { - --newlen; - } - - size_t ii(i); - for (; j < len + 1; ++j, ++ii) - { - pStr[ii] = pStr[j]; - } - - assert(newlen == strlen(pStr)); - len = newlen; - remove = false; - } - else - { - remove = pStr[i] == ' '; - } - } - - if (len > 0 && pStr[len - 1] == ' ') - { - pStr[len - 1] = '\0'; - } -} - - -static void GetCPUName(char* pName, size_t bufferSize) -{ - if (!pName || !bufferSize) - { - return; - } - - char name[12 * 4 + 1]; - - int CPUInfo[4]; - __cpuid(CPUInfo, 0x80000000); - if (CPUInfo[0] >= 0x80000004) - { - __cpuid(CPUInfo, 0x80000002); - ((int*)name)[0] = CPUInfo[0]; - ((int*)name)[1] = CPUInfo[1]; - ((int*)name)[2] = CPUInfo[2]; - ((int*)name)[3] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000003); - ((int*)name)[4] = CPUInfo[0]; - ((int*)name)[5] = CPUInfo[1]; - ((int*)name)[6] = CPUInfo[2]; - ((int*)name)[7] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000004); - ((int*)name)[8] = CPUInfo[0]; - ((int*)name)[9] = CPUInfo[1]; - ((int*)name)[10] = CPUInfo[2]; - ((int*)name)[11] = CPUInfo[3]; - - name[48] = '\0'; - } - else - { - name[0] = '\0'; - } - - int ret(azsnprintf(pName, bufferSize, name)); - if (ret >= bufferSize || ret < 0) - { - pName[bufferSize - 1] = '\0'; - } -} - - -void Win32SysInspect::GetOS(SPlatformInfo::EWinVersion& ver, bool& is64Bit, char* pName, size_t bufferSize) -{ - ver = SPlatformInfo::WinUndetected; - is64Bit = false; - - if (pName && bufferSize) - { - pName[0] = '\0'; - } - - //GetVersionEx was changed to work based on how the application is manifest - //meaning we have to specifically state that this application supports - //Windows 10, Windows 8.1 etc if we want GetVersionEx to return those version numbers. - //RtlGetVersion does not require a manifest. - auto RtlGetVersion = reinterpret_cast(GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion")); - AZ_Assert(RtlGetVersion, "Failed to get address to RtlGetVersion from ntdll.dll"); - - RTL_OSVERSIONINFOEXW sysInfo; - sysInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); - - if (RtlGetVersion(&sysInfo) == 0) - { - if (sysInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) - { - if (sysInfo.dwMajorVersion == 5) - { - if (sysInfo.dwMinorVersion == 0) - { - ver = SPlatformInfo::Win2000; - } - else if (sysInfo.dwMinorVersion == 1) - { - ver = SPlatformInfo::WinXP; - } - else if (sysInfo.dwMinorVersion == 2) - { - if (sysInfo.wProductType == VER_NT_WORKSTATION) - { - ver = SPlatformInfo::WinXP; // 64 bit windows actually but this will be detected later anyway - } - else if (sysInfo.wProductType == VER_NT_SERVER || sysInfo.wProductType == VER_NT_DOMAIN_CONTROLLER) - { - ver = SPlatformInfo::WinSrv2003; - } - } - } - else if (sysInfo.dwMajorVersion == 6) - { - if (sysInfo.dwMinorVersion == 0) - { - ver = SPlatformInfo::WinVista; - } - else if (sysInfo.dwMinorVersion == 1) - { - ver = SPlatformInfo::Win7; - } - else if (sysInfo.dwMinorVersion == 2) - { - ver = SPlatformInfo::Win8; - } - else if (sysInfo.dwMinorVersion == 3) - { - ver = SPlatformInfo::Win81; - } - } - else if (sysInfo.dwMajorVersion == 10) - { - ver = SPlatformInfo::Win10; - } - } - - typedef BOOL (WINAPI * FP_GetSystemWow64Directory)(LPSTR, UINT); - FP_GetSystemWow64Directory pgsw64d((FP_GetSystemWow64Directory) GetProcAddress(GetModuleHandle("kernel32"), "GetSystemWow64DirectoryA")); - if (pgsw64d) - { - char str[MAX_PATH]; - if (!pgsw64d(str, sizeof(str))) - { - is64Bit = GetLastError() != ERROR_CALL_NOT_IMPLEMENTED; - } - else - { - is64Bit = true; - } - } - - if (pName && bufferSize) - { - const char* windowsVersionText(0); - switch (ver) - { - case SPlatformInfo::Win2000: - windowsVersionText = "Windows 2000"; - break; - case SPlatformInfo::WinXP: - windowsVersionText = "Windows XP"; - break; - case SPlatformInfo::WinSrv2003: - windowsVersionText = "Windows Server 2003"; - break; - case SPlatformInfo::WinVista: - windowsVersionText = "Windows Vista"; - break; - case SPlatformInfo::Win7: - windowsVersionText = "Windows 7"; - break; - case SPlatformInfo::Win8: - windowsVersionText = "Windows 8"; - break; - case SPlatformInfo::Win81: - windowsVersionText = "Windows 8.1"; - break; - case SPlatformInfo::Win10: - windowsVersionText = "Windows 10"; - break; - default: - windowsVersionText = "Windows"; - break; - } - - char sptext[32]; - sptext[0] = '\0'; - if (sysInfo.wServicePackMajor > 0) - { - azsnprintf(sptext, sizeof(sptext), "SP %d ", sysInfo.wServicePackMajor); - } - - int ret(azsnprintf(pName, bufferSize, "%s %s %s(build %d.%d.%d)", windowsVersionText, is64Bit ? "64 bit" : "32 bit", - sptext, sysInfo.dwMajorVersion, sysInfo.dwMinorVersion, sysInfo.dwBuildNumber)); - if (ret >= bufferSize || ret < 0) - { - pName[bufferSize - 1] = '\0'; - } - } - } -} - -bool Win32SysInspect::IsVistaKB940105Required() -{ -#if defined(WIN32) && !defined(WIN64) - OSVERSIONINFO osv; - memset(&osv, 0, sizeof(osv)); - osv.dwOSVersionInfoSize = sizeof(osv); - GetVersionEx(&osv); - - if (osv.dwMajorVersion != 6 || osv.dwMinorVersion != 0 || (osv.dwBuildNumber > 6000)) - { - // This QFE only ever applies to Windows Vista RTM. Windows Vista SP1 already has this fix, - // and earlier versions of Windows do not implement WDDM - return false; - } - - //MEMORYSTATUSEX mex; - //memset(&mex, 0, sizeof(mex)); - //mex.dwLength = sizeof(mex); - //GlobalMemoryStatusEx(&mex); - - //if (mex.ullTotalVirtual >= 4294836224) - //{ - // // If there is 4 GB of VA space total for this process, then we are a - // // 32-bit Large Address Aware application running on a Windows 64-bit OS. - - // // We could be a 32-bit Large Address Aware application running on a - // // Windows 32-bit OS and get up to 3 GB, but that has stability implications. - // // Therefore, we recommend the QFE for all 32-bit versions of the OS. - - // // No need for the fix unless the game is pushing 4 GB of VA - // return false; - //} - - const char* sysFile = "dxgkrnl.sys"; - - // Ensure we are checking the system copy of the file - char sysPath[MAX_PATH]; - GetSystemDirectory(sysPath, sizeof(sysPath)); - - cry_strcat(sysPath, "\\drivers\\"); - cry_strcat(sysPath, sysFile); - - char buf[2048]; - if (!GetFileVersionInfo(sysPath, 0, sizeof(buf), buf)) - { - // This should never happen, but we'll assume it's a newer .sys file since we've - // narrowed the test to a Windows Vista RTM OS. - return false; - } - - VS_FIXEDFILEINFO* ver; - UINT size; - if (!VerQueryValue(buf, "\\", (void**) &ver, &size) || size != sizeof(VS_FIXEDFILEINFO) || ver->dwSignature != 0xFEEF04BD) - { - // This should never happen, but we'll assume it's a newer .sys file since we've - // narrowed the test to a Windows Vista RTM OS. - return false; - } - - // File major.minor.build.qfe version comparison - // WORD major = HIWORD( ver->dwFileVersionMS ); WORD minor = LOWORD( ver->dwFileVersionMS ); - // WORD build = HIWORD( ver->dwFileVersionLS ); WORD qfe = LOWORD( ver->dwFileVersionLS ); - - if (ver->dwFileVersionMS > MAKELONG(0, 6) || (ver->dwFileVersionMS == MAKELONG(0, 6) && ver->dwFileVersionLS >= MAKELONG(20648, 6000))) - { - // QFE fix version of dxgkrnl.sys is 6.0.6000.20648 - return false; - } - - return true; -#else - return false; // The QFE is not required for a 64-bit native application as it has 8 TB of VA -#endif -} - - -static void GetSystemMemory(uint64& totSysMem) -{ - typedef BOOL (WINAPI * FP_GlobalMemoryStatusEx)(LPMEMORYSTATUSEX); - FP_GlobalMemoryStatusEx pgmsex((FP_GlobalMemoryStatusEx) GetProcAddress(GetModuleHandle("kernel32"), "GlobalMemoryStatusEx")); - if (pgmsex) - { - MEMORYSTATUSEX memStats; - memStats.dwLength = sizeof(memStats); - if (pgmsex(&memStats)) - { - totSysMem = memStats.ullTotalPhys; - } - else - { - totSysMem = 0; - } - } - else - { - MEMORYSTATUS memStats; - memStats.dwLength = sizeof(memStats); - GlobalMemoryStatus(&memStats); - totSysMem = memStats.dwTotalPhys; - } -} - - -static bool IsVistaOrAbove() -{ - typedef BOOL (WINAPI * FP_VerifyVersionInfo)(LPOSVERSIONINFOEX, DWORD, DWORDLONG); - FP_VerifyVersionInfo pvvi((FP_VerifyVersionInfo) GetProcAddress(GetModuleHandle("kernel32"), "VerifyVersionInfoA")); - - if (pvvi) - { - typedef ULONGLONG (WINAPI * FP_VerSetConditionMask)(ULONGLONG, DWORD, BYTE); - FP_VerSetConditionMask pvscm((FP_VerSetConditionMask) GetProcAddress(GetModuleHandle("kernel32"), "VerSetConditionMask")); - assert(pvscm); - - OSVERSIONINFOEX osvi; - memset(&osvi, 0, sizeof(osvi)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - osvi.dwMajorVersion = 6; - osvi.dwMinorVersion = 0; - osvi.wServicePackMajor = 0; - osvi.wServicePackMinor = 0; - - ULONGLONG mask(0); - mask = pvscm(mask, VER_MAJORVERSION, VER_GREATER_EQUAL); - mask = pvscm(mask, VER_MINORVERSION, VER_GREATER_EQUAL); - mask = pvscm(mask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - mask = pvscm(mask, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - - if (pvvi(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, mask)) - { - return true; - } - } - - return false; -} - - -// Preferred solution to determine the number of available CPU cores, works reliably only on WinVista/Win7 32/64 and above -// See http://msdn2.microsoft.com/en-us/library/ms686694.aspx for reasons -static void GetNumCPUCoresGlpi(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess) -{ - typedef BOOL (WINAPI * FP_GetLogicalProcessorInformation)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); - FP_GetLogicalProcessorInformation pglpi((FP_GetLogicalProcessorInformation) GetProcAddress(GetModuleHandle("kernel32"), "GetLogicalProcessorInformation")); - if (pglpi && IsVistaOrAbove()) - { - unsigned long bufferSize(0); - pglpi(0, &bufferSize); - - void* pBuffer(alloca(bufferSize)); - - SYSTEM_LOGICAL_PROCESSOR_INFORMATION* pLogProcInfo((SYSTEM_LOGICAL_PROCESSOR_INFORMATION*) pBuffer); - if (pLogProcInfo && pglpi(pLogProcInfo, &bufferSize)) - { - DWORD_PTR processAffinity, systemAffinity; - GetProcessAffinityMask(GetCurrentProcess(), &processAffinity, &systemAffinity); - - unsigned long numEntries(bufferSize / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); - for (unsigned long i(0); i < numEntries; ++i) - { - switch (pLogProcInfo[i].Relationship) - { - case RelationProcessorCore: - { - ++totAvailToSystem; - if (pLogProcInfo[i].ProcessorMask & processAffinity) - { - ++totAvailToProcess; - } - } - break; - - default: - break; - } - } - } - } -} - - -class CApicExtractor -{ -public: - CApicExtractor(unsigned int logProcsPerPkg = 1, unsigned int coresPerPkg = 1) - { - SetPackageTopology(logProcsPerPkg, coresPerPkg); - } - - unsigned char SmtId(unsigned char apicId) const - { - return apicId & m_smtIdMask.mask; - } - - unsigned char CoreId(unsigned char apicId) const - { - return (apicId & m_coreIdMask.mask) >> m_smtIdMask.width; - } - - unsigned char PackageId(unsigned char apicId) const - { - return (apicId & m_pkgIdMask.mask) >> (m_smtIdMask.width + m_coreIdMask.width); - } - - unsigned char PackageCoreId(unsigned char apicId) const - { - return (apicId & (m_pkgIdMask.mask | m_coreIdMask.mask)) >> m_smtIdMask.width; - } - - unsigned int GetLogProcsPerPkg() const - { - return m_logProcsPerPkg; - } - - unsigned int GetCoresPerPkg() const - { - return m_coresPerPkg; - } - - void SetPackageTopology(unsigned int logProcsPerPkg, unsigned int coresPerPkg) - { - m_logProcsPerPkg = (unsigned char) logProcsPerPkg; - m_coresPerPkg = (unsigned char) coresPerPkg; - - m_smtIdMask.width = GetMaskWidth(m_logProcsPerPkg / m_coresPerPkg); - m_coreIdMask.width = GetMaskWidth(m_coresPerPkg); - m_pkgIdMask.width = 8 - (m_smtIdMask.width + m_coreIdMask.width); - - m_pkgIdMask.mask = (unsigned char) (0xFF << (m_smtIdMask.width + m_coreIdMask.width)); - m_coreIdMask.mask = (unsigned char) ((0xFF << m_smtIdMask.width) ^ m_pkgIdMask.mask); - m_smtIdMask.mask = (unsigned char) ~(0xFF << m_smtIdMask.width); - } - -private: - unsigned char GetMaskWidth(unsigned char maxIds) const - { - --maxIds; - unsigned char msbIdx(8); - unsigned char msbMask(0x80); - while (msbMask && !(msbMask & maxIds)) - { - --msbIdx; - msbMask >>= 1; - } - return msbIdx; - } - - struct IdMask - { - unsigned char width; - unsigned char mask; - }; - - unsigned char m_logProcsPerPkg; - unsigned char m_coresPerPkg; - IdMask m_smtIdMask; - IdMask m_coreIdMask; - IdMask m_pkgIdMask; -}; - - -// Fallback solution for WinXP 32/64 -static void GetNumCPUCoresApic(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess) -{ - unsigned int numLogicalPerPhysical(1); - unsigned int numCoresPerPhysical(1); - - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - if ((CPUInfo[3] & 0x10000000) != 0) // Hyperthreading / Multicore bit set - { - numLogicalPerPhysical = (CPUInfo[1] & 0x00FF0000) >> 16; - - if (IsIntel()) - { - __cpuid(CPUInfo, 0x00000000); - if (CPUInfo[0] >= 0x00000004) - { - __cpuidex(CPUInfo, 4, 0); - numCoresPerPhysical = ((CPUInfo[0] & 0xFC000000) >> 26) + 1; - } - } - else if (IsAMD()) - { - __cpuid(CPUInfo, 0x80000000); - if (CPUInfo[0] >= 0x80000008) - { - __cpuid(CPUInfo, 0x80000008); - if (CPUInfo[2] & 0x0000F000) - { - numCoresPerPhysical = 1 << ((CPUInfo[2] & 0x0000F000) >> 12); - } - else - { - numCoresPerPhysical = (CPUInfo[2] & 0xFF) + 1; - } - } - } - } - - HANDLE hCurProcess(GetCurrentProcess()); - HANDLE hCurThread(GetCurrentThread()); - - const int c_maxLogicalProcessors(sizeof(DWORD_PTR) * 8); - unsigned char apicIds[c_maxLogicalProcessors] = { 0 }; - unsigned char items(0); - - DWORD_PTR processAffinity, systemAffinity; - GetProcessAffinityMask(hCurProcess, &processAffinity, &systemAffinity); - - if (systemAffinity == 1) - { - assert(numLogicalPerPhysical == 1); - apicIds[items++] = 0; - } - else - { - if (processAffinity != systemAffinity) - { - SetProcessAffinityMask(hCurProcess, systemAffinity); - } - - DWORD_PTR prevThreadAffinity(0); - for (DWORD_PTR threadAffinity = 1; threadAffinity && threadAffinity <= systemAffinity; threadAffinity <<= 1) - { - if (systemAffinity & threadAffinity) - { - if (!prevThreadAffinity) - { - assert(!items); - prevThreadAffinity = SetThreadAffinityMask(hCurThread, threadAffinity); - } - else - { - assert(items > 0); - SetThreadAffinityMask(hCurThread, threadAffinity); - } - - Sleep(0); - - int CPUInfo2[4]; - __cpuid(CPUInfo2, 0x00000001); - apicIds[items++] = (unsigned char) ((CPUInfo2[1] & 0xFF000000) >> 24); - } - } - - SetProcessAffinityMask(hCurProcess, processAffinity); - SetThreadAffinityMask(hCurThread, prevThreadAffinity); - Sleep(0); - } - - CApicExtractor apicExtractor(numLogicalPerPhysical, numCoresPerPhysical); - - totAvailToSystem = 0; - { - unsigned char pkgCoreIds[c_maxLogicalProcessors] = { 0 }; - for (unsigned int i(0); i < items; ++i) - { - unsigned int j(0); - for (; j < totAvailToSystem; ++j) - { - if (pkgCoreIds[j] == apicExtractor.PackageCoreId(apicIds[i])) - { - break; - } - } - if (j == totAvailToSystem) - { - pkgCoreIds[j] = apicExtractor.PackageCoreId(apicIds[i]); - ++totAvailToSystem; - } - } - } - - totAvailToProcess = 0; - { - unsigned char pkgCoreIds[c_maxLogicalProcessors] = { 0 }; - for (unsigned int i(0); i < items; ++i) - { - if (processAffinity & ((DWORD_PTR) 1 << i)) - { - unsigned int j(0); - for (; j < totAvailToProcess; ++j) - { - if (pkgCoreIds[j] == apicExtractor.PackageCoreId(apicIds[i])) - { - break; - } - } - if (j == totAvailToProcess) - { - pkgCoreIds[j] = apicExtractor.PackageCoreId(apicIds[i]); - ++totAvailToProcess; - } - } - } - } -} - -const char* Win32SysInspect::GetFeatureLevelAsString(Win32SysInspect::DXFeatureLevel featureLevel) -{ - switch (featureLevel) - { - case Win32SysInspect::DXFL_Undefined: - return "unknown"; - case Win32SysInspect::DXFL_9_1: - return "DX9 (SM 2.0)"; - case Win32SysInspect::DXFL_9_2: - return "DX9 (SM 2.0)"; - case Win32SysInspect::DXFL_9_3: - return "DX9 (SM 2.x)"; - case Win32SysInspect::DXFL_10_0: - return "DX10 (SM 4.0)"; - case Win32SysInspect::DXFL_10_1: - return "DX10.1 (SM 4.x)"; - case Win32SysInspect::DXFL_11_0: - default: - return "DX11 (SM 5.0)"; - } -} - -void Win32SysInspect::GetNumCPUCores(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess) -{ - totAvailToSystem = 0; - totAvailToProcess = 0; - - GetNumCPUCoresGlpi(totAvailToSystem, totAvailToProcess); - - if (!totAvailToSystem) - { - GetNumCPUCoresApic(totAvailToSystem, totAvailToProcess); - } -} - - -static Win32SysInspect::DXFeatureLevel GetFeatureLevel(D3D_FEATURE_LEVEL featureLevel) -{ - switch (featureLevel) - { - case D3D_FEATURE_LEVEL_9_1: - return Win32SysInspect::DXFL_9_1; - case D3D_FEATURE_LEVEL_9_2: - return Win32SysInspect::DXFL_9_2; - case D3D_FEATURE_LEVEL_9_3: - return Win32SysInspect::DXFL_9_3; - case D3D_FEATURE_LEVEL_10_0: - return Win32SysInspect::DXFL_10_0; - case D3D_FEATURE_LEVEL_10_1: - return Win32SysInspect::DXFL_10_1; - case D3D_FEATURE_LEVEL_11_0: - default: - return Win32SysInspect::DXFL_11_0; - } -} - - -static int GetDXGIAdapterOverride() -{ -#if defined(WIN32) || defined(WIN64) - ICVar* pCVar = gEnv->pConsole ? gEnv->pConsole->GetCVar("r_overrideDXGIAdapter") : 0; - return pCVar ? pCVar->GetIVal() : -1; -#else - return -1; -#endif -} - - -static void LogDeviceInfo(unsigned int adapterIdx, const DXGI_ADAPTER_DESC1& ad, Win32SysInspect::DXFeatureLevel fl, bool displaysConnected) -{ - const bool suitableDevice = fl >= Win32SysInspect::DXFL_11_0 && displaysConnected; - - CryLogAlways("- %s (vendor = 0x%.4x, device = 0x%.4x)", CryStringUtils::WStrToUTF8(ad.Description).c_str(), ad.VendorId, ad.DeviceId); - CryLogAlways(" - Adapter index: %d", adapterIdx); - CryLogAlways(" - Dedicated video memory: %d MB", ad.DedicatedVideoMemory >> 20); - CryLogAlways(" - Feature level: %s", GetFeatureLevelAsString(fl)); - CryLogAlways(" - Displays connected: %s", displaysConnected ? "yes" : "no"); - CryLogAlways(" - Suitable rendering device: %s", suitableDevice ? "yes" : "no"); -} - - -static bool FindGPU(DXGI_ADAPTER_DESC1& adapterDesc, Win32SysInspect::DXFeatureLevel& featureLevel) -{ - memset(&adapterDesc, 0, sizeof(adapterDesc)); - featureLevel = Win32SysInspect::DXFL_Undefined; - - if (!IsVistaOrAbove()) - { - return false; - } - - typedef HRESULT (WINAPI * FP_CreateDXGIFactory1)(REFIID, void**); - FP_CreateDXGIFactory1 pCDXGIF = (FP_CreateDXGIFactory1) GetProcAddress(LoadLibraryA("dxgi.dll"), "CreateDXGIFactory1"); - - IDXGIFactory1* pFactory = 0; - if (pCDXGIF && SUCCEEDED(pCDXGIF(__uuidof(IDXGIFactory1), (void**) &pFactory)) && pFactory) - { - typedef HRESULT (WINAPI * FP_D3D11CreateDevice)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, CONST D3D_FEATURE_LEVEL*, UINT, UINT, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext**); - FP_D3D11CreateDevice pD3D11CD = (FP_D3D11CreateDevice) GetProcAddress(LoadLibraryA("d3d11.dll"), "D3D11CreateDevice"); - - if (pD3D11CD) - { - const int r_overrideDXGIAdapter = GetDXGIAdapterOverride(); - const bool logDeviceInfo = !gEnv->pRenderer && r_overrideDXGIAdapter < 0; - - if (logDeviceInfo) - { - CryLogAlways("Logging video adapters:"); - } - - unsigned int nAdapter = r_overrideDXGIAdapter >= 0 ? r_overrideDXGIAdapter : 0; - IDXGIAdapter1* pAdapter = 0; - while (pFactory->EnumAdapters1(nAdapter, &pAdapter) != DXGI_ERROR_NOT_FOUND) - { - if (pAdapter) - { - ID3D11Device* pDevice = 0; - D3D_FEATURE_LEVEL levels[] = {D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1}; - D3D_FEATURE_LEVEL deviceFeatureLevel = D3D_FEATURE_LEVEL_9_1; - HRESULT hr = pD3D11CD(pAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, levels, sizeof(levels) / sizeof(levels[0]), D3D11_SDK_VERSION, &pDevice, &deviceFeatureLevel, NULL); - if (SUCCEEDED(hr) && pDevice) - { - IDXGIOutput* pOutput = 0; - const bool displaysConnected = SUCCEEDED(pAdapter->EnumOutputs(0, &pOutput)) && pOutput; - SAFE_RELEASE(pOutput); - - DXGI_ADAPTER_DESC1 ad; - pAdapter->GetDesc1(&ad); - - const Win32SysInspect::DXFeatureLevel fl = GetFeatureLevel(deviceFeatureLevel); - - if (logDeviceInfo) - { - LogDeviceInfo(nAdapter, ad, fl, displaysConnected); - } - - if (featureLevel < fl && displaysConnected) - { - adapterDesc = ad; - featureLevel = fl; - } - else if (r_overrideDXGIAdapter >= 0) - { - CryLogAlways("No display connected to DXGI adapter override %d. Adapter cannot be used for rendering.", r_overrideDXGIAdapter); - } - } - - SAFE_RELEASE(pDevice); - SAFE_RELEASE(pAdapter); - } - if (r_overrideDXGIAdapter >= 0) - { - break; - } - ++nAdapter; - } - } - } - SAFE_RELEASE(pFactory); - return featureLevel != Win32SysInspect::DXFL_Undefined; -} - - -bool Win32SysInspect::IsDX11Supported() -{ - DXGI_ADAPTER_DESC1 adapterDesc = {}; - DXFeatureLevel featureLevel = Win32SysInspect::DXFL_Undefined; - return FindGPU(adapterDesc, featureLevel) && featureLevel >= DXFL_11_0; -} - - -bool Win32SysInspect::GetGPUInfo(char* pName, size_t bufferSize, unsigned int& vendorID, unsigned int& deviceID, unsigned int& totLocalVidMem, DXFeatureLevel& featureLevel) -{ - if (pName && bufferSize) - { - pName[0] = '\0'; - } - - vendorID = 0; - deviceID = 0; - totLocalVidMem = 0; - featureLevel = Win32SysInspect::DXFL_Undefined; - - DXGI_ADAPTER_DESC1 adapterDesc = {}; - const bool gpuFound = FindGPU(adapterDesc, featureLevel); - if (gpuFound) - { - vendorID = adapterDesc.VendorId; - deviceID = adapterDesc.DeviceId; - - if (pName && bufferSize) - { - sprintf_s(pName, bufferSize, "%s", CryStringUtils::WStrToUTF8(adapterDesc.Description).c_str()); - } - - totLocalVidMem = adapterDesc.DedicatedVideoMemory; - } - - return gpuFound; -} - - -class CGPURating -{ -public: - CGPURating(); - ~CGPURating(); - - int GetRating(unsigned int vendorId, unsigned int deviceId) const; - -private: - struct SGPUID - { - SGPUID(unsigned int vendorId, unsigned int deviceId) - : vendor(vendorId) - , device(deviceId) - { - } - - bool operator < (const SGPUID& rhs) const - { - if (vendor == rhs.vendor) - { - return device < rhs.device; - } - else - { - return vendor < rhs.vendor; - } - } - - unsigned int vendor; - unsigned int device; - }; - - typedef std::map GPURatingMap; - -private: - GPURatingMap m_gpuRatingMap; -}; - - -static size_t SafeReadLine(AZ::IO::IArchive* pPak, AZ::IO::HandleType fileHandle, char* buffer, size_t bufferSize) -{ - assert(buffer && bufferSize); - - memset(buffer, 0, bufferSize); - - size_t bytesRead = pPak->FRead(buffer, bufferSize - 1, fileHandle); - if (!bytesRead) - { - return 0; - } - - char* currentPosition = buffer; - size_t len = 0; - - bool done = false; - int slashRPosition = -1; - do - { - if (*currentPosition != '\r' && *currentPosition != '\n' && len < bufferSize - 1) - { - len++; - currentPosition++; - } - else - { - done = true; - if (*currentPosition == '\r') - { - slashRPosition = len; - } - } - } while (!done); - - // null terminate string - buffer[len] = '\0'; - - ////////////////////////////////////////// - //seek back to the end of the string - int seekback = bytesRead - len - 1; - - // handle CR/LF for file coming from different platforms - if (slashRPosition > -1 && bytesRead > slashRPosition && buffer[slashRPosition + 1] == '\n') - { - seekback--; - } - pPak->FSeek(fileHandle, -seekback, SEEK_CUR); - /////////////////////////////////////////// - - return len; -} - - -#define BUILDPATH_GPURATING(x) "config/gpu/" x - -CGPURating::CGPURating() -{ - auto pPak(gEnv->pCryPak); - - AZ::IO::ArchiveFileIterator h(pPak->FindFirst(BUILDPATH_GPURATING("*.txt"))); - if (h) - { - do - { - char filename[128]; - azsnprintf(filename, sizeof(filename), BUILDPATH_GPURATING("%.*s"), aznumeric_cast(h.m_filename.size()), h.m_filename.data()); - - AZ::IO::HandleType fileHandle = pPak->FOpen(filename, "rb"); - if (fileHandle != AZ::IO::InvalidHandle) - { - size_t lineNr(0); - while (!pPak->FEof(fileHandle)) - { - char line[1024]; - line[0] = '\0'; - size_t len(SafeReadLine(pPak, fileHandle, line, sizeof(line))); - ++lineNr; - - if (len > 2 && line[0] != '/' && line[1] != '/') - { - unsigned int vendorId(0), deviceId(0); - int rating(0); - if (_snscanf_s(line, sizeof(line), "%x,%x,%d", &vendorId, &deviceId, &rating) == 3) - { - GPURatingMap::iterator it(m_gpuRatingMap.find(SGPUID(vendorId, deviceId))); - if (it == m_gpuRatingMap.end()) - { - m_gpuRatingMap.insert(GPURatingMap::value_type(SGPUID(vendorId, deviceId), rating)); - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "%s line %d contains a multiple defined GPU rating!", filename, lineNr); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "%s line %d contains incomplete GPU rating!", filename, lineNr); - } - } - } - - pPak->FClose(fileHandle); - } - } while (h = pPak->FindNext(h)); - - pPak->FindClose(h); - } -} - - -CGPURating::~CGPURating() -{ -} - - -int CGPURating::GetRating(unsigned int vendorId, unsigned int deviceId) const -{ - GPURatingMap::const_iterator it(m_gpuRatingMap.find(SGPUID(vendorId, deviceId))); - if (it != m_gpuRatingMap.end()) - { - return (*it).second; - } - else - { - return 0; - } -} - - -int Win32SysInspect::GetGPURating([[maybe_unused]] unsigned int vendorId, [[maybe_unused]] unsigned int deviceId) -{ - return 0; // All GPUs unrated as the database is out of date - - //CGPURating gpuRatingDb; - //return gpuRatingDb.GetRating(vendorId, deviceId); -} - - -static int GetFinalSpecValue(int cpuRating, unsigned int totSysMemMB, int gpuRating, unsigned int totVidMemMB, ESystemConfigSpec maxConfigSpec) -{ - int sysMemRating = 1; - if (totSysMemMB >= Win32SysInspect::SafeMemoryThreshold(12228)) - { - sysMemRating = 3; - } - else if (totSysMemMB >= Win32SysInspect::SafeMemoryThreshold(8192)) - { - sysMemRating = 2; - } - - cpuRating = sysMemRating < cpuRating ? sysMemRating : cpuRating; - - // just a sanity check, GPU should reflect overall GPU perf including memory (higher rated GPUs usually come with enough memory) - if (totVidMemMB < Win32SysInspect::SafeMemoryThreshold(1024)) - { - gpuRating = 1; - } - - int finalRating = cpuRating < gpuRating ? cpuRating : gpuRating; - - return min(finalRating, (int) maxConfigSpec); -} - - -void CSystem::AutoDetectSpec(const bool detectResolution) -{ - CryLogAlways("Running machine spec auto detect (%d bit)...", sizeof(void*) << 3); - - char tempBuf[512]; - - // get OS - SPlatformInfo::EWinVersion winVer(SPlatformInfo::WinUndetected); - bool is64bit(false); - Win32SysInspect::GetOS(winVer, is64bit, tempBuf, sizeof(tempBuf)); - CryLogAlways("- %s", tempBuf); - - // get system memory - uint64 totSysMem(0); - GetSystemMemory(totSysMem); - CryLogAlways("- System memory"); - CryLogAlways("--- %d MB", totSysMem >> 20); - - // get CPU name - GetCPUName(tempBuf, sizeof(tempBuf)); - TrimExcessiveWhiteSpaces(tempBuf); - CryLogAlways("- %s", tempBuf); - - // get number of CPU cores - unsigned int numSysCores(1), numProcCores(1); - Win32SysInspect::GetNumCPUCores(numSysCores, numProcCores); - CryLogAlways("--- Number of available cores: %d (out of %d)", numProcCores, numSysCores); - const int numLogicalProcs = gEnv->pi.numLogicalProcessors; - CryLogAlways("--- Number of logical processors: %d", numLogicalProcs); - - // get CPU rating - const int cpuRating = numLogicalProcs >= 8 ? 3 : (numLogicalProcs >= 6 ? 2 : 1); - - // get GPU info - unsigned int gpuVendorId(0), gpuDeviceId(0), totVidMem(0); - Win32SysInspect::DXFeatureLevel featureLevel(Win32SysInspect::DXFL_Undefined); - Win32SysInspect::GetGPUInfo(tempBuf, sizeof(tempBuf), gpuVendorId, gpuDeviceId, totVidMem, featureLevel); - - CryLogAlways("- %s (vendor = 0x%.4x, device = 0x%.4x)", tempBuf, gpuVendorId, gpuDeviceId); - CryLogAlways("--- Dedicated video memory: %d MB", totVidMem >> 20); - CryLogAlways("--- Feature level: %s", GetFeatureLevelAsString(featureLevel)); - - // get GPU rating - const int gpuRating = (totVidMem >> 20) >= Win32SysInspect::SafeMemoryThreshold(4096) ? 3 : ((totVidMem >> 20) >= Win32SysInspect::SafeMemoryThreshold(2048) ? 2 : 1); - - // get final rating - int finalSpecValue(GetFinalSpecValue(cpuRating, totSysMem >> 20, gpuRating, totVidMem >> 20, CONFIG_VERYHIGH_SPEC)); - CryLogAlways("- Final rating: Machine class %d", finalSpecValue); - - m_sys_GraphicsQuality->Set(finalSpecValue); - - if (detectResolution) - { - if ((m_rWidth->GetFlags() & VF_WASINCONFIG) == 0) - { - m_rWidth->Set(GetSystemMetrics(SM_CXFULLSCREEN)); - } - if ((m_rHeight->GetFlags() & VF_WASINCONFIG) == 0) - { - m_rHeight->Set(GetSystemMetrics(SM_CYFULLSCREEN)); - } - if ((m_rFullscreen->GetFlags() & VF_WASINCONFIG) == 0) - { - m_rFullscreen->Set(1); - } - } -} - - -#else - -#include "System.h" - -void CSystem::AutoDetectSpec(const bool detectResolution) -{ - AZ_UNUSED(detectResolution); -} - - -#endif diff --git a/Code/CryEngine/CrySystem/AutoDetectSpec.h b/Code/CryEngine/CrySystem/AutoDetectSpec.h deleted file mode 100644 index a710141668..0000000000 --- a/Code/CryEngine/CrySystem/AutoDetectSpec.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_AUTODETECTSPEC_H -#define CRYINCLUDE_CRYSYSTEM_AUTODETECTSPEC_H -#pragma once - - - -#if defined(WIN32) || defined(WIN64) - -// exposed AutoDetectSpec() helper functions for reuse in CrySystem -namespace Win32SysInspect -{ - enum DXFeatureLevel - { - DXFL_Undefined, - DXFL_9_1, - DXFL_9_2, - DXFL_9_3, - DXFL_10_0, - DXFL_10_1, - DXFL_11_0 - }; - - const char* GetFeatureLevelAsString(DXFeatureLevel featureLevel); - - void GetNumCPUCores(unsigned int& totAvailToSystem, unsigned int& totAvailToProcess); - bool IsDX11Supported(); - bool GetGPUInfo(char* pName, size_t bufferSize, unsigned int& vendorID, unsigned int& deviceID, unsigned int& totLocalVidMem, DXFeatureLevel& featureLevel); - int GetGPURating(unsigned int vendorId, unsigned int deviceId); - void GetOS(SPlatformInfo::EWinVersion& ver, bool& is64Bit, char* pName, size_t bufferSize); - bool IsVistaKB940105Required(); - - inline size_t SafeMemoryThreshold(size_t memMB) - { - return (memMB * 8) / 10; - } -} - -#endif // #if defined(WIN32) || defined(WIN64) - - -#endif // CRYINCLUDE_CRYSYSTEM_AUTODETECTSPEC_H diff --git a/Code/CryEngine/CrySystem/CMakeLists.txt b/Code/CryEngine/CrySystem/CMakeLists.txt index 1a5593e5d8..5a43051ed7 100644 --- a/Code/CryEngine/CrySystem/CMakeLists.txt +++ b/Code/CryEngine/CrySystem/CMakeLists.txt @@ -9,46 +9,17 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME}) -ly_get_list_relative_pal_filename(common_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/Common) add_subdirectory(XML) -# The following target is a 'C' file only library to work around an issue in cmake and VS generators that -# will append 'std=c++17' to both C and C++ compiler flags for clang. Do not add any .cpp files to this -# library. -ly_add_target( - NAME CrySystem.DLMalloc.C STATIC - NAMESPACE Legacy - FILES_CMAKE - crysystem_dlmalloc_files.cmake - INCLUDE_DIRECTORIES - PUBLIC - . - PRIVATE - ${pal_dir} -) - - -ly_get_pal_tool_dirs(pal_tool_dirs ${CMAKE_CURRENT_LIST_DIR}/Platform) - ly_add_target( NAME CrySystem.Static STATIC NAMESPACE Legacy FILES_CMAKE crysystem_files.cmake - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake INCLUDE_DIRECTORIES PUBLIC . - ${pal_dir} - PRIVATE - ${common_dir} - ${pal_tool_dirs} BUILD_DEPENDENCIES - PUBLIC - Legacy::CrySystem.DLMalloc.C PRIVATE 3rdParty::expat 3rdParty::lz4 @@ -68,19 +39,11 @@ ly_add_source_properties( VALUES ${LY_PAL_TOOLS_DEFINES} ) -ly_add_source_properties( - SOURCES SystemCFG.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES LY_BUILD=${LY_VERSION_BUILD_NUMBER} -) - ly_add_target( NAME CrySystem ${PAL_TRAIT_MONOLITHIC_DRIVEN_LIBRARY_TYPE} NAMESPACE Legacy FILES_CMAKE crysystem_shared_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake INCLUDE_DIRECTORIES PUBLIC . @@ -89,32 +52,4 @@ ly_add_target( Legacy::CrySystem.Static AZ::AzCore Legacy::CryCommon - Legacy::CryCommon.EngineSettings.Static ) - -################################################################################ -# Tests -################################################################################ -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - - ly_add_target( - NAME CrySystem.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Legacy - FILES_CMAKE - crysystem_test_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - . - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - Legacy::CryCommon - Legacy::CryCommon.EngineSettings.Static - Legacy::CrySystem.Static - AZ::AzFramework - ) - ly_add_googletest( - NAME Legacy::CrySystem.Tests - ) -endif() - diff --git a/Code/CryEngine/CrySystem/CPUDetect.cpp b/Code/CryEngine/CrySystem/CPUDetect.cpp deleted file mode 100644 index 6d924a1514..0000000000 --- a/Code/CryEngine/CrySystem/CPUDetect.cpp +++ /dev/null @@ -1,1622 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "AutoDetectSpec.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CPUDETECT_CPP_SECTION_1 1 -#define CPUDETECT_CPP_SECTION_2 2 -#endif - -#if defined(WIN32) -#include -#elif defined(LINUX) || defined(APPLE) -#include // setrlimit, getrlimit -#endif - -#if defined(APPLE) -#include -#include // mach_thread_self -#include // Mac OS Thread affinity API -#include -#endif - -#if defined(LINUX) -#ifndef __GNU_SOURCE -#define __GNU_SOURCE -#endif -#include //already includes sched.h -#endif - -/* features */ -#define FPU_FLAG 0x0001 -#define SERIAL_FLAG 0x40000 -#define MMX_FLAG 0x800000 -#define ISSE_FLAG 0x2000000 - -#ifdef __GNUC__ -# define cpuid(op, eax, ebx, ecx, edx) __asm__("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (op) : "cc"); -#endif - -int g_CpuFlags; - -struct SAutoMaxPriority -{ - SAutoMaxPriority() - { - /* get a copy of the current thread and process priorities */ -#if defined(WIN32) - priority_class = GetPriorityClass(GetCurrentProcess()); - thread_priority = GetThreadPriority(GetCurrentThread()); -#elif defined(LINUX) || defined(APPLE) - nice_priority = getpriority(PRIO_PROCESS, 0); - success = nice_priority >= 0 && - pthread_getschedparam(pthread_self(), &thread_policy, &thread_sched_param) == 0; -#endif - - /* make this thread the highest possible priority */ -#if defined(WIN32) - SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); -#elif defined(LINUX) || defined(APPLE) - if (success) - { - setpriority(PRIO_PROCESS, 0, MAX_NICE_PRIORITY); - - sched_param new_sched_param = thread_sched_param; - new_sched_param.sched_priority = sched_get_priority_max(thread_policy); - pthread_setschedparam(pthread_self(), thread_policy, &new_sched_param); - } -#endif - } - - ~SAutoMaxPriority() - { - /* restore the thread priority */ -#if defined(WIN32) - SetPriorityClass(GetCurrentProcess(), priority_class); - SetThreadPriority(GetCurrentThread(), thread_priority); -#elif defined(LINUX) || defined(APPLE) - if (success) - { - pthread_setschedparam(pthread_self(), thread_policy, &thread_sched_param); - setpriority(PRIO_PROCESS, 0, nice_priority); - } -#endif - } - -#if defined(WIN32) - uint32 priority_class; - int thread_priority; -#elif defined(LINUX) || defined(APPLE) - rlimit nice_limit; - int nice_priority; - int thread_policy; - sched_param thread_sched_param; - bool success; - enum - { - MAX_NICE_PRIORITY = 40 - }; -#endif -}; - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_ASM_VOLATILE_CPUID -static inline void __cpuid(int CPUInfo[4], int InfoType) -{ - asm volatile("cpuid" : "=a" (*CPUInfo), "=b" (*(CPUInfo + 1)), "=c" (*(CPUInfo + 2)), "=d" (*(CPUInfo + 3)) : "a" (InfoType)); -} -#endif - -bool IsAMD() -{ -// Broken out for validation support. -#if defined(WIN32) || (defined(LINUX) && !defined(ANDROID)) || defined(MAC) - #define AZ_SUPPORTS_AMD -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CPUDETECT_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(CPUDetect_cpp) -#endif - -#if defined(AZ_SUPPORTS_AMD) - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000000); - - char szCPU[13]; - memset(szCPU, 0, sizeof(szCPU)); - *(int*)&szCPU[0] = CPUInfo[1]; - *(int*)&szCPU[4] = CPUInfo[3]; - *(int*)&szCPU[8] = CPUInfo[2]; - - return (strcmp(szCPU, "AuthenticAMD") == 0); -#else - return false; -#endif -} - -bool IsIntel() -{ -#if defined(WIN32) || (defined(LINUX) && !defined(ANDROID)) || defined(MAC) - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000000); - - char szCPU[13]; - memset(szCPU, 0, sizeof(szCPU)); - *(int*)&szCPU[0] = CPUInfo[1]; - *(int*)&szCPU[4] = CPUInfo[3]; - *(int*)&szCPU[8] = CPUInfo[2]; - - return (strcmp(szCPU, "GenuineIntel") == 0); -#else - return false; -#endif -} - -bool Has64bitExtension() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HAS64BITEXT - int CPUInfo[4]; - __cpuid(CPUInfo, 0x80000001); // Argument "Processor Signature and AMD Features" - if (CPUInfo[3] & 0x20000000) // Bit 29 in edx is set if 64-bit address extension is supported - { - return true; - } - else - { - return false; - } -#elif defined(WIN64) || defined(LINUX64) || defined(MAC) - return true; -#else - return false; -#endif -} - -bool HTSupported() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HTSUPPORTED - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - if (CPUInfo[3] & 0x10000000) // Bit 28 in edx is set if HT is supported - { - return true; - } - else - { - return false; - } -#else - return false; -#endif -} - -uint8 LogicalProcPerPhysicalProc() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - // Bits 16-23 in ebx contain the number of logical processors per physical processor when execute cpuid with eax set to 1 - return (uint8) ((CPUInfo[1] & 0x00FF0000) >> 16); -#else - return 1; -#endif -} - -uint8 GetAPIC_ID() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - // Bits 24-31 in ebx contain the unique initial APIC ID for the processor this code is running on. Default value = 0xff if HT is not supported. - return (uint8) ((CPUInfo[1] & 0xFF000000) >> 24); -#else - return 0; -#endif -} - -void GetCPUName(char* pName) -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - if (pName) - { - int CPUInfo[4]; - __cpuid(CPUInfo, 0x80000000); - if (CPUInfo[0] >= 0x80000004) - { - __cpuid(CPUInfo, 0x80000002); - ((int*)pName)[0] = CPUInfo[0]; - ((int*)pName)[1] = CPUInfo[1]; - ((int*)pName)[2] = CPUInfo[2]; - ((int*)pName)[3] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000003); - ((int*)pName)[4] = CPUInfo[0]; - ((int*)pName)[5] = CPUInfo[1]; - ((int*)pName)[6] = CPUInfo[2]; - ((int*)pName)[7] = CPUInfo[3]; - - __cpuid(CPUInfo, 0x80000004); - ((int*)pName)[8] = CPUInfo[0]; - ((int*)pName)[9] = CPUInfo[1]; - ((int*)pName)[10] = CPUInfo[2]; - ((int*)pName)[11] = CPUInfo[3]; - } - else - { - pName[0] = '\0'; - } - } -#else - if (pName) - { - pName[0] = '\0'; - } -#endif -} - -bool HasFPUOnChip() -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - // Bit 0 in edx indicates presents of on chip FPU - return (CPUInfo[3] & 0x00000001) != 0; -#else - return false; -#endif -} - -void GetCPUSteppingModelFamily(int& stepping, int& model, int& family) -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID - int CPUInfo[4]; - __cpuid(CPUInfo, 0x00000001); - stepping = CPUInfo[0] & 0xF; // Bit 0-3 in eax specifies stepping - model = (CPUInfo[0] >> 4) & 0xF; // Bit 4-7 in eax specifies model - family = (CPUInfo[0] >> 8) & 0xF; // Bit 8-11 in eax specifies family -#else - stepping = 0; - model = 0; - family = 0; -#endif -} - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASCPUID -unsigned long GetCPUFeatureSet() -{ - unsigned long features = 0; - - int CPUInfo[4]; - - __cpuid(CPUInfo, 0); - const int nIds = CPUInfo[0]; - - __cpuid(CPUInfo, 0x80000000); - const unsigned int nExIds = CPUInfo[0]; - - if (nIds > 0) - { - __cpuid(CPUInfo, 0x00000001); - - if (CPUInfo[3] & (1 << 26)) - { - features |= CFI_SSE2; - } - if (CPUInfo[3] & (1 << 25)) - { - features |= CFI_SSE; - } - if (CPUInfo[2] & (1 << 0)) - { - features |= CFI_SSE3; - } - if (CPUInfo[2] & (1 << 29)) - { - features |= CFI_F16C; - } - if (CPUInfo[2] & (1 << 19)) - { - features |= CFI_SSE41; - } - } - - if (nExIds > 0x80000000) - { - __cpuid(CPUInfo, 0x80000001); - if (CPUInfo[3] & (1 << 31)) - { - features |= CFI_3DNOW; - } - } - - return features; -} -#endif - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEFINE_DETECT_PROCESSOR -static unsigned long __stdcall DetectProcessor(void* arg) -{ - const char hex_chars[16] = - { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - unsigned long signature = 0; - unsigned long cache_temp; - unsigned long cache_eax = 0; - unsigned long cache_ebx = 0; - unsigned long cache_ecx = 0; - unsigned long cache_edx = 0; - unsigned long features_edx = 0; - unsigned long serial_number[3]; - unsigned char cpu_type; - unsigned char fpu_type; - unsigned char CPUID_flag = 0; - unsigned char celeron_flag = 0; - unsigned char pentiumxeon_flag = 0; - unsigned char amd3d_flag = 0; - unsigned char name_flag = 0; - char vendor[13]; - vendor[0] = '\0'; - char name[49]; - name[0] = '\0'; - char* serial; - const char* cpu_string; - const char* cpu_extra_string; - const char* fpu_string; - const char* vendor_string; - SCpu* p = (SCpu*) arg; - - memset(p, 0, sizeof(*p)); - - if (IsAMD() && Has64bitExtension()) - { - p->meVendor = eCVendor_AMD; - p->mFeatures |= GetCPUFeatureSet(); - p->mbSerialPresent = false; - azstrcpy(p->mSerialNumber, AZ_ARRAY_SIZE(p->mSerialNumber), ""); - GetCPUSteppingModelFamily(p->mStepping, p->mModel, p->mFamily); - azstrcpy(p->mVendor, AZ_ARRAY_SIZE(p->mVendor), "AMD"); - GetCPUName(p->mCpuType); - azstrcpy(p->mFpuType, AZ_ARRAY_SIZE(p->mFpuType), HasFPUOnChip() ? "On-Chip" : "Unknown"); - p->mbPhysical = true; - - return 1; - } - else if (IsIntel() && Has64bitExtension()) - { - p->meVendor = eCVendor_Intel; - p->mFeatures |= GetCPUFeatureSet(); - p->mbSerialPresent = false; - azstrcpy(p->mSerialNumber, AZ_ARRAY_SIZE(p->mSerialNumber), ""); - GetCPUSteppingModelFamily(p->mStepping, p->mModel, p->mFamily); - azstrcpy(p->mVendor, AZ_ARRAY_SIZE(p->mVendor), "Intel"); - GetCPUName(p->mCpuType); - azstrcpy(p->mFpuType, AZ_ARRAY_SIZE(p->mFpuType), HasFPUOnChip() ? "On-Chip" : "Unknown"); - - p->mbPhysical = true; - - return 1; - } - - cpu_type = 0xF; - fpu_type = 3; - signature = 0; - - p->mFamily = cpu_type; - p->mModel = (signature >> 4) & 0xf; - p->mStepping = signature & 0xf; - - p->mFeatures = 0; - - p->mFeatures |= amd3d_flag ? CFI_3DNOW : 0; - p->mFeatures |= (features_edx & MMX_FLAG) ? CFI_MMX : 0; - p->mFeatures |= (features_edx & ISSE_FLAG) ? CFI_SSE : 0; - p->mbSerialPresent = ((features_edx & SERIAL_FLAG) != 0); - - if (features_edx & SERIAL_FLAG) - { - serial_number[0] = serial_number[1] = serial_number[2] = 0; - - /* format number */ - serial = p->mSerialNumber; - - serial[0] = hex_chars[(serial_number[2] >> 28) & 0x0f]; - serial[1] = hex_chars[(serial_number[2] >> 24) & 0x0f]; - serial[2] = hex_chars[(serial_number[2] >> 20) & 0x0f]; - serial[3] = hex_chars[(serial_number[2] >> 16) & 0x0f]; - - serial[4] = '-'; - - serial[5] = hex_chars[(serial_number[2] >> 12) & 0x0f]; - serial[6] = hex_chars[(serial_number[2] >> 8) & 0x0f]; - serial[7] = hex_chars[(serial_number[2] >> 4) & 0x0f]; - serial[8] = hex_chars[(serial_number[2] >> 0) & 0x0f]; - - serial[9] = '-'; - - serial[10] = hex_chars[(serial_number[1] >> 28) & 0x0f]; - serial[11] = hex_chars[(serial_number[1] >> 24) & 0x0f]; - serial[12] = hex_chars[(serial_number[1] >> 20) & 0x0f]; - serial[13] = hex_chars[(serial_number[1] >> 16) & 0x0f]; - - serial[14] = '-'; - - serial[15] = hex_chars[(serial_number[1] >> 12) & 0x0f]; - serial[16] = hex_chars[(serial_number[1] >> 8) & 0x0f]; - serial[17] = hex_chars[(serial_number[1] >> 4) & 0x0f]; - serial[18] = hex_chars[(serial_number[1] >> 0) & 0x0f]; - - serial[19] = '-'; - - serial[20] = hex_chars[(serial_number[0] >> 28) & 0x0f]; - serial[21] = hex_chars[(serial_number[0] >> 24) & 0x0f]; - serial[22] = hex_chars[(serial_number[0] >> 20) & 0x0f]; - serial[23] = hex_chars[(serial_number[0] >> 16) & 0x0f]; - - serial[24] = '-'; - - serial[25] = hex_chars[(serial_number[0] >> 12) & 0x0f]; - serial[26] = hex_chars[(serial_number[0] >> 8) & 0x0f]; - serial[27] = hex_chars[(serial_number[0] >> 4) & 0x0f]; - serial[28] = hex_chars[(serial_number[0] >> 0) & 0x0f]; - - serial[29] = 0; - } - - vendor_string = "Unknown"; - cpu_string = "Unknown"; - cpu_extra_string = ""; - fpu_string = "Unknown"; - - if (!CPUID_flag) - { - switch (cpu_type) - { - case 0: - cpu_string = "8086"; - break; - - case 2: - cpu_string = "80286"; - break; - - case 3: - cpu_string = "80386"; - switch (fpu_type) - { - case 2: - fpu_string = "80287"; - break; - - case 1: - fpu_string = "80387"; - break; - - default: - fpu_string = "None"; - break; - } - break; - - case 4: - if (fpu_type) - { - cpu_string = "80486DX, 80486DX2 or 80487SX"; - fpu_string = "on-chip"; - } - else - { - cpu_string = "80486SX"; - } - break; - } - } - else - { /* using CPUID instruction */ - if (!name_flag) - { - if (!strcmp(vendor, "GenuineIntel")) - { - vendor_string = "Intel"; - switch (cpu_type) - { - case 4: - switch (p->mModel) - { - case 0: - case 1: - cpu_string = "80486DX"; - break; - - case 2: - cpu_string = "80486SX"; - break; - - case 3: - cpu_string = "80486DX2"; - break; - - case 4: - cpu_string = "80486SL"; - break; - - case 5: - cpu_string = "80486SX2"; - break; - - case 7: - cpu_string = "Write-Back Enhanced 80486DX2"; - break; - - case 8: - cpu_string = "80486DX4"; - break; - - default: - cpu_string = "80486"; - } - break; - - case 5: - switch (p->mModel) - { - default: - case 1: - case 2: - case 3: - cpu_string = "Pentium"; - break; - - case 4: - cpu_string = "Pentium MMX"; - break; - } - break; - - case 6: - switch (p->mModel) - { - case 1: - cpu_string = "Pentium Pro"; - break; - - case 3: - cpu_string = "Pentium II"; - break; - - case 5: - case 7: - { - cache_temp = cache_eax & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_eax & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_eax & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ebx & 0xFF; - if (cache_temp == 0x40) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44) && (cache_temp <= 0x45)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_ecx & 0xFF; - if (cache_temp == 0x40) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44) && (cache_temp <= 0x45)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF000000; - if (cache_temp == 0x40000000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44000000) && (cache_temp <= 0x45000000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF0000; - if (cache_temp == 0x400000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x440000) && (cache_temp <= 0x450000)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF00; - if (cache_temp == 0x4000) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x4400) && (cache_temp <= 0x4500)) - { - pentiumxeon_flag = 1; - } - cache_temp = cache_edx & 0xFF; - if (cache_temp == 0x40) - { - celeron_flag = 1; - } - if ((cache_temp >= 0x44) && (cache_temp <= 0x45)) - { - pentiumxeon_flag = 1; - } - - if (celeron_flag) - { - cpu_string = "Celeron"; - } - else - { - if (pentiumxeon_flag) - { - if (p->mModel == 5) - { - cpu_string = "Pentium II Xeon"; - } - else - { - cpu_string = "Pentium III Xeon"; - } - } - else - { - if (p->mModel == 5) - { - cpu_string = "Pentium II"; - } - else - { - cpu_string = "Pentium III"; - } - } - } - } - break; - - case 6: - cpu_string = "Celeron"; - break; - - case 8: - cpu_string = "Pentium III"; - break; - } - break; - } - - if (signature & 0x1000) - { - cpu_extra_string = " OverDrive"; - } - else - if (signature & 0x2000) - { - cpu_extra_string = " dual upgrade"; - } - } - else - if (!strcmp(vendor, "CyrixInstead")) - { - vendor_string = "Cyrix"; - switch (p->mFamily) - { - case 4: - switch (p->mModel) - { - case 4: - cpu_string = "MediaGX"; - break; - } - break; - - case 5: - switch (p->mModel) - { - case 2: - cpu_string = "6x86"; - break; - - case 4: - cpu_string = "GXm"; - break; - } - break; - - case 6: - switch (p->mModel) - { - case 0: - cpu_string = "6x86MX"; - break; - } - break; - } - } - else - if (!strcmp(vendor, "AuthenticAMD")) - { - cry_strcpy(p->mVendor, "AMD"); - switch (p->mFamily) - { - case 4: - cpu_string = "Am486 or Am5x86"; - break; - - case 5: - switch (p->mModel) - { - case 0: - case 1: - case 2: - case 3: - cpu_string = "K5"; - break; - - case 4: - case 5: - case 6: - case 7: - cpu_string = "K6"; - break; - - case 8: - cpu_string = "K6-2"; - break; - - case 9: - cpu_string = "K6-III"; - break; - } - break; - - case 6: - cpu_string = "Athlon"; - break; - } - } - else - if (!strcmp(vendor, "CentaurHauls")) - { - vendor_string = "Centaur"; - switch (cpu_type) - { - case 5: - switch (p->mModel) - { - case 4: - cpu_string = "WinChip"; - break; - - case 8: - cpu_string = "WinChip2"; - break; - } - break; - } - } - else - if (!strcmp(vendor, "UMC UMC UMC ")) - { - vendor_string = "UMC"; - } - else - if (!strcmp(vendor, "NexGenDriven")) - { - vendor_string = "NexGen"; - } - } - else - { - vendor_string = vendor; - cpu_string = name; - } - - if (features_edx & FPU_FLAG) - { - fpu_string = "On-Chip"; - } - else - { - fpu_string = "Unknown"; - } - } - - stack_string sCpuType = stack_string(cpu_string) + cpu_extra_string; - - cry_strcpy(p->mCpuType, sCpuType.c_str()); - cry_strcpy(p->mFpuType, fpu_string); - cry_strcpy(p->mVendor, vendor_string); - - if (!azstricmp(vendor_string, "Intel")) - { - p->meVendor = eCVendor_Intel; - } - else - if (!azstricmp(vendor_string, "Cyrix")) - { - p->meVendor = eCVendor_Cyrix; - } - else - if (!azstricmp(vendor_string, "AMD")) - { - p->meVendor = eCVendor_AMD; - } - else - if (!azstricmp(vendor_string, "Centaur")) - { - p->meVendor = eCVendor_Centaur; - } - else - if (!azstricmp(vendor_string, "NexGen")) - { - p->meVendor = eCVendor_NexGen; - } - else - if (!azstricmp(vendor_string, "UMC")) - { - p->meVendor = eCVendor_UMC; - } - else - { - p->meVendor = eCVendor_Unknown; - } - - if (strstr(cpu_string, "8086")) - { - p->meModel = eCpu_8086; - } - else - if (strstr(cpu_string, "80286")) - { - p->meModel = eCpu_80286; - } - else - if (strstr(cpu_string, "80386")) - { - p->meModel = eCpu_80386; - } - else - if (strstr(cpu_string, "80486")) - { - p->meModel = eCpu_80486; - } - else - if (!azstricmp(cpu_string, "Pentium MMX") || !azstricmp(cpu_string, "Pentium")) - { - p->meModel = eCpu_Pentium; - } - else - if (!azstricmp(cpu_string, "Pentium Pro")) - { - p->meModel = eCpu_PentiumPro; - } - else - if (!azstricmp(cpu_string, "Pentium II")) - { - p->meModel = eCpu_Pentium2; - } - else - if (!azstricmp(cpu_string, "Pentium III")) - { - p->meModel = eCpu_Pentium3; - } - else - if (!azstricmp(cpu_string, "Pentium 4")) - { - p->meModel = eCpu_Pentium4; - } - else - if (!azstricmp(cpu_string, "Celeron")) - { - p->meModel = eCpu_Celeron; - } - else - if (!azstricmp(cpu_string, "Pentium II Xeon")) - { - p->meModel = eCpu_Pentium2Xeon; - } - else - if (!azstricmp(cpu_string, "Pentium III Xeon")) - { - p->meModel = eCpu_Pentium3Xeon; - } - else - if (!azstricmp(cpu_string, "MediaGX")) - { - p->meModel = eCpu_CyrixMediaGX; - } - else - if (!azstricmp(cpu_string, "6x86")) - { - p->meModel = eCpu_Cyrix6x86; - } - else - if (!azstricmp(cpu_string, "GXm")) - { - p->meModel = eCpu_CyrixGXm; - } - else - if (!azstricmp(cpu_string, "6x86MX")) - { - p->meModel = eCpu_Cyrix6x86MX; - } - else - if (!azstricmp(cpu_string, "Am486 or Am5x86")) - { - p->meModel = eCpu_Am5x86; - } - else - if (!azstricmp(cpu_string, "K5")) - { - p->meModel = eCpu_AmK5; - } - else - if (!azstricmp(cpu_string, "K6")) - { - p->meModel = eCpu_AmK6; - } - else - if (!azstricmp(cpu_string, "K6-2")) - { - p->meModel = eCpu_AmK6_2; - } - else - if (!azstricmp(cpu_string, "K6-III")) - { - p->meModel = eCpu_AmK6_3; - } - else - if (!azstricmp(cpu_string, "Athlon")) - { - p->meModel = eCpu_AmAthlon; - } - else - if (!azstricmp(cpu_string, "Duron")) - { - p->meModel = eCpu_AmDuron; - } - else - if (!azstricmp(cpu_string, "WinChip")) - { - p->meModel = eCpu_CenWinChip; - } - else - if (!azstricmp(cpu_string, "WinChip2")) - { - p->meModel = eCpu_CenWinChip2; - } - else - { - p->meModel = eCpu_Unknown; - } - - p->mbPhysical = true; - if (!strcmp(vendor_string, "GenuineIntel") && p->mStepping > 4 && HTSupported()) - { - p->mbPhysical = (GetAPIC_ID() & LogicalProcPerPhysicalProc() - 1) == 0; - } - - return 1; -} -#endif //AZ_LEGACY_CRYSYSTEM_TRAIT_DEFINE_DETECT_PROCESSOR - -#if defined(MAC) || (defined(LINUX) && !defined(ANDROID)) -static void* DetectProcessorThreadProc(void* pData) -{ - DetectProcessor(pData); - return NULL; -} -#endif // MAC LINUX - -// #define SQRT_TEST -#ifdef SQRT_TEST -/* ------------------------------------------------------------------------------ */ - -ILINE float CorrectInvSqrt(float fNum, float fInvSqrtEst) -{ - // Newton-Rhapson method for improving estimated inv sqrt. - // f(x) = x^(-1/2) - // f(n) = f(a) + (n-a)f'(a) - // = a^(-1/2) + (n-a)(-1/2)a^(-3/2) - // = a^(-1/2)*3/2 - na^(-3/2)/2 - // = e*3/2 - ne^3/2 - return fInvSqrtEst * (1.5f - fNum * fInvSqrtEst * fInvSqrtEst * 0.5f); -} - - -float Null(float f) { return f; } -float Inv(float f) { return 1.f / f; } - -float Square(float f) { return f * f; } -float InvSquare(float f) { return 1.f / (f * f); } - -float Sqrt(float f) { return sqrtf(f); } -float SqrtT(float f) { return sqrt_tpl(f); } -float SqrtFT(float f) { return sqrt_fast_tpl(f); } - -float InvSqrt(float f) { return 1.f / sqrtf(f); } -float ISqrtT(float f) { return isqrt_tpl(f); } -float ISqrtFT(float f) { return isqrt_fast_tpl(f); } - -float SSEInv(float f) -{ - __m128 s = _mm_rcp_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSESqrt(float f) -{ - __m128 s = _mm_sqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSEISqrt(float f) -{ - __m128 s = _mm_sqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return 1.f / r; -} -float SSERSqrt(float f) -{ - __m128 s = _mm_rsqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSERSqrtInv(float f) -{ - __m128 s = _mm_rcp_ss(_mm_rsqrt_ss(_mm_load_ss(&f))); - float r; - _mm_store_ss(&r, s); - return r; -} -float SSERSqrtNR(float f) -{ - __m128 s = _mm_rsqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return CorrectInvSqrt(f, r); -} -float SSERISqrtNR(float f) -{ - __m128 s = _mm_rsqrt_ss(_mm_load_ss(&f)); - float r; - _mm_store_ss(&r, s); - return 1.f / CorrectInvSqrt(f, r); -} - -inline float cryISqrtf(float fVal) -{ - unsigned int* n1 = (unsigned int*)&fVal; - unsigned int n = 0x5f3759df - (*n1 >> 1); - float* n2 = (float*)&n; - fVal = (1.5f - (fVal * 0.5f) * *n2 * *n2) * *n2; - return fVal; -} - -float cryISqrtNRf(float f) -{ - return CorrectInvSqrt(f, cryISqrtf(f)); -} - -inline float crySqrtf(float fVal) -{ - return 1.0f / cryISqrtf(fVal); -} - -/* ------------------------------------------------------------------------------ */ -struct SMathTest -{ - typedef int64 TTime; - static inline TTime GetTime() - { - return CryGetTicks(); - } - - static const int T = 100, N = 1000; - float fNullTime; - - float aTestVals[T]; - float aResVals[T]; - - typedef float (* FFloatFunc)(float f); - - float Timer(const char* sName, FFloatFunc func, FFloatFunc finv) - { - for (int i = 0; i < T; i++) - { - aResVals[i] = func(aTestVals[i]); - } - TTime tStart = GetTime(); - for (int r = 0; r < N; r++) - { - for (int i = 0; i < T; i++) - { - aResVals[i] = func(aTestVals[i]); - } - } - float fTime = (GetTime() - tStart) / float(N * T); - - // Error computation. - float fAvgErr = 0.f, fMaxErr = 0.f; - for (int i = 0; i < T; i++) - { - float fErr = abs(finv(aResVals[i]) / aTestVals[i] - 1.f); - fAvgErr += fErr; - fMaxErr = max(fMaxErr, fErr); - } - fAvgErr /= float(T); - - CryLogAlways("%-20s : %5.2f cycles, avg err %.2e, max err %.2e", sName, fTime - fNullTime, fAvgErr, fMaxErr); - - return fTime; - }; - - SMathTest() - { - for (int i = 0; i < T; i++) - { - aTestVals[i] = powf(cry_random(1.f, 2.f), cry_random(-30.f, 30.f)); - } - - CryLogAlways("--- Math Test ---"); - - fNullTime = 0.f; - fNullTime = Timer("(null)", &Null, &Null); - - CryLogAlways("-- Inverse methods"); - Timer("1/f", &Inv, &Inv); - Timer("rcpss", &SSEInv, &Inv); - - CryLogAlways("-- Sqrt methods"); - Timer("sqrtf()", &Sqrt, &Square); - Timer("sqrt_tpl()", &SqrtT, &Square); - Timer("sqrt_fast_tpl()", &SqrtFT, &Square); - Timer("crySqrt()", &crySqrtf, &Square); - - // Timer("sqrtss", &SSESqrt, &Square); - // Timer("rsqrtss,rcpss", &SSERSqrtInv, &Square); - Timer("1/rsqrtss,correction", &SSERISqrtNR, &Square); - - CryLogAlways("-- InvSqrt methods"); - Timer("1/sqrtf()", &InvSqrt, &InvSquare); - Timer("isqrt_tpl()", &ISqrtT, &InvSquare); - Timer("isqrt_fast_tpl()", &ISqrtFT, &InvSquare); - Timer("cryISqrt()", &cryISqrtf, &InvSquare); - - Timer("1/sqrtss", &SSEISqrt, &InvSquare); - // Timer("rsqrtss", &SSERSqrt, &InvSquare); - // Timer("rsqrtss,correction", &SSERSqrtNR, &InvSquare); - Timer("cryISqrt,correction", &cryISqrtNRf, &InvSquare); - - CryLogAlways("--------------------"); - } -}; - -#endif // SQRT_TEST - -#if defined(LINUX) -// collection of functions to read from /proc/cpuinfo - -static bool proc_read_str(char* buffer, char* output, size_t output_length) -{ - if (!buffer || !output || output_length <= 0) - { - return false; - } - while (*buffer && *buffer != ':') - { - ++buffer; - } - if (*buffer == ':') - { - buffer += 2; - cry_strcpy(output, output_length, buffer); - const int len = strlen(output); - if (len > 0 && output[len - 1] == '\n') - { - output[len - 1] = '\0'; - } - return true; - } - return false; -} - - -static bool proc_read_int(char* buffer, int& output) -{ - if (!buffer) - { - return false; - } - while (*buffer && *buffer != ':') - { - ++buffer; - } - if (*buffer == ':') - { - buffer += 2; - output = atoi(buffer); - return true; - } - return false; -} -#endif - -/* ------------------------------------------------------------------------------ */ -void CCpuFeatures::Detect(void) -{ - m_NumSystemProcessors = 1; - m_NumAvailProcessors = 0; - - ////////////////////////////////////////////////////////////////////////// -#if AZ_LEGACY_CRYSYSTEM_TRAIT_HASAFFINITYMASK - CryLogAlways(""); - - DWORD_PTR process_affinity_mask = 1; - - /* get the system info to derive the number of processors within the system. */ - - SYSTEM_INFO sys_info; - DWORD_PTR system_affinity_mask; - GetSystemInfo(&sys_info); - m_NumLogicalProcessors = m_NumSystemProcessors = sys_info.dwNumberOfProcessors; - m_NumAvailProcessors = 0; - GetProcessAffinityMask(GetCurrentProcess(), &process_affinity_mask, &system_affinity_mask); - - for (unsigned char c = 0; c < m_NumSystemProcessors; c++) - { - if (process_affinity_mask & ((DWORD_PTR)1 << c)) - { - m_NumAvailProcessors++; - SetProcessAffinityMask(GetCurrentProcess(), DWORD_PTR(1) << c); - DetectProcessor(&m_Cpu[c]); - m_Cpu[c].mAffinityMask = ((DWORD_PTR)1 << c); - } - } - - SetProcessAffinityMask(GetCurrentProcess(), process_affinity_mask); - - m_bOS_ISSE = false; - m_bOS_ISSE_EXCEPTIONS = false; -#elif defined(LINUX) - // Retrieve information from /proc/cpuinfo - FILE* cpu_info = fopen("/proc/cpuinfo", "r"); - if (!cpu_info) - { - m_NumLogicalProcessors = m_NumSystemProcessors = m_NumAvailProcessors = 1; - CryLogAlways("Could not open /proc/cpuinfo, defaulting values to 1."); - } - else - { - int nCores = 0; - int nCpu = -1; - int index = 0; - char buffer[512]; - while (!feof(cpu_info)) - { - if (nCpu >= MAX_CPU) - { - --nCpu; //Decrement so the sets after the while loop matches the number of CPUs examined - CryLogAlways("Found a higher than expected number of CPUs, defaulting to %d", MAX_CPU); - break; - } - - fgets(buffer, sizeof(buffer), cpu_info); - - if (buffer[0] == '\0' || buffer[0] == '\n') - { - continue; - } - - if (strncmp("processor", buffer, (index = strlen("processor"))) == 0) - { - ++nCpu; - } - else if (strncmp("vendor_id", buffer, (index = strlen("vendor_id"))) == 0) - { - proc_read_str(&buffer[index], m_Cpu[nCpu].mVendor, sizeof(m_Cpu[nCpu].mVendor)); - } - else if (strncmp("model name", buffer, (index = strlen("model name"))) == 0) - { - proc_read_str(&buffer[index], m_Cpu[nCpu].mCpuType, sizeof(m_Cpu[nCpu].mCpuType)); - } - else if (strncmp("cpu cores", buffer, (index = strlen("cpu cores"))) == 0 && nCores == 0) - { - proc_read_int(&buffer[index], nCores); - } - else if (strncmp("fpu", buffer, (index = strlen("fpu"))) == 0) - { - while (buffer[index] != ':' && index < 512) - { - ++index; - } - if (buffer[index] == ':') - { - if (strncmp(&buffer[index + 2], "yes", 3) == 0) - { - snprintf(m_Cpu[nCpu].mFpuType, sizeof(m_Cpu[nCpu].mFpuType), "On-Chip"); - } - else - { - snprintf(m_Cpu[nCpu].mFpuType, sizeof(m_Cpu[nCpu].mFpuType), "Unkown"); - } - } - } - else if (strncmp("cpu family", buffer, (index = strlen("cpu family"))) == 0) - { - proc_read_int(&buffer[index], m_Cpu[nCpu].mFamily); - } - else if (strncmp("model", buffer, (index = strlen("model"))) == 0) - { - proc_read_int(&buffer[index], m_Cpu[nCpu].mModel); - } - else if (strncmp("stepping", buffer, (index = strlen("stepping"))) == 0) - { - proc_read_int(&buffer[index], m_Cpu[nCpu].mStepping); - } - else if (strncmp("flags", buffer, (index = strlen("flags"))) == 0) - { - if (strstr(buffer + index, "mmx")) - { - m_Cpu[nCpu].mFeatures |= CFI_MMX; - } - - if (strstr(buffer + index, "sse")) - { - m_Cpu[nCpu].mFeatures |= CFI_SSE; - } - - if (strstr(buffer + index, "sse2")) - { - m_Cpu[nCpu].mFeatures |= CFI_SSE2; - } - } - } - m_NumLogicalProcessors = m_NumAvailProcessors = nCpu + 1; - m_NumSystemProcessors = nCores; - } - - -#elif defined(APPLE) - size_t len; - unsigned int ncpu; - - len = sizeof(ncpu); - if (sysctlbyname ("hw.physicalcpu_max", &ncpu, &len, NULL, 0) == 0) - { - m_NumSystemProcessors = ncpu; - } - else - { - CryLogAlways("Failed to detect the number of available processors, defaulting to 1"); - m_NumSystemProcessors = 1; - } - - if (sysctlbyname ("hw.logicalcpu_max", &ncpu, &len, NULL, 0) == 0) - { - m_NumAvailProcessors = m_NumLogicalProcessors = ncpu; - } - else - { - CryLogAlways("Failed to detect the number of available logical processors, defaulting to 1"); - m_NumAvailProcessors = m_NumLogicalProcessors = 1; - } - uint64_t cpu_freq; - len = sizeof(cpu_freq); - if (sysctlbyname ("hw.cpufrequency_max", &cpu_freq, &len, NULL, 0) != 0) - { - CryLogAlways("Failed to detect cpu frequency , defaulting to 0"); - cpu_freq = 0; - } - - // On macs, the processors are always the same model, so we can easily - // calculate once and apply the settings for all. - SCpu cpuInfo; -#if !defined(IOS) - DetectProcessor(&cpuInfo); -#endif - for (int c = 0; c < m_NumAvailProcessors; c++) - { - m_Cpu[c] = cpuInfo; - } - -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CPUDETECT_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(CPUDetect_cpp) -#endif - - -#if defined(WIN32) || defined(WIN64) - CryLogAlways("Total number of logical processors: %d", m_NumSystemProcessors); - CryLogAlways("Number of available logical processors: %d", m_NumAvailProcessors); - - unsigned int numSysCores(1), numProcessCores(1); - Win32SysInspect::GetNumCPUCores(numSysCores, numProcessCores); - m_NumSystemProcessors = numSysCores; - m_NumAvailProcessors = numProcessCores; - CryLogAlways("Total number of system cores: %d", m_NumSystemProcessors); - CryLogAlways("Number of cores available to process: %d", m_NumAvailProcessors); - -#else - CryLogAlways("Number of system processors: %d", m_NumSystemProcessors); - CryLogAlways("Number of available processors: %d", m_NumAvailProcessors); -#endif - - if (m_NumAvailProcessors > MAX_CPU) - { - m_NumAvailProcessors = MAX_CPU; - } - - for (int i = 0; i < m_NumAvailProcessors; i++) - { - SCpu* p = &m_Cpu[i]; - - CryLogAlways(" "); - CryLogAlways("Processor %d:", i); - CryLogAlways(" CPU: %s %s", p->mVendor, p->mCpuType); - CryLogAlways(" Family: %d, Model: %d, Stepping: %d", p->mFamily, p->mModel, p->mStepping); - CryLogAlways(" FPU: %s", p->mFpuType); - CryLogAlways(" 3DNow!: %s", (p->mFeatures & CFI_3DNOW) ? "present" : "not present"); - CryLogAlways(" MMX: %s", (p->mFeatures & CFI_MMX) ? "present" : "not present"); - CryLogAlways(" SSE: %s", (p->mFeatures & CFI_SSE) ? "present" : "not present"); - CryLogAlways(" SSE2: %s", (p->mFeatures & CFI_SSE2) ? "present" : "not present"); - CryLogAlways(" SSE3: %s", (p->mFeatures & CFI_SSE3) ? "present" : "not present"); - CryLogAlways(" SSE4.1: %s", (p->mFeatures& CFI_SSE41) ? "present" : "not present"); - if (p->mbSerialPresent) - { - CryLogAlways(" Serial number: %s", p->mSerialNumber); - } - else - { - CryLogAlways(" Serial number not present or disabled"); - } - } - -#ifdef SQRT_TEST - SMathTest test; -#endif - - CryLogAlways(" "); - - //m_NumPhysicsProcessors = m_NumSystemProcessors; - for (int i = m_NumPhysicsProcessors = 0; i < m_NumAvailProcessors; i++) - { - if (m_Cpu[i].mbPhysical) - { - ++m_NumPhysicsProcessors; - } - } - - // Set the cpu flags global variable - g_CpuFlags = 0; - if (hasMMX()) - { - g_CpuFlags |= CPUF_MMX; - } - if (hasSSE()) - { - g_CpuFlags |= CPUF_SSE; - } - if (hasSSE2()) - { - g_CpuFlags |= CPUF_SSE2; - } - if (hasSSE3()) - { - g_CpuFlags |= CPUF_SSE3; - } - if (hasSSE41()) - { - g_CpuFlags |= CPUF_SSE41; - } - if (has3DNow()) - { - g_CpuFlags |= CPUF_3DNOW; - } - if (hasF16C()) - { - g_CpuFlags |= CPUF_F16C; - } -} - diff --git a/Code/CryEngine/CrySystem/CPUDetect.h b/Code/CryEngine/CrySystem/CPUDetect.h deleted file mode 100644 index e2851d5f23..0000000000 --- a/Code/CryEngine/CrySystem/CPUDetect.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_CPUDETECT_H -#define CRYINCLUDE_CRYSYSTEM_CPUDETECT_H -#pragma once - - -//------------------------------------------------------- -/// Cpu class -//------------------------------------------------------- -#if defined(WIN64) || defined(LINUX) - #define MAX_CPU 96 -#else - #define MAX_CPU 32 -#endif - -/// Cpu Features -#define CFI_FPUEMULATION 0x01 -#define CFI_MMX 0x02 -#define CFI_3DNOW 0x04 -#define CFI_SSE 0x08 -#define CFI_SSE2 0x10 -#define CFI_SSE3 0x20 -#define CFI_F16C 0x40 -#define CFI_SSE41 0x80 - -/// Type of Cpu Vendor. -enum ECpuVendor -{ - eCVendor_Unknown, - eCVendor_Intel, - eCVendor_Cyrix, - eCVendor_AMD, - eCVendor_Centaur, - eCVendor_NexGen, - eCVendor_UMC, - eCVendor_M68K -}; - -/// Type of Cpu Model. -enum ECpuModel -{ - eCpu_Unknown, - - eCpu_8086, - eCpu_80286, - eCpu_80386, - eCpu_80486, - eCpu_Pentium, - eCpu_PentiumPro, - eCpu_Pentium2, - eCpu_Pentium3, - eCpu_Pentium4, - eCpu_Pentium2Xeon, - eCpu_Pentium3Xeon, - eCpu_Celeron, - eCpu_CeleronA, - - eCpu_Am5x86, - eCpu_AmK5, - eCpu_AmK6, - eCpu_AmK6_2, - eCpu_AmK6_3, - eCpu_AmK6_3D, - eCpu_AmAthlon, - eCpu_AmDuron, - - eCpu_CyrixMediaGX, - eCpu_Cyrix6x86, - eCpu_CyrixGXm, - eCpu_Cyrix6x86MX, - - eCpu_CenWinChip, - eCpu_CenWinChip2, -}; - -struct SCpu -{ - ECpuVendor meVendor; - ECpuModel meModel; - unsigned long mFeatures; - bool mbSerialPresent; - char mSerialNumber[30]; - int mFamily; - int mModel; - int mStepping; - char mVendor[64]; - char mCpuType[64]; - char mFpuType[64]; - bool mbPhysical; // false for hyperthreaded - DWORD_PTR mAffinityMask; - - // constructor - SCpu() - : meVendor(eCVendor_Unknown) - , meModel(eCpu_Unknown) - , mFeatures(0) - , mbSerialPresent(false) - , mFamily(0) - , mModel(0) - , mStepping(0) - , mbPhysical(true) - , mAffinityMask(0) - { - memset(mSerialNumber, 0, sizeof(mSerialNumber)); - memset(mVendor, 0, sizeof(mVendor)); - memset(mCpuType, 0, sizeof(mCpuType)); - memset(mFpuType, 0, sizeof(mFpuType)); - } -}; - -class CCpuFeatures -{ -private: - int m_NumLogicalProcessors; - int m_NumSystemProcessors; - int m_NumAvailProcessors; - int m_NumPhysicsProcessors; - bool m_bOS_ISSE; - bool m_bOS_ISSE_EXCEPTIONS; -public: - - SCpu m_Cpu[MAX_CPU]; - -public: - CCpuFeatures() - { - m_NumLogicalProcessors = 0; - m_NumSystemProcessors = 0; - m_NumAvailProcessors = 0; - m_NumPhysicsProcessors = 0; - m_bOS_ISSE = 0; - m_bOS_ISSE_EXCEPTIONS = 0; - ZeroMemory(m_Cpu, sizeof(m_Cpu)); - } - - void Detect(void); - bool hasSSE() { return (m_Cpu[0].mFeatures & CFI_SSE) != 0; } - bool hasSSE2() { return (m_Cpu[0].mFeatures & CFI_SSE2) != 0; } - bool hasSSE3() { return (m_Cpu[0].mFeatures & CFI_SSE3) != 0; } - bool hasSSE41() { return (m_Cpu[0].mFeatures & CFI_SSE41) != 0; } - bool has3DNow() { return (m_Cpu[0].mFeatures & CFI_3DNOW) != 0; } - bool hasMMX() { return (m_Cpu[0].mFeatures & CFI_MMX) != 0; } - bool hasF16C() { return (m_Cpu[0].mFeatures & CFI_F16C) != 0; } - - unsigned int GetLogicalCPUCount() { return m_NumLogicalProcessors; } - unsigned int GetPhysCPUCount() { return m_NumPhysicsProcessors; } - unsigned int GetCPUCount() { return m_NumAvailProcessors; } - DWORD_PTR GetCPUAffinityMask(unsigned int iCPU) { assert(iCPU < MAX_CPU); return iCPU < GetCPUCount() ? m_Cpu[iCPU].mAffinityMask : 0; } - DWORD_PTR GetPhysCPUAffinityMask(unsigned int iCPU) - { - if (iCPU > GetPhysCPUCount()) - { - return 0; - } - int i; - for (i = 0; (int)iCPU >= 0; i++) - { - if (m_Cpu[i].mbPhysical) - { - --iCPU; - } - } - PREFAST_ASSUME(i > 0 && i < MAX_CPU); - return m_Cpu[i - 1].mAffinityMask; - } -}; - -#endif // CRYINCLUDE_CRYSYSTEM_CPUDETECT_H diff --git a/Code/CryEngine/CrySystem/ClientHandler.cpp b/Code/CryEngine/CrySystem/ClientHandler.cpp deleted file mode 100644 index a708d876f9..0000000000 --- a/Code/CryEngine/CrySystem/ClientHandler.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "ClientHandler.h" - -ClientHandler::ClientHandler(const char* bucket, int affinity, int clientTimeout) - : HandlerBase(bucket, affinity) -{ - m_clientTimeout = clientTimeout; - Reset(); -} - -void ClientHandler::Reset() -{ - m_srvLock.reset(0); - for (int i = 0; i < MAX_CLIENTS_NUM; i++) - { - std::unique_ptr srv(new SSyncLock(m_serverLockName, i, false)); - - // first get the client lock up! - if (!srv->IsValid()) - { - //try to create client lock - m_clientLock.reset(new SSyncLock(m_clientLockName, i, true)); - if (m_clientLock->IsValid()) - { - break; - } - else - { - m_clientLock.reset(0); - } - } - } -} - -bool ClientHandler::ServerIsValid() -{ - if (!m_srvLock.get()) - { - if (m_clientLock.get() && m_clientLock->IsValid()) - { - m_srvLock.reset(new SSyncLock(m_serverLockName, m_clientLock->number, false)); - if (m_srvLock->IsValid()) - { - SetAffinity(); - //got synched - return true; - } - m_srvLock.reset(0); - } - return false; - } - return m_srvLock->IsValid(); -} - -bool ClientHandler::Sync() -{ - if (ServerIsValid()) - { - m_clientLock->Signal();//signal that we're done and - if (m_srvLock->Wait(m_clientTimeout))//wait for server - { - //bla bla, track waiting - return true; - } - else - { - Reset(); - } - } - return false; -} - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/ClientHandler.h b/Code/CryEngine/CrySystem/ClientHandler.h deleted file mode 100644 index ce325270ad..0000000000 --- a/Code/CryEngine/CrySystem/ClientHandler.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_CLIENTHANDLER_H -#define CRYINCLUDE_CRYSYSTEM_CLIENTHANDLER_H -#pragma once - -#include "HandlerBase.h" -#include "SyncLock.h" - -struct ClientHandler - : public HandlerBase -{ - ClientHandler(const char* bucket, int affinity, int clientTimeout); - - void Reset(); - bool ServerIsValid(); - bool Sync(); - -private: - int m_clientTimeout; - std::unique_ptr m_clientLock; - std::unique_ptr m_srvLock; -}; - -#endif diff --git a/Code/CryEngine/CrySystem/Components/MathConversionTests.cpp b/Code/CryEngine/CrySystem/Components/MathConversionTests.cpp deleted file mode 100644 index 2ee2bc71f2..0000000000 --- a/Code/CryEngine/CrySystem/Components/MathConversionTests.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" -#include - -#include -#include -#include - -//namespace MathConversionUnitTests -//{ -const float kEpsilon = 0.01f; - -bool IsNearlyEqual(const AZ::Vector3& az, const Vec3& ly) -{ - return fcmp(az.GetX(), ly.x, kEpsilon) - && fcmp(az.GetY(), ly.y, kEpsilon) - && fcmp(az.GetZ(), ly.z, kEpsilon); -} - -bool IsNearlyEqual(const AZ::Quaternion& az, const Quat& ly) -{ - return fcmp(az.GetX(), ly.v.x, kEpsilon) - && fcmp(az.GetY(), ly.v.y, kEpsilon) - && fcmp(az.GetZ(), ly.v.z, kEpsilon) - && fcmp(az.GetW(), ly.w, kEpsilon); -} - -bool IsNearlyEqual(const AZ::Transform& az, const Matrix34& ly) -{ - float azFloats[12]; - const AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromTransform(az); - matrix3x4.StoreToRowMajorFloat12(azFloats); - - const float* lyFloats = ly.GetData(); - - for (int i = 0; i < 12; ++i) - { - if (!fcmp(azFloats[i], lyFloats[i], kEpsilon)) - { - return false; - } - } - return true; -} - -bool IsNearlyEqual(const AZ::Transform& az, const QuatT& ly) -{ - return IsNearlyEqual(az.GetTranslation(), ly.t) - && IsNearlyEqual(az.GetRotation(), ly.q); -} - -TEST(MathConversionTests, BasicConversions) -{ - { // check vector3 comparisons - AZ::Vector3 az(1.f, 2.f, 3.f); - Vec3 ly(1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // reverse XYZ - ly = Vec3(3.f, 2.f, 1.f); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - - // off by 0.1 - ly = Vec3(1.1f, 2.1f, 3.1f); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check vector3 conversions - Vec3 ly1(1.f, 2.f, 3.f); - AZ::Vector3 az = LYVec3ToAZVec3(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - Vec3 ly2 = AZVec3ToLYVec3(az); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - EXPECT_TRUE(ly1.IsEquivalent(ly2)); - } - - { // check quaternion comparisons - AZ::Quaternion az(AZ::Quaternion::CreateIdentity()); - Quat ly(IDENTITY); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - az = AZ::Quaternion(1.f, 2.f, 3.f, 4.f); - ly = Quat(4.f, 1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // w in wrong place - ly = Quat(1.f, 2.f, 3.f, 4.f); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check quaternion conversions - Quat ly1(4.f, 1.f, 2.f, 3.f); - AZ::Quaternion az = LYQuaternionToAZQuaternion(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - Quat ly2 = AZQuaternionToLYQuaternion(az); - EXPECT_TRUE(IsNearlyEqual(az, ly2)); - EXPECT_TRUE(Quat::IsEquivalent(ly1, ly2)); - } - - { // check transform comparisons - AZ::Transform az = AZ::Transform::Identity(); - Matrix34 ly = Matrix34::CreateIdentity(); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // rotating pi/2 will get us a non-symmetric matrix. - // good for testing that we're not confusing rows & columns - float rotation = gf_PI / 2.f; - - ly = Matrix34::CreateRotationX(rotation, Vec3(1.f, 2.f, 3.f)); - az = AZ::Transform::CreateRotationX(rotation); - az.SetTranslation(1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // rotate around different axis - ly = Matrix34::CreateRotationY(rotation, Vec3(1.f, 2.f, 3.f)); - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check transform conversions - Matrix34 ly1 = Matrix34::CreateRotationXYZ(Ang3(0.1f, 0.5f, 0.9f), Vec3(1.f, 2.f, 3.f)); - AZ::Transform az = LYTransformToAZTransform(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - Matrix34 ly2 = AZTransformToLYTransform(az); - EXPECT_TRUE(IsNearlyEqual(az, ly2)); - EXPECT_TRUE(Matrix34::IsEquivalent(ly1, ly2)); - } - - { // check QuatT comparisons - AZ::Transform az = AZ::Transform::Identity(); - QuatT ly(IDENTITY); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - az = AZ::Transform::CreateRotationX(AZ::Constants::HalfPi); - az.SetTranslation(1.f, 2.f, 3.f); - ly.q.SetRotationX(AZ::Constants::HalfPi); - ly.t.Set(1.f, 2.f, 3.f); - EXPECT_TRUE(IsNearlyEqual(az, ly)); - - // off by 0.1 - ly.t.z += 0.1f; - EXPECT_TRUE(!IsNearlyEqual(az, ly)); - } - - { // check QuatT conversions - QuatT ly1(Quat::CreateRotationX(AZ::Constants::HalfPi), Vec3(5.f, 6.f, 7.f)); - AZ::Transform az = LYQuatTToAZTransform(ly1); - EXPECT_TRUE(IsNearlyEqual(az, ly1)); - - QuatT ly2 = AZTransformToLYQuatT(az); - EXPECT_TRUE(IsNearlyEqual(az, ly2)); - EXPECT_TRUE(QuatT::IsEquivalent(ly1, ly2)); - } -} -//} // namespace MathConversionUnitTests diff --git a/Code/CryEngine/CrySystem/CompressedFile.cpp b/Code/CryEngine/CrySystem/CompressedFile.cpp deleted file mode 100644 index 9166466e3d..0000000000 --- a/Code/CryEngine/CrySystem/CompressedFile.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "CryZlib.h" - -bool CSystem::CompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize, int level) -{ - uLongf destLen = outputSize; - Bytef* dest = static_cast(output); - uLong sourceLen = inputSize; - const Bytef* source = static_cast(input); - bool ok = Z_OK == compress2(dest, &destLen, source, sourceLen, level); - outputSize = destLen; - return ok; -} - -bool CSystem::DecompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize) -{ - uLongf destLen = outputSize; - Bytef* dest = static_cast(output); - uLong sourceLen = inputSize; - const Bytef* source = static_cast(input); - bool ok = Z_OK == uncompress(dest, &destLen, source, sourceLen); - outputSize = destLen; - return ok; -} diff --git a/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp b/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp index 946edb9b64..b6eced4df3 100644 --- a/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp +++ b/Code/CryEngine/CrySystem/ConsoleBatchFile.cpp @@ -87,14 +87,6 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) filename = PathUtil::ReplaceExtension(filename, "cfg"); } -#if defined(CVARS_WHITELIST) - bool ignoreWhitelist = true; - if (_stricmp(sFilename, "autoexec.cfg") == 0) - { - ignoreWhitelist = false; - } -#endif // defined(CVARS_WHITELIST) - ////////////////////////////////////////////////////////////////////////// CCryFile file; @@ -179,18 +171,9 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename) continue; } -#if defined(CVARS_WHITELIST) - if (ignoreWhitelist || (gEnv->pSystem->GetCVarsWhiteList() && gEnv->pSystem->GetCVarsWhiteList()->IsWhiteListed(strLine, false))) -#endif // defined(CVARS_WHITELIST) { m_pConsole->ExecuteString(strLine); } -#if defined(CVARS_WHITELIST) - else if (gEnv->IsDedicated()) - { - gEnv->pSystem->GetILog()->LogError("Failed to execute command: '%s' as it is not whitelisted\n", strLine.c_str()); - } -#endif // defined(CVARS_WHITELIST) } // See above // ((CXConsole*)m_pConsole)->SetStatus(bConsoleStatus); diff --git a/Code/CryEngine/CrySystem/CrashHandler.rc b/Code/CryEngine/CrySystem/CrashHandler.rc deleted file mode 100644 index 01afa72550..0000000000 --- a/Code/CryEngine/CrySystem/CrashHandler.rc +++ /dev/null @@ -1,114 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_CRITICAL_ERROR, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 260 - BOTTOMMARGIN, 223 - END - - IDD_EXCEPTION, DIALOG - BEGIN - END - - IDD_CONFIRM_SAVE_LEVEL, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 239 - TOPMARGIN, 7 - BOTTOMMARGIN, 96 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_CRITICAL_ERROR DIALOGEX 0, 0, 267, 230 -STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -CAPTION "Critical Exception" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "&Abort",IDB_EXIT,100,207,58,14 - EDITTEXT IDC_CALLSTACK,10,95,245,102,ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL - EDITTEXT IDC_EXCEPTION_CODE,10,25,50,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Call Stack Trace",IDC_STATIC,13,85,54,8 - LTEXT "Code",IDC_STATIC,10,15,18,8 - LTEXT "Address:",IDC_STATIC,66,15,28,8 - EDITTEXT IDC_EXCEPTION_ADDRESS,65,25,75,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Description",IDC_STATIC,10,40,36,8 - GROUPBOX "Exception Info",IDC_STATIC,5,5,255,200 - EDITTEXT IDC_EXCEPTION_MODULE,145,25,110,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Module",IDC_STATIC,145,15,24,8 - EDITTEXT IDC_EXCEPTION_DESC,10,50,245,30,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY - PUSHBUTTON "&Ignore",IDB_IGNORE,160,207,59,14,WS_DISABLED -END - -IDD_EXCEPTION DIALOG 0, 0, 138, 52 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU -CAPTION "Exception" -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Exception Intercepted\r\nRetrieving Info...",IDC_STATIC,33,18,71,19 -END - -IDD_CONFIRM_SAVE_LEVEL DIALOGEX 0, 0, 280, 123 -STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION -EXSTYLE WS_EX_TOPMOST -CAPTION "Engine, Game or Editor Crash" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Save",IDB_CONFIRM_SAVE,4,96,68,20 - PUSHBUTTON "Cancel",IDB_DONT_SAVE,206,96,68,20 - LTEXT "Open 3D Engine has encountered an error and needs to close.\n\nA backup has been saved to the '_savebackup' subfolder.\n\nIf you are unable to save your file, you can recover by copying the contents of the _savebackup folder over the broken files.",IDC_STATIC,60,8,210,61 - LTEXT "Attempt save?",IDC_STATIC,60,72,180,21 - CONTROL 128,IDC_STATIC,"Static",SS_BITMAP | SS_CENTERIMAGE | SS_REALSIZEIMAGE,8,8,48,40 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_CRASH_FACE BITMAP "crash_face.bmp" -#endif // English (United States) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp b/Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp deleted file mode 100644 index b2aaea1634..0000000000 --- a/Code/CryEngine/CrySystem/CryAsyncMemcpy.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include - -namespace -{ - static void cryAsyncMemcpy_Int( - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::System); - - cryMemcpy(dst, src, size, nFlags); - if (sync) - { - CryInterlockedDecrement(sync); - } - } -} - -#if !defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpy( -#else -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpyDelegate( -#endif - void* dst - , const void* src - , size_t size - , int nFlags - , volatile int* sync) -{ - AZ::Job* job = AZ::CreateJobFunction( - [dst, src, size, nFlags, sync]() - { - cryAsyncMemcpy_Int(dst, src, size, nFlags, sync); - }, - true); // Auto-delete - job->Start(); -} - - - diff --git a/Code/CryEngine/CrySystem/CryDLMalloc.c b/Code/CryEngine/CrySystem/CryDLMalloc.c deleted file mode 100644 index bcb835b0d5..0000000000 --- a/Code/CryEngine/CrySystem/CryDLMalloc.c +++ /dev/null @@ -1,6645 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#define DEFAULT_GRANULARITY (64 * 1024) //this gets #undef and redefined in the .inl this has to come before that - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CRYDLMALLOC_C_SECTION_1 1 -#define CRYDLMALLOC_C_SECTION_2 2 - -#include "../../Framework/AzCore/AzCore/PlatformRestrictedFileDef.h" -#define AZ_RESTRICTED_SECTION CRYDLMALLOC_C_SECTION_1 -#include AZ_RESTRICTED_FILE(CryDLMalloc_c) -#elif defined(_WIN32) || defined(LINUX) || defined(APPLE) -#define TRAIT_ENABLE_DLMALLOC 1 -#endif - -#if defined(BUCKET_SIMULATOR) || TRAIT_ENABLE_DLMALLOC -/* - This is a version (aka dlmalloc) of malloc/free/realloc written by - Doug Lea and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. Send questions, - comments, complaints, performance data, etc to dl@cs.oswego.edu - -* Version 2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at - ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - -* Quickstart - - This library is all in one file to simplify the most common usage: - ftp it, compile it (-O3), and link it into another program. All of - the compile-time options default to reasonable values for use on - most platforms. You might later want to step through various - compile-time and dynamic tuning options. - - For convenience, an include file for code using this malloc is at: - ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.4.h - You don't really need this .h file unless you call functions not - defined in your system include files. The .h file contains only the - excerpts from this file needed for using this malloc on ANSI C/C++ - systems, so long as you haven't changed compile-time options about - naming and tuning parameters. If you do, then you can create your - own malloc.h that does include all settings by cutting at the point - indicated below. Note that you may already by default be using a C - library containing a malloc that is based on some version of this - malloc (for example in linux). You might still want to use the one - in this file to customize settings or to avoid overheads associated - with library versions. - -* Vital statistics: - - Supported pointer/size_t representation: 4 or 8 bytes - size_t MUST be an unsigned type of the same width as - pointers. (If you are using an ancient system that declares - size_t as a signed type, or need it to be a different width - than pointers, you can use a previous release of this malloc - (e.g. 2.7.2) supporting these.) - - Alignment: 8 bytes (default) - This suffices for nearly all current machines and C compilers. - However, you can define MALLOC_ALIGNMENT to be wider than this - if necessary (up to 128bytes), at the expense of using more space. - - Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) - 8 or 16 bytes (if 8byte sizes) - Each malloced chunk has a hidden word of overhead holding size - and status information, and additional cross-check word - if FOOTERS is defined. - - Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) - 8-byte ptrs: 32 bytes (including overhead) - - Even a request for zero bytes (i.e., malloc(0)) returns a - pointer to something of the minimum allocatable size. - The maximum overhead wastage (i.e., number of extra bytes - allocated than were requested in malloc) is less than or equal - to the minimum size, except for requests >= mmap_threshold that - are serviced via mmap(), where the worst case wastage is about - 32 bytes plus the remainder from a system page (the minimal - mmap unit); typically 4096 or 8192 bytes. - - Security: static-safe; optionally more or less - The "security" of malloc refers to the ability of malicious - code to accentuate the effects of errors (for example, freeing - space that is not currently malloc'ed or overwriting past the - ends of chunks) in code that calls malloc. This malloc - guarantees not to modify any memory locations below the base of - heap, i.e., static variables, even in the presence of usage - errors. The routines additionally detect most improper frees - and reallocs. All this holds as long as the static bookkeeping - for malloc itself is not corrupted by some other means. This - is only one aspect of security -- these checks do not, and - cannot, detect all possible programming errors. - - If FOOTERS is defined nonzero, then each allocated chunk - carries an additional check word to verify that it was malloced - from its space. These check words are the same within each - execution of a program using malloc, but differ across - executions, so externally crafted fake chunks cannot be - freed. This improves security by rejecting frees/reallocs that - could corrupt heap memory, in addition to the checks preventing - writes to statics that are always on. This may further improve - security at the expense of time and space overhead. (Note that - FOOTERS may also be worth using with MSPACES.) - - By default detected errors cause the program to abort (calling - "abort()"). You can override this to instead proceed past - errors by defining PROCEED_ON_ERROR. In this case, a bad free - has no effect, and a malloc that encounters a bad address - caused by user overwrites will ignore the bad address by - dropping pointers and indices to all known memory. This may - be appropriate for programs that should continue if at all - possible in the face of programming errors, although they may - run out of memory because dropped memory is never reclaimed. - - If you don't like either of these options, you can define - CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything - else. And if if you are sure that your program using malloc has - no errors or vulnerabilities, you can define INSECURE to 1, - which might (or might not) provide a small performance improvement. - - Thread-safety: NOT thread-safe unless USE_LOCKS defined - When USE_LOCKS is defined, each public call to malloc, free, - etc is surrounded with either a pthread mutex or a win32 - spinlock (depending on WIN32). This is not especially fast, and - can be a major bottleneck. It is designed only to provide - minimal protection in concurrent environments, and to provide a - basis for extensions. If you are using malloc in a concurrent - program, consider instead using nedmalloc - (http://www.nedprod.com/programs/portable/nedmalloc/) or - ptmalloc (See http://www.malloc.de), which are derived - from versions of this malloc. - - System requirements: Any combination of MORECORE and/or MMAP/MUNMAP - This malloc can use unix sbrk or any emulation (invoked using - the CALL_MORECORE macro) and/or mmap/munmap or any emulation - (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system - memory. On most unix systems, it tends to work best if both - MORECORE and MMAP are enabled. On Win32, it uses emulations - based on VirtualAlloc. It also uses common C library functions - like memset. - - Compliance: I believe it is compliant with the Single Unix Specification - (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably - others as well. - -* Overview of algorithms - - This is not the fastest, most space-conserving, most portable, or - most tunable malloc ever written. However it is among the fastest - while also being among the most space-conserving, portable and - tunable. Consistent balance across these factors results in a good - general-purpose allocator for malloc-intensive programs. - - In most ways, this malloc is a best-fit allocator. Generally, it - chooses the best-fitting existing chunk for a request, with ties - broken in approximately least-recently-used order. (This strategy - normally maintains low fragmentation.) However, for requests less - than 256bytes, it deviates from best-fit when there is not an - exactly fitting available chunk by preferring to use space adjacent - to that used for the previous small request, as well as by breaking - ties in approximately most-recently-used order. (These enhance - locality of series of small allocations.) And for very large requests - (>= 256Kb by default), it relies on system memory mapping - facilities, if supported. (This helps avoid carrying around and - possibly fragmenting memory used only for large chunks.) - - All operations (except malloc_stats and mallinfo) have execution - times that are bounded by a constant factor of the number of bits in - a size_t, not counting any clearing in calloc or copying in realloc, - or actions surrounding MORECORE and MMAP that have times - proportional to the number of non-contiguous regions returned by - system allocation routines, which is often just 1. In real-time - applications, you can optionally suppress segment traversals using - NO_SEGMENT_TRAVERSAL, which assures bounded execution even when - system allocators return non-contiguous spaces, at the typical - expense of carrying around more memory and increased fragmentation. - - The implementation is not very modular and seriously overuses - macros. Perhaps someday all C compilers will do as good a job - inlining modular code as can now be done by brute-force expansion, - but now, enough of them seem not to. - - Some compilers issue a lot of warnings about code that is - dead/unreachable only on some platforms, and also about intentional - uses of negation on unsigned types. All known cases of each can be - ignored. - - For a longer but out of date high-level description, see - http://gee.cs.oswego.edu/dl/html/malloc.html - -* MSPACES - If MSPACES is defined, then in addition to malloc, free, etc., - this file also defines mspace_malloc, mspace_free, etc. These - are versions of malloc routines that take an "mspace" argument - obtained using create_mspace, to control all internal bookkeeping. - If ONLY_MSPACES is defined, only these versions are compiled. - So if you would like to use this allocator for only some allocations, - and your system malloc for others, you can compile with - ONLY_MSPACES and then do something like... - static mspace mymspace = create_mspace(0,0); // for example - #define mymalloc(bytes) mspace_malloc(mymspace, bytes) - - (Note: If you only need one instance of an mspace, you can instead - use "USE_DL_PREFIX" to relabel the global malloc.) - - You can similarly create thread-local allocators by storing - mspaces as thread-locals. For example: - static __thread mspace tlms = 0; - void* tlmalloc(size_t bytes) { - if (tlms == 0) tlms = create_mspace(0, 0); - return mspace_malloc(tlms, bytes); - } - void tlfree(void* mem) { mspace_free(tlms, mem); } - - Unless FOOTERS is defined, each mspace is completely independent. - You cannot allocate from one and free to another (although - conformance is only weakly checked, so usage errors are not always - caught). If FOOTERS is defined, then each chunk carries around a tag - indicating its originating mspace, and frees are directed to their - originating spaces. - - ------------------------- Compile-time options --------------------------- - -Be careful in setting #define values for numerical constants of type -size_t. On some systems, literal values are not automatically extended -to size_t precision unless they are explicitly casted. You can also -use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. - -WIN32 default: defined if _WIN32 defined - Defining WIN32 sets up defaults for MS environment and compilers. - Otherwise defaults are for unix. Beware that there seem to be some - cases where this malloc might not be a pure drop-in replacement for - Win32 malloc: Random-looking failures from Win32 GDI API's (eg; - SetDIBits()) may be due to bugs in some video driver implementations - when pixel buffers are malloc()ed, and the region spans more than - one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) - default granularity, pixel buffers may straddle virtual allocation - regions more often than when using the Microsoft allocator. You can - avoid this by using VirtualAlloc() and VirtualFree() for all pixel - buffers rather than using malloc(). If this is not possible, - recompile this malloc with a larger DEFAULT_GRANULARITY. - -MALLOC_ALIGNMENT default: (size_t)8 - Controls the minimum alignment for malloc'ed chunks. It must be a - power of two and at least 8, even on machines for which smaller - alignments would suffice. It may be defined as larger than this - though. Note however that code and data structures are optimized for - the case of 8-byte alignment. - -MSPACES default: 0 (false) - If true, compile in support for independent allocation spaces. - This is only supported if HAVE_MMAP is true. - -ONLY_MSPACES default: 0 (false) - If true, only compile in mspace versions, not regular versions. - -USE_LOCKS default: 0 (false) - Causes each call to each public routine to be surrounded with - pthread or WIN32 mutex lock/unlock. (If set true, this can be - overridden on a per-mspace basis for mspace versions.) If set to a - non-zero value other than 1, locks are used, but their - implementation is left out, so lock functions must be supplied manually, - as described below. - -USE_SPIN_LOCKS default: 1 iff USE_LOCKS and on x86 using gcc or MSC - If true, uses custom spin locks for locking. This is currently - supported only for x86 platforms using gcc or recent MS compilers. - Otherwise, posix locks or win32 critical sections are used. - -FOOTERS default: 0 - If true, provide extra checking and dispatching by placing - information in the footers of allocated chunks. This adds - space and time overhead. - -INSECURE default: 0 - If true, omit checks for usage errors and heap space overwrites. - -USE_DL_PREFIX default: NOT defined - Causes compiler to prefix all public routines with the string 'dl'. - This can be useful when you only want to use this malloc in one part - of a program, using your regular system malloc elsewhere. - -ABORT default: defined as abort() - Defines how to abort on failed checks. On most systems, a failed - check cannot die with an "assert" or even print an informative - message, because the underlying print routines in turn call malloc, - which will fail again. Generally, the best policy is to simply call - abort(). It's not very useful to do more than this because many - errors due to overwriting will show up as address faults (null, odd - addresses etc) rather than malloc-triggered checks, so will also - abort. Also, most compilers know that abort() does not return, so - can better optimize code conditionally calling it. - -PROCEED_ON_ERROR default: defined as 0 (false) - Controls whether detected bad addresses cause them to bypassed - rather than aborting. If set, detected bad arguments to free and - realloc are ignored. And all bookkeeping information is zeroed out - upon a detected overwrite of freed heap space, thus losing the - ability to ever return it from malloc again, but enabling the - application to proceed. If PROCEED_ON_ERROR is defined, the - static variable malloc_corruption_error_count is compiled in - and can be examined to see if errors have occurred. This option - generates slower code than the default abort policy. - -DEBUG default: NOT defined - The DEBUG setting is mainly intended for people trying to modify - this code or diagnose problems when porting to new platforms. - However, it may also be able to better isolate user errors than just - using runtime checks. The assertions in the check routines spell - out in more detail the assumptions and invariants underlying the - algorithms. The checking is fairly extensive, and will slow down - execution noticeably. Calling malloc_stats or mallinfo with DEBUG - set will attempt to check every non-mmapped allocated and free chunk - in the course of computing the summaries. - -ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) - Debugging assertion failures can be nearly impossible if your - version of the assert macro causes malloc to be called, which will - lead to a cascade of further failures, blowing the runtime stack. - ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), - which will usually make debugging easier. - -MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 - The action to take before "return 0" when malloc fails to be able to - return memory because there is none available. - -HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES - True if this system supports sbrk or an emulation of it. - -MORECORE default: sbrk - The name of the sbrk-style system routine to call to obtain more - memory. See below for guidance on writing custom MORECORE - functions. The type of the argument to sbrk/MORECORE varies across - systems. It cannot be size_t, because it supports negative - arguments, so it is normally the signed type of the same width as - size_t (sometimes declared as "intptr_t"). It doesn't much matter - though. Internally, we only call it with arguments less than half - the max value of a size_t, which should work across all reasonable - possibilities, although sometimes generating compiler warnings. - -MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE - If true, take advantage of fact that consecutive calls to MORECORE - with positive arguments always return contiguous increasing - addresses. This is true of unix sbrk. It does not hurt too much to - set it true anyway, since malloc copes with non-contiguities. - Setting it false when definitely non-contiguous saves time - and possibly wasted space it would take to discover this though. - -MORECORE_CANNOT_TRIM default: NOT defined - True if MORECORE cannot release space back to the system when given - negative arguments. This is generally necessary only if you are - using a hand-crafted MORECORE function that cannot handle negative - arguments. - -NO_SEGMENT_TRAVERSAL default: 0 - If non-zero, suppresses traversals of memory segments - returned by either MORECORE or CALL_MMAP. This disables - merging of segments that are contiguous, and selectively - releasing them to the OS if unused, but bounds execution times. - -HAVE_MMAP default: 1 (true) - True if this system supports mmap or an emulation of it. If so, and - HAVE_MORECORE is not true, MMAP is used for all system - allocation. If set and HAVE_MORECORE is true as well, MMAP is - primarily used to directly allocate very large blocks. It is also - used as a backup strategy in cases where MORECORE fails to provide - space from system. Note: A single call to MUNMAP is assumed to be - able to unmap memory that may have be allocated using multiple calls - to MMAP, so long as they are adjacent. - -HAVE_MREMAP default: 1 on linux, else 0 - If true realloc() uses mremap() to re-allocate large blocks and - extend or shrink allocation spaces. - -MMAP_CLEARS default: 1 except on WINCE. - True if mmap clears memory so calloc doesn't need to. This is true - for standard unix mmap using /dev/zero and on WIN32 except for WINCE. - -USE_BUILTIN_FFS default: 0 (i.e., not used) - Causes malloc to use the builtin ffs() function to compute indices. - Some compilers may recognize and intrinsify ffs to be faster than the - supplied C version. Also, the case of x86 using gcc is special-cased - to an asm instruction, so is already as fast as it can be, and so - this setting has no effect. Similarly for Win32 under recent MS compilers. - (On most x86s, the asm version is only slightly faster than the C version.) - -malloc_getpagesize default: derive from system includes, or 4096. - The system page size. To the extent possible, this malloc manages - memory from the system in page-size units. This may be (and - usually is) a function rather than a constant. This is ignored - if WIN32, where page size is determined using getSystemInfo during - initialization. - -USE_DEV_RANDOM default: 0 (i.e., not used) - Causes malloc to use /dev/random to initialize secure magic seed for - stamping footers. Otherwise, the current time is used. - -NO_MALLINFO default: 0 - If defined, don't compile "mallinfo". This can be a simple way - of dealing with mismatches between system declarations and - those in this file. - -MALLINFO_FIELD_TYPE default: size_t - The type of the fields in the mallinfo struct. This was originally - defined as "int" in SVID etc, but is more usefully defined as - size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set - -REALLOC_ZERO_BYTES_FREES default: not defined - This should be set if a call to realloc with zero bytes should - be the same as a call to free. Some people think it should. Otherwise, - since this malloc returns a unique pointer for malloc(0), so does - realloc(p, 0). - -LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H -LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H -LACKS_STDLIB_H default: NOT defined unless on WIN32 - Define these if your system does not have these header files. - You might need to manually insert some of the declarations they provide. - -DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, - system_info.dwAllocationGranularity in WIN32, - otherwise 64K. - Also settable using mallopt(M_GRANULARITY, x) - The unit for allocating and deallocating memory from the system. On - most systems with contiguous MORECORE, there is no reason to - make this more than a page. However, systems with MMAP tend to - either require or encourage larger granularities. You can increase - this value to prevent system allocation functions to be called so - often, especially if they are slow. The value must be at least one - page and must be a power of two. Setting to 0 causes initialization - to either page size or win32 region size. (Note: In previous - versions of malloc, the equivalent of this option was called - "TOP_PAD") - -DEFAULT_TRIM_THRESHOLD default: 2MB - Also settable using mallopt(M_TRIM_THRESHOLD, x) - The maximum amount of unused top-most memory to keep before - releasing via malloc_trim in free(). Automatic trimming is mainly - useful in long-lived programs using contiguous MORECORE. Because - trimming via sbrk can be slow on some systems, and can sometimes be - wasteful (in cases where programs immediately afterward allocate - more large chunks) the value should be high enough so that your - overall system performance would improve by releasing this much - memory. As a rough guide, you might set to a value close to the - average size of a process (program) running on your system. - Releasing this much memory would allow such a process to run in - memory. Generally, it is worth tuning trim thresholds when a - program undergoes phases where several large chunks are allocated - and released in ways that can reuse each other's storage, perhaps - mixed with phases where there are no such chunks at all. The trim - value must be greater than page size to have any useful effect. To - disable trimming completely, you can set to MAX_SIZE_T. Note that the trick - some people use of mallocing a huge space and then freeing it at - program startup, in an attempt to reserve system memory, doesn't - have the intended effect under automatic trimming, since that memory - will immediately be returned to the system. - -DEFAULT_MMAP_THRESHOLD default: 256K - Also settable using mallopt(M_MMAP_THRESHOLD, x) - The request size threshold for using MMAP to directly service a - request. Requests of at least this size that cannot be allocated - using already-existing space will be serviced via mmap. (If enough - normal freed space already exists it is used instead.) Using mmap - segregates relatively large chunks of memory so that they can be - individually obtained and released from the host system. A request - serviced through mmap is never reused by any other request (at least - not directly; the system may just so happen to remap successive - requests to the same locations). Segregating space in this way has - the benefits that: Mmapped space can always be individually released - back to the system, which helps keep the system level memory demands - of a long-lived program low. Also, mapped memory doesn't become - `locked' between other chunks, as can happen with normally allocated - chunks, which means that even trimming via malloc_trim would not - release them. However, it has the disadvantage that the space - cannot be reclaimed, consolidated, and then used to service later - requests, as happens with normal chunks. The advantages of mmap - nearly always outweigh disadvantages for "large" chunks, but the - value of "large" may vary across systems. The default is an - empirically derived value that works well in most systems. You can - disable mmap by setting to MAX_SIZE_T. - -MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP - The number of consolidated frees between checks to release - unused segments when freeing. When using non-contiguous segments, - especially with multiple mspaces, checking only for topmost space - doesn't always suffice to trigger trimming. To compensate for this, - free() will, with a period of MAX_RELEASE_CHECK_RATE (or the - current number of segments, if greater) try to release unused - segments to the OS when freeing chunks that result in - consolidation. The best value for this parameter is a compromise - between slowing down frees with relatively costly checks that - rarely trigger versus holding on to unused memory. To effectively - disable, set to MAX_SIZE_T. This may lead to a very slight speed - improvement at the expense of carrying around more memory. -*/ - -/* Version identifier to allow people to support multiple versions */ - -#ifndef DLMALLOC_VERSION -#define DLMALLOC_VERSION 20804 -#endif /* DLMALLOC_VERSION */ - - -#define MAX_RELEASE_CHECK_RATE 255 -#define REALLOC_ZERO_BYTES_FREES -#define USE_DL_PREFIX 1 - -#define mspace_create_overhead dlmspace_create_overhead -#define create_mspace dlcreate_mspace -#define destroy_mspace dldestroy_mspace -#define create_mspace_with_base dlcreate_mspace_with_base -#define mspace_track_large_chunks dlmspace_track_large_chunks -#define mspace_malloc dlmspace_malloc -#define mspace_free dlmspace_free -#define mspace_realloc dlmspace_realloc -#define mspace_calloc dlmspace_calloc -#define mspace_memalign dlmspace_memalign -#define mspace_independent_calloc dlmspace_independent_calloc -#define mspace_independent_comalloc dlmspace_independent_comalloc -#define mspace_footprint dlmspace_footprint -#define mspace_max_footprint dlmspace_max_footprint -#define mspace_mallinfo dlmspace_mallinfo -#define mspace_usable_size dlmspace_usable_size -#define mspace_malloc_stats dlmspace_malloc_stats -#define mspace_get_used_space dlmspace_get_used_space -#define mspace_trim dlmspace_trim -#define mspace_mallopt dlmspace_mallopt - -// Avoid x64 warnings with size_t converted to int -#pragma warning(disable : 4267) -#pragma warning(disable : 6239) -#pragma warning(disable : 6297) -#pragma warning(disable : 28182) - -// Conditional expression is constant -#pragma warning(disable : 4127) - -#ifdef BUCKET_SIMULATOR - -#define HAVE_MORECORE 0 -#define MORECORE SimSBrk -#define DEFAULT_MMAP_THRESHOLD (1024 * 1024) -#define DEFAULT_TRIM_THRESHOLD (256 * 1024) - -#include -#include -#include -#include /* For size_t */ -#include - -static void* s_sbrkBase; -static void* s_sbrkEnd; -static void* s_sbrkMax; - -extern volatile int dlmallocmapped; - -void* SimSBrk(ptrdiff_t size) -{ - void* ret = NULL; - - if (!s_sbrkBase) - { - s_sbrkBase = VirtualAlloc(NULL, 64 * 1024 * 1024, MEM_RESERVE, PAGE_READWRITE); - s_sbrkEnd = s_sbrkBase; - s_sbrkMax = (LPVOID) ((INT_PTR) s_sbrkBase + 64 * 1024 * 1024); - } - - if (s_sbrkEnd) - { - if (size > 0) - { - INT_PTR end = (INT_PTR) s_sbrkEnd; - INT_PTR newEnd = end + size; - - if (newEnd <= (INT_PTR) s_sbrkMax) - { - ret = VirtualAlloc(s_sbrkEnd, size, MEM_COMMIT, PAGE_READWRITE); - if (ret) - { - s_sbrkEnd = (LPVOID) newEnd; - CryInterlockedAdd(&dlmallocmapped, (LONG) size); - } - } - } - else if (size < 0) - { - INT_PTR end = (INT_PTR) s_sbrkEnd; - INT_PTR newEnd = end + size; - - if (newEnd >= (INT_PTR) s_sbrkBase) - { - VirtualFree((LPVOID) newEnd, -size, MEM_DECOMMIT); - CryInterlockedAdd(&dlmallocmapped, (LONG) size); - } - } - else - { - ret = s_sbrkEnd; - } - } - - if (!ret) - { - ret = (void*) -1; - errno = ENOMEM; - } - - return ret; -} -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#elif defined(_WIN32) - -#define HAVE_MMAP 1 -#define HAVE_MORECORE (!HAVE_MMAP) -#define USE_LOCKS 0 -#define FOOTERS 0 -#define ONLY_MSPACES 1 -#define DEFAULT_MMAP_THRESHOLD (1024 * 1024) -#define DEFAULT_TRIM_THRESHOLD (256 * 1024) - -#define PROT_READ 0 -#define PROT_WRITE 0 -#define MAP_PRIVATE 0 -#define MAP_ANONYMOUS 1 - -#define MALLOC_ALIGNMENT 16 - -#define malloc_getpagesize (64 * 1024) - -#include -#include - -#elif defined(LINUX) || defined(APPLE) -#include -#define HAVE_MMAP 1 -#define HAVE_MORECORE (!HAVE_MMAP) -#define USE_LOCKS 0 -#define FOOTERS 0 -#define ONLY_MSPACES 1 -#define DEFAULT_MMAP_THRESHOLD (16 * 1024 * 1024) -#define DEFAULT_TRIM_THRESHOLD (16 * 1024 * 1024) - -#if !defined(ANDROID) && !defined(LINUX_CROSS_COMPILE) -#define PROT_READ 0 -#define PROT_WRITE 0 -#define MAP_PRIVATE 0 -#define MAP_ANONYMOUS 1 -#endif - -#define MALLOC_ALIGNMENT 16 - -#define malloc_getpagesize (64 * 1024) - -#include - -// ( || ) is always a non-zero constant. -#pragma warning(disable:6285) - -// Potential comparison of a constant with another constant -#pragma warning(disable:6326) - -// Dereferencing NULL pointer -#pragma warning(disable:6011) - -#endif - -#ifndef WIN32 -#ifdef _WIN32 -#define WIN32 1 -#endif /* _WIN32 */ -#ifdef _WIN32_WCE -#define LACKS_FCNTL_H -#define WIN32 1 -#endif /* _WIN32_WCE */ -#endif /* WIN32 */ - -#ifdef WIN32 -#include -#define HAVE_MMAP 1 -#ifndef HAVE_MORECORE -#define HAVE_MORECORE 0 -#endif -#define LACKS_UNISTD_H -#define LACKS_SYS_PARAM_H -#define LACKS_SYS_MMAN_H -#define LACKS_STRING_H -#define LACKS_STRINGS_H -#define LACKS_SYS_TYPES_H -#define LACKS_ERRNO_H -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION -#endif /* MALLOC_FAILURE_ACTION */ -#ifdef _WIN32_WCE /* WINCE reportedly does not clear */ -#define MMAP_CLEARS 0 -#else -#define MMAP_CLEARS 1 -#endif /* _WIN32_WCE */ -#endif /* WIN32 */ - -#if defined(DARWIN) || defined(_DARWIN) -/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ -#ifndef HAVE_MORECORE -#define HAVE_MORECORE 0 -#define HAVE_MMAP 1 -/* OSX allocators provide 16 byte alignment */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)16U) -#endif -#endif /* HAVE_MORECORE */ -#endif /* DARWIN */ - -#ifndef LACKS_SYS_TYPES_H -#include /* For size_t */ -#endif /* LACKS_SYS_TYPES_H */ - -#if (defined(__GNUC__) && ((defined(__i386__) || defined(__x86_64__)))) || (defined(_MSC_VER)) -#define SPIN_LOCKS_AVAILABLE 1 -#else -#define SPIN_LOCKS_AVAILABLE 0 -#endif - -/* The maximum possible size_t value has all bits set */ -#define MAX_SIZE_T (~(size_t)0) - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 /* define to a value */ -#else -#define ONLY_MSPACES 1 -#endif /* ONLY_MSPACES */ -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)8U) -#endif /* MALLOC_ALIGNMENT */ -#ifndef FOOTERS -#define FOOTERS 0 -#endif /* FOOTERS */ -#ifndef ABORT -#define ABORT abort() -#endif /* ABORT */ -#ifndef ABORT_ON_ASSERT_FAILURE -#define ABORT_ON_ASSERT_FAILURE 1 -#endif /* ABORT_ON_ASSERT_FAILURE */ -#ifndef PROCEED_ON_ERROR -#define PROCEED_ON_ERROR 0 -#endif /* PROCEED_ON_ERROR */ -#ifndef USE_LOCKS -#define USE_LOCKS 0 -#endif /* USE_LOCKS */ -#ifndef USE_SPIN_LOCKS -#if USE_LOCKS && SPIN_LOCKS_AVAILABLE -#define USE_SPIN_LOCKS 1 -#else -#define USE_SPIN_LOCKS 0 -#endif /* USE_LOCKS && SPIN_LOCKS_AVAILABLE. */ -#endif /* USE_SPIN_LOCKS */ -#ifndef INSECURE -#define INSECURE 0 -#endif /* INSECURE */ -#ifndef HAVE_MMAP -#define HAVE_MMAP 1 -#endif /* HAVE_MMAP */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif /* MMAP_CLEARS */ -#ifndef HAVE_MREMAP -#ifdef linux -#define HAVE_MREMAP 1 -#else /* linux */ -#define HAVE_MREMAP 0 -#endif /* linux */ -#endif /* HAVE_MREMAP */ -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION errno = ENOMEM; -#endif /* MALLOC_FAILURE_ACTION */ -#ifndef HAVE_MORECORE -#if ONLY_MSPACES -#define HAVE_MORECORE 0 -#else /* ONLY_MSPACES */ -#define HAVE_MORECORE 1 -#endif /* ONLY_MSPACES */ -#endif /* HAVE_MORECORE */ -#if !HAVE_MORECORE -#define MORECORE_CONTIGUOUS 0 -#else /* !HAVE_MORECORE */ -#define MORECORE_DEFAULT sbrk -#ifndef MORECORE_CONTIGUOUS -#define MORECORE_CONTIGUOUS 1 -#endif /* MORECORE_CONTIGUOUS */ -#endif /* HAVE_MORECORE */ -#ifndef DEFAULT_GRANULARITY -#if (MORECORE_CONTIGUOUS || defined(WIN32)) -#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ -#else /* MORECORE_CONTIGUOUS */ -#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#endif /* MORECORE_CONTIGUOUS */ -#endif /* DEFAULT_GRANULARITY */ -#ifndef DEFAULT_TRIM_THRESHOLD -#ifndef MORECORE_CANNOT_TRIM -#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) -#else /* MORECORE_CANNOT_TRIM */ -#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#endif /* MORECORE_CANNOT_TRIM */ -#endif /* DEFAULT_TRIM_THRESHOLD */ -#ifndef DEFAULT_MMAP_THRESHOLD -#if HAVE_MMAP -#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#else /* HAVE_MMAP */ -#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* DEFAULT_MMAP_THRESHOLD */ -#ifndef MAX_RELEASE_CHECK_RATE -#if HAVE_MMAP -#define MAX_RELEASE_CHECK_RATE 4095 -#else -#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* MAX_RELEASE_CHECK_RATE */ -#ifndef USE_BUILTIN_FFS -#define USE_BUILTIN_FFS 0 -#endif /* USE_BUILTIN_FFS */ -#ifndef USE_DEV_RANDOM -#define USE_DEV_RANDOM 0 -#endif /* USE_DEV_RANDOM */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -#ifndef NO_SEGMENT_TRAVERSAL -#define NO_SEGMENT_TRAVERSAL 0 -#endif /* NO_SEGMENT_TRAVERSAL */ - -/* - mallopt tuning options. SVID/XPG defines four standard parameter - numbers for mallopt, normally defined in malloc.h. None of these - are used in this malloc, so setting them has no effect. But this - malloc does support the following options. -*/ - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - -// --------- Traits -------------- - -#if !defined(AZ_RESTRICTED_PLATFORM) - #if defined(_MSC_VER) - #define TRAIT_HAS_BITSCANFORWARD 1 - #define TRAIT_HAS_BITSCANREVERSE 1 - #endif - #if defined(WIN32) - #define TRAIT_HAS_WIN32_MMAP 1 - #endif - #if defined(WIN32) || defined(WIN64) - #define TRAIT_HAS_GETSYSTEMINFO 1 - #endif - #if defined(_WIN32) - #define TRAIT_USE_QUERYPERFORMANCECOUNTER 1 - #endif -#endif - -/* ------------------------ Mallinfo declarations ------------------------ */ - -#if !NO_MALLINFO -/* - This version of malloc supports the standard SVID/XPG mallinfo - routine that returns a struct containing usage properties and - statistics. It should work on any system that has a - /usr/include/malloc.h defining struct mallinfo. The main - declaration needed is the mallinfo struct that is returned (by-copy) - by mallinfo(). The malloinfo struct contains a bunch of fields that - are not even meaningful in this version of malloc. These fields are - are instead filled by mallinfo() with other numbers that might be of - interest. - - HAVE_USR_INCLUDE_MALLOC_H should be set if you have a - /usr/include/malloc.h file that includes a declaration of struct - mallinfo. If so, it is included; else a compliant version is - declared below. These must be precisely the same for mallinfo() to - work. The original SVID version of this struct, defined on most - systems with mallinfo, declares all fields as ints. But some others - define as unsigned long. If your system defines the fields using a - type of different width than listed here, you MUST #include your - system version and #define HAVE_USR_INCLUDE_MALLOC_H. -*/ - -/* #define HAVE_USR_INCLUDE_MALLOC_H */ - -#ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" -#else /* HAVE_USR_INCLUDE_MALLOC_H */ -#ifndef STRUCT_MALLINFO_DECLARED -#define STRUCT_MALLINFO_DECLARED 1 -struct mallinfo -{ - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; -#endif /* STRUCT_MALLINFO_DECLARED */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* NO_MALLINFO */ - -/* - Try to persuade compilers to inline. The most critical functions for - inlining are defined as macros, so these aren't used for them. -*/ - -#ifndef FORCEINLINE - #if defined(__GNUC__) -#define FORCEINLINE __inline __attribute__ ((always_inline)) - #elif defined(_MSC_VER) - #define FORCEINLINE __forceinline - #endif -#endif -#ifndef NOINLINE - #if defined(__GNUC__) - #define NOINLINE __attribute__ ((noinline)) - #elif defined(_MSC_VER) - #define NOINLINE __declspec(noinline) - #else - #define NOINLINE - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#ifndef FORCEINLINE - #define FORCEINLINE inline -#endif -#endif /* __cplusplus */ -#ifndef FORCEINLINE - #define FORCEINLINE -#endif - -typedef void* (* dlmmap_handler)(void*, size_t); -typedef int (* dlmunmap_handler)(void*, void*, size_t); - -#if !ONLY_MSPACES - -/* ------------------- Declarations of public routines ------------------- */ - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign memalign -#define dlrealloc realloc -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlmalloc_max_footprint malloc_max_footprint -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ - - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -void* dlmalloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cause the current program to abort. -*/ -void dlfree(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* dlcalloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ - -void* dlrealloc(void*, size_t); - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* dlmemalign(size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* dlvalloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. To workaround the fact that mallopt is specified to use int, - not size_t parameters, the value -1 is specially treated as the - maximum unsigned size_t value. - - SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt. See below for details. Briefly, supported - parameters are as follows (listed defaults are for "typical" - configurations). - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -int dlmallopt(int, int); - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -size_t dlmalloc_footprint(void); - -/* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ -size_t dlmalloc_max_footprint(void); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ -struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -void** dlindependent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -void** dlindependent_comalloc(size_t, size_t*, void**); - - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* dlpvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -int dlmalloc_trim(size_t); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ -void dlmalloc_stats(void); -void dlmalloc_stats_ret(size_t* sys, size_t* maxSys, size_t* used); - -#endif /* ONLY_MSPACES */ - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t dlmalloc_usable_size(void*); - - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - mspace_create_overhead returns the number of bytes used by an mspace for - internal tracking. Can be used with the capacity argument when creating - an mspace to allocate an exact amount of space upfront. -*/ -int mspace_create_overhead(void); - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -mspace create_mspace(size_t capacity, int locked, void* user, dlmmap_handler mmap, dlmunmap_handler munmap); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_track_large_chunks controls whether requests for large chunks - are allocated in their own untracked mmapped regions, separate from - others in this mspace. By default large chunks are not tracked, - which reduces fragmentation. However, such chunks are not - necessarily released to the system upon destroy_mspace. Enabling - tracking by setting to true may increase fragmentation, but avoids - leakage when relying on destroy_mspace to release all memory - allocated using this space. The function returns the previous - setting. -*/ -int mspace_track_large_chunks(mspace msp, int enable); - - -/* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ -void* mspace_malloc(mspace msp, size_t bytes); - -/* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ -void mspace_free(mspace msp, void* mem); - -/* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ -void* mspace_realloc(mspace msp, void* mem, size_t newsize); - -/* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - -/* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); - -/* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); - -/* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); - -/* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ -size_t mspace_footprint(mspace msp); - -/* - mspace_max_footprint() returns the peak number of bytes obtained from the - system for this space. -*/ -size_t mspace_max_footprint(mspace msp); - - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - malloc_usable_size(void* p) behaves the same as malloc_usable_size; -*/ -size_t mspace_usable_size(void* mem); - -/* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ -void mspace_malloc_stats(mspace msp); - -/* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ -int mspace_trim(mspace msp, size_t pad); - -/* - An alias for mallopt. -*/ -int mspace_mallopt(int, int); - -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif /* __cplusplus */ - -/* - ======================================================================== - To make a fully customizable malloc.h header file, cut everything - above this line, put into file malloc.h, edit to suit, and #include it - on the next line, as well as in programs that use this malloc. - ======================================================================== -*/ - -/* #include "malloc.h" */ - -/*------------------------------ internal #includes ---------------------- */ - -#ifdef WIN32 -#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ -#endif /* WIN32 */ - -#include /* for printing in malloc_stats */ - -#ifndef LACKS_ERRNO_H -#include /* for MALLOC_FAILURE_ACTION */ -#endif /* LACKS_ERRNO_H */ -#if FOOTERS || DEBUG -#include /* for magic initialization */ -#endif /* FOOTERS */ -#ifndef LACKS_STDLIB_H -#include /* for abort() */ -#endif /* LACKS_STDLIB_H */ -#ifdef DEBUG -#if ABORT_ON_ASSERT_FAILURE -#undef assert -#define assert(x) if (!(x)) ABORT -#else /* ABORT_ON_ASSERT_FAILURE */ -#include -#endif /* ABORT_ON_ASSERT_FAILURE */ -#else /* DEBUG */ -#ifndef assert -#define assert(x) -#endif -#define DEBUG 0 -#endif /* DEBUG */ -#ifndef LACKS_STRING_H -#include /* for memset etc */ -#endif /* LACKS_STRING_H */ -#if USE_BUILTIN_FFS -#ifndef LACKS_STRINGS_H -#include /* for ffs */ -#endif /* LACKS_STRINGS_H */ -#endif /* USE_BUILTIN_FFS */ -#if HAVE_MMAP -#ifndef LACKS_SYS_MMAN_H -/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ -#if (defined(linux) && !defined(__USE_GNU)) -#define __USE_GNU 1 -#include /* for mmap */ -#undef __USE_GNU -#else -#include /* for mmap */ -#endif /* linux */ -#endif /* LACKS_SYS_MMAN_H */ -#ifndef LACKS_FCNTL_H -#include -#endif /* LACKS_FCNTL_H */ -#endif /* HAVE_MMAP */ -#ifndef LACKS_UNISTD_H -#include /* for sbrk, sysconf */ -#else /* LACKS_UNISTD_H */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(_WIN32) -extern void* sbrk(ptrdiff_t); -#endif /* FreeBSD etc */ -#endif /* LACKS_UNISTD_H */ - -/* Declarations for locking */ -#if USE_LOCKS -#ifndef WIN32 -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CRYDLMALLOC_C_SECTION_2 -#include AZ_RESTRICTED_FILE(CryDLMalloc_c) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -#include -#endif -#if defined (__SVR4) && defined (__sun) /* solaris */ -#include -#endif /* solaris */ -#else -#ifndef _M_AMD64 -/* These are already defined on AMD64 builds */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -LONG __cdecl _InterlockedCompareExchange(LONG volatile* Dest, LONG Exchange, LONG Comp); -LONG __cdecl _InterlockedExchange(LONG volatile* Target, LONG Value); -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _M_AMD64 */ -#pragma intrinsic (_InterlockedCompareExchange) -#pragma intrinsic (_InterlockedExchange) -#define interlockedcompareexchange _InterlockedCompareExchange -#define interlockedexchange _InterlockedExchange -#endif /* Win32 */ -#endif /* USE_LOCKS */ - -/* Declarations for bit scanning on win32 */ -#if defined(_MSC_VER) && _MSC_VER >= 1300 -#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -unsigned char _BitScanForward(unsigned long* index, unsigned long mask); -unsigned char _BitScanReverse(unsigned long* index, unsigned long mask); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define BitScanForward _BitScanForward -#define BitScanReverse _BitScanReverse -#pragma intrinsic(_BitScanForward) -#pragma intrinsic(_BitScanReverse) -#endif /* BitScanForward */ -#endif /* defined(_MSC_VER) */ - -#ifndef WIN32 -#ifndef malloc_getpagesize -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -# ifndef _SC_PAGE_SIZE -# define _SC_PAGE_SIZE _SC_PAGESIZE -# endif -# endif -# ifdef _SC_PAGE_SIZE -# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -# else -# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) -extern size_t getpagesize(); -# define malloc_getpagesize getpagesize() -# else -# ifdef WIN32 /* use supplied emulation of getpagesize */ -# define malloc_getpagesize getpagesize() -# else -# ifndef LACKS_SYS_PARAM_H -# include -# endif -# ifdef EXEC_PAGESIZE -# define malloc_getpagesize EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define malloc_getpagesize NBPG -# else -# define malloc_getpagesize (NBPG * CLSIZE) -# endif -# else -# ifdef NBPC -# define malloc_getpagesize NBPC -# else -# ifdef PAGESIZE -# define malloc_getpagesize PAGESIZE -# else /* just guess */ -# define malloc_getpagesize ((size_t)4096U) -# endif -# endif -# endif -# endif -# endif -# endif -# endif -#endif -#endif - - - -/* ------------------- size_t and alignment properties -------------------- */ - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some platforms */ -#define SIZE_T_ZERO ((size_t)0) -#define SIZE_T_ONE ((size_t)1) -#define SIZE_T_TWO ((size_t)2) -#define SIZE_T_FOUR ((size_t)4) -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE << 1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE << 2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES + TWO_SIZE_T_SIZES) -#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* True if address a has acceptable alignment */ -#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A) \ - ((((size_t)(A) &CHUNK_ALIGN_MASK) == 0) ? 0 : \ - ((MALLOC_ALIGNMENT - ((size_t)(A) &CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) - -/* -------------------------- MMAP preliminaries ------------------------- */ - -/* - If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and - checks to fail so compiler optimizer can delete code rather than - using so many "#if"s. -*/ - - -/* MORECORE and MMAP must return MFAIL on failure */ -#define MFAIL ((void*)(MAX_SIZE_T)) -#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ - -#if HAVE_MMAP - -#if !TRAIT_HAS_WIN32_MMAP -#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) -#define MMAP_PROT (PROT_READ | PROT_WRITE) -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANON */ -#ifdef MAP_ANONYMOUS -#define MMAP_FLAGS (MAP_PRIVATE | MAP_ANONYMOUS) -#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) -#else /* MAP_ANONYMOUS */ -/* - Nearly all versions of mmap support MAP_ANONYMOUS, so the following - is unlikely to be needed, but is supplied just in case. -*/ -#define MMAP_FLAGS (MAP_PRIVATE) -static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ -#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ - (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) -#endif /* MAP_ANONYMOUS */ - -#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) - -#else /* TRAIT_HAS_WIN32_MMAP */ - -/* Win32 MMAP via VirtualAlloc */ -static FORCEINLINE void* win32mmap(size_t size) -{ - void* ptr = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; -} - -/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static FORCEINLINE void* win32direct_mmap(size_t size) -{ - void* ptr = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, - PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; -} - -/* This function supports releasing coalesed segments */ -static FORCEINLINE int win32munmap(void* ptr, size_t size) -{ - MEMORY_BASIC_INFORMATION minfo; - char* cptr = (char*)ptr; - while (size) - { - if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) - { - return -1; - } - if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || - minfo.State != MEM_COMMIT || minfo.RegionSize > size) - { - return -1; - } - if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) - { - return -1; - } - cptr += minfo.RegionSize; - size -= minfo.RegionSize; - } - return 0; -} - -#define MMAP_DEFAULT(s) win32mmap(s) -#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) -#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) -#endif /* TRAIT_HAS_WIN32_MMAP */ -#endif /* HAVE_MMAP */ - -#if HAVE_MREMAP -#ifndef WIN32 -#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) -#endif /* WIN32 */ -#endif /* HAVE_MREMAP */ - - -/** - * Define CALL_MORECORE - */ -#if HAVE_MORECORE - #ifdef MORECORE - #define CALL_MORECORE(S) MORECORE(S) - #else /* MORECORE */ - #define CALL_MORECORE(S) MORECORE_DEFAULT(S) - #endif /* MORECORE */ -#else /* HAVE_MORECORE */ - #define CALL_MORECORE(S) MFAIL -#endif /* HAVE_MORECORE */ - -/** - * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP - */ -#if HAVE_MMAP - #define USE_MMAP_BIT (SIZE_T_ONE) - - #ifdef MMAP - #define CALL_MMAP(s) MMAP(s) - #else /* MMAP */ - #define CALL_MMAP(s) MMAP_DEFAULT(s) - #endif /* MMAP */ - #ifdef MUNMAP - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) - #else /* MUNMAP */ - #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) - #endif /* MUNMAP */ - #ifdef DIRECT_MMAP - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #else /* DIRECT_MMAP */ - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) - #endif /* DIRECT_MMAP */ -#else /* HAVE_MMAP */ - #define USE_MMAP_BIT (SIZE_T_ZERO) - - #define MMAP(s) MFAIL - #define MUNMAP(a, s) (-1) - #define DIRECT_MMAP(s) MFAIL - #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) - #define CALL_MMAP(s) MMAP(s) - #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) -#endif /* HAVE_MMAP */ - -/** - * Define CALL_MREMAP - */ -#if HAVE_MMAP && HAVE_MREMAP - #ifdef MREMAP - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) - #else /* MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) - #endif /* MREMAP */ -#else /* HAVE_MMAP && HAVE_MREMAP */ - #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL -#endif /* HAVE_MMAP && HAVE_MREMAP */ - -/* mstate bit set if continguous morecore disabled or failed */ -#define USE_NONCONTIGUOUS_BIT (4U) - -/* segment bit set in create_mspace_with_base */ -#define EXTERN_BIT (8U) - - -/* --------------------------- Lock preliminaries ------------------------ */ - -/* - When locks are defined, there is one global lock, plus - one per-mspace lock. - - The global lock_ensures that mparams.magic and other unique - mparams values are initialized only once. It also protects - sequences of calls to MORECORE. In many cases sys_alloc requires - two calls, that should not be interleaved with calls by other - threads. This does not protect against direct calls to MORECORE - by other threads not using this lock, so there is still code to - cope the best we can on interference. - - Per-mspace locks surround calls to malloc, free, etc. To enable use - in layered extensions, per-mspace locks are reentrant. - - Because lock-protected regions generally have bounded times, it is - OK to use the supplied simple spinlocks in the custom versions for - x86. Spinlocks are likely to improve performance for lightly - contended applications, but worsen performance under heavy - contention. - - If USE_LOCKS is > 1, the definitions of lock routines here are - bypassed, in which case you will need to define the type MLOCK_T, - and at least INITIAL_LOCK, ACQUIRE_LOCK, RELEASE_LOCK and possibly - TRY_LOCK (which is not used in this malloc, but commonly needed in - extensions.) You must also declare a - static MLOCK_T malloc_global_mutex = { initialization values };. - -*/ - -#if USE_LOCKS == 1 - -#if USE_SPIN_LOCKS && SPIN_LOCKS_AVAILABLE -#ifndef WIN32 - -/* Custom pthread-style spin locks on x86 and x64 for gcc */ -struct pthread_mlock_t -{ - volatile unsigned int l; - unsigned int c; - pthread_t threadid; -}; -#define MLOCK_T struct pthread_mlock_t -#define CURRENT_THREAD pthread_self() -#define INITIAL_LOCK(sl) ((sl)->threadid = 0, (sl)->l = (sl)->c = 0, 0) -#define ACQUIRE_LOCK(sl) pthread_acquire_lock(sl) -#define RELEASE_LOCK(sl) pthread_release_lock(sl) -#define TRY_LOCK(sl) pthread_try_lock(sl) -#define SPINS_PER_YIELD 63 - -static MLOCK_T malloc_global_mutex = { 0, 0, 0}; - -static FORCEINLINE int pthread_acquire_lock (MLOCK_T* sl) -{ - int spins = 0; - volatile unsigned int* lp = &sl->l; - for (;; ) - { - if (*lp != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 0; - } - } - else - { - /* place args to cmpxchgl in locals to evade oddities in some gccs */ - int cmp = 0; - int val = 1; - int ret; - __asm__ __volatile__ ("lock; cmpxchgl %1, %2" - : "=a" (ret) - : "r" (val), "m" (*(lp)), "0" (cmp) - : "memory", "cc"); - if (!ret) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 0; - } - } - if ((++spins & SPINS_PER_YIELD) == 0) - { -#if defined (__SVR4) && defined (__sun) /* solaris */ - thr_yield(); -#else -#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) - sched_yield(); -#else /* no-op yield on unknown systems */ - ; -#endif /* __linux__ || __FreeBSD__ || __APPLE__ */ -#endif /* solaris */ - } - } -} - -static FORCEINLINE void pthread_release_lock (MLOCK_T* sl) -{ - volatile unsigned int* lp = &sl->l; - assert(*lp != 0); - assert(sl->threadid == CURRENT_THREAD); - if (--sl->c == 0) - { - sl->threadid = 0; - int prev = 0; - int ret; - __asm__ __volatile__ ("lock; xchgl %0, %1" - : "=r" (ret) - : "m" (*(lp)), "0" (prev) - : "memory"); - } -} - -static FORCEINLINE int pthread_try_lock (MLOCK_T* sl) -{ - volatile unsigned int* lp = &sl->l; - if (*lp != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 1; - } - } - else - { - int cmp = 0; - int val = 1; - int ret; - __asm__ __volatile__ ("lock; cmpxchgl %1, %2" - : "=a" (ret) - : "r" (val), "m" (*(lp)), "0" (cmp) - : "memory", "cc"); - if (!ret) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 1; - } - } - return 0; -} - - -#else /* WIN32 */ -/* Custom win32-style spin locks on x86 and x64 for MSC */ -struct win32_mlock_t -{ - volatile long l; - unsigned int c; - long threadid; -}; - -#define MLOCK_T struct win32_mlock_t -#define CURRENT_THREAD GetCurrentThreadId() -#define INITIAL_LOCK(sl) ((sl)->threadid = 0, (sl)->l = (sl)->c = 0, 0) -#define ACQUIRE_LOCK(sl) win32_acquire_lock(sl) -#define RELEASE_LOCK(sl) win32_release_lock(sl) -#define TRY_LOCK(sl) win32_try_lock(sl) -#define SPINS_PER_YIELD 63 - -static MLOCK_T malloc_global_mutex = { 0, 0, 0}; - -static FORCEINLINE int win32_acquire_lock (MLOCK_T* sl) -{ - int spins = 0; - for (;; ) - { - if (sl->l != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 0; - } - } - else - { - if (!interlockedexchange(&sl->l, 1)) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 0; - } - } - if ((++spins & SPINS_PER_YIELD) == 0) - { - SleepEx(0, FALSE); - } - } -} - -static FORCEINLINE void win32_release_lock (MLOCK_T* sl) -{ - assert(sl->threadid == CURRENT_THREAD); - assert(sl->l != 0); - if (--sl->c == 0) - { - sl->threadid = 0; - interlockedexchange (&sl->l, 0); - } -} - -static FORCEINLINE int win32_try_lock (MLOCK_T* sl) -{ - if (sl->l != 0) - { - if (sl->threadid == CURRENT_THREAD) - { - ++sl->c; - return 1; - } - } - else - { - if (!interlockedexchange(&sl->l, 1)) - { - assert(!sl->threadid); - sl->threadid = CURRENT_THREAD; - sl->c = 1; - return 1; - } - } - return 0; -} - -#endif /* WIN32 */ -#else /* USE_SPIN_LOCKS */ - -#ifndef WIN32 -/* pthreads-based locks */ - -#define MLOCK_T pthread_mutex_t -#define CURRENT_THREAD pthread_self() -#define INITIAL_LOCK(sl) pthread_init_lock(sl) -#define ACQUIRE_LOCK(sl) pthread_mutex_lock(sl) -#define RELEASE_LOCK(sl) pthread_mutex_unlock(sl) -#define TRY_LOCK(sl) (!pthread_mutex_trylock(sl)) - -static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; - -/* Cope with old-style linux recursive lock initialization by adding */ -/* skipped internal declaration from pthread.h */ -#ifdef linux -#ifndef PTHREAD_MUTEX_RECURSIVE -extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t * __attr, - int __kind)); -#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP -#define pthread_mutexattr_settype(x, y) pthread_mutexattr_setkind_np(x, y) -#endif -#endif - -static int pthread_init_lock (MLOCK_T* sl) -{ - pthread_mutexattr_t attr; - if (pthread_mutexattr_init(&attr)) - { - return 1; - } - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) - { - return 1; - } - if (pthread_mutex_init(sl, &attr)) - { - return 1; - } - if (pthread_mutexattr_destroy(&attr)) - { - return 1; - } - return 0; -} - -#else /* WIN32 */ -/* Win32 critical sections */ -#define MLOCK_T CRITICAL_SECTION -#define CURRENT_THREAD GetCurrentThreadId() -#define INITIAL_LOCK(s) (!InitializeCriticalSectionAndSpinCount((s), 0x80000000 | 4000)) -#define ACQUIRE_LOCK(s) (EnterCriticalSection(sl), 0) -#define RELEASE_LOCK(s) LeaveCriticalSection(sl) -#define TRY_LOCK(s) TryEnterCriticalSection(sl) -#define NEED_GLOBAL_LOCK_INIT - -static MLOCK_T malloc_global_mutex; -static volatile long malloc_global_mutex_status; - -/* Use spin loop to initialize global lock */ -static void init_malloc_global_mutex() -{ - for (;; ) - { - long stat = malloc_global_mutex_status; - if (stat > 0) - { - return; - } - /* transition to < 0 while initializing, then to > 0) */ - if (stat == 0 && - interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) - { - InitializeCriticalSection(&malloc_global_mutex); - interlockedexchange(&malloc_global_mutex_status, 1); - return; - } - SleepEx(0, FALSE); - } -} - -#endif /* WIN32 */ -#endif /* USE_SPIN_LOCKS */ -#endif /* USE_LOCKS == 1 */ - -/* ----------------------- User-defined locks ------------------------ */ - -#if USE_LOCKS > 1 -/* Define your own lock implementation here */ -/* #define INITIAL_LOCK(sl) ... */ -/* #define ACQUIRE_LOCK(sl) ... */ -/* #define RELEASE_LOCK(sl) ... */ -/* #define TRY_LOCK(sl) ... */ -/* static MLOCK_T malloc_global_mutex = ... */ -#endif /* USE_LOCKS > 1 */ - -/* ----------------------- Lock-based state ------------------------ */ - -#if USE_LOCKS -#define USE_LOCK_BIT (2U) -#else /* USE_LOCKS */ -#define USE_LOCK_BIT (0U) -#define INITIAL_LOCK(l) -#endif /* USE_LOCKS */ - -#if USE_LOCKS -#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK -#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); -#endif -#ifndef RELEASE_MALLOC_GLOBAL_LOCK -#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); -#endif -#else /* USE_LOCKS */ -#define ACQUIRE_MALLOC_GLOBAL_LOCK() -#define RELEASE_MALLOC_GLOBAL_LOCK() -#endif /* USE_LOCKS */ - - -/* ----------------------- Chunk representations ------------------------ */ - -/* - (The following includes lightly edited explanations by Colin Plumb.) - - The malloc_chunk declaration below is misleading (but accurate and - necessary). It declares a "view" into memory allowing access to - necessary fields at known offsets from a given base. - - Chunks of memory are maintained using a `boundary tag' method as - originally described by Knuth. (See the paper by Paul Wilson - ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such - techniques.) Sizes of free chunks are stored both in the front of - each chunk and at the end. This makes consolidating fragmented - chunks into bigger chunks fast. The head fields also hold bits - representing whether chunks are free or in use. - - Here are some pictures to make it clearer. They are "exploded" to - show that the state of a chunk can be thought of as extending from - the high 31 bits of the head field of its header through the - prev_foot and PINUSE_BIT bit of the following chunk header. - - A chunk that's in use looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk (if P = 0) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 1| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +- -+ - | | - +- -+ - | : - +- size - sizeof(size_t) available payload bytes -+ - : | - chunk-> +- -+ - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| - | Size of next chunk (may or may not be in use) | +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - And if it's free, it looks like this: - - chunk-> +- -+ - | User payload (must be in use, or we would have merged!) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 0| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Next pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Prev pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- size - sizeof(struct chunk) unused bytes -+ - : | - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| - | Size of next chunk (must be in use, or we would have merged)| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- User payload -+ - : | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0| - +-+ - Note that since we always merge adjacent free chunks, the chunks - adjacent to a free chunk must be in use. - - Given a pointer to a chunk (which can be derived trivially from the - payload pointer) we can, in O(1) time, find out whether the adjacent - chunks are free, and if so, unlink them from the lists that they - are on and merge them with the current chunk. - - Chunks always begin on even word boundaries, so the mem portion - (which is returned to the user) is also on an even word boundary, and - thus at least double-word aligned. - - The P (PINUSE_BIT) bit, stored in the unused low-order bit of the - chunk size (which is always a multiple of two words), is an in-use - bit for the *previous* chunk. If that bit is *clear*, then the - word before the current chunk size contains the previous chunk - size, and can be used to find the front of the previous chunk. - The very first chunk allocated always has this bit set, preventing - access to non-existent (or non-owned) memory. If pinuse is set for - any given chunk, then you CANNOT determine the size of the - previous chunk, and might even get a memory addressing fault when - trying to do so. - - The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of - the chunk size redundantly records whether the current chunk is - inuse (unless the chunk is mmapped). This redundancy enables usage - checks within free and realloc, and reduces indirection when freeing - and consolidating chunks. - - Each freshly allocated chunk must have both cinuse and pinuse set. - That is, each allocated chunk borders either a previously allocated - and still in-use chunk, or the base of its memory arena. This is - ensured by making all allocations from the the `lowest' part of any - found chunk. Further, no free chunk physically borders another one, - so each free chunk is known to be preceded and followed by either - inuse chunks or the ends of memory. - - Note that the `foot' of the current chunk is actually represented - as the prev_foot of the NEXT chunk. This makes it easier to - deal with alignments etc but can be very confusing when trying - to extend or adapt this code. - - The exceptions to all this are - - 1. The special chunk `top' is the top-most available chunk (i.e., - the one bordering the end of available memory). It is treated - specially. Top is never included in any bin, is used only if - no other chunk is available, and is released back to the - system if it is very large (see M_TRIM_THRESHOLD). In effect, - the top chunk is treated as larger (and thus less well - fitting) than any other available chunk. The top chunk - doesn't update its trailing size field since there is no next - contiguous chunk that would have to index off it. However, - space is still allocated for it (TOP_FOOT_SIZE) to enable - separation or merging when space is extended. - - 3. Chunks allocated via mmap, have both cinuse and pinuse bits - cleared in their head fields. Because they are allocated - one-by-one, each must carry its own prev_foot field, which is - also used to hold the offset this chunk has within its mmapped - region, which is needed to preserve alignment. Each mmapped - chunk is trailed by the first two fields of a fake next-chunk - for sake of usage checks. - -*/ - -struct malloc_chunk -{ - size_t prev_foot;/* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk* fd; /* double links -- used only if free. */ - struct malloc_chunk* bk; -}; - -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk* mchunkptr; -typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ - -/* ------------------- Chunks sizes and alignments ----------------------- */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#if FOOTERS -#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -#else /* FOOTERS */ -#define CHUNK_OVERHEAD (SIZE_T_SIZE) -#endif /* FOOTERS */ - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE \ - ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* Bounds on request (not chunk) sizes. */ -#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) -#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* pad request, checking for minimum (but not maximum) */ -#define request2size(req) \ - (((req) < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(req)) - - -/* ------------------ Operations on head and foot fields ----------------- */ - -/* - The head field of a chunk is or'ed with PINUSE_BIT when previous - adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in - use, unless mmapped, in which case both bits are cleared. - - FLAG4_BIT is not used by this malloc, but might be useful in extensions. -*/ - -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define FLAG4_BIT (SIZE_T_FOUR) -#define INUSE_BITS (PINUSE_BIT | CINUSE_BIT) -#define FLAG_BITS (PINUSE_BIT | CINUSE_BIT | FLAG4_BIT) - -/* Head value for fenceposts */ -#define FENCEPOST_HEAD (INUSE_BITS | SIZE_T_SIZE) - -/* extraction of fields from head words */ -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) -#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) - -#define chunksize(p) ((p)->head & ~(FLAG_BITS)) - -#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) - -/* Treat space at ptr +/- offset as a chunk */ -#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) -#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) - -/* Ptr to next or previous physical malloc_chunk. */ -#define next_chunk(p) ((mchunkptr)(((char*)(p)) + ((p)->head & ~FLAG_BITS))) -#define prev_chunk(p) ((mchunkptr)(((char*)(p)) - ((p)->prev_foot))) - -/* extract next chunk's pinuse bit */ -#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) - -/* Get/set size at footer */ -#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) -#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) - -/* Set size, pinuse bit, and foot */ -#define set_size_and_pinuse_of_free_chunk(p, s) \ - ((p)->head = (s | PINUSE_BIT), set_foot(p, s)) - -/* Set size, pinuse bit, foot, and clear next pinuse */ -#define set_free_with_pinuse(p, s, n) \ - (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p) \ - (is_mmapped(p) ? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -/* Return true if malloced space is not necessarily cleared */ -#if MMAP_CLEARS -#define calloc_must_clear(p) (!is_mmapped(p)) -#else /* MMAP_CLEARS */ -#define calloc_must_clear(p) (1) -#endif /* MMAP_CLEARS */ - -/* ---------------------- Overlaid data structures ----------------------- */ - -/* - When chunks are not in use, they are treated as nodes of either - lists or trees. - - "Small" chunks are stored in circular doubly-linked lists, and look - like this: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space (may be 0 bytes long) . - . . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Larger chunks are kept in a form of bitwise digital trees (aka - tries) keyed on chunksizes. Because malloc_tree_chunks are only for - free chunks greater than 256 bytes, their size doesn't impose any - constraints on user chunk sizes. Each node looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to left child (child[0]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to right child (child[1]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to parent | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | bin index of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Each tree holding treenodes is a tree of unique chunk sizes. Chunks - of the same size are arranged in a circularly-linked list, with only - the oldest chunk (the next to be used, in our FIFO ordering) - actually in the tree. (Tree members are distinguished by a non-null - parent pointer.) If a chunk with the same size an an existing node - is inserted, it is linked off the existing node using pointers that - work in the same way as fd/bk pointers of small chunks. - - Each tree contains a power of 2 sized range of chunk sizes (the - smallest is 0x100 <= x < 0x180), which is is divided in half at each - tree level, with the chunks in the smaller half of the range (0x100 - <= x < 0x140 for the top nose) in the left subtree and the larger - half (0x140 <= x < 0x180) in the right subtree. This is, of course, - done by inspecting individual bits. - - Using these rules, each node's left subtree contains all smaller - sizes than its right subtree. However, the node at the root of each - subtree has no particular ordering relationship to either. (The - dividing line between the subtree sizes is based on trie relation.) - If we remove the last chunk of a given size from the interior of the - tree, we need to replace it with a leaf node. The tree ordering - rules permit a node to be replaced by any leaf below it. - - The smallest chunk in a tree (a common operation in a best-fit - allocator) can be found by walking a path to the leftmost leaf in - the tree. Unlike a usual binary tree, where we follow left child - pointers until we reach a null, here we follow the right child - pointer any time the left one is null, until we reach a leaf with - both child pointers null. The smallest chunk in the tree will be - somewhere along that path. - - The worst case number of steps to add, find, or remove a node is - bounded by the number of bits differentiating chunks within - bins. Under current bin calculations, this ranges from 6 up to 21 - (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case - is of course much better. -*/ - -struct malloc_tree_chunk -{ - /* The first four fields must be compatible with malloc_chunk */ - size_t prev_foot; - size_t head; - struct malloc_tree_chunk* fd; - struct malloc_tree_chunk* bk; - - struct malloc_tree_chunk* child[2]; - struct malloc_tree_chunk* parent; - bindex_t index; -}; - -typedef struct malloc_tree_chunk tchunk; -typedef struct malloc_tree_chunk* tchunkptr; -typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ - -/* A little helper macro for trees */ -#define leftmost_child(t) ((t)->child[0] != 0 ? (t)->child[0] : (t)->child[1]) - -/* ----------------------------- Segments -------------------------------- */ - -/* - Each malloc space may include non-contiguous segments, held in a - list headed by an embedded malloc_segment record representing the - top-most space. Segments also include flags holding properties of - the space. Large chunks that are directly allocated by mmap are not - included in this list. They are instead independently created and - destroyed without otherwise keeping track of them. - - Segment management mainly comes into play for spaces allocated by - MMAP. Any call to MMAP might or might not return memory that is - adjacent to an existing segment. MORECORE normally contiguously - extends the current space, so this space is almost always adjacent, - which is simpler and faster to deal with. (This is why MORECORE is - used preferentially to MMAP when both are available -- see - sys_alloc.) When allocating using MMAP, we don't use any of the - hinting mechanisms (inconsistently) supported in various - implementations of unix mmap, or distinguish reserving from - committing memory. Instead, we just ask for space, and exploit - contiguity when we get it. It is probably possible to do - better than this on some systems, but no general scheme seems - to be significantly better. - - Management entails a simpler variant of the consolidation scheme - used for chunks to reduce fragmentation -- new adjacent memory is - normally prepended or appended to an existing segment. However, - there are limitations compared to chunk consolidation that mostly - reflect the fact that segment processing is relatively infrequent - (occurring only when getting memory from system) and that we - don't expect to have huge numbers of segments: - - * Segments are not indexed, so traversal requires linear scans. (It - would be possible to index these, but is not worth the extra - overhead and complexity for most programs on most platforms.) - * New segments are only appended to old ones when holding top-most - memory; if they cannot be prepended to others, they are held in - different segments. - - Except for the top-most segment of an mstate, each segment record - is kept at the tail of its segment. Segments are added by pushing - segment records onto the list headed by &mstate.seg for the - containing mstate. - - Segment flags control allocation/merge/deallocation policies: - * If EXTERN_BIT set, then we did not allocate this segment, - and so should not try to deallocate or merge with others. - (This currently holds only for the initial segment passed - into create_mspace_with_base.) - * If USE_MMAP_BIT set, the segment may be merged with - other surrounding mmapped segments and trimmed/de-allocated - using munmap. - * If neither bit is set, then the segment was obtained using - MORECORE so can be merged with surrounding MORECORE'd segments - and deallocated/trimmed using MORECORE with negative arguments. -*/ - -struct malloc_segment -{ - char* base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment* next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) -#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) - -typedef struct malloc_segment msegment; -typedef struct malloc_segment* msegmentptr; - -/* ---------------------------- malloc_state ----------------------------- */ - -/* - A malloc_state holds all of the bookkeeping for a space. - The main fields are: - - Top - The topmost chunk of the currently active segment. Its size is - cached in topsize. The actual size of topmost space is - topsize+TOP_FOOT_SIZE, which includes space reserved for adding - fenceposts and segment records if necessary when getting more - space from the system. The size at which to autotrim top is - cached from mparams in trim_check, except that it is disabled if - an autotrim fails. - - Designated victim (dv) - This is the preferred chunk for servicing small requests that - don't have exact fits. It is normally the chunk split off most - recently to service another small request. Its size is cached in - dvsize. The link fields of this chunk are not maintained since it - is not kept in a bin. - - SmallBins - An array of bin headers for free chunks. These bins hold chunks - with sizes less than MIN_LARGE_SIZE bytes. Each bin contains - chunks of all the same size, spaced 8 bytes apart. To simplify - use in double-linked lists, each bin header acts as a malloc_chunk - pointing to the real first node, if it exists (else pointing to - itself). This avoids special-casing for headers. But to avoid - waste, we allocate only the fd/bk pointers of bins, and then use - repositioning tricks to treat these as the fields of a chunk. - - TreeBins - Treebins are pointers to the roots of trees holding a range of - sizes. There are 2 equally spaced treebins for each power of two - from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything - larger. - - Bin maps - There is one bit map for small bins ("smallmap") and one for - treebins ("treemap). Each bin sets its bit when non-empty, and - clears the bit when empty. Bit operations are then used to avoid - bin-by-bin searching -- nearly all "search" is done without ever - looking at bins that won't be selected. The bit maps - conservatively use 32 bits per map word, even if on 64bit system. - For a good description of some of the bit-based techniques used - here, see Henry S. Warren Jr's book "Hacker's Delight" (and - supplement at http://hackersdelight.org/). Many of these are - intended to reduce the branchiness of paths through malloc etc, as - well as to reduce the number of memory locations read or written. - - Segments - A list of segments headed by an embedded malloc_segment record - representing the initial space. - - Address check support - The least_addr field is the least address ever obtained from - MORECORE or MMAP. Attempted frees and reallocs of any address less - than this are trapped (unless INSECURE is defined). - - Magic tag - A cross-check field that should always hold same value as mparams.magic. - - Flags - Bits recording whether to use MMAP, locks, or contiguous MORECORE - - Statistics - Each space keeps track of current and maximum system memory - obtained via MORECORE or MMAP. - - Trim support - Fields holding the amount of unused topmost memory that should trigger - timming, and a counter to force periodic scanning to release unused - non-topmost segments. - - Locking - If USE_LOCKS is defined, the "mutex" lock is acquired and released - around every public call using this mspace. - - Extension support - A void* pointer and a size_t field that can be used to help implement - extensions to this malloc. -*/ - -/* Bin types, widths and sizes */ -#define NSMALLBINS (32U) -#define NTREEBINS (32U) -#define SMALLBIN_SHIFT (3U) -#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) -#define TREEBIN_SHIFT (8U) -#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) -#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) -#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) - -struct malloc_state -{ - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char* least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t release_checks; - size_t magic; - mchunkptr smallbins[(NSMALLBINS + 1) * 2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - flag_t mflags; -#if USE_LOCKS - MLOCK_T mutex; /* locate lock among fields that rarely change */ -#endif /* USE_LOCKS */ - msegment seg; - void* extp; /* Unused but available for extensions */ - size_t exts; - dlmmap_handler mmap; - dlmunmap_handler munmap; -}; - -typedef struct malloc_state* mstate; - -/* ------------- Global malloc_state and malloc_params ------------------- */ - -/* - malloc_params holds global properties, including those that can be - dynamically set using mallopt. There is a single instance, mparams, - initialized in init_mparams. Note that the non-zeroness of "magic" - also serves as an initialization flag. -*/ - -struct malloc_params -{ - volatile size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; -}; - -static struct malloc_params mparams; - -/* Ensure mparams initialized */ -#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) - -#if !ONLY_MSPACES - -/* The global malloc_state used for all non-"mspace" calls */ -static struct malloc_state _gm_; -#define gm (&_gm_) -#define is_global(M) ((M) == &_gm_) - -#endif /* !ONLY_MSPACES */ - -#define is_initialized(M) ((M)->top != 0) - -/* -------------------------- system alloc setup ------------------------- */ - -/* Operations on mflags */ - -#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) -#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) -#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) - -#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) -#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) -#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) - -#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) -#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) - -#define set_lock(M, L) \ - ((M)->mflags = (L) ? \ - ((M)->mflags | USE_LOCK_BIT) : \ - ((M)->mflags & ~USE_LOCK_BIT)) - -/* page-align a size */ -#define page_align(S) \ - (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) - -/* granularity-align a size */ -#define granularity_align(S) \ - (((S) + (mparams.granularity - SIZE_T_ONE)) \ - & ~(mparams.granularity - SIZE_T_ONE)) - - -/* For mmap, use granularity alignment on windows, else page-align */ -#ifdef WIN32 -#define mmap_align(S) granularity_align(S) -#else -#define mmap_align(S) page_align(S) -#endif - -/* For sys_alloc, enough padding to ensure can malloc request on success */ -#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) - -#define is_page_aligned(S) \ - (((size_t)(S) &(mparams.page_size - SIZE_T_ONE)) == 0) -#define is_granularity_aligned(S) \ - (((size_t)(S) &(mparams.granularity - SIZE_T_ONE)) == 0) - -/* True if segment S holds address A */ -#define segment_holds(S, A) \ - ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) - -/* Return segment holding given address */ -static msegmentptr segment_holding(mstate m, char* addr) -{ - msegmentptr sp = &m->seg; - for (;; ) - { - if (addr >= sp->base && addr < sp->base + sp->size) - { - return sp; - } - if ((sp = sp->next) == 0) - { - return 0; - } - } -} - -/* Return true if segment contains a segment link */ -static int has_segment_link(mstate m, msegmentptr ss) -{ - msegmentptr sp = &m->seg; - for (;; ) - { - if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) - { - return 1; - } - if ((sp = sp->next) == 0) - { - return 0; - } - } -} - -#ifndef MORECORE_CANNOT_TRIM -#define should_trim(M, s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ -#define should_trim(M, s) (0) -#endif /* MORECORE_CANNOT_TRIM */ - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE \ - (align_offset(chunk2mem(0)) + pad_request(sizeof(struct malloc_segment)) + MIN_CHUNK_SIZE) - - -/* ------------------------------- Hooks -------------------------------- */ - -/* - PREACTION should be defined to return 0 on success, and nonzero on - failure. If you are not using locking, you can redefine these to do - anything you like. -*/ - -#if USE_LOCKS - -#define PREACTION(M) ((use_lock(M)) ? ACQUIRE_LOCK(&(M)->mutex) : 0) -#define POSTACTION(M) { if (use_lock(M)) {RELEASE_LOCK(&(M)->mutex); } \ -} -#else /* USE_LOCKS */ - -#ifndef PREACTION -#define PREACTION(M) (0) -#endif /* PREACTION */ - -#ifndef POSTACTION -#define POSTACTION(M) -#endif /* POSTACTION */ - -#endif /* USE_LOCKS */ - -/* - CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. - USAGE_ERROR_ACTION is triggered on detected bad frees and - reallocs. The argument p is an address that might have triggered the - fault. It is ignored by the two predefined actions, but might be - useful in custom actions that try to help diagnose errors. -*/ - -#if PROCEED_ON_ERROR - -/* A count of the number of corruption errors causing resets */ -int malloc_corruption_error_count; - -/* default corruption action */ -static void reset_on_error(mstate m); - -#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) -#define USAGE_ERROR_ACTION(m, p) - -#else /* PROCEED_ON_ERROR */ - -#ifndef CORRUPTION_ERROR_ACTION -#define CORRUPTION_ERROR_ACTION(m) ABORT -#endif /* CORRUPTION_ERROR_ACTION */ - -#ifndef USAGE_ERROR_ACTION -#define USAGE_ERROR_ACTION(m, p) ABORT -#endif /* USAGE_ERROR_ACTION */ - -#endif /* PROCEED_ON_ERROR */ - -/* -------------------------- Debugging setup ---------------------------- */ - -#if !DEBUG - -#define check_free_chunk(M, P) -#define check_inuse_chunk(M, P) -#define check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) -#define check_malloc_state(M) -#define check_top_chunk(M, P) - -#else /* DEBUG */ -#define check_free_chunk(M, P) do_check_free_chunk(M, P) -#define check_inuse_chunk(M, P) do_check_inuse_chunk(M, P) -#define check_top_chunk(M, P) do_check_top_chunk(M, P) -#define check_malloced_chunk(M, P, N) do_check_malloced_chunk(M, P, N) -#define check_mmapped_chunk(M, P) do_check_mmapped_chunk(M, P) -#define check_malloc_state(M) do_check_malloc_state(M) - -static void do_check_any_chunk(mstate m, mchunkptr p); -static void do_check_top_chunk(mstate m, mchunkptr p); -static void do_check_mmapped_chunk(mstate m, mchunkptr p); -static void do_check_inuse_chunk(mstate m, mchunkptr p); -static void do_check_free_chunk(mstate m, mchunkptr p); -static void do_check_malloced_chunk(mstate m, void* mem, size_t s); -static void do_check_tree(mstate m, tchunkptr t); -static void do_check_treebin(mstate m, bindex_t i); -static void do_check_smallbin(mstate m, bindex_t i); -static void do_check_malloc_state(mstate m); -static int bin_find(mstate m, mchunkptr x); -static size_t traverse_and_check(mstate m); -#endif /* DEBUG */ - -/* ---------------------------- Indexing Bins ---------------------------- */ - -#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) -#define small_index(s) ((s) >> SMALLBIN_SHIFT) -#define small_index2size(i) ((i) << SMALLBIN_SHIFT) -#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) - -/* addressing by index. See above about smallbin repositioning */ -#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i) << 1]))) -#define treebin_at(M, i) (&((M)->treebins[i])) - -/* assign tree index for size S to variable I. Use x86 asm if possible */ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_tree_index(S, I) \ - { \ - unsigned int X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int K; \ - __asm__("bsrl\t%1, %0\n\t" : "=r" (K) : "g" (X)); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } - -#elif defined (__INTEL_COMPILER) -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int K = _bit_scan_reverse (X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } - -#elif TRAIT_HAS_BITSCANREVERSE -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int K; \ - _BitScanReverse((DWORD*) &K, X); \ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1))); \ - } \ - } - -#else /* GNUC */ -#define compute_tree_index(S, I) \ - { \ - size_t X = S >> TREEBIN_SHIFT; \ - if (X == 0) { \ - I = 0; } \ - else if (X > 0xFFFF) { \ - I = NTREEBINS - 1; } \ - else { \ - unsigned int Y = (unsigned int)X; \ - unsigned int N = ((Y - 0x100) >> 16) & 8; \ - unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4; \ - N += K; \ - N += K = (((Y <<= K) - 0x4000) >> 16) & 2; \ - K = 14 - N + ((Y <<= K) >> 15); \ - I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT - 1)) & 1)); \ - } \ - } -#endif /* GNUC */ - -/* Bit representing maximum resolved size in a treebin at i */ -#define bit_for_tree_index(i) \ - (i == NTREEBINS - 1) ? (SIZE_T_BITSIZE - 1) : (((i) >> 1) + TREEBIN_SHIFT - 2) - -/* Shift placing maximum resolved bit in a treebin at i as sign bit */ -#define leftshift_for_tree_index(i) \ - ((i == NTREEBINS - 1) ? 0 : \ - ((SIZE_T_BITSIZE - SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) - -/* The size of the smallest chunk held in bin with index i */ -#define minsize_for_tree_index(i) \ - ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ - (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) - - -/* ------------------------ Operations on bin maps ----------------------- */ - -/* bit corresponding to given index */ -#define idx2bit(i) ((binmap_t)(1) << (i)) - -/* Mark/Clear bits with given index */ -#define mark_smallmap(M, i) ((M)->smallmap |= idx2bit(i)) -#define clear_smallmap(M, i) ((M)->smallmap &= ~idx2bit(i)) -#define smallmap_is_marked(M, i) ((M)->smallmap & idx2bit(i)) - -#define mark_treemap(M, i) ((M)->treemap |= idx2bit(i)) -#define clear_treemap(M, i) ((M)->treemap &= ~idx2bit(i)) -#define treemap_is_marked(M, i) ((M)->treemap & idx2bit(i)) - -/* isolate the least set bit of a bitmap */ -#define least_bit(x) ((x) & - (x)) - -/* mask with all bits to left of least bit of x on */ -#define left_bits(x) ((x << 1) | -(x << 1)) - -/* mask with all bits to left of or equal to least bit of x on */ -#define same_or_left_bits(x) ((x) | -(x)) - -/* index corresponding to given bit. Use x86 asm if possible */ - -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - __asm__("bsfl\t%1, %0\n\t" : "=r" (J) : "g" (X)); \ - I = (bindex_t)J; \ - } - -#elif defined (__INTEL_COMPILER) -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - J = _bit_scan_forward (X); \ - I = (bindex_t)J; \ - } - -#elif TRAIT_HAS_BITSCANFORWARD -#define compute_bit2idx(X, I) \ - { \ - unsigned int J; \ - _BitScanForward((DWORD*) &J, X); \ - I = (bindex_t)J; \ - } - -#elif USE_BUILTIN_FFS -#define compute_bit2idx(X, I) I = ffs(X) - 1 - -#else -#define compute_bit2idx(X, I) \ - { \ - unsigned int Y = X - 1; \ - unsigned int K = Y >> (16 - 4) & 16; \ - unsigned int N = K; Y >>= K; \ - N += K = Y >> (8 - 3) & 8; Y >>= K; \ - N += K = Y >> (4 - 2) & 4; Y >>= K; \ - N += K = Y >> (2 - 1) & 2; Y >>= K; \ - N += K = Y >> (1 - 0) & 1; Y >>= K; \ - I = (bindex_t)(N + Y); \ - } -#endif /* GNUC */ - - -/* ----------------------- Runtime Check Support ------------------------- */ - -/* - For security, the main invariant is that malloc/free/etc never - writes to a static address other than malloc_state, unless static - malloc_state itself has been corrupted, which cannot occur via - malloc (because of these checks). In essence this means that we - believe all pointers, sizes, maps etc held in malloc_state, but - check all of those linked or offsetted from other embedded data - structures. These checks are interspersed with main code in a way - that tends to minimize their run-time cost. - - When FOOTERS is defined, in addition to range checking, we also - verify footer fields of inuse chunks, which can be used guarantee - that the mstate controlling malloc/free is intact. This is a - streamlined version of the approach described by William Robertson - et al in "Run-time Detection of Heap-based Overflows" LISA'03 - http://www.usenix.org/events/lisa03/tech/robertson.html The footer - of an inuse chunk holds the xor of its mstate and a random seed, - that is checked upon calls to free() and realloc(). This is - (probablistically) unguessable from outside the program, but can be - computed by any code successfully malloc'ing any chunk, so does not - itself provide protection against code that has already broken - security through some other means. Unlike Robertson et al, we - always dynamically check addresses of all offset chunks (previous, - next, etc). This turns out to be cheaper than relying on hashes. -*/ - -#if !INSECURE -/* Check if address a is at least as high as any from MORECORE or MMAP */ -#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) -/* Check if address of next chunk n is higher than base chunk p */ -#define ok_next(p, n) ((char*)(p) < (char*)(n)) -/* Check if p has inuse status */ -#define ok_inuse(p) is_inuse(p) -/* Check if p has its pinuse bit on */ -#define ok_pinuse(p) pinuse(p) - -#else /* !INSECURE */ -#define ok_address(M, a) (1) -#define ok_next(b, n) (1) -#define ok_inuse(p) (1) -#define ok_pinuse(p) (1) -#endif /* !INSECURE */ - -#if (FOOTERS && !INSECURE) -/* Check if (alleged) mstate m has expected magic field */ -#define ok_magic(M) ((M)->magic == mparams.magic) -#else /* (FOOTERS && !INSECURE) */ -#define ok_magic(M) (1) -#endif /* (FOOTERS && !INSECURE) */ - - -/* In gcc, use __builtin_expect to minimize impact of checks */ -#if !INSECURE -#if defined(__GNUC__) && __GNUC__ >= 3 -#define RTCHECK(e) __builtin_expect(e, 1) -#else /* GNUC */ -#define RTCHECK(e) (e) -#endif /* GNUC */ -#else /* !INSECURE */ -#define RTCHECK(e) (1) -#endif /* !INSECURE */ - -/* macros to set up inuse chunks with or without footers */ - -#if !FOOTERS - -#define mark_inuse_foot(M, p, s) - -/* Macros for setting head/foot of non-mmapped chunks */ - -/* Set cinuse bit and pinuse bit of next chunk */ -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set size, cinuse and pinuse bit of this chunk */ -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT)) - -#else /* FOOTERS */ - -/* Set foot of inuse chunk to be xor of mstate and seed */ -#define mark_inuse_foot(M, p, s) \ - (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) - -#define get_mstate_for(p) \ - ((mstate)(((mchunkptr)((char*)(p) + \ - (chunksize(p))))->prev_foot ^ mparams.magic)) - -#define set_inuse(M, p, s) \ - ((p)->head = (((p)->head & PINUSE_BIT) | s | CINUSE_BIT), \ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_inuse_and_pinuse(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#define set_size_and_pinuse_of_inuse_chunk(M, p, s) \ - ((p)->head = (s | PINUSE_BIT | CINUSE_BIT), \ - mark_inuse_foot(M, p, s)) - -#endif /* !FOOTERS */ - -/* ---------------------------- setting mparams -------------------------- */ - -/* Initialize mparams */ -int init_mparams(void) -{ -#ifdef NEED_GLOBAL_LOCK_INIT - if (malloc_global_mutex_status <= 0) - { - init_malloc_global_mutex(); - } -#endif - - ACQUIRE_MALLOC_GLOBAL_LOCK(); - if (mparams.magic == 0) - { - size_t magic; - size_t psize; - size_t gsize; - -#if TRAIT_HAS_GETSYSTEMINFO - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - psize = system_info.dwPageSize; - gsize = ((DEFAULT_GRANULARITY != 0) ? - DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); - } -#else - psize = malloc_getpagesize; - gsize = ((DEFAULT_GRANULARITY != 0) ? DEFAULT_GRANULARITY : psize); -#endif //#if TRAIT_HAS_GETSYSTEMINFO - - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if ((sizeof(size_t) != sizeof(char*)) || - (MAX_SIZE_T < MIN_CHUNK_SIZE) || - (sizeof(int) < 4) || - (MALLOC_ALIGNMENT < (size_t)8U) || - ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT - SIZE_T_ONE)) != 0) || - ((MCHUNK_SIZE & (MCHUNK_SIZE - SIZE_T_ONE)) != 0) || - ((gsize & (gsize - SIZE_T_ONE)) != 0) || - ((psize & (psize - SIZE_T_ONE)) != 0)) - { - ABORT; - } - - mparams.granularity = gsize; - mparams.page_size = psize; - mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; -#if MORECORE_CONTIGUOUS - mparams.default_mflags = USE_LOCK_BIT | USE_MMAP_BIT; -#else /* MORECORE_CONTIGUOUS */ - mparams.default_mflags = USE_LOCK_BIT | USE_MMAP_BIT | USE_NONCONTIGUOUS_BIT; -#endif /* MORECORE_CONTIGUOUS */ - -#if !ONLY_MSPACES - /* Set up lock for main malloc area */ - gm->mflags = mparams.default_mflags; - INITIAL_LOCK(&gm->mutex); -#endif - - { -#if USE_DEV_RANDOM - int fd; - unsigned char buf[sizeof(size_t)]; - /* Try to use /dev/urandom, else fall back on using time */ - if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && - read(fd, buf, sizeof(buf)) == sizeof(buf)) - { - magic = *((size_t*) buf); - close(fd); - } - else -#endif /* USE_DEV_RANDOM */ -#if TRAIT_USE_QUERYPERFORMANCECOUNTER - { - // GetTickCount not available on Metro style apps - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - magic = (size_t)(li.QuadPart ^ (size_t)0x55555555U); - } -#elif defined(WIN32) - magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); -#else - magic = (size_t)(time(0) ^ (size_t)0x55555555U); -#endif - magic |= (size_t)8U; /* ensure nonzero */ - magic &= ~(size_t)7U; /* improve chances of fault for bad values */ - mparams.magic = magic; - } - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - return 1; -} - -/* support for mallopt */ -static int change_mparam(int param_number, int value) -{ - size_t val; - ensure_initialization(); - val = (value == -1) ? MAX_SIZE_T : (size_t)value; - switch (param_number) - { - case M_TRIM_THRESHOLD: - mparams.trim_threshold = val; - return 1; - case M_GRANULARITY: - if (val >= mparams.page_size && ((val & (val - 1)) == 0)) - { - mparams.granularity = val; - return 1; - } - else - { - return 0; - } - case M_MMAP_THRESHOLD: - mparams.mmap_threshold = val; - return 1; - default: - return 0; - } -} - -#if DEBUG -/* ------------------------- Debugging Support --------------------------- */ - -/* Check properties of any chunk, whether free, inuse, mmapped etc */ -static void do_check_any_chunk(mstate m, mchunkptr p) -{ - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); -} - -/* Check properties of top chunk */ -static void do_check_top_chunk(mstate m, mchunkptr p) -{ - msegmentptr sp = segment_holding(m, (char*)p); - size_t sz = p->head & ~INUSE_BITS;/* third-lowest bit can be set! */ - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!pinuse(chunk_plus_offset(p, sz))); -} - -/* Check properties of (inuse) mmapped chunks */ -static void do_check_mmapped_chunk(mstate m, mchunkptr p) -{ - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (mparams.page_size - SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz + SIZE_T_SIZE)->head == 0); -} - -/* Check properties of inuse chunks */ -static void do_check_inuse_chunk(mstate m, mchunkptr p) -{ - do_check_any_chunk(m, p); - assert(is_inuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if (is_mmapped(p)) - { - do_check_mmapped_chunk(m, p); - } -} - -/* Check properties of free chunks */ -static void do_check_free_chunk(mstate m, mchunkptr p) -{ - size_t sz = chunksize(p); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!is_inuse(p)); - assert(!next_pinuse(p)); - assert (!is_mmapped(p)); - if (p != m->dv && p != m->top) - { - if (sz >= MIN_CHUNK_SIZE) - { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert (next == m->top || is_inuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } - else /* markers are always of size SIZE_T_SIZE */ - { - assert(sz == SIZE_T_SIZE); - } - } -} - -/* Check properties of malloced chunks at the point they are malloced */ -static void do_check_malloced_chunk(mstate m, void* mem, size_t s) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~INUSE_BITS; - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } -} - -/* Check a tree and its subtrees. */ -static void do_check_tree(mstate m, tchunkptr t) -{ - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS - 1) || (tsize < minsize_for_tree_index((idx + 1)))); - - do /* traverse through chain of same-sized nodes */ - { - do_check_any_chunk(m, ((mchunkptr)u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!is_inuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if (u->parent == 0) - { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } - else - { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert (u->parent->child[0] == u || - u->parent->child[1] == u || - *((tbinptr*)(u->parent)) == u); - if (u->child[0] != 0) - { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if (u->child[1] != 0) - { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if (u->child[0] != 0 && u->child[1] != 0) - { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while (u != t); - assert(head != 0); -} - -/* Check all the chunks in a treebin. */ -static void do_check_treebin(mstate m, bindex_t i) -{ - tbinptr* tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if (t == 0) - { - assert(empty); - } - if (!empty) - { - do_check_tree(m, t); - } -} - -/* Check all the chunks in a smallbin. */ -static void do_check_smallbin(mstate m, bindex_t i) -{ - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if (p == b) - { - assert(empty); - } - if (!empty) - { - for (; p != b; p = p->bk) - { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if (q->head != FENCEPOST_HEAD) - { - do_check_inuse_chunk(m, q); - } - } - } -} - -/* Find x in a bin. Used in other check functions. */ -static int bin_find(mstate m, mchunkptr x) -{ - size_t size = chunksize(x); - if (is_small(size)) - { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if (smallmap_is_marked(m, sidx)) - { - mchunkptr p = b; - do - { - if (p == x) - { - return 1; - } - } while ((p = p->fd) != b); - } - } - else - { - bindex_t tidx; - compute_tree_index(size, tidx); - if (treemap_is_marked(m, tidx)) - { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while (t != 0 && chunksize(t) != size) - { - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if (t != 0) - { - tchunkptr u = t; - do - { - if (u == (tchunkptr)x) - { - return 1; - } - } while ((u = u->fd) != t); - } - } - } - return 0; -} - -/* Traverse each chunk and check it; return total */ -static size_t traverse_and_check(mstate m) -{ - size_t sum = 0; - if (is_initialized(m)) - { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - sum += chunksize(q); - if (is_inuse(q)) - { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } - else - { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; - } - } - return sum; -} - -/* Check all properties of malloc_state. */ -static void do_check_malloc_state(mstate m) -{ - bindex_t i; - size_t total; - /* check bins */ - for (i = 0; i < NSMALLBINS; ++i) - { - do_check_smallbin(m, i); - } - for (i = 0; i < NTREEBINS; ++i) - { - do_check_treebin(m, i); - } - - if (m->dvsize != 0) /* check dv chunk */ - { - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } - - if (m->top != 0) /* check top chunk */ - { - do_check_top_chunk(m, m->top); - /*assert(m->topsize == chunksize(m->top)); redundant */ - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } - - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); -} -#endif /* DEBUG */ - -/* ----------------------------- statistics ------------------------------ */ - -#if !NO_MALLINFO -static struct mallinfo internal_mallinfo(mstate m) -{ - struct mallinfo nm = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - ensure_initialization(); - if (!PREACTION(m)) - { - check_malloc_state(m); - if (is_initialized(m)) - { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = m->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &m->seg; - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - size_t sz = chunksize(q); - sum += sz; - if (!is_inuse(q)) - { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = m->footprint - sum; - nm.usmblks = m->max_footprint; - nm.uordblks = m->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = m->topsize; - } - - POSTACTION(m); - } - return nm; -} -#endif /* !NO_MALLINFO */ - -static void internal_malloc_stats(mstate m) -{ - ensure_initialization(); - if (!PREACTION(m)) - { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) - { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - if (!is_inuse(q)) - { - used -= chunksize(q); - } - q = next_chunk(q); - } - s = s->next; - } - } - - fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); - fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); - fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); - - POSTACTION(m); - } -} - -static void internal_malloc_stats_ret(mstate m, size_t* sysOut, size_t* maxSysOut, size_t* usedOut) -{ - ensure_initialization(); - if (!PREACTION(m)) - { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) - { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) - { - if (!is_inuse(q)) - { - used -= chunksize(q); - } - q = next_chunk(q); - } - s = s->next; - } - } - - (*sysOut) = fp; - (*maxSysOut) = maxfp; - (*usedOut) = used; - - POSTACTION(m); - } -} - -/* ----------------------- Operations on smallbins ----------------------- */ - -/* - Various forms of linking and unlinking are defined as macros. Even - the ones for trees, which are very long but have very short typical - paths. This is ugly but reduces reliance on inlining support of - compilers. -*/ - -/* Link a free chunk into a smallbin */ -#define insert_small_chunk(M, P, S) { \ - bindex_t I = small_index(S); \ - mchunkptr B = smallbin_at(M, I); \ - mchunkptr F = B; \ - assert(S >= MIN_CHUNK_SIZE); \ - if (!smallmap_is_marked(M, I)) { \ - mark_smallmap(M, I); } \ - else if (RTCHECK(ok_address(M, B->fd))) { \ - F = B->fd; } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - B->fd = P; \ - F->bk = P; \ - P->fd = F; \ - P->bk = B; \ -} - -/* Unlink a chunk from a smallbin */ -#define unlink_small_chunk(M, P, S) { \ - mchunkptr F = P->fd; \ - mchunkptr B = P->bk; \ - bindex_t I = small_index(S); \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if (F == B) { \ - clear_smallmap(M, I); } \ - else if (RTCHECK((F == smallbin_at(M, I) || ok_address(M, F)) && \ - (B == smallbin_at(M, I) || ok_address(M, B)))) { \ - F->bk = B; \ - B->fd = F; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ -} - -/* Unlink the first chunk from a smallbin */ -#define unlink_first_small_chunk(M, B, P, I) { \ - mchunkptr F = P->fd; \ - assert(P != B); \ - assert(P != F); \ - assert(chunksize(P) == small_index2size(I)); \ - if (B == F) { \ - clear_smallmap(M, I); } \ - else if (RTCHECK(ok_address(M, F))) { \ - B->fd = F; \ - F->bk = B; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ -} - - - -/* Replace dv node, binning the old one */ -/* Used only when dvsize known to be small */ -#define replace_dv(M, P, S) { \ - size_t DVS = M->dvsize; \ - if (DVS != 0) { \ - mchunkptr DV = M->dv; \ - assert(is_small(DVS)); \ - insert_small_chunk(M, DV, DVS); \ - } \ - M->dvsize = S; \ - M->dv = P; \ -} - -/* ------------------------- Operations on trees ------------------------- */ - -/* Insert chunk into tree */ -#define insert_large_chunk(M, X, S) { \ - tbinptr* H; \ - bindex_t I; \ - compute_tree_index(S, I); \ - H = treebin_at(M, I); \ - X->index = I; \ - X->child[0] = X->child[1] = 0; \ - if (!treemap_is_marked(M, I)) { \ - mark_treemap(M, I); \ - * H = X; \ - X->parent = (tchunkptr)H; \ - X->fd = X->bk = X; \ - } \ - else { \ - tchunkptr T = * H; \ - size_t K = S << leftshift_for_tree_index(I); \ - for (;; ) { \ - if (chunksize(T) != S) { \ - tchunkptr* C = & (T->child[(K >> (SIZE_T_BITSIZE - SIZE_T_ONE))& 1]); \ - K <<= 1; \ - if (* C != 0) { \ - T = * C; } \ - else if (RTCHECK(ok_address(M, C))) { \ - * C = X; \ - X->parent = T; \ - X->fd = X->bk = X; \ - break; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } \ - else { \ - tchunkptr F = T->fd; \ - if (RTCHECK(ok_address(M, T) && ok_address(M, F))) { \ - T->fd = F->bk = X; \ - X->fd = F; \ - X->bk = T; \ - X->parent = 0; \ - break; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - break; \ - } \ - } \ - } \ - } \ -} - -/* - Unlink steps: - - 1. If x is a chained node, unlink it from its same-sized fd/bk links - and choose its bk node as its replacement. - 2. If x was the last node of its size, but not a leaf node, it must - be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent - of x. We could use any other leaf, but this is easy to locate and - tends to counteract removal of leftmosts elsewhere, and so keeps - paths shorter than minimally guaranteed. This doesn't loop much - because on average a node in a tree is near the bottom. - 3. If x is the base of a chain (i.e., has parent links) relink - x's parent and children to x's replacement (or null if none). -*/ - -#define unlink_large_chunk(M, X) { \ - tchunkptr XP = X->parent; \ - tchunkptr R; \ - if (X->bk != X) { \ - tchunkptr F = X->fd; \ - R = X->bk; \ - if (RTCHECK(ok_address(M, F))) { \ - F->bk = R; \ - R->fd = F; \ - } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - else { \ - tchunkptr* RP; \ - if (((R = *(RP = & (X->child[1]))) != 0) || \ - ((R = *(RP = & (X->child[0]))) != 0)) { \ - tchunkptr* CP; \ - while ((*(CP = & (R->child[1])) != 0) || \ - (*(CP = & (R->child[0])) != 0)) { \ - R = *(RP = CP); \ - } \ - if (RTCHECK(ok_address(M, RP))) { \ - * RP = 0; } \ - else { \ - CORRUPTION_ERROR_ACTION(M); \ - } \ - } \ - } \ - if (XP != 0) { \ - tbinptr* H = treebin_at(M, X->index); \ - if (X == * H) { \ - if ((* H = R) == 0) { \ - clear_treemap(M, X->index); } \ - } \ - else if (RTCHECK(ok_address(M, XP))) { \ - if (XP->child[0] == X) { \ - XP->child[0] = R; } \ - else{ \ - XP->child[1] = R; } \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - if (R != 0) { \ - if (RTCHECK(ok_address(M, R))) { \ - tchunkptr C0, C1; \ - R->parent = XP; \ - if ((C0 = X->child[0]) != 0) { \ - if (RTCHECK(ok_address(M, C0))) { \ - R->child[0] = C0; \ - C0->parent = R; \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - } \ - if ((C1 = X->child[1]) != 0) { \ - if (RTCHECK(ok_address(M, C1))) { \ - R->child[1] = C1; \ - C1->parent = R; \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - } \ - } \ - else{ \ - CORRUPTION_ERROR_ACTION(M); } \ - } \ - } \ -} - -/* Relays to large vs small bin operations */ - -#define insert_chunk(M, P, S) \ - if (is_small(S)) { insert_small_chunk(M, P, S) } \ - else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } - -#define unlink_chunk(M, P, S) \ - if (is_small(S)) { unlink_small_chunk(M, P, S) } \ - else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } - - -/* Relays to internal calls to malloc/free from realloc, memalign etc */ - -#if ONLY_MSPACES -#define internal_malloc(m, b) mspace_malloc(m, b) -#define internal_free(m, mem) mspace_free(m, mem); -#else /* ONLY_MSPACES */ -#if MSPACES -#define internal_malloc(m, b) \ - (m == gm) ? dlmalloc(b) : mspace_malloc(m, b) -#define internal_free(m, mem) \ - if (m == gm) { dlfree(mem); } else{ mspace_free(m, mem); } -#else /* MSPACES */ -#define internal_malloc(m, b) dlmalloc(b) -#define internal_free(m, mem) dlfree(mem) -#endif /* MSPACES */ -#endif /* ONLY_MSPACES */ - -/* ----------------------- Direct-mmapping chunks ----------------------- */ - -/* - Directly mmapped chunks are set up with an offset to the start of - the mmapped region stored in the prev_foot field of the chunk. This - allows reconstruction of the required argument to MUNMAP when freed, - and also allows adjustment of the returned chunk to meet alignment - requirements (especially in memalign). -*/ - -/* Malloc using mmap */ -static void* mmap_alloc(mstate m, size_t nb) -{ - size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if (mmsize > nb) /* Check for wrap around 0 */ - { - char* mm = (char*)((*m->mmap)(m->extp, mmsize)); - if (mm != CMFAIL) - { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr)(mm + offset); - p->prev_foot = offset; - p->head = psize; - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize + SIZE_T_SIZE)->head = 0; - - if (m->least_addr == 0 || mm < m->least_addr) - { - m->least_addr = mm; - } - if ((m->footprint += mmsize) > m->max_footprint) - { - m->max_footprint = m->footprint; - } - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } - } - return 0; -} - -/* Realloc using mmap */ -static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) -{ - size_t oldsize = chunksize(oldp); - if (is_small(nb)) /* Can't shrink mmap regions below small size */ - { - return 0; - } - /* Keep old chunk if big enough but not too big */ - if (oldsize >= nb + SIZE_T_SIZE && - (oldsize - nb) <= (mparams.granularity << 1)) - { - return oldp; - } - else - { - size_t offset = oldp->prev_foot; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - char* cp = (char*)CALL_MREMAP((char*)oldp - offset, - oldmmsize, newmmsize, 1); - if (cp != CMFAIL) - { - mchunkptr newp = (mchunkptr)(cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = psize; - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize + SIZE_T_SIZE)->head = 0; - - if (cp < m->least_addr) - { - m->least_addr = cp; - } - if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) - { - m->max_footprint = m->footprint; - } - check_mmapped_chunk(m, newp); - return newp; - } - } - return 0; -} - -/* -------------------------- mspace management -------------------------- */ - -/* Initialize top chunk and its size */ -static void init_top(mstate m, mchunkptr p, size_t psize) -{ - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr)((char*)p + offset); - psize -= offset; - - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = mparams.trim_threshold; /* reset on each update */ -} - -/* Initialize bins for a new mstate that is otherwise zeroed out */ -static void init_bins(mstate m) -{ - /* Establish circular links for smallbins */ - bindex_t i; - for (i = 0; i < NSMALLBINS; ++i) - { - sbinptr bin = smallbin_at(m, i); - bin->fd = bin->bk = bin; - } -} - -#if PROCEED_ON_ERROR - -/* default corruption action */ -static void reset_on_error(mstate m) -{ - int i; - ++malloc_corruption_error_count; - /* Reinitialize fields to forget about all memory */ - m->smallbins = m->treebins = 0; - m->dvsize = m->topsize = 0; - m->seg.base = 0; - m->seg.size = 0; - m->seg.next = 0; - m->top = m->dv = 0; - for (i = 0; i < NTREEBINS; ++i) - { - *treebin_at(m, i) = 0; - } - init_bins(m); -} -#endif /* PROCEED_ON_ERROR */ - -/* Allocate chunk and prepend remainder with chunk in successor base. */ -static void* prepend_alloc(mstate m, char* newbase, char* oldbase, - size_t nb) -{ - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char*)oldfirst - (char*)p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - - assert((char*)oldfirst > (char*)q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); - - /* consolidate remainder with first chunk of old base */ - if (oldfirst == m->top) - { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } - else if (oldfirst == m->dv) - { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } - else - { - if (!is_inuse(oldfirst)) - { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); - } - - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); -} - -/* Add a segment to hold a new noncontiguous region */ -static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) -{ - /* Determine locations and sizes of segment, fenceposts, old top */ - char* old_top = (char*)m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char* old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct malloc_segment)); - char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char* asp = rawsp + offset; - char* csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp; - mchunkptr sp = (mchunkptr)csp; - msegmentptr ss = (msegmentptr)(chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; - - /* reset top to new space */ - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; - - /* Insert trailing fenceposts */ - for (;; ) - { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if ((char*)(&(nextp->head)) < old_end) - { - p = nextp; - } - else - { - break; - } - } - assert(nfences >= 2); - - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if (csp != old_top) - { - mchunkptr q = (mchunkptr)old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } - - check_top_chunk(m, m->top); -} - -/* -------------------------- System allocation -------------------------- */ - -/* Get memory from system using MORECORE or MMAP */ -static void* sys_alloc(mstate m, size_t nb) -{ - char* tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; - - ensure_initialization(); - - /* Directly map large chunks, but only if already initialized */ - if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) - { - void* mem = mmap_alloc(m, nb); - if (mem != 0) - { - return mem; - } - } - - /* - Try getting memory in any of three ways (in most-preferred to - least-preferred order): - 1. A call to MORECORE that can normally contiguously extend memory. - (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or - or main space is mmapped or a previous contiguous call failed) - 2. A call to MMAP new space (disabled if not HAVE_MMAP). - Note that under the default settings, if MORECORE is unable to - fulfill a request, and HAVE_MMAP is true, then mmap is - used as a noncontiguous system allocator. This is a useful backup - strategy for systems with holes in address spaces -- in this case - sbrk cannot contiguously expand the heap, but mmap may be able to - find space. - 3. A call to MORECORE that cannot usually contiguously extend memory. - (disabled if not HAVE_MORECORE) - - In all cases, we need to request enough bytes from system to ensure - we can malloc nb bytes upon success, so pad with enough space for - top_foot, plus alignment-pad to make sure we don't lose bytes if - not on boundary, and round this up to a granularity unit. - */ - - if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) - { - char* br = CMFAIL; - msegmentptr ss = (m->top == 0) ? 0 : segment_holding(m, (char*)m->top); - size_t asize = 0; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - - if (ss == 0) /* First time through or recovery */ - { - char* base = (char*)CALL_MORECORE(0); - if (base != CMFAIL) - { - asize = granularity_align(nb + SYS_ALLOC_PADDING); - /* Adjust to end on a page boundary */ - if (!is_page_aligned(base)) - { - asize += (page_align((size_t)base) - (size_t)base); - } - /* Can't call MORECORE if size is negative when treated as signed */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == base) - { - tbase = base; - tsize = asize; - } - } - } - else - { - /* Subtract out existing available top space from MORECORE request. */ - asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); - /* Use mem here only if it did continuously extend old space */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == ss->base + ss->size) - { - tbase = br; - tsize = asize; - } - } - - if (tbase == CMFAIL) /* Cope with partial failure */ - { - if (br != CMFAIL) /* Try to use/extend the space we did get */ - { - if (asize < HALF_MAX_SIZE_T && - asize < nb + SYS_ALLOC_PADDING) - { - size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize); - if (esize < HALF_MAX_SIZE_T) - { - char* end = (char*)CALL_MORECORE(esize); - if (end != CMFAIL) - { - asize += esize; - } - else /* Can't use; try to release */ - { - (void) CALL_MORECORE(-asize); - br = CMFAIL; - } - } - } - } - if (br != CMFAIL) /* Use the space we did get */ - { - tbase = br; - tsize = asize; - } - else - { - disable_contiguous(m); /* Don't try contiguous path in the future */ - } - } - - RELEASE_MALLOC_GLOBAL_LOCK(); - } - - if (HAVE_MMAP && tbase == CMFAIL) /* Try MMAP */ - { - size_t rsize = granularity_align(nb + SYS_ALLOC_PADDING); - if (rsize > nb) /* Fail if wraps around zero */ - { - char* mp = (char*)((*m->mmap)(m->extp, rsize)); - if (mp != CMFAIL) - { - tbase = mp; - tsize = rsize; - mmap_flag = USE_MMAP_BIT; - } - } - } - - if (HAVE_MORECORE && tbase == CMFAIL) /* Try noncontiguous MORECORE */ - { - size_t asize = granularity_align(nb + SYS_ALLOC_PADDING); - if (asize < HALF_MAX_SIZE_T) - { - char* br = CMFAIL; - char* end = CMFAIL; - ACQUIRE_MALLOC_GLOBAL_LOCK(); - br = (char*)(CALL_MORECORE(asize)); - end = (char*)(CALL_MORECORE(0)); - RELEASE_MALLOC_GLOBAL_LOCK(); - if (br != CMFAIL && end != CMFAIL && br < end) - { - size_t ssize = end - br; - if (ssize > nb + TOP_FOOT_SIZE) - { - tbase = br; - tsize = ssize; - } - } - } - } - - if (tbase != CMFAIL) - { - if ((m->footprint += tsize) > m->max_footprint) - { - m->max_footprint = m->footprint; - } - - if (!is_initialized(m)) /* first-time initialization */ - { - if (m->least_addr == 0 || tbase < m->least_addr) - { - m->least_addr = tbase; - } - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - init_bins(m); -#if !ONLY_MSPACES - if (is_global(m)) - { - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - } - else -#endif - { - /* Offset top by embedded malloc_state */ - mchunkptr mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); - } - } - - else - { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - /* Only consider most recent segment if traversal suppressed */ - while (sp != 0 && tbase != sp->base + sp->size) - { - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - } - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag && - segment_holds(sp, m->top)) /* append */ - { - sp->size += tsize; - init_top(m, m->top, m->topsize + tsize); - } - else - { - if (tbase < m->least_addr) - { - m->least_addr = tbase; - } - sp = &m->seg; - while (sp != 0 && sp->base != tbase + tsize) - { - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - } - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & USE_MMAP_BIT) == mmap_flag) - { - char* oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return prepend_alloc(m, tbase, oldbase, nb); - } - else - { - add_segment(m, tbase, tsize, mmap_flag); - } - } - } - - if (nb < m->topsize) /* Allocate from new or extended top space */ - { - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); - } - } - - MALLOC_FAILURE_ACTION; - return 0; -} - -/* ----------------------- system deallocation -------------------------- */ - -/* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t release_unused_segments(mstate m) -{ - size_t released = 0; - int nsegs = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while (sp != 0) - { - char* base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - ++nsegs; - if (is_mmapped_segment(sp) && !is_extern_segment(sp)) - { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) - { - tchunkptr tp = (tchunkptr)p; - assert(segment_holds(sp, (char*)sp)); - if (p == m->dv) - { - m->dv = 0; - m->dvsize = 0; - } - else - { - unlink_large_chunk(m, tp); - } - if ((*m->munmap)(m->extp, base, size) == 0) - { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } - else /* back out if cannot unmap */ - { - insert_large_chunk(m, tp, psize); - } - } - } - if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ - { - break; - } - pred = sp; - sp = next; - } - /* Reset check counter */ - m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE) ? - nsegs : MAX_RELEASE_CHECK_RATE); - return released; -} - -static int sys_trim(mstate m, size_t pad) -{ - size_t released = 0; - ensure_initialization(); - if (pad < MAX_REQUEST && is_initialized(m)) - { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - - if (m->topsize > pad) - { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = mparams.granularity; - size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - - SIZE_T_ONE) * unit; - msegmentptr sp = segment_holding(m, (char*)m->top); - - if (!is_extern_segment(sp)) - { - if (is_mmapped_segment(sp)) - { - if (HAVE_MMAP && - sp->size >= extra && - 1 /*!has_segment_link(m, sp)*/) /* can't shrink if pinned */ - { - size_t newsize = sp->size - extra; - /* Prefer mremap, fall back to munmap */ - if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || - ((*m->munmap)(m->extp, sp->base + newsize, extra) == 0)) - { - released = extra; - } - } - } - else if (HAVE_MORECORE) - { - if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ - { - extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; - } - ACQUIRE_MALLOC_GLOBAL_LOCK(); - { - /* Make sure end of memory is where we last set it. */ - char* old_br = (char*)(CALL_MORECORE(0)); - if (old_br == sp->base + sp->size) - { - char* rel_br = (char*)(CALL_MORECORE(-extra)); - char* new_br = (char*)(CALL_MORECORE(0)); - if (rel_br != CMFAIL && new_br < old_br) - { - released = old_br - new_br; - } - } - } - RELEASE_MALLOC_GLOBAL_LOCK(); - } - } - - if (released != 0) - { - sp->size -= released; - m->footprint -= released; - init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); - } - } - - /* Unmap any unused mmapped segments */ - if (HAVE_MMAP) - { - released += release_unused_segments(m); - } - - /* On failure, disable autotrim to avoid repeated failed future calls */ - if (released == 0 && m->topsize > m->trim_check) - { - m->trim_check = MAX_SIZE_T; - } - } - - return (released != 0) ? 1 : 0; -} - - -/* ---------------------------- malloc support --------------------------- */ - -/* allocate a large request from the best fitting chunk in a treebin */ -static void* tmalloc_large(mstate m, size_t nb) -{ - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); - if ((t = *treebin_at(m, idx)) != 0) - { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for (;; ) - { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if (trem < rsize) - { - v = t; - if ((rsize = trem) == 0) - { - break; - } - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - if (rt != 0 && rt != t) - { - rst = rt; - } - if (t == 0) - { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } - } - if (t == 0 && v == 0) /* set t to root of next non-empty treebin */ - { - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if (leftbits != 0) - { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } - } - - while (t != 0) /* find smallest of tree or subtree */ - { - size_t trem = chunksize(t) - nb; - if (trem < rsize) - { - rsize = trem; - v = t; - } - t = leftmost_child(t); - } - - /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t)(m->dvsize - nb)) - { - if (RTCHECK(ok_address(m, v))) /* split */ - { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) - { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(m, v, (rsize + nb)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - } - return 0; -} - -/* allocate a small request from the best fitting chunk in a treebin */ -static void* tmalloc_small(mstate m, size_t nb) -{ - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; - - while ((t = leftmost_child(t)) != 0) - { - size_t trem = chunksize(t) - nb; - if (trem < rsize) - { - rsize = trem; - v = t; - } - } - - if (RTCHECK(ok_address(m, v))) - { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) - { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(m, v, (rsize + nb)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } - } - - CORRUPTION_ERROR_ACTION(m); -#if PROCEED_ON_ERROR - return 0; -#endif -} - -/* --------------------------- realloc support --------------------------- */ - -static void* internal_realloc(mstate m, void* oldmem, size_t bytes) -{ - if (bytes >= MAX_REQUEST) - { - MALLOC_FAILURE_ACTION; - return 0; - } - if (!PREACTION(m)) - { - mchunkptr oldp = mem2chunk(oldmem); - size_t oldsize = chunksize(oldp); - mchunkptr next = chunk_plus_offset(oldp, oldsize); - mchunkptr newp = 0; - void* extra = 0; - - /* Try to either shrink or extend into top. Else malloc-copy-free */ - - if (RTCHECK(ok_address(m, oldp) && ok_inuse(oldp) && - ok_next(oldp, next) && ok_pinuse(next))) - { - size_t nb = request2size(bytes); - if (is_mmapped(oldp)) - { - newp = mmap_resize(m, oldp, nb); - } - else if (oldsize >= nb) /* already big enough */ - { - size_t rsize = oldsize - nb; - newp = oldp; - if (rsize >= MIN_CHUNK_SIZE) - { - mchunkptr remainder = chunk_plus_offset(newp, nb); - set_inuse(m, newp, nb); - set_inuse_and_pinuse(m, remainder, rsize); - extra = chunk2mem(remainder); - } - } - else if (next == m->top && oldsize + m->topsize > nb) - { - /* Expand into top */ - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(oldp, nb); - set_inuse(m, oldp, nb); - newtop->head = newtopsize | PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = oldp; - } - } - else - { - USAGE_ERROR_ACTION(m, oldmem); - POSTACTION(m); -#if PROCEED_ON_ERROR - return 0; -#endif - } -#if DEBUG - if (newp != 0) - { - check_inuse_chunk(m, newp); /* Check requires lock */ - } -#endif - - POSTACTION(m); - - if (newp != 0) - { - if (extra != 0) - { - internal_free(m, extra); - } - return chunk2mem(newp); - } - else - { - void* newmem = internal_malloc(m, bytes); - if (newmem != 0) - { - size_t oc = oldsize - overhead_for(oldp); - memcpy(newmem, oldmem, (oc < bytes) ? oc : bytes); - internal_free(m, oldmem); - } - return newmem; - } - } - return 0; -} - -/* --------------------------- memalign support -------------------------- */ - -static void* internal_memalign(mstate m, size_t alignment, size_t bytes) -{ - if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ - { - return internal_malloc(m, bytes); - } - if (alignment < MIN_CHUNK_SIZE)/* must be at least a minimum chunk size */ - { - alignment = MIN_CHUNK_SIZE; - } - if ((alignment & (alignment - SIZE_T_ONE)) != 0)/* Ensure a power of 2 */ - { - size_t a = MALLOC_ALIGNMENT << 1; - while (a < alignment) - { - a <<= 1; - } - alignment = a; - } - - if (bytes >= MAX_REQUEST - alignment) - { - if (m != 0) /* Test isn't needed but avoids compiler warning */ - { - MALLOC_FAILURE_ACTION; - } - } - else - { - size_t nb = request2size(bytes); - size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - char* mem = (char*)internal_malloc(m, req); - if (mem != 0) - { - void* leader = 0; - void* trailer = 0; - mchunkptr p = mem2chunk(mem); - - if (PREACTION(m)) - { - return 0; - } - if ((((size_t)(mem)) % alignment) != 0) /* misaligned */ - { - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - char* br = (char*)mem2chunk((size_t)(((size_t)(mem + - alignment - - SIZE_T_ONE)) & - - alignment)); - char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE) ? - br : br + alignment; - mchunkptr newp = (mchunkptr)pos; - size_t leadsize = pos - (char*)(p); - size_t newsize = chunksize(p) - leadsize; - - if (is_mmapped(p)) /* For mmapped chunks, just adjust offset */ - { - newp->prev_foot = p->prev_foot + leadsize; - newp->head = newsize; - } - else /* Otherwise, give back leader, use the rest */ - { - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - leader = chunk2mem(p); - } - p = newp; - } - - /* Give back spare room at the end */ - if (!is_mmapped(p)) - { - size_t size = chunksize(p); - if (size > nb + MIN_CHUNK_SIZE) - { - size_t remainder_size = size - nb; - mchunkptr remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - trailer = chunk2mem(remainder); - } - } - - assert (chunksize(p) >= nb); - assert((((size_t)(chunk2mem(p))) % alignment) == 0); - check_inuse_chunk(m, p); - POSTACTION(m); - if (leader != 0) - { - internal_free(m, leader); - } - if (trailer != 0) - { - internal_free(m, trailer); - } - return chunk2mem(p); - } - } - return 0; -} - -/* ------------------------ comalloc/coalloc support --------------------- */ - -static void** ialloc(mstate m, - size_t n_elements, - size_t* sizes, - int opts, - void* chunks[]) -{ - /* - This provides common support for independent_X routines, handling - all of the combinations that can result. - - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed - */ - - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size;/* total size of elements */ - size_t array_size; /* request size of pointer array */ - void* mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size;/* remaining bytes while splitting */ - void** marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; - - ensure_initialization(); - /* compute array length, if needed */ - if (chunks != 0) - { - if (n_elements == 0) - { - return chunks; /* nothing to do */ - } - marray = chunks; - array_size = 0; - } - else - { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) - { - return (void**)internal_malloc(m, 0); - } - marray = 0; - array_size = request2size(n_elements * (sizeof(void*))); - } - - /* compute total element size */ - if (opts & 0x1) /* all-same-size */ - { - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } - else /* add up all the sizes */ - { - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) - { - contents_size += request2size(sizes[i]); - } - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = internal_malloc(m, size - CHUNK_OVERHEAD); - if (was_enabled) - { - enable_mmap(m); - } - if (mem == 0) - { - return 0; - } - - if (PREACTION(m)) - { - return 0; - } - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if (opts & 0x2) /* optionally clear the elements */ - { - memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) - { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = (void**) (chunk2mem(array_chunk)); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0;; ++i) - { - marray[i] = chunk2mem(p); - if (i != n_elements - 1) - { - if (element_size != 0) - { - size = element_size; - } - else - { - size = request2size(sizes[i]); - } - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } - else /* the final element absorbs any overallocation slop */ - { - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#if DEBUG - if (marray != chunks) - { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) - { - assert(remainder_size == element_size); - } - else - { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } - for (i = 0; i != n_elements; ++i) - { - check_inuse_chunk(m, mem2chunk(marray[i])); - } - -#endif /* DEBUG */ - - POSTACTION(m); - return marray; -} - - -/* -------------------------- public routines ---------------------------- */ - -#if !ONLY_MSPACES - -void* dlmalloc(size_t bytes) -{ - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): - 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. - 4. If it is big enough, use the top chunk. - 5. If available, get memory from system and use it - Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. - 3. If it is big enough, use the top chunk. - 4. If request size >= mmap threshold, try to directly mmap this chunk. - 5. If available, get memory from system and use it - - The ugly goto's here ensure that postaction occurs along all paths. - */ - -#if USE_LOCKS - ensure_initialization(); /* initialize in sys_alloc if not using locks */ -#endif - - if (!PREACTION(gm)) - { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) - { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = gm->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) /* Remainderless fit to a smallbin. */ - { - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(gm, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(gm, b, p, idx); - set_inuse_and_pinuse(gm, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb > gm->dvsize) - { - if (smallbits != 0) /* Use chunk in next nonempty smallbin */ - { - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(gm, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(gm, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(gm, p, small_index2size(i)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) - { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - { - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - } - else - { - nb = pad_request(bytes); - if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) - { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - - if (nb <= gm->dvsize) - { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if (rsize >= MIN_CHUNK_SIZE) /* split dv */ - { - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } - else /* exhaust dv */ - { - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb < gm->topsize) /* Split top */ - { - size_t rsize = gm->topsize -= nb; - mchunkptr p = gm->top; - mchunkptr r = gm->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - mem = chunk2mem(p); - check_top_chunk(gm, gm->top); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - mem = sys_alloc(gm, nb); - -postaction: - POSTACTION(gm); - return mem; - } - - return 0; -} - -void dlfree(void* mem) -{ - /* - Consolidate freed chunks with preceeding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ - - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - if (!ok_magic(fm)) - { - USAGE_ERROR_ACTION(fm, p); - return; - } -#else /* FOOTERS */ -#define fm gm -#endif /* FOOTERS */ - if (!PREACTION(fm)) - { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) - { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) - { - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) - { - psize += prevsize + MMAP_FOOT_PAD; - if ((*fm->munmap)(fm->extp, (char*)p - prevsize, psize) == 0) - { - fm->footprint -= psize; - } - goto postaction; - } - else - { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) /* consolidate backward */ - { - if (p != fm->dv) - { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) - { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - { - goto erroraction; - } - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) - { - if (!cinuse(next)) /* consolidate forward */ - { - if (next == fm->top) - { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) - { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - { - sys_trim(fm, 0); - } - goto postaction; - } - else if (next == fm->dv) - { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else - { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) - { - fm->dvsize = psize; - goto postaction; - } - } - } - else - { - set_free_with_pinuse(p, psize, next); - } - - if (is_small(psize)) - { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else - { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - { - release_unused_segments(fm); - } - } - goto postaction; - } - } -erroraction: - USAGE_ERROR_ACTION(fm, p); -postaction: - POSTACTION(fm); - } - } -#if !FOOTERS -#undef fm -#endif /* FOOTERS */ -} - -void* dlcalloc(size_t n_elements, size_t elem_size) -{ - void* mem; - size_t req = 0; - if (n_elements != 0) - { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - { - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - } - mem = dlmalloc(req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - { - memset(mem, 0, req); - } - return mem; -} - -void* dlrealloc(void* oldmem, size_t bytes) -{ - if (oldmem == 0) - { - return dlmalloc(bytes); - } -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) - { - dlfree(oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else - { -#if !FOOTERS - mstate m = gm; -#else /* FOOTERS */ - mstate m = get_mstate_for(mem2chunk(oldmem)); - if (!ok_magic(m)) - { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - return internal_realloc(m, oldmem, bytes); - } -} - -void* dlmemalign(size_t alignment, size_t bytes) -{ - return internal_memalign(gm, alignment, bytes); -} - -void** dlindependent_calloc(size_t n_elements, size_t elem_size, - void* chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(gm, n_elements, &sz, 3, chunks); -} - -void** dlindependent_comalloc(size_t n_elements, size_t sizes[], - void* chunks[]) -{ - return ialloc(gm, n_elements, sizes, 0, chunks); -} - -void* dlvalloc(size_t bytes) -{ - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); -} - -void* dlpvalloc(size_t bytes) -{ - size_t pagesz; - ensure_initialization(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); -} - -int dlmalloc_trim(size_t pad) -{ - int result = 0; - ensure_initialization(); - if (!PREACTION(gm)) - { - result = sys_trim(gm, pad); - POSTACTION(gm); - } - return result; -} - -size_t dlmalloc_footprint(void) -{ - return gm->footprint; -} - -size_t dlmalloc_max_footprint(void) -{ - return gm->max_footprint; -} - -#if !NO_MALLINFO -struct mallinfo dlmallinfo(void) -{ - return internal_mallinfo(gm); -} -#endif /* NO_MALLINFO */ - -void dlmalloc_stats() -{ - internal_malloc_stats(gm); -} - -void dlmalloc_stats_ret(size_t* sys, size_t* maxSys, size_t* used) -{ - internal_malloc_stats_ret(gm, sys, maxSys, used); -} - -int dlmallopt(int param_number, int value) -{ - return change_mparam(param_number, value); -} - -void dlPrintStats(void) -{ - struct mallinfo info = dlmallinfo(); - fprintf(stdout, "Non-MMap:%d\nFreeChunks:%d\nMMap Space:%d\nTotal Space:%d\nAlloc Space:%d\nFree Space:%d\nReleasable:%d\n", - (int)info.arena, (int)info.ordblks, (int)info.hblkhd, (int)info.usmblks, (int)info.uordblks, (int)info.fordblks, (int)info.keepcost); - - ensure_initialization(); - if (!PREACTION(gm)) - { - check_malloc_state(gm); - if (is_initialized(gm)) - { - msegmentptr s = &gm->seg; - while (s != 0) - { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != gm->top && q->head != FENCEPOST_HEAD) - { - size_t sz = chunksize(q); - if (!is_inuse(q)) - { - fprintf(stdout, "Free: %p %d\n", q, (int)sz); - } - else - { - fprintf(stdout, "InUse: %p %d\n", q, (int)sz); - } - q = next_chunk(q); - } - s = s->next; - } - } - } -} -#endif /* !ONLY_MSPACES */ - -size_t dlmalloc_usable_size(void* mem) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); - if (is_inuse(p)) - { - return chunksize(p) - overhead_for(p); - } - } - return 0; -} - -/* ----------------------------- user mspaces ---------------------------- */ - -#if MSPACES - -static mstate init_user_mstate(char* tbase, size_t tsize, void* user, dlmmap_handler mmap, dlmunmap_handler munmap) -{ - size_t msize = pad_request(sizeof(struct malloc_state)); - mchunkptr mn; - mchunkptr msp = align_as_chunk(tbase); - mstate m = (mstate)(chunk2mem(msp)); - memset(m, 0, msize); - INITIAL_LOCK(&m->mutex); - msp->head = (msize | INUSE_BITS); - m->seg.base = m->least_addr = tbase; - m->seg.size = m->footprint = m->max_footprint = tsize; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - m->mflags = mparams.default_mflags; - m->extp = user; - m->exts = 0; - m->mmap = mmap; - m->munmap = munmap; - disable_contiguous(m); - init_bins(m); - mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); - check_top_chunk(m, m->top); - return m; -} - -static void* mmap_default(void* u, size_t sz) -{ - (void)u; - return CALL_MMAP(sz); -} - -static int munmap_default(void* u, void* p, size_t s) -{ - (void)u; - return CALL_MUNMAP(p, s); -} - -static void* mmap_missing(void* u, size_t sz) -{ - (void)u; - (void)sz; - return (void*) -1; -} - -static int munmap_missing(void* u, void* p, size_t s) -{ - (void)u; - (void)p; - (void)s; - return -1; -} - -int mspace_create_overhead(void) -{ - size_t msize = pad_request(sizeof(struct malloc_state)); - return msize + TOP_FOOT_SIZE; -} - -mspace create_mspace(size_t capacity, int locked, void* user, dlmmap_handler mmap, dlmunmap_handler munmap) -{ - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - - if (!mmap) - { - mmap = mmap_default; - } - if (!munmap) - { - munmap = munmap_default; - } - - if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) - { - size_t rs = ((capacity == 0) ? mparams.granularity : - (capacity + TOP_FOOT_SIZE + msize)); - size_t tsize = granularity_align(rs); - char* tbase = (char*)((*mmap)(user, tsize)); - if (tbase != CMFAIL) - { - m = init_user_mstate(tbase, tsize, user, mmap, munmap); - m->seg.sflags = USE_MMAP_BIT; - set_lock(m, locked); - } - } - return (mspace)m; -} - -mspace create_mspace_with_base(void* base, size_t capacity, int locked) -{ - mstate m = 0; - size_t msize; - ensure_initialization(); - msize = pad_request(sizeof(struct malloc_state)); - if (capacity > msize + TOP_FOOT_SIZE && - capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) - { - m = init_user_mstate((char*)base, capacity, NULL, mmap_missing, munmap_missing); - m->seg.sflags = EXTERN_BIT; - set_lock(m, locked); - } - return (mspace)m; -} - -int mspace_track_large_chunks(mspace msp, int enable) -{ - int ret = 0; - mstate ms = (mstate)msp; - if (!PREACTION(ms)) - { - if (!use_mmap(ms)) - { - ret = 1; - } - if (!enable) - { - enable_mmap(ms); - } - else - { - disable_mmap(ms); - } - POSTACTION(ms); - } - return ret; -} - -size_t destroy_mspace(mspace msp) -{ - size_t freed = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - msegmentptr sp = &ms->seg; - while (sp != 0) - { - char* base = sp->base; - size_t size = sp->size; - flag_t flag = sp->sflags; - sp = sp->next; - if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && - (*ms->munmap)(ms->extp, base, size) == 0) - { - freed += size; - } - } - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return freed; -} - -/* - mspace versions of routines are near-clones of the global - versions. This is not so nice but better than the alternatives. -*/ - - -void* mspace_malloc(mspace msp, size_t bytes) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - if (!PREACTION(ms)) - { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) - { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = ms->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) /* Remainderless fit to a smallbin. */ - { - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(ms, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(ms, b, p, idx); - set_inuse_and_pinuse(ms, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb > ms->dvsize) - { - if (smallbits != 0) /* Use chunk in next nonempty smallbin */ - { - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(ms, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(ms, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - { - set_inuse_and_pinuse(ms, p, small_index2size(i)); - } - else - { - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(ms, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) - { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - { - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - } - else - { - nb = pad_request(bytes); - if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) - { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - - if (nb <= ms->dvsize) - { - size_t rsize = ms->dvsize - nb; - mchunkptr p = ms->dv; - if (rsize >= MIN_CHUNK_SIZE) /* split dv */ - { - mchunkptr r = ms->dv = chunk_plus_offset(p, nb); - ms->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - } - else /* exhaust dv */ - { - size_t dvs = ms->dvsize; - ms->dvsize = 0; - ms->dv = 0; - set_inuse_and_pinuse(ms, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb < ms->topsize) /* Split top */ - { - size_t rsize = ms->topsize -= nb; - mchunkptr p = ms->top; - mchunkptr r = ms->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - mem = chunk2mem(p); - check_top_chunk(ms, ms->top); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - mem = sys_alloc(ms, nb); - -postaction: - POSTACTION(ms); - return mem; - } - - return 0; -} - -void mspace_free(mspace msp, void* mem) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - msp = msp; /* placate people compiling -Wunused */ -#else /* FOOTERS */ - mstate fm = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(fm)) - { - USAGE_ERROR_ACTION(fm, p); - return; - } - if (!PREACTION(fm)) - { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) - { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) - { - size_t prevsize = p->prev_foot; - if (is_mmapped(p)) - { - psize += prevsize + MMAP_FOOT_PAD; - if ((*fm->munmap)(fm->extp, (char*)p - prevsize, psize) == 0) - { - fm->footprint -= psize; - } - goto postaction; - } - else - { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) /* consolidate backward */ - { - if (p != fm->dv) - { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) - { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - { - goto erroraction; - } - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) - { - if (!cinuse(next)) /* consolidate forward */ - { - if (next == fm->top) - { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) - { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - { - sys_trim(fm, 0); - } - goto postaction; - } - else if (next == fm->dv) - { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else - { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) - { - fm->dvsize = psize; - goto postaction; - } - } - } - else - { - set_free_with_pinuse(p, psize, next); - } - - if (is_small(psize)) - { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else - { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - { - release_unused_segments(fm); - } - } - goto postaction; - } - } -erroraction: - USAGE_ERROR_ACTION(fm, p); -postaction: - POSTACTION(fm); - } - } -} - -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) -{ - void* mem; - size_t req = 0; - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - if (n_elements != 0) - { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - { - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - } - mem = internal_malloc(ms, req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - { - memset(mem, 0, req); - } - return mem; -} - -void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) -{ - if (oldmem == 0) - { - return mspace_malloc(msp, bytes); - } -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) - { - mspace_free(msp, oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else - { -#if FOOTERS - mchunkptr p = mem2chunk(oldmem); - mstate ms = get_mstate_for(p); -#else /* FOOTERS */ - mstate ms = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return internal_realloc(ms, oldmem, bytes); - } -} - -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return internal_memalign(ms, alignment, bytes); -} - -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return ialloc(ms, n_elements, &sz, 3, chunks); -} - -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); -#if PROCEED_ON_ERROR - return 0; -#endif - } - return ialloc(ms, n_elements, sizes, 0, chunks); -} - -int mspace_trim(mspace msp, size_t pad) -{ - int result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - if (!PREACTION(ms)) - { - result = sys_trim(ms, pad); - POSTACTION(ms); - } - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return result; -} - -void mspace_malloc_stats(mspace msp) -{ - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - internal_malloc_stats(ms); - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } -} - -size_t mspace_footprint(mspace msp) -{ - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - result = ms->footprint; - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return result; -} - - -size_t mspace_max_footprint(mspace msp) -{ - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) - { - result = ms->max_footprint; - } - else - { - USAGE_ERROR_ACTION(ms, ms); - } - return result; -} - - -#if !NO_MALLINFO -struct mallinfo mspace_mallinfo(mspace msp) -{ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) - { - USAGE_ERROR_ACTION(ms, ms); - } - return internal_mallinfo(ms); -} - -size_t mspace_get_used_space(mspace msp) -{ - struct mallinfo info = mspace_mallinfo(msp); - return info.uordblks; -} -#endif /* NO_MALLINFO */ - -size_t mspace_usable_size(void* mem) -{ - if (mem != 0) - { - mchunkptr p = mem2chunk(mem); - if (is_inuse(p)) - { - return chunksize(p) - overhead_for(p); - } - } - return 0; -} - -int mspace_mallopt(int param_number, int value) -{ - return change_mparam(param_number, value); -} - -#endif /* MSPACES */ - - -/* -------------------- Alternative MORECORE functions ------------------- */ - -/* - Guidelines for creating a custom version of MORECORE: - - * For best performance, MORECORE should allocate in multiples of pagesize. - * MORECORE may allocate more memory than requested. (Or even less, - but this will usually result in a malloc failure.) - * MORECORE must not allocate memory when given argument zero, but - instead return one past the end address of memory from previous - nonzero call. - * For best performance, consecutive calls to MORECORE with positive - arguments should return increasing addresses, indicating that - space has been contiguously extended. - * Even though consecutive calls to MORECORE need not return contiguous - addresses, it must be OK for malloc'ed chunks to span multiple - regions in those cases where they do happen to be contiguous. - * MORECORE need not handle negative arguments -- it may instead - just return MFAIL when given negative arguments. - Negative arguments are always multiples of pagesize. MORECORE - must not misinterpret negative args as large positive unsigned - args. You can suppress all such calls from even occurring by defining - MORECORE_CANNOT_TRIM, - - As an example alternative MORECORE, here is a custom allocator - kindly contributed for pre-OSX macOS. It uses virtually but not - necessarily physically contiguous non-paged memory (locked in, - present and won't get swapped out). You can use it by uncommenting - this section, adding some #includes, and setting up the appropriate - defines above: - - #define MORECORE osMoreCore - - There is also a shutdown routine that should somehow be called for - cleanup upon program exit. - - #define MAX_POOL_ENTRIES 100 - #define MINIMUM_MORECORE_SIZE (64 * 1024U) - static int next_os_pool; - void *our_os_pools[MAX_POOL_ENTRIES]; - - void *osMoreCore(int size) - { - void *ptr = 0; - static void *sbrk_top = 0; - - if (size > 0) - { - if (size < MINIMUM_MORECORE_SIZE) - size = MINIMUM_MORECORE_SIZE; - if (CurrentExecutionLevel() == kTaskLevel) - ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); - if (ptr == 0) - { - return (void *) MFAIL; - } - // save ptrs so they can be freed during cleanup - our_os_pools[next_os_pool] = ptr; - next_os_pool++; - ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); - sbrk_top = (char *) ptr + size; - return ptr; - } - else if (size < 0) - { - // we don't currently support shrink behavior - return (void *) MFAIL; - } - else - { - return sbrk_top; - } - } - - // cleanup any allocated memory pools - // called as last thing before shutting down driver - - void osCleanupMem(void) - { - void **ptr; - - for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) - if (*ptr) - { - PoolDeallocate(*ptr); - *ptr = 0; - } - } - -*/ - - -/* ----------------------------------------------------------------------- -History: - V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) - * Use zeros instead of prev foot for is_mmapped - * Add mspace_track_large_chunks; thanks to Jean Brouwers - * Fix set_inuse in internal_realloc; thanks to Jean Brouwers - * Fix insufficient sys_alloc padding when using 16byte alignment - * Fix bad error check in mspace_footprint - * Adaptations for ptmalloc; thanks to Wolfram Gloger. - * Reentrant spin locks; thanks to Earl Chew and others - * Win32 improvements; thanks to Niall Douglas and Earl Chew - * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options - * Extension hook in malloc_state - * Various small adjustments to reduce warnings on some compilers - * Various configuration extensions/changes for more platforms. Thanks - to all who contributed these. - - V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) - * Add max_footprint functions - * Ensure all appropriate literals are size_t - * Fix conditional compilation problem for some #define settings - * Avoid concatenating segments with the one provided - in create_mspace_with_base - * Rename some variables to avoid compiler shadowing warnings - * Use explicit lock initialization. - * Better handling of sbrk interference. - * Simplify and fix segment insertion, trimming and mspace_destroy - * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x - * Thanks especially to Dennis Flanagan for help on these. - - V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) - * Fix memalign brace error. - - V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) - * Fix improper #endif nesting in C++ - * Add explicit casts needed for C++ - - V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) - * Use trees for large bins - * Support mspaces - * Use segments to unify sbrk-based and mmap-based system allocation, - removing need for emulation on most platforms without sbrk. - * Default safety checks - * Optional footer checks. Thanks to William Robertson for the idea. - * Internal code refactoring - * Incorporate suggestions and platform-specific changes. - Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, - Aaron Bachmann, Emery Berger, and others. - * Speed up non-fastbin processing enough to remove fastbins. - * Remove useless cfree() to avoid conflicts with other apps. - * Remove internal memcpy, memset. Compilers handle builtins better. - * Remove some options that no one ever used and rename others. - - V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - * Fix malloc_state bitmap array misdeclaration - - V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) - * Allow tuning of FIRST_SORTED_BIN_SIZE - * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. - * Better detection and support for non-contiguousness of MORECORE. - Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger - * Bypass most of malloc if no frees. Thanks To Emery Berger. - * Fix freeing of old top non-contiguous chunk im sysmalloc. - * Raised default trim and map thresholds to 256K. - * Fix mmap-related #defines. Thanks to Lubos Lunak. - * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. - * Branch-free bin calculation - * Default trim and mmap thresholds now 256K. - - V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) - * Introduce independent_comalloc and independent_calloc. - Thanks to Michael Pachos for motivation and help. - * Make optional .h file available - * Allow > 2GB requests on 32bit systems. - * new WIN32 sbrk, mmap, munmap, lock code from . - Thanks also to Andreas Mueller , - and Anonymous. - * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for - helping test this.) - * memalign: check alignment arg - * realloc: don't try to shift chunks backwards, since this - leads to more fragmentation in some programs and doesn't - seem to help in any others. - * Collect all cases in malloc requiring system memory into sysmalloc - * Use mmap as backup to sbrk - * Place all internal state in malloc_state - * Introduce fastbins (although similar to 2.5.1) - * Many minor tunings and cosmetic improvements - * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK - * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS - Thanks to Tony E. Bennett and others. - * Include errno.h to support default failure action. - - V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) - * return null for negative arguments - * Added Several WIN32 cleanups from Martin C. Fong - * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' - (e.g. WIN32 platforms) - * Cleanup header file inclusion for WIN32 platforms - * Cleanup code to avoid Microsoft Visual C++ compiler complaints - * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing - memory allocation routines - * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) - * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to - usage of 'assert' in non-WIN32 code - * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to - avoid infinite loop - * Always call 'fREe()' rather than 'free()' - - V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) - * Fixed ordering problem with boundary-stamping - - V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) - * Added pvalloc, as recommended by H.J. Liu - * Added 64bit pointer support mainly from Wolfram Gloger - * Added anonymously donated WIN32 sbrk emulation - * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen - * malloc_extend_top: fix mask error that caused wastage after - foreign sbrks - * Add linux mremap support code from HJ Liu - - V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) - * Integrated most documentation with the code. - * Add support for mmap, with help from - Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Use last_remainder in more cases. - * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold - * Eliminate block-local decls to simplify tracing and debugging. - * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. - * Rely on page size for units instead of SBRK_UNIT to - avoid surprises about sbrk alignment conventions. - * Add mallinfo, mallopt. Thanks to Raymond Nijssen - (raymond@es.ele.tue.nl) for the suggestion. - * Add `pad' argument to malloc_trim and top_pad mallopt parameter. - * More precautions for cases where other routines call sbrk, - courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Added macros etc., allowing use in linux libc from - H.J. Lu (hjl@gnu.ai.mit.edu) - * Inverted this history list - - V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) - * Re-tuned and fixed to behave more nicely with V2.6.0 changes. - * Removed all preallocation code since under current scheme - the work required to undo bad preallocations exceeds - the work saved in good cases for most test programs. - * No longer use return list or unconsolidated bins since - no scheme using them consistently outperforms those that don't - given above changes. - * Use best fit for very large chunks to prevent some worst-cases. - * Added some support for debugging - - V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) - * Removed footers when chunks are in use. Thanks to - Paul Wilson (wilson@cs.texas.edu) for the suggestion. - - V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) - * Added malloc_trim, with help from Wolfram Gloger - (wmglo@Dent.MED.Uni-Muenchen.DE). - - V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) - - V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) - * realloc: try to expand in both directions - * malloc: swap order of clean-bin strategy; - * realloc: only conditionally expand backwards - * Try not to scavenge used bins - * Use bin counts as a guide to preallocation - * Occasionally bin return list chunks in first scan - * Add a few optimizations from colin@nyx10.cs.du.edu - - V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) - * faster bin computation & slightly different binning - * merged all consolidations to one part of malloc proper - (eliminating old malloc_find_space & malloc_clean_bin) - * Scan 2 returns chunks (not just 1) - * Propagate failure in realloc if malloc returns 0 - * Add stuff to allow compilation on non-ANSI compilers - from kpv@research.att.com - - V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) - * removed potential for odd address access in prev_chunk - * removed dependency on getpagesize.h - * misc cosmetics and a bit more internal documentation - * anticosmetics: mangled names in macros to evade debugger strangeness - * tested on sparc, hp-700, dec-mips, rs6000 - with gcc & native cc (hp, dec only) allowing - Detlefs & Zorn comparison study (in SIGPLAN Notices.) - - Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) - * Based loosely on libg++-1.2X malloc. (It retains some of the overall - structure of old version, but most details differ.) - -*/ - -#endif diff --git a/Code/CryEngine/CrySystem/CrySizerImpl.cpp b/Code/CryEngine/CrySystem/CrySizerImpl.cpp deleted file mode 100644 index bd26b05b9e..0000000000 --- a/Code/CryEngine/CrySystem/CrySizerImpl.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include -#include "CrySizerImpl.h" - -CrySizerImpl::CrySizerImpl() - : m_pResourceCollector(0) -{ - m_nFlags = 0; - m_nTotalSize = 0; - // to avoid reallocations during walk through the memory tree, reserve the space for the names - clear(); -} - -CrySizerImpl::~CrySizerImpl() -{ -} - -void CrySizerImpl::Push (const char* szComponentName) -{ - m_stackNames.push_back (getNameIndex(getCurrentName(), szComponentName)); - // if the depth is too deep, something is wrong, perhaps an infinite loop - assert (m_stackNames.size() < 128); -} - -void CrySizerImpl::PushSubcomponent (const char* szSubcomponentName) -{ - Push (szSubcomponentName); -} - - -void CrySizerImpl::Pop () -{ - if (!m_stackNames.empty()) - { - m_stackNames.pop_back(); - } - else - { - assert (0); - } -} - -// returns the index of the current name on the top of the name stack -size_t CrySizerImpl::getCurrentName() const -{ - assert(!m_stackNames.empty()); - return m_stackNames.empty() ? 0 : m_stackNames.back(); -} - - - -// searches for the name in the name array; adds the name if it's not there and returns the index -size_t CrySizerImpl::getNameIndex(size_t nParent, const char* szComponentName) -{ - NameArray::const_iterator it = m_arrNames.begin(), itEnd = it + m_arrNames.size(); - for (; it != itEnd; ++it) - { -#if defined(LINUX) - if (!strcasecmp(it->strName.c_str(), szComponentName) && it->nParent == nParent) -#else - if (!strcmp(it->strName.c_str(), szComponentName) && it->nParent == nParent) -#endif - { - return (size_t)(it - m_arrNames.begin());//it-m_arrNames.begin(); - } - } - - size_t nNewName = m_arrNames.size(); - m_arrNames.resize(nNewName + 1); - - m_arrNames[nNewName].assign(szComponentName, nParent); - - m_arrNames[nParent].arrChildren.push_back(nParent); - - return nNewName; -} - -static NullResCollector s_nullCollector; - -IResourceCollector* CrySizerImpl::GetResourceCollector() -{ - return m_pResourceCollector != 0 ? m_pResourceCollector : &s_nullCollector; -} - -void CrySizerImpl::Reset() -{ - clear(); - - m_nTotalSize = 0; - - //m_arrNames.resize(0); - //m_arrNames.push_back("TOTAL"); // the default name, with index 0 - //m_LastObject.clear(); - ////m_nFlags; - //m_nTotalSize=0; - //if (m_pResourceCollector) - //{ - // m_pResourceCollector->Reset(); - //} - //m_setObjects->clear(); - //m_stackNames.resize(0); - //m_stackNames.push_back(0); -} - - -// adds an object identified by the unique pointer (it needs not be -// the actual object position in the memory, though it would be nice, -// but it must be unique throughout the system and unchanging for this object) -// RETURNS: true if the object has actually been added (for the first time) -// and calculated -bool CrySizerImpl::AddObject (const void* pIdentifier, size_t sizeBytes, int nCount) -{ - if (!pIdentifier || !sizeBytes) - { - return false; // we don't add the NULL objects - } - Object NewObject(pIdentifier, sizeBytes, getCurrentName()); - - // check if the last object was the same - if (NewObject == m_LastObject) - { - assert (m_LastObject.nSize == sizeBytes); - return false; - } - - ObjectSet& rSet = m_setObjects[getHash(pIdentifier)]; - ObjectSet::iterator it = rSet.find (NewObject); - if (it == rSet.end()) - { - // there's no such object in the map, add it - rSet.insert (NewObject); - ComponentName& CompName = m_arrNames[getCurrentName()]; - CompName.numObjects += nCount; - CompName.sizeObjects += sizeBytes; - - m_nTotalSize += sizeBytes; - return true; - } - else - { - Object* pObj = const_cast(&(*it)); - - // if we do an heap check, don't accept the same object twice - if (sizeBytes != pObj->nSize) - { - // if the following assert fails: - // assert (0); - // .. it means we have one object that's added two times with different sizes; that's screws up the whole idea - // we assume there are two different objects that are for some reason assigned the same id - pObj->nSize += sizeBytes; // anyway it's an invalid situation - ComponentName& CompName = m_arrNames[getCurrentName()]; - CompName.sizeObjects += sizeBytes; - return true; // yes we added the object, though there were an error condition - } - - return false; - } -} - -size_t CrySizerImpl::GetObjectCount() -{ - size_t count = m_stackNames.size(); - for (int i = 0; i < g_nHashSize; i++) - { - count += m_setObjects[i].size(); - } - return count; -} - - -// finalizes data collection, should be called after all objects have been added -void CrySizerImpl::End() -{ - // clean up the totals of each name - int i; - for (i = 0; i < m_arrNames.size(); ++i) - { - assert (i == 0 || ((int)m_arrNames[i].nParent < i && m_arrNames[i].nParent >= 0)); - m_arrNames[i].sizeObjectsTotal = m_arrNames[i].sizeObjects; - } - - // add the component's size to the total size of the parent. - // for every component, all their children are put after them in the name array - // we don't include the root because it doesn't belong to any other parent (nowhere further to add) - for (i = m_arrNames.size() - 1; i > 0; --i) - { - // the parent's total size is increased by the _total_ size (already calculated) of this object - m_arrNames[m_arrNames[i].nParent].sizeObjectsTotal += m_arrNames[i].sizeObjectsTotal; - } -} - - -void CrySizerImpl::clear() -{ - for (unsigned i = 0; i < g_nHashSize; ++i) - { - m_setObjects[i].clear(); - } - - m_arrNames.clear(); - m_arrNames.push_back("TOTAL"); // the default name, with index 0 - m_stackNames.clear(); - m_stackNames.push_back(0); - m_LastObject.pId = NULL; - - if (m_pResourceCollector) - { - m_pResourceCollector->Reset(); - } -} - -// hash function for an address; returns value 0..1<> 4) & (g_nHashSize-1); - - // pseudorandomizing transform - ldiv_t Qrem = (ldiv_t)ldiv(((uint32)(UINT_PTR)pId >> 2), 127773); - Qrem.rem = 16807 * Qrem.rem - 2836 * Qrem.quot; - if (Qrem.rem < 0) - { - Qrem.rem += 2147483647; // 0x7FFFFFFF - } - return ((unsigned)Qrem.rem) & (g_nHashSize - 1); -} -unsigned CrySizerImpl::GetDepthLevel(unsigned nCurrent) -{ - uint32 nDepth = 0; - nCurrent = m_arrNames[nCurrent].nParent; - while (nCurrent != 0) - { - nDepth++; - nCurrent = m_arrNames[nCurrent].nParent; - } - return nDepth; -} - diff --git a/Code/CryEngine/CrySystem/CrySizerImpl.h b/Code/CryEngine/CrySystem/CrySizerImpl.h deleted file mode 100644 index f43ee25297..0000000000 --- a/Code/CryEngine/CrySystem/CrySizerImpl.h +++ /dev/null @@ -1,184 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of the ICrySizer interface, which is used to -// calculate the memory usage by the subsystems and components, to help -// the artists keep the memory budged low. - - -#ifndef CRYINCLUDE_CRYSYSTEM_CRYSIZERIMPL_H -#define CRYINCLUDE_CRYSYSTEM_CRYSIZERIMPL_H -#pragma once - - - -// prerequisities - -////////////////////////////////////////////////////////////////////////// -// implementation of interface ICrySizer -// ICrySizer is passed to all subsystems and has a lot of helper functions that -// are compiled in the appropriate subsystems. CrySizerImpl is created in CrySystem -// and is passed to all the other subsystems -class CrySizerImpl - : public ICrySizer -{ -public: - CrySizerImpl(); - ~CrySizerImpl(); - - virtual void Release() { delete this; } - virtual size_t GetTotalSize() { return m_nTotalSize; }; - virtual size_t GetObjectCount(); - - void Reset(); - - // adds an object identified by the unique pointer (it needs not be - // the actual object position in the memory, though it would be nice, - // but it must be unique throughout the system and unchanging for this object) - // RETURNS: true if the object has actually been added (for the first time) - // and calculated - virtual bool AddObject (const void* pIdentifier, size_t nSizeBytes, int nCount = 1); - - virtual IResourceCollector* GetResourceCollector(); - - // finalizes data collection, should be called after all objects have been added - void End(); - - void clear(); - - // Arguments: - // pColl - can be 0 - void SetResourceCollector(IResourceCollector* pColl) { m_pResourceCollector = pColl; } - -protected: - - IResourceCollector* m_pResourceCollector; // - - // these functions must operate on the component name stack - // they are to be only accessible from within class CrySizerComponentNameHelper - // which should be used through macro SIZER_COMPONENT_NAME - virtual void Push (const char* szComponentName); - virtual void PushSubcomponent (const char* szSubcomponentName); - virtual void Pop (); - - // searches for the name in the name array; adds the name if it's not there and returns the index - size_t getNameIndex (size_t nParent, const char* szComponentName); - - // returns the index of the current name on the top of the name stack - size_t getCurrentName() const; - -protected: - friend class CrySizerStatsBuilder; - - // the stack of subsystem names; the indices in the name array are kept, not the names themselves - typedef DynArray NameStack; - NameStack m_stackNames; - - // the array of names; each name ever pushed on the stack is present here - struct ComponentName - { - ComponentName (){} - ComponentName (const char* szName, size_t parent = 0) - : strName (szName) - , nParent (parent) - , numObjects(0) - , sizeObjects (0) - , sizeObjectsTotal (0) - { - } - - void assign (const char* szName, size_t parent = 0) - { - strName = szName; - nParent = parent; - numObjects = 0; - sizeObjects = 0; - sizeObjectsTotal = 0; - arrChildren.clear(); - } - - // the component name, not including the parents' names - string strName; - // the index of the parent, 0 being the root - size_t nParent; - // the number of objects within this component - size_t numObjects; - // the size of the objects belonging to this component, in bytes - size_t sizeObjects; - // the total size of all objects; gets filled by the end() method of the CrySizerImpl - size_t sizeObjectsTotal; - // the children components - DynArray arrChildren; - }; - typedef DynArray NameArray; - NameArray m_arrNames; - - - - // the set of objects and their sizes: the key is the object address/id, - // the value is the size of the object and its name (the index of the name actually) - struct Object - { - const void* pId; // unique pointer identifying the object in memory - size_t nSize; // the size of the object in bytes - size_t nName; // the index of the name in the name array - - Object () - {clear(); } - - Object (const void* id, size_t size = 0, size_t name = 0) - : pId(id) - , nSize(size) - , nName(name) {} - - // the objects are sorted by their Id - bool operator < (const Object& right) const {return (UINT_PTR)pId < (UINT_PTR)right.pId; } - bool operator < (const void* right) const {return (UINT_PTR)pId < (UINT_PTR)right; } - //friend bool operator < (const void* left, const Object& right); - - bool operator == (const Object& right) const {return pId == right.pId; } - - void clear() - { - pId = NULL; - nSize = 0; - nName = 0; - } - }; - typedef std::set ObjectSet; - // 2^g_nHashPower == the number of subsets comprising the hash - - enum - { - g_nHashPower = 12 - }; - - // hash size (number of subsets) - enum - { - g_nHashSize = 1 << g_nHashPower - }; - // hash function for an address; returns value 0..1< 0x10000000 ? 0 : nMinSubcomponentBytes) -{ -} - - -// creates the map of names from old (in the sizer Impl) to new (in the Stats) -void CrySizerStatsBuilder::processNames() -{ - size_t numCompNames = m_pSizer->m_arrNames.size(); - m_pStats->m_arrComponents.reserve (numCompNames); - m_pStats->m_arrComponents.clear(); - - m_mapNames.resize (numCompNames, (size_t)-1); - - // add all root objects - addNameSubtree(0, 0); -} - - -////////////////////////////////////////////////////////////////////////// -// given the name in the old system, adds the subtree of names to the -// name map and components. In case all the subtree is empty, returns false and -// adds nothing -size_t CrySizerStatsBuilder::addNameSubtree (unsigned nDepth, size_t nName) -{ - assert ((int)nName < m_pSizer->m_arrNames.size()); - - CrySizerImpl::ComponentName& rCompName = m_pSizer->m_arrNames[nName]; - size_t sizeObjectsTotal = rCompName.sizeObjectsTotal; - - if (sizeObjectsTotal <= m_nMinSubcomponentBytes) - { - return sizeObjectsTotal; // the subtree didn't pass - } - // the index of the component in the stats object (sorted by the depth-first traverse order) - size_t nNewName = m_pStats->m_arrComponents.size(); - m_pStats->m_arrComponents.resize (nNewName + 1); - - Component& rNewComp = m_pStats->m_arrComponents[nNewName]; - rNewComp.strName = rCompName.strName; - rNewComp.nDepth = nDepth; - rNewComp.numObjects = rCompName.numObjects; - rNewComp.sizeBytes = rCompName.sizeObjects; - rNewComp.sizeBytesTotal = sizeObjectsTotal; - m_mapNames[nName] = nNewName; - - // find the immediate children and sort them by their total size - typedef std::map UintUintMap; - UintUintMap mapSizeName; // total size -> child index (name in old indexation) - - for (int i = nName + 1; i < m_pSizer->m_arrNames.size(); ++i) - { - CrySizerImpl::ComponentName& rChild = m_pSizer->m_arrNames[i]; - if (rChild.nParent == nName && rChild.sizeObjectsTotal > m_nMinSubcomponentBytes) - { - mapSizeName.insert (UintUintMap::value_type(rChild.sizeObjectsTotal, i)); - } - } - - // add the sorted components - /* - for (unsigned i = nName + 1; i < m_pSizer->m_arrNames.size(); ++i) - if (m_pSizer->m_arrNames[i].nParent == nName) - addNameSubtree(nDepth+1,i); - */ - - for (UintUintMap::reverse_iterator it = mapSizeName.rbegin(); it != mapSizeName.rend(); ++it) - { - addNameSubtree(nDepth + 1, it->second); - } - - return sizeObjectsTotal; -} - - -////////////////////////////////////////////////////////////////////////// -// creates the statistics out of the given CrySizerImpl into the given CrySizerStats -// Maps the old to new names according to the depth-walk tree rule -void CrySizerStatsBuilder::build (CrySizerStats* pStats) -{ - m_pStats = pStats; - - m_mapNames.clear(); - - processNames(); - - m_pSizer->clear(); - pStats->refresh(); - pStats->m_nAgeFrames = 0; -} - - -////////////////////////////////////////////////////////////////////////// -// constructs the statistics based on the given cry sizer -CrySizerStats::CrySizerStats (CrySizerImpl* pCrySizer) -{ - CrySizerStatsBuilder builder (pCrySizer); - builder.build(this); -} - -CrySizerStats::CrySizerStats () - : m_nStartRow(0) -{ -} - -void CrySizerStats::updateKeys() -{ - const unsigned int statSize = size(); - //assume 10 pixels for font - unsigned int height = gEnv->pRenderer->GetHeight() / 12; - if (CryGetAsyncKeyState(VK_UP)) - { - if (m_nStartRow > 0) - { - --m_nStartRow; - } - } - if (CryGetAsyncKeyState(VK_DOWN)) - { - if (statSize > height + m_nStartRow) - { - ++m_nStartRow; - } - } - if (CryGetAsyncKeyState(VK_RIGHT) & 1) - { - //assume 10 pixels for font - if (statSize > height) - { - m_nStartRow = statSize - height; - } - } - if (CryGetAsyncKeyState(VK_LEFT) & 1) - { - m_nStartRow = 0; - } -} - -// if there is already such name in the map, then just returns the index -// of the compoentn in the component array; otherwise adds an entry to themap -// and to the component array nad returns its index -CrySizerStatsBuilder::Component& CrySizerStatsBuilder::mapName (unsigned nName) -{ - assert (m_mapNames[nName] != -1); - return m_pStats->m_arrComponents[m_mapNames[nName]]; - /* - IdToIdMap::iterator it = m_mapNames.find (nName); - if (it == m_mapNames.end()) - { - unsigned nNewName = m_arrComponents.size(); - m_mapNames.insert (IdToIdMap::value_type(nName, nNewName)); - m_arrComponents.resize(nNewName + 1); - m_arrComponents[nNewName].strName.swap(m_pSizer->m_arrNames[nName]); - return m_arrComponents.back(); - } - else - { - assert (it->second < m_arrComponents.size()); - return m_arrComponents[it->second]; - } - */ -} - -// refreshes the statistics built after the component array is built -void CrySizerStats::refresh() -{ - m_nMaxNameLength = 0; - for (size_t i = 0; i < m_arrComponents.size(); ++i) - { - size_t nLength = m_arrComponents[i].strName.length() + m_arrComponents[i].nDepth; - if (nLength > m_nMaxNameLength) - { - m_nMaxNameLength = nLength; - } - } -} - - -bool CrySizerStats::Component::GenericOrder::operator () (const Component& left, const Component& right) const -{ - return left.strName < right.strName; -} - - -CrySizerStatsRenderer::CrySizerStatsRenderer (ISystem* pSystem, CrySizerStats* pStats, unsigned nMaxSubcomponentDepth, int nMinSubcomponentBytes) - : m_pStats(pStats) - , m_pRenderer(pSystem->GetIRenderer()) - , m_pLog (pSystem->GetILog()) - , m_pTextModeConsole(pSystem->GetITextModeConsole()) - , m_nMinSubcomponentBytes (nMinSubcomponentBytes < 0 || nMinSubcomponentBytes > 0x10000000 ? 0x8000 : nMinSubcomponentBytes) - , m_nMaxSubcomponentDepth (nMaxSubcomponentDepth) -{ -} - - -static void DrawStatsText(float x, float y, float fScale, float color[4], const char* format, ...) -{ - va_list args; - va_start(args, format); - SDrawTextInfo ti; - ti.xscale = fScale; - ti.yscale = fScale; - ti.color[0] = color[0]; - ti.color[1] = color[1]; - ti.color[2] = color[2]; - ti.color[3] = color[3]; - ti.flags = eDrawText_2D | eDrawText_FixedSize | eDrawText_Monospace; - gEnv->pRenderer->DrawTextQueued(Vec3(x, y, 0.5f), ti, format, args); - va_end(args); -} - -void CrySizerStatsRenderer::render(bool bRefreshMark) -{ - if (!m_pStats->size()) - { - return; - } - - int x, y, dx, dy; - m_pRenderer->GetViewport(&x, &y, &dx, &dy); - - // left coordinate of the text - unsigned nNameWidth = (unsigned)(m_pStats->getMaxNameLength() + 1); - if (nNameWidth < 25) - { - nNameWidth = 25; - } - float fCharScaleX = 1.2f; - float fLeft = 0; - float fTop = 8; - float fVStep = 9; - -#ifdef _DEBUG - const char* szCountStr1 = "count"; - const char* szCountStr2 = "_____"; -#else // _DEBUG - const char* szCountStr1 = "", * szCountStr2 = ""; -#endif // _DEBUG - - float fTextColor[4] = {0.9f, 0.85f, 1, 0.85f}; - DrawStatsText(fLeft, fTop, fCharScaleX, fTextColor, - "%-*s total partial %s", nNameWidth, bRefreshMark ? "Memory usage (refresh*)" : "Memory usage (refresh )", szCountStr1); - DrawStatsText(fLeft, fTop + fVStep * 0.25f, fCharScaleX, fTextColor, - "%*s _____ _______ %s", nNameWidth, "", szCountStr2); - - unsigned nSubgroupDepth = 1; - - // different colors used to paint the statistics subgroups - // a new statistic subgroup starts with a new subtree of depth <= specified - float fGray = 0;//0.45f; - float fLightGray = 0.5f;//0.8f; - float fColors[] = - { - fLightGray, fLightGray, fGray, 1, - 1, 1, 1, 1, - fGray, 1, 1, 1, - 1, fGray, 1, 1, - 1, 1, fGray, 1, - fGray, fLightGray, 1, 1, - fGray, 1, fGray, 1, - 1, fGray, fGray, 1 - }; - float* pColor = fColors; - - unsigned statSize = m_pStats->size(); - unsigned startRow = m_pStats->row(); - unsigned i = 0; - for (; i < startRow; ++i) - { - const Component& rComp = (*m_pStats)[i]; - if (rComp.nDepth <= nSubgroupDepth) - { - //switch the color - pColor += 4; - if (pColor >= fColors + sizeof(fColors) / sizeof(fColors[0])) - { - pColor = fColors; - } - - fTop += fVStep * (0.333333f + (nSubgroupDepth - rComp.nDepth) * 0.15f); - } - } - - for (unsigned r = startRow; i < statSize; ++i) - { - const Component& rComp = (*m_pStats)[i]; - if (rComp.nDepth <= nSubgroupDepth) - { - //switch the color - pColor += 4; - if (pColor >= fColors + sizeof(fColors) / sizeof(fColors[0])) - { - pColor = fColors; - } - - fTop += fVStep * (0.333333f + (nSubgroupDepth - rComp.nDepth) * 0.15f); - } - - if (rComp.sizeBytesTotal <= m_nMinSubcomponentBytes || rComp.nDepth > m_nMaxSubcomponentDepth) - { - continue; - } - - fTop += fVStep; - - char szDepth[32] = " .............................."; - if (rComp.nDepth < sizeof(szDepth)) - { - szDepth[rComp.nDepth] = '\0'; - } - - char szSize[32]; - if (rComp.sizeBytes > 0) - { - if (rComp.sizeBytesTotal > rComp.sizeBytes) - { - azsprintf(szSize, "%7.3f %7.3f", rComp.getTotalSizeMBytes(), rComp.getSizeMBytes()); - } - else - { - azsprintf(szSize, " %7.3f", rComp.getSizeMBytes()); - } - } - else - { - assert (rComp.sizeBytesTotal > 0); - azsprintf(szSize, "%7.3f ", rComp.getTotalSizeMBytes()); - } - char szCount[16]; -#ifdef _DEBUG - if (rComp.numObjects) - { - azsprintf(szCount, "%zd" PRIu64 "", rComp.numObjects); - } - else -#endif - szCount[0] = '\0'; - - DrawStatsText(fLeft, fTop, fCharScaleX, pColor, - "%s%-*s:%s%s", szDepth, nNameWidth - rComp.nDepth, rComp.strName.c_str(), szSize, szCount); - - if (m_pTextModeConsole) - { - string text; - text.Format("%s%-*s:%s%s", szDepth, nNameWidth - rComp.nDepth, rComp.strName.c_str(), szSize, szCount); - m_pTextModeConsole->PutText(0, r++, text.c_str()); - } - } - - float fLTGrayColor[4] = {fLightGray, fLightGray, fLightGray, 1.0f}; - fTop += 0.25f * fVStep; - DrawStatsText(fLeft, fTop, fCharScaleX, fLTGrayColor, - "%-*s %s", nNameWidth, "___________________________", "________________"); - fTop += fVStep; - - const char* szOverheadNames[CrySizerStats::g_numTimers] = - { - ".Collection", - ".Transformation", - ".Cleanup" - }; - bool bOverheadsHeaderPrinted = false; - for (i = 0; i < CrySizerStats::g_numTimers; ++i) - { - float fTime = m_pStats->getTime(i); - if (fTime < 20) - { - continue; - } - // print the header - if (!bOverheadsHeaderPrinted) - { - DrawStatsText(fLeft, fTop, fCharScaleX, fTextColor, - "%-*s", nNameWidth, "Overheads"); - fTop += fVStep; - bOverheadsHeaderPrinted = true; - } - - DrawStatsText(fLeft, fTop, fCharScaleX, fTextColor, - "%-*s:%7.1f ms", nNameWidth, szOverheadNames[i], fTime); - fTop += fVStep; - } -} - -void CrySizerStatsRenderer::dump(bool bUseKB) -{ - if (!m_pStats->size()) - { - return; - } - - unsigned nNameWidth = (unsigned)(m_pStats->getMaxNameLength() + 1); - - // left coordinate of the text - m_pLog->LogToFile ("Memory Statistics: %s", bUseKB ? "KB" : "MB"); - m_pLog->LogToFile("%-*s TOTAL partial count", nNameWidth, ""); - - // different colors used to paint the statistics subgroups - // a new statistic subgroup starts with a new subtree of depth <= specified - - for (unsigned i = 0; i < m_pStats->size(); ++i) - { - const Component& rComp = (*m_pStats)[i]; - - if (rComp.sizeBytesTotal <= m_nMinSubcomponentBytes || rComp.nDepth > m_nMaxSubcomponentDepth) - { - continue; - } - - char szDepth[32] = " .............................."; - if (rComp.nDepth < sizeof(szDepth)) - { - szDepth[rComp.nDepth] = '\0'; - } - - char szSize[32]; - if (rComp.sizeBytes > 0) - { - if (rComp.sizeBytesTotal > rComp.sizeBytes) - { - azsprintf(szSize, bUseKB ? "%7.2f %7.2f" : "%7.3f %7.3f", bUseKB ? rComp.getTotalSizeKBytes() : rComp.getTotalSizeMBytes(), bUseKB ? rComp.getSizeKBytes() : rComp.getSizeMBytes()); - } - else - { - azsprintf(szSize, bUseKB ? " %7.2f" : " %7.3f", bUseKB ? rComp.getSizeKBytes() : rComp.getSizeMBytes()); - } - } - else - { - assert (rComp.sizeBytesTotal > 0); - azsprintf(szSize, bUseKB ? "%7.2f " : "%7.3f ", bUseKB ? rComp.getTotalSizeKBytes() : rComp.getTotalSizeMBytes()); - } - char szCount[16]; - - if (rComp.numObjects) - { - azsprintf(szCount, "%8u", (unsigned int)rComp.numObjects); - } - else - { - szCount[0] = '\0'; - } - - m_pLog->LogToFile ("%s%-*s:%s%s", szDepth, nNameWidth - rComp.nDepth, rComp.strName.c_str(), szSize, szCount); - } -} - - -void CrySizerStats::startTimer(unsigned nTimer, ITimer* pTimer) -{ - assert (nTimer < g_numTimers); - m_fTime[nTimer] = pTimer->GetAsyncCurTime(); -} - -void CrySizerStats::stopTimer(unsigned nTimer, ITimer* pTimer) -{ - assert (nTimer < g_numTimers); - m_fTime[nTimer] = 1000 * (pTimer->GetAsyncCurTime() - m_fTime[nTimer]); -} diff --git a/Code/CryEngine/CrySystem/CrySizerStats.h b/Code/CryEngine/CrySystem/CrySizerStats.h deleted file mode 100644 index fc8c43a7c2..0000000000 --- a/Code/CryEngine/CrySystem/CrySizerStats.h +++ /dev/null @@ -1,207 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Declaration of the CrySizerStats class, which is used to -// calculate the memory usage by the subsystems and components, to help -// the artists keep the memory budged low. - -#ifndef CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H -#define CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H -#pragma once - - -class CrySizerImpl; - -////////////////////////////////////////////////////////////////////////// -// This class holds only the necessary statistics data, which can be carried -// over a few frames without significant impact on memory usage -// CrySizerImpl is an implementation of ICrySizer, which is used to collect -// those data; it must be destructed immediately after constructing the Stats -// object to avoid excessive memory usage. -class CrySizerStats -{ -public: - // constructs the statistics based on the given cry sizer - CrySizerStats (CrySizerImpl* pCrySizer); - - CrySizerStats (); - - // this structure describes one component of the memory size statistics - struct Component - { - Component() {clear(); } - Component (const string& name, unsigned size = 0, unsigned num = 0) - : strName(name) - , sizeBytes(size) - , numObjects(num) - , nDepth(0) {} - void clear() - { - strName = ""; - sizeBytes = 0; - numObjects = 0; - nDepth = 0; - } - - // the name of the component, as it appeared in the push() call - string strName; - // the total size, in bytes, of objects in the component - size_t sizeBytes; - // the total size including the subcomponents - size_t sizeBytesTotal; - // the number of objects allocated - size_t numObjects; - unsigned nDepth; - - float getSizeKBytes() const {return sizeBytes / float(1 << 10); } - - float getTotalSizeKBytes () const {return sizeBytesTotal / float(1 << 10); } - - float getSizeMBytes() const {return sizeBytes / float(1 << 20); } - - float getTotalSizeMBytes () const {return sizeBytesTotal / float(1 << 20); } - - struct NameOrder - { - bool operator () (const Component& left, const Component& right) const {return left.strName < right.strName; } - }; - - struct SizeOrder - { - bool operator () (const Component& left, const Component& right) const {return left.sizeBytes < right.sizeBytes; } - }; - - struct GenericOrder - { - bool operator () (const Component& left, const Component& right) const; - }; - }; - - // returns the number of different subsystems/components used - unsigned numComponents() const {return (unsigned)m_arrComponents.size(); } - // returns the name of the i-th component - const Component& getComponent(unsigned nComponent) const {return m_arrComponents[nComponent]; } - - unsigned size() const {return numComponents(); } - const Component& operator [] (unsigned i) const {return getComponent(i); } - const Component& operator [] (signed i) const {return getComponent(i); } - - unsigned row() const {return m_nStartRow; } - void updateKeys(); - - size_t getMaxNameLength() const {return m_nMaxNameLength; } - enum - { - g_numTimers = 3 - }; - - void startTimer(unsigned nTimer, ITimer* pTimer); - void stopTimer(unsigned nTimer, ITimer* pTimer); - float getTime(unsigned nTimer) const {assert (nTimer < g_numTimers); return m_fTime[nTimer]; } - int getAgeFrames() const {return m_nAgeFrames; } - void incAgeFrames() {++m_nAgeFrames; } -protected: - // refreshes the statistics built after the component array is built - void refresh(); -protected: - // the names of the components - typedef std::vector ComponentArray; - ComponentArray m_arrComponents; - - // the maximum length of the component name, in characters - size_t m_nMaxNameLength; - - // the timer that counts the time spent on statistics gathering - float m_fTime[g_numTimers]; - - // the age of the statistics, in frames - int m_nAgeFrames; - - //current row offset inc/dec by cursor keys - unsigned m_nStartRow; - - friend class CrySizerStatsBuilder; -}; - - -////////////////////////////////////////////////////////////////////////// -// this is the constructor for the CrySizerStats -class CrySizerStatsBuilder -{ -public: - CrySizerStatsBuilder (CrySizerImpl* pSizer, int nMinSubcomponentBytes = 0); - - void build (CrySizerStats* pStats); - -protected: - typedef CrySizerStats::Component Component; - // if there is already such name in the map, then just returns the index - // of the compoentn in the component array; otherwise adds an entry to themap - // and to the component array nad returns its index - Component& mapName (unsigned nName); - - // creates the map of names from old to new, and initializes the components themselves - void processNames(); - - // given the name in the old system, adds the subtree of names to the - // name map and components. In case all the subtree is empty, returns 0 and - // adds nothing. Otherwise, returns the total size of objects belonging to the - // subtree - size_t addNameSubtree (unsigned nDepth, size_t nName); - -protected: - CrySizerStats* m_pStats; - CrySizerImpl* m_pSizer; - - // this is the mapping from the old names into the new componentn indices - typedef std::vector IdToIdMap; - // from old to new - IdToIdMap m_mapNames; - - // this is the threshold: if the total number of bytes in the subcomponent - // is less than this, the subcomponent isn't shown - unsigned m_nMinSubcomponentBytes; -}; - - - -////////////////////////////////////////////////////////////////////////// -// Renders the given usage stats; gets created upon every rendering -class CrySizerStatsRenderer -{ -public: - // constructor - CrySizerStatsRenderer (ISystem* pSystem, CrySizerStats* pStats, unsigned nMaxDepth = 2, int nMinSubcomponentBytes = -1); - void render(bool bRefreshMark = false); - // dumps it to log. uses MB as default - void dump (bool bUseKB = false); - -protected: // ------------------------------------------------- - - typedef CrySizerStats::Component Component; - - IRenderer* m_pRenderer; // - ILog* m_pLog; // - CrySizerStats* m_pStats; // - - ITextModeConsole* m_pTextModeConsole; - - // this is the threshold: if the total number of bytes in the subcomponent - // is less than this, the subcomponent isn't shown - unsigned m_nMinSubcomponentBytes; - - // the max depth of the branch to output - unsigned m_nMaxSubcomponentDepth; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_CRYSIZERSTATS_H diff --git a/Code/CryEngine/CrySystem/CrySystem.rc b/Code/CryEngine/CrySystem/CrySystem.rc deleted file mode 100644 index f3412468f5..0000000000 --- a/Code/CryEngine/CrySystem/CrySystem.rc +++ /dev/null @@ -1,91 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN -#pragma code_page(1252) - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000904b0" - BEGIN - VALUE "CompanyName", "Amazon.com, Inc." - VALUE "FileVersion", "1, 0, 0, 1" - VALUE "LegalCopyright", "Portions of this file Copyright (c) Amazon.com, Inc. or its affiliates. All Rights Reserved. Original file Copyright (c) Crytek GMBH. Used under license by Amazon.com, Inc. and its affiliates." - VALUE "ProductName", "Lumberyard" - VALUE "ProductVersion", "1, 0, 0, 1" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x9, 1200 - END -END - -#endif // German (Germany) resources -///////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////// -// English (United States) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""winres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED -#endif // English (United States) resources diff --git a/Code/CryEngine/CrySystem/CrySystem_precompiled.h b/Code/CryEngine/CrySystem/CrySystem_precompiled.h index b446199b4e..1fab2d4ce1 100644 --- a/Code/CryEngine/CrySystem/CrySystem_precompiled.h +++ b/Code/CryEngine/CrySystem/CrySystem_precompiled.h @@ -117,7 +117,6 @@ struct IRenderer; struct ISystem; struct ITimer; struct IFFont; -struct IKeyboard; struct ICVar; struct IConsole; struct IProcess; diff --git a/Code/CryEngine/CrySystem/CryThreadUtil_pthread.h b/Code/CryEngine/CrySystem/CryThreadUtil_pthread.h deleted file mode 100644 index 4c920898f0..0000000000 --- a/Code/CryEngine/CrySystem/CryThreadUtil_pthread.h +++ /dev/null @@ -1,259 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -////////////////////////////////////////////////////////////////////////// -// NOTE: INTERNAL HEADER NOT FOR PUBLIC USE -// This header should only be include by SystemThreading.cpp only -// It provides an interface for PThread intrinsics -// It's only client should be CThreadManager which should manage all thread interaction -#if !defined(INCLUDED_FROM_SYSTEM_THREADING_CPP) -# error "CRYTEK INTERNAL HEADER. ONLY INCLUDE FROM SYSTEMTHRADING.CPP." -#endif -////////////////////////////////////////////////////////////////////////// - -#define DEFAULT_THREAD_STACK_SIZE_KB 0 -#define CRY_PTHREAD_THREAD_NAME_MAX 16 - -////////////////////////////////////////////////////////////////////////// -// THREAD CREATION AND MANAGMENT -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - // Define type for platform specific thread handle - typedef pthread_t TThreadHandle; - - struct SThreadCreationDesc - { - // Define platform specific thread entry function functor type - typedef void* (* EntryFunc)(void*); - - const char* szThreadName; - EntryFunc fpEntryFunc; - void* pArgList; - uint32 nStackSizeInBytes; - }; - - ////////////////////////////////////////////////////////////////////////// - TThreadHandle CryGetCurrentThreadHandle() - { - return (TThreadHandle)pthread_self(); - } - - ////////////////////////////////////////////////////////////////////////// - // Note: Handle must be closed lated via CryCloseThreadHandle() - TThreadHandle CryDuplicateThreadHandle(const TThreadHandle& hThreadHandle) - { - // Do not do anything - // If you add a new platform which duplicates handles make sure to mirror the change in CryCloseThreadHandle(..) - return hThreadHandle; - } - - ////////////////////////////////////////////////////////////////////////// - void CryCloseThreadHandle(TThreadHandle& hThreadHandle) - { - pthread_detach(hThreadHandle); - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetCurrentThreadId() - { - return threadID(pthread_self()); - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetThreadId(TThreadHandle hThreadHandle) - { - return threadID(hThreadHandle); - } - - ////////////////////////////////////////////////////////////////////////// - // Note: On OSX the thread name can only be set by the thread itself. - void CrySetThreadName(TThreadHandle pThreadHandle, const char* sThreadName) - { - char threadName[CRY_PTHREAD_THREAD_NAME_MAX]; - if (!cry_strcpy(threadName, sThreadName)) - { - CryLog(" CrySetThreadName: input thread name '%s' truncated to '%s'", sThreadName, threadName); - } -#if AZ_TRAIT_OS_PLATFORM_APPLE - // On OSX the thread name can only be set by the thread itself. - assert(pthread_equal(pthread_self(), (pthread_t )pThreadHandle)); - - if (pthread_setname_np(threadName) != 0) -#else - if (pthread_setname_np(pThreadHandle, threadName) != 0) -#endif - { - switch (errno) - { - case ERANGE: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadName: Unable to rename thread \"%s\". Error Msg: \"Name to long. Exceeds %d bytes.\"", sThreadName, CRY_PTHREAD_THREAD_NAME_MAX); - break; - default: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadName: Unsupported error code: %i", errno); - break; - } - } - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadAffinityMask(TThreadHandle pThreadHandle, DWORD dwAffinityMask) - { -#if defined(AZ_PLATFORM_ANDROID) - // Not supported on ANDROID - // Alternative solution - // Watch out that android will clear the mask after a core has been switched off hence loosing the affinity mask setting! - // http://stackoverflow.com/questions/16319725/android-set-thread-affinity -#elif AZ_TRAIT_OS_PLATFORM_APPLE -# pragma message "Warning: CrySetThreadAffinityMask not implemented for platform" - // Implementation details can be found here - // https://developer.apple.com/library/mac/releasenotes/Performance/RN-AffinityAPI/ -#else - cpu_set_t cpu_mask; - CPU_ZERO(&cpu_mask); - for (int cpu = 0; cpu < sizeof(cpu_mask) * 8; ++cpu) - { - if (dwAffinityMask & (1 << cpu)) - { - CPU_SET(cpu, &cpu_mask); - } - } - - if (sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask) != 0) - { - switch (errno) - { - case EFAULT: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: Supplied memory address was invalid."); - break; - case EINVAL: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: The affinity bit mask [%u] contains no processors that are currently physically on the system and permitted to the process .", dwAffinityMask); - break; - case EPERM: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: The calling process does not have appropriate privileges. Mask [%u].", dwAffinityMask); - break; - case ESRCH: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: The process whose ID is pid could not be found."); - break; - default: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " CrySetThreadAffinityMask: Unsupported error code: %i", errno); - break; - } - } -#endif - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriority(TThreadHandle pThreadHandle, DWORD dwPriority) - { - int policy; - struct sched_param param; - - pthread_getschedparam(pThreadHandle, &policy, ¶m); - param.sched_priority = sched_get_priority_max(dwPriority); - pthread_setschedparam(pThreadHandle, policy, ¶m); - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriorityBoost(TThreadHandle pThreadHandle, bool bEnabled) - { - // Not supported - } - - ////////////////////////////////////////////////////////////////////////// - bool CryCreateThread(TThreadHandle* pThreadHandle, const SThreadCreationDesc& threadDesc) - { - uint32 nStackSize = threadDesc.nStackSizeInBytes != 0 ? threadDesc.nStackSizeInBytes : DEFAULT_THREAD_STACK_SIZE_KB * 1024; - - assert(pThreadHandle != reinterpret_cast(THREADID_NULL)); - pthread_attr_t threadAttr; - sched_param schedParam; - pthread_attr_init(&threadAttr); - pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setstacksize(&threadAttr, nStackSize); - - const int err = pthread_create( - pThreadHandle, - &threadAttr, - threadDesc.fpEntryFunc, - threadDesc.pArgList); - - // Handle error on thread creation - switch (err) - { - case 0: - // No error - break; - case EAGAIN: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Error Msg: \"Insufficient resources to create another thread, or a system-imposed limit on the number of threads was encountered.\"", threadDesc.szThreadName); - return false; - case EINVAL: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Error Msg: \"Invalid attribute setting for thread creation.\"", threadDesc.szThreadName); - return false; - case EPERM: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Error Msg: \"No permission to set the scheduling policy and parameters specified in attribute setting\"", threadDesc.szThreadName); - return false; - default: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". Unknown error message. Error code %i", threadDesc.szThreadName, err); - break; - } - - // Print info to log - CryComment(": New thread \"%s\" | StackSize: %u(KB)", threadDesc.szThreadName, threadDesc.nStackSizeInBytes / 1024); - return true; - } - - ////////////////////////////////////////////////////////////////////////// - void CryThreadExitCall() - { - // Notes on: pthread_exit - // A thread that was create with pthread_create implicitly calls pthread_exit when the thread returns from its start routine (the function that was first called after a thread was created). - // pthread_exit(NULL); - } -} - - -////////////////////////////////////////////////////////////////////////// -// FLOATING POINT EXCEPTIONS -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - /////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions(EFPE_Severity eFPESeverity) - { - // TODO: - // Not implemented - // for potential implementation see http://linux.die.net/man/3/feenableexcept - } - - ////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions(threadID nThreadId, EFPE_Severity eFPESeverity) - { - // TODO: - // Not implemented - // for potential implementation see http://linux.die.net/man/3/feenableexcept - } - - ////////////////////////////////////////////////////////////////////////// - uint GetFloatingPointExceptionMask() - { - // Not implemented - return ~0; - } - - ////////////////////////////////////////////////////////////////////////// - void SetFloatingPointExceptionMask(uint nMask) - { - // Not implemented - } -} diff --git a/Code/CryEngine/CrySystem/CryThreadUtil_win32_thread.h b/Code/CryEngine/CrySystem/CryThreadUtil_win32_thread.h deleted file mode 100644 index e5c7510feb..0000000000 --- a/Code/CryEngine/CrySystem/CryThreadUtil_win32_thread.h +++ /dev/null @@ -1,432 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -////////////////////////////////////////////////////////////////////////// -// NOTE: INTERNAL HEADER NOT FOR PUBLIC USE -// This header should only be include by SystemThreading.cpp only -// It provides an interface for WinApi intrinsics -// It's only client should be CThreadManager which should manage all thread interaction - -#pragma once - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CRYTHREADUTIL_WIN32_THREAD_H_SECTION_1 1 -#define CRYTHREADUTIL_WIN32_THREAD_H_SECTION_2 2 -#endif - -#if !defined(INCLUDED_FROM_SYSTEM_THREADING_CPP) -# error "CRYTEK INTERNAL HEADER. ONLY INCLUDE FROM SYSTEMTHRADING.CPP." -#endif -////////////////////////////////////////////////////////////////////////// - -#define DEFAULT_THREAD_STACK_SIZE_KB 0 - -// Returns the last Win32 error, in string format. Returns an empty string if there is no error. -static string GetLastErrorAsString() -{ - // Get the error message, if any. - DWORD errorMessageID = GetLastError(); - if (errorMessageID == 0) - { - return ""; - } - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CRYTHREADUTIL_WIN32_THREAD_H_SECTION_1 -#include AZ_RESTRICTED_FILE(CryThreadUtil_win32_thread_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - LPSTR messageBuffer = nullptr; - size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), messageBuffer, 0, NULL); - - string message(messageBuffer, size); - - // Free the buffer. - LocalFree(messageBuffer); - - return message; -#endif -} - -////////////////////////////////////////////////////////////////////////// -// THREAD CREATION AND MANAGMENT -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - // Define type for platform specific thread handle - typedef THREAD_HANDLE TThreadHandle; - - struct SThreadCreationDesc - { - // Define platform specific thread entry function functor type - typedef unsigned int(_stdcall * EntryFunc)(void*); - - const char* szThreadName; - EntryFunc fpEntryFunc; - void* pArgList; - uint32 nStackSizeInBytes; - }; - - ////////////////////////////////////////////////////////////////////////// - TThreadHandle CryGetCurrentThreadHandle() - { - return GetCurrentThread(); // most likely returns pseudo handle (0xfffffffe) - } - - ////////////////////////////////////////////////////////////////////////// - // Note: Handle must be closed lated via CryCloseThreadHandle() - TThreadHandle CryDuplicateThreadHandle(const TThreadHandle& hThreadHandle) - { - // NOTES: - // GetCurrentThread() may return a psydo handle to the current thread - // to avoid going into the slower kernel mode. - // Hence the handle is useless when being used from an other thread. - // - GetCurrentThread() -> 0xfffffffe - // - GetCurrentProcess() -> 0xffffffff - - HANDLE hRealHandle = 0; - DuplicateHandle(GetCurrentProcess(), // Source Process Handle. - hThreadHandle, // Source Handle to dup. - GetCurrentProcess(), // Target Process Handle. - &hRealHandle, // Target Handle pointer. - 0, // Options flag. - TRUE, // Inheritable flag - DUPLICATE_SAME_ACCESS); // Options - - return (TThreadHandle)hRealHandle; - } - - ////////////////////////////////////////////////////////////////////////// - void CryCloseThreadHandle(TThreadHandle& hThreadHandle) - { - if (hThreadHandle) - { - CloseHandle(hThreadHandle); - } - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetCurrentThreadId() - { - return GetCurrentThreadId(); - } - - ////////////////////////////////////////////////////////////////////////// - threadID CryGetThreadId(TThreadHandle hThreadHandle) - { - return GetThreadId(hThreadHandle); - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadName(TThreadHandle pThreadHandle, const char* sThreadName) - { - const DWORD MS_VC_EXCEPTION = 0x406D1388; - - struct SThreadNameDesc - { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. - }; - - SThreadNameDesc info; - info.dwType = 0x1000; - info.szName = sThreadName; - info.dwThreadID = GetThreadId(pThreadHandle); - info.dwFlags = 0; -AZ_PUSH_DISABLE_WARNING(6312 6322, "-Wunknown-warning-option") - // warning C6312: Possible infinite loop: use of the constant EXCEPTION_CONTINUE_EXECUTION in the exception-filter expression of a try-except - // warning C6322: empty _except block - __try - { - // Raise exception to set thread name for attached debugger - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR*)&info); - } - __except (GetExceptionCode() == MS_VC_EXCEPTION ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER) - { - } -AZ_POP_DISABLE_WARNING - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadAffinityMask(TThreadHandle pThreadHandle, DWORD dwAffinityMask) - { - SetThreadAffinityMask(pThreadHandle, dwAffinityMask); - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriority(TThreadHandle pThreadHandle, DWORD dwPriority) - { - if (!SetThreadPriority(pThreadHandle, dwPriority)) - { - string errMsg = GetLastErrorAsString(); - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to set thread priority. System Error Msg: \"%s\"", errMsg.c_str()); - return; - } - } - - ////////////////////////////////////////////////////////////////////////// - void CrySetThreadPriorityBoost(TThreadHandle pThreadHandle, bool bEnabled) - { - SetThreadPriorityBoost(pThreadHandle, !bEnabled); - } - - ////////////////////////////////////////////////////////////////////////// - bool CryCreateThread(TThreadHandle* pThreadHandle, const SThreadCreationDesc& threadDesc) - { - const uint32 nStackSize = threadDesc.nStackSizeInBytes != 0 ? threadDesc.nStackSizeInBytes : DEFAULT_THREAD_STACK_SIZE_KB * 1024; - - // Create thread - unsigned int threadId = 0; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CRYTHREADUTIL_WIN32_THREAD_H_SECTION_2 -#include AZ_RESTRICTED_FILE(CryThreadUtil_win32_thread_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - *pThreadHandle = (void*)_beginthreadex(NULL, nStackSize, threadDesc.fpEntryFunc, threadDesc.pArgList, CREATE_SUSPENDED, &threadId); -#endif - - if (!(*pThreadHandle)) - { - string errMsg = GetLastErrorAsString(); - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Unable to create thread \"%s\". System Error Msg: \"%s\"", threadDesc.szThreadName, errMsg.c_str()); - return false; - } - - // Start thread - ResumeThread(*pThreadHandle); - - // Print info to log - CryComment(": New thread \"%s\" | StackSize: %u(KB)", threadDesc.szThreadName, threadDesc.nStackSizeInBytes / 1024); - return true; - } - - ////////////////////////////////////////////////////////////////////////// - void CryThreadExitCall() - { - // Note on: ExitThread() (from MSDN) - // ExitThread is the preferred method of exiting a thread in C code. - // However, in C++ code, the thread is exited before any destructor can be called or any other automatic cleanup can be performed. - // Therefore, in C++ code, you should return from your thread function. - } -} - -////////////////////////////////////////////////////////////////////////// -// FLOATING POINT EXCEPTIONS -////////////////////////////////////////////////////////////////////////// -namespace CryThreadUtil -{ - /////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions([[maybe_unused]] EFPE_Severity eFPESeverity) - { -AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option") - - // Optimization - // Enable DAZ/FZ - // Denormals Are Zeros - // Flush-to-Zero - _controlfp(_DN_FLUSH, _MCW_DN); - _mm_setcsr(_mm_getcsr() | _MM_FLUSH_ZERO_ON); - -#ifndef _RELEASE - if (eFPESeverity == eFPE_None) - { - // mask all floating exceptions off. - _controlfp(_MCW_EM, _MCW_EM); - _mm_setcsr(_mm_getcsr() | _MM_MASK_MASK); - } - else - { - // Clear pending exceptions - _fpreset(); - - if (eFPESeverity == eFPE_Basic) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - // Disable: - // - _EM_DENORMAL - // - _EM_OVERFLOW - // - _EM_UNDERFLOW - // - _EM_INEXACT - - _controlfp(_EM_INEXACT | _EM_DENORMAL | _EM_UNDERFLOW | _EM_OVERFLOW, _MCW_EM); - _mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (_MM_MASK_DENORM | _MM_MASK_INEXACT | _MM_MASK_UNDERFLOW | _MM_MASK_OVERFLOW)); - - //_mm_setcsr(_mm_getcsr() & ~0x280); - } - - if (eFPESeverity == eFPE_All) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - _EM_UNDERFLOW - // - _EM_OVERFLOW - // - // Disable: - // - _EM_INEXACT - // - _EM_DENORMAL - - _controlfp(_EM_INEXACT | _EM_DENORMAL, _MCW_EM); - _mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (_MM_MASK_INEXACT | _MM_MASK_DENORM)); - } - } -#endif // _RELEASE - -AZ_POP_DISABLE_WARNING -} - - ////////////////////////////////////////////////////////////////////////// - void EnableFloatExceptions(threadID nThreadId, EFPE_Severity eFPESeverity) - { - if (eFPESeverity >= eFPE_LastEntry) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Floating Point Exception (FPE) severity is out of range. (%i)", eFPESeverity); - } - - // Check if the thread ID matches the current thread - if (nThreadId == 0 || nThreadId == CryGetCurrentThreadId()) - { - EnableFloatExceptions(eFPESeverity); - return; - } - - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, true, nThreadId); - - if (hThread == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Unable to open thread. %p", hThread); - return; - } - - SuspendThread(hThread); - - CONTEXT ctx; - memset(&ctx, 0, sizeof(ctx)); - ctx.ContextFlags = CONTEXT_ALL; - if (GetThreadContext(hThread, &ctx) == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Unable to get thread context"); - ResumeThread(hThread); - CloseHandle(hThread); - return; - } - -#ifdef PLATFORM_64BIT - ////////////////////////////////////////////////////////////////////////// - // Note: - // DO NOT USE ctx.FltSave.MxCsr ... SetThreadContext() will copy the value of ctx.MxCsr into it - ////////////////////////////////////////////////////////////////////////// - DWORD& floatMxCsr = ctx.MxCsr; // Hold FPE Mask and Status for MMX (SSE) floating point registers - WORD& floatControlWord = ctx.FltSave.ControlWord; // Hold FPE Mask for floating point registers - #ifndef _RELEASE - WORD& floatStatuslWord = ctx.FltSave.StatusWord; // Holds FPE Status for floating point registers - #endif -#else - DWORD& floatMxCsr = *(DWORD*)(&ctx.ExtendedRegisters[24]); // Hold FPE Mask and Status for MMX (SSE) floating point registers - DWORD& floatControlWord = ctx.FloatSave.ControlWord; // Hold FPE Mask for floating point registers - DWORD& floatStatuslWord = ctx.FloatSave.StatusWord; // Holds FPE Status for floating point registers -#endif - - // Flush-To-Zero Mode - // Two conditions must be met for FTZ processing to occur: - // - The FTZ bit (bit 15) in the MXCSR register must be masked (value = 1). - // - The underflow exception (bit 11) needs to be masked (value = 1). - - // Set flush mode to zero mode - floatControlWord = (floatControlWord & ~_MCW_DN) | _DN_FLUSH; - floatMxCsr = (floatMxCsr & ~_MM_FLUSH_ZERO_MASK) | (_MM_FLUSH_ZERO_ON); - -#ifndef _RELEASE - - // Reset FPE bits - floatControlWord = floatControlWord | _MCW_EM; - floatMxCsr = floatMxCsr | _MM_MASK_MASK; - - // Clear pending exceptions - floatStatuslWord = floatStatuslWord & ~(_SW_INEXACT | _SW_UNDERFLOW | _SW_OVERFLOW | _SW_ZERODIVIDE | _SW_INVALID | _SW_DENORMAL); - floatMxCsr = floatMxCsr & ~(_MM_EXCEPT_INEXACT | _MM_EXCEPT_UNDERFLOW | _MM_EXCEPT_OVERFLOW | _MM_EXCEPT_DIV_ZERO | _MM_EXCEPT_INVALID | _MM_EXCEPT_DENORM); - - if (eFPESeverity == eFPE_Basic) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - // Disable: - // - _EM_DENORMAL - // - _EM_OVERFLOW - // - _EM_UNDERFLOW - // - _EM_INEXACT - - floatControlWord = (floatControlWord & ~_MCW_EM) | (_EM_DENORMAL | _EM_INEXACT | EM_UNDERFLOW | _EM_OVERFLOW); - floatMxCsr = (floatMxCsr & ~_MM_MASK_MASK) | (_MM_MASK_DENORM | _MM_MASK_INEXACT | _MM_MASK_UNDERFLOW | _MM_MASK_OVERFLOW); - } - - if (eFPESeverity == eFPE_All) - { - // Enable: - // - _EM_ZERODIVIDE - // - _EM_INVALID - // - _EM_UNDERFLOW - // - _EM_OVERFLOW - // - // Disable: - // - _EM_INEXACT - // - _EM_DENORMAL - - floatControlWord = (floatControlWord & ~_MCW_EM) | (_EM_INEXACT | _EM_DENORMAL); - floatMxCsr = (floatMxCsr & ~_MM_MASK_MASK) | (_MM_MASK_INEXACT | _MM_MASK_DENORM); - } -#endif - - ctx.ContextFlags = CONTEXT_ALL; - if (SetThreadContext(hThread, &ctx) == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Error setting ThreadContext for ThreadID: %u", nThreadId); - ResumeThread(hThread); - CloseHandle(hThread); - return; - } - - ResumeThread(hThread); - CloseHandle(hThread); - } - - ////////////////////////////////////////////////////////////////////////// - uint GetFloatingPointExceptionMask() - { - uint nMask = 0; - _clearfp(); - _controlfp_s(&nMask, 0, 0); - return nMask; - } - - ////////////////////////////////////////////////////////////////////////// - void SetFloatingPointExceptionMask(uint nMask) - { - uint temp = 0; - _clearfp(); - const unsigned int kAllowedBits = _MCW_DN | _MCW_EM | _MCW_RC; - _controlfp_s(&temp, nMask, kAllowedBits); - } -} diff --git a/Code/CryEngine/CrySystem/CryWaterMark.h b/Code/CryEngine/CrySystem/CryWaterMark.h deleted file mode 100644 index 4272b63aab..0000000000 --- a/Code/CryEngine/CrySystem/CryWaterMark.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Header for adding a watermark to an exe, which can then be set -// by the external CryWaterMark program. To use, simply write: -// -// WATERMARKDATA(__blah); -// -// anywhere in the global scope in the program - - -#ifndef CRYINCLUDE_CRYSYSTEM_CRYWATERMARK_H -#define CRYINCLUDE_CRYSYSTEM_CRYWATERMARK_H -#pragma once - - -#define NUMMARKWORDS 10 -#define WATERMARKDATA(name) unsigned int name[] = { 0xDEBEFECA, 0xFABECEDA, 0xADABAFBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -// (the name is such that you can have multiple watermarks in one exe, don't use -// names like "watermark" just incase you accidentally give out an exe with -// debug information). - -#endif // CRYINCLUDE_CRYSYSTEM_CRYWATERMARK_H diff --git a/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp b/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp deleted file mode 100644 index efc03779de..0000000000 --- a/Code/CryEngine/CrySystem/CustomMemoryHeap.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CustomMemoryHeap.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define CUSTOMMEMORYHEAP_CPP_SECTION_1 1 -#define CUSTOMMEMORYHEAP_CPP_SECTION_2 2 -#define CUSTOMMEMORYHEAP_CPP_SECTION_3 3 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeapBlock::CCustomMemoryHeapBlock(CCustomMemoryHeap* pHeap) - : m_pHeap(pHeap) - , m_pData(0) - , m_nSize(0) - , m_nGPUHandle(0) -{ -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeapBlock::~CCustomMemoryHeapBlock() -{ - m_pHeap->DeallocateBlock(this); -} - -////////////////////////////////////////////////////////////////////////// -void* CCustomMemoryHeapBlock::GetData() -{ - return m_pData; -} - -////////////////////////////////////////////////////////////////////////// -void CCustomMemoryHeapBlock::CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize) -{ - assert(nOffset + nSize <= m_nSize); - if (nOffset + nSize <= m_nSize) - { - memcpy(pOutputBuffer, (uint8*)m_pData + nOffset, nSize); - } - else - { - CryFatalError("Bad CopyMemoryRegion range"); - } -} - -////////////////////////////////////////////////////////////////////////// -ICustomMemoryBlock* CCustomMemoryHeap::AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment /* = 16 */) -{ - CCustomMemoryHeapBlock* pBlock = new CCustomMemoryHeapBlock(this); - pBlock->m_sUsage = sUsage; - pBlock->m_nSize = nAllocateSize; - - switch (m_eAllocPolicy) - { - case IMemoryManager::eapDefaultAllocator: - { - size_t allocated = 0; - pBlock->m_pData = CryMalloc(nAllocateSize, allocated, nAlignment); - break; - } - case IMemoryManager::eapPageMapped: - pBlock->m_pData = CryMemory::AllocPages(nAllocateSize); - break; - case IMemoryManager::eapCustomAlignment: -#if defined(DEBUG) - if (nAlignment == 0) - { - CryFatalError("CCustomMemoryHeap: trying to allocate memory via eapCustomAlignment with an alignment of zero!"); - } -#endif - pBlock->m_pData = CryModuleMemalign(nAllocateSize, nAlignment); - break; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - default: - CryFatalError("CCustomMemoryHeap: unknown allocation policy during AllocateBlock!"); - break; - } - - CryInterlockedAdd(&m_nAllocatedSize, nAllocateSize); - - return pBlock; -} - -void CCustomMemoryHeap::DeallocateBlock(CCustomMemoryHeapBlock* pBlock) -{ - switch (m_eAllocPolicy) - { - case IMemoryManager::eapDefaultAllocator: - CryFree(pBlock->m_pData, 0); - break; - case IMemoryManager::eapPageMapped: - CryMemory::FreePages(pBlock->m_pData, pBlock->GetSize()); - break; - case IMemoryManager::eapCustomAlignment: - CryModuleMemalignFree(pBlock->m_pData); - break; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION CUSTOMMEMORYHEAP_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE(CustomMemoryHeap_cpp) -#endif - default: - CryFatalError("CCustomMemoryHeap: unknown allocation policy during DeallocateBlock!"); - break; - } - - int nAllocateSize = (int)pBlock->m_nSize; - CryInterlockedAdd(&m_nAllocatedSize, -nAllocateSize); -} - -////////////////////////////////////////////////////////////////////////// -void CCustomMemoryHeap::GetMemoryUsage(ICrySizer* pSizer) -{ - pSizer->AddObject(this, m_nAllocatedSize); -} - -////////////////////////////////////////////////////////////////////////// -size_t CCustomMemoryHeap::GetAllocated() -{ - return m_nAllocatedSize; -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeap::CCustomMemoryHeap(IMemoryManager::EAllocPolicy const eAllocPolicy) -{ - m_nAllocatedSize = 0; - m_eAllocPolicy = eAllocPolicy; - m_nTraceHeapHandle = 0; -} - -////////////////////////////////////////////////////////////////////////// -CCustomMemoryHeap::~CCustomMemoryHeap() -{ -} diff --git a/Code/CryEngine/CrySystem/DebugCallStack.cpp b/Code/CryEngine/CrySystem/DebugCallStack.cpp index da3876a422..2a219ce674 100644 --- a/Code/CryEngine/CrySystem/DebugCallStack.cpp +++ b/Code/CryEngine/CrySystem/DebugCallStack.cpp @@ -18,13 +18,25 @@ #include #include -#include #include "System.h" #include #include -#include "resource.h" +#define VS_VERSION_INFO 1 +#define IDD_CRITICAL_ERROR 101 +#define IDB_CONFIRM_SAVE 102 +#define IDB_DONT_SAVE 103 +#define IDD_CONFIRM_SAVE_LEVEL 127 +#define IDB_CRASH_FACE 128 +#define IDD_EXCEPTION 245 +#define IDC_CALLSTACK 1001 +#define IDC_EXCEPTION_CODE 1002 +#define IDC_EXCEPTION_ADDRESS 1003 +#define IDC_EXCEPTION_MODULE 1004 +#define IDC_EXCEPTION_DESC 1005 +#define IDB_EXIT 1008 +#define IDB_IGNORE 1010 __pragma(comment(lib, "version.lib")) //! Needs one external of DLL handle. @@ -276,29 +288,6 @@ int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer) sprintf_s(excAddr, "0x%04X:0x%p", exception_pointer->ContextRecord->SegCs, exception_pointer->ExceptionRecord->ExceptionAddress); sprintf_s(excCode, "0x%08X", exception_pointer->ExceptionRecord->ExceptionCode); WriteLineToLog("Exception: %s, at Address: %s", excCode, excAddr); - - { - IMemoryManager::SProcessMemInfo memInfo; - if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo)) - { - uint32 nMemUsage = (uint32)(memInfo.PagefileUsage / (1024 * 1024)); - WriteLineToLog("Virtual memory usage: %dMb", nMemUsage); - } - gEnv->szDebugStatus[SSystemGlobalEnvironment::MAX_DEBUG_STRING_LENGTH - 1] = '\0'; - WriteLineToLog("Debug Status: %s", gEnv->szDebugStatus); - } - - if (gEnv->pRenderer) - { - ID3DDebugMessage* pMsg = 0; - gEnv->pRenderer->EF_Query(EFQ_GetLastD3DDebugMessage, pMsg); - if (pMsg) - { - const char* pStr = pMsg->GetMessage(); - WriteLineToLog("Last D3D debug message: %s", pStr ? pStr : "#unknown#"); - SAFE_RELEASE(pMsg); - } - } } firstTime = false; @@ -422,8 +411,6 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex) FILE* f = nullptr; azfopen(&f, fileName.c_str(), "wt"); - CDebugAllowFileAccess ignoreInvalidFileAccess; - static char errorString[s_iCallStackSize]; errorString[0] = 0; @@ -498,33 +485,9 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex) excCode, excAddr, m_excModule, excName, desc); - IMemoryManager::SProcessMemInfo memInfo; - if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo)) - { - char memoryString[256]; - double MB = 1024 * 1024; - sprintf_s(memoryString, "Memory in use: %3.1fMB\n", (double)(memInfo.PagefileUsage) / MB); - cry_strcat(errs, memoryString); - } - { - const int tempStringSize = 256; - char tempString[tempStringSize]; - - gEnv->szDebugStatus[SSystemGlobalEnvironment::MAX_DEBUG_STRING_LENGTH - 1] = '\0'; - sprintf_s(tempString, tempStringSize, "Debug Status: %s\n", gEnv->szDebugStatus); - cry_strcat(errs, tempString); - - sprintf_s(tempString, tempStringSize, "Out of Memory: %d\n", gEnv->bIsOutOfMemory); - cry_strcat(errs, tempString); - } cry_strcat(errs, "\nCall Stack Trace:\n"); std::vector funcs; - if (gEnv->bIsOutOfMemory) - { - cry_strcat(errs, "1) OUT_OF_MEMORY()\n"); - } - else { AZ::Debug::StackFrame frames[25]; AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)]; @@ -558,7 +521,6 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex) if (f) { fwrite(errorString, strlen(errorString), 1, f); - if (!gEnv->bIsOutOfMemory) { if (g_cvars.sys_dump_aux_threads) { @@ -832,17 +794,6 @@ int DebugCallStack::SubmitBug(EXCEPTION_POINTERS* exception_pointer) assert(!hwndException); - // If in full screen minimize render window - { - ICVar* pFullscreen = (gEnv && gEnv->pConsole) ? gEnv->pConsole->GetCVar("r_Fullscreen") : 0; - if (pFullscreen && pFullscreen->GetIVal() != 0 && gEnv->pRenderer && gEnv->pRenderer->GetHWND()) - { - ::ShowWindow((HWND)gEnv->pRenderer->GetHWND(), SW_MINIMIZE); - } - } - - //hwndException = CreateDialog( gDLLHandle,MAKEINTRESOURCE(IDD_EXCEPTION),NULL,NULL ); - RemoveOldFiles(); AZ::Debug::Trace::PrintCallstack("", 2); diff --git a/Code/CryEngine/CrySystem/DefragAllocator.cpp b/Code/CryEngine/CrySystem/DefragAllocator.cpp deleted file mode 100644 index 8858724be1..0000000000 --- a/Code/CryEngine/CrySystem/DefragAllocator.cpp +++ /dev/null @@ -1,1976 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "DefragAllocator.h" -#include "IRenderAuxGeom.h" - -CDefragAllocatorWalker::CDefragAllocatorWalker(CDefragAllocator& alloc) -{ - m_pAlloc = &alloc; - m_pAlloc->m_lock.Lock(); - - m_nChunkIdx = CDefragAllocator::AddrStartSentinal; -} - -CDefragAllocatorWalker::~CDefragAllocatorWalker() -{ - m_pAlloc->m_lock.Unlock(); -} - -const SDefragAllocChunk* CDefragAllocatorWalker::Next() -{ - m_nChunkIdx = m_pAlloc->m_chunks[m_nChunkIdx].addrNextIdx; - if (m_nChunkIdx == CDefragAllocator::AddrEndSentinal) - { - return NULL; - } - return &m_pAlloc->m_chunks[m_nChunkIdx]; -} - -CDefragAllocator::CDefragAllocator() - : m_isThreadSafe(false) - , m_chunksAreFixed(false) - , m_capacity(0) - , m_available(0) - , m_numAllocs(0) - , m_minAlignment(1) - , m_logMinAlignment(0) - , m_nCancelledMoves(0) -{ -} - -CDefragAllocator::~CDefragAllocator() -{ -} - -void CDefragAllocator::Release(bool bDiscard) -{ - if (!bDiscard) - { - if (m_policy.pDefragPolicy) - { - Defrag_CompletePendingMoves(); - } - - for (PendingMoveVec::iterator it = m_pendingMoves.begin(), itEnd = m_pendingMoves.end(); it != itEnd; ++it) - { - CDBA_ASSERT(it->dstChunkIdx == InvalidChunkIdx); - } - } - - delete this; -} - -void CDefragAllocator::Init(UINT_PTR capacity, UINT_PTR minAlignment, const Policy& policy) -{ - CDBA_ASSERT((capacity & (minAlignment - 1)) == 0); - CDBA_ASSERT((minAlignment & (minAlignment - 1)) == 0); - CDBA_ASSERT(!policy.pDefragPolicy || policy.maxAllocs > 0); - CDBA_ASSERT((capacity / minAlignment) < (1 << SDefragAllocChunkAttr::SizeWidth)); - - uint32 logMinAlignment = (uint32)IntegerLog2(minAlignment); - - capacity >>= logMinAlignment; - - CDBA_ASSERT(capacity <= (uint32) - 1); - - m_isThreadSafe = policy.pDefragPolicy != NULL; - - m_capacity = (uint32)capacity; - m_available = (uint32)capacity; - m_numAllocs = 0; - - m_minAlignment = (uint32)minAlignment; - m_logMinAlignment = logMinAlignment; - - m_chunks.clear(); - m_unusedChunks.clear(); - - m_policy = policy; - if (policy.pDefragPolicy) - { - m_pendingMoves.resize(MaxPendingMoves); - } - - m_chunks.reserve(NumBuckets + 3); - - // Create sentinal chunk for by-address list - { - SDefragAllocChunk addrStartSentinal = {0}; - addrStartSentinal.addrNextIdx = 1; - addrStartSentinal.addrPrevIdx = 1; - addrStartSentinal.attr.SetBusy(true); - addrStartSentinal.ptr = 0; - m_chunks.push_back(addrStartSentinal); - - SDefragAllocChunk addrEndSentinal = {0}; - addrEndSentinal.addrNextIdx = 0; - addrEndSentinal.addrPrevIdx = 0; - addrEndSentinal.attr.SetBusy(true); - addrEndSentinal.ptr = m_capacity; - m_chunks.push_back(addrEndSentinal); - } - - SDefragAllocSegment seg; - seg.address = 0; - seg.capacity = (uint32)capacity; - seg.headSentinalChunkIdx = AddrStartSentinal; - - // Create sentinal chunks for the bucket lists - for (size_t bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx) - { - Index chunkIdx = bucketIdx + 2; - - SDefragAllocChunk chunk = {0}; - chunk.attr.SetBusy(true); - chunk.freeNextIdx = chunkIdx; - chunk.freePrevIdx = chunkIdx; - - m_freeBuckets[bucketIdx] = chunkIdx; - m_chunks.push_back(chunk); - } - - Index totalChunkIdx = AllocateChunk(); - SDefragAllocChunk& totalChunk = m_chunks[totalChunkIdx]; - totalChunk.attr.SetSize((unsigned int)capacity); - totalChunk.attr.SetPinCount(0); - totalChunk.attr.SetMoving(0); - LinkAddrChunk(totalChunkIdx, 0); - LinkFreeChunk(totalChunkIdx); - - if (policy.maxAllocs > 0) - { - size_t curChunksSize = m_chunks.size(); - m_chunks.resize(policy.maxAllocs); - for (Index i = (Index)curChunksSize, c = (Index)m_chunks.size(); i < c; ++i) - { - m_unusedChunks.push_back(i); - } - } - - m_chunksAreFixed = policy.pDefragPolicy != NULL; - - m_segments.reserve(policy.maxSegments); - m_segments.push_back(seg); -} - -#ifndef _RELEASE -void CDefragAllocator::DumpState(const char* filename) -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - - FILE* fp = nullptr; - azfopen(&fp, filename, "wb"); - if (fp) - { - uint32 magic = 0xdef7a6e7; - fwrite(&magic, sizeof(magic), 1, fp); - - fwrite(&m_capacity, sizeof(m_capacity), 1, fp); - fwrite(&m_available, sizeof(m_available), 1, fp); - fwrite(&m_numAllocs, sizeof(m_numAllocs), 1, fp); - fwrite(&m_minAlignment, sizeof(m_minAlignment), 1, fp); - fwrite(&m_logMinAlignment, sizeof(m_logMinAlignment), 1, fp); - fwrite(&m_freeBuckets[0], sizeof(m_freeBuckets), 1, fp); - - uint32 numChunks = (uint32)m_chunks.size(); - fwrite(&numChunks, sizeof(numChunks), 1, fp); - fwrite(&m_chunks[0], sizeof(m_chunks[0]), numChunks, fp); - uint32 numUnused = (uint32)m_unusedChunks.size(); - fwrite(&numUnused, sizeof(numUnused), 1, fp); - fwrite(&m_unusedChunks[0], sizeof(m_unusedChunks[0]), numUnused, fp); - uint32 numPending = (uint32)m_pendingMoves.size(); - fwrite(&numPending, sizeof(numPending), 1, fp); - fwrite(&m_pendingMoves[0], sizeof(m_pendingMoves[0]), numPending, fp); - uint32 numSegs = (uint32)m_segments.size(); - fwrite(&numSegs, sizeof(numSegs), 1, fp); - fwrite(&m_segments[0], sizeof(m_segments[0]), numSegs, fp); - - fclose(fp); - } -} - -void CDefragAllocator::RestoreState(const char* filename) -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - - FILE* fp = nullptr; - azfopen(&fp, filename, "rb"); - if (fp) - { - uint32 magic; - fread(&magic, sizeof(magic), 1, fp); - - bool bSwap = magic == 0xe7a6f7de; - - fread(&m_capacity, sizeof(m_capacity), 1, fp); - SwapEndian(m_capacity, bSwap); - - fread(&m_available, sizeof(m_available), 1, fp); - SwapEndian(m_available, bSwap); - - fread(&m_numAllocs, sizeof(m_numAllocs), 1, fp); - SwapEndian(m_numAllocs, bSwap); - - fread(&m_minAlignment, sizeof(m_minAlignment), 1, fp); - SwapEndian(m_minAlignment, bSwap); - - fread(&m_logMinAlignment, sizeof(m_logMinAlignment), 1, fp); - SwapEndian(m_logMinAlignment, bSwap); - - fread(&m_freeBuckets[0], sizeof(m_freeBuckets), 1, fp); - SwapEndian(&m_freeBuckets[0], NumBuckets, bSwap); - - uint32 numChunks; - fread(&numChunks, sizeof(numChunks), 1, fp); - SwapEndian(numChunks, bSwap); - - m_chunks.resize(numChunks); - fread(&m_chunks[0], sizeof(m_chunks[0]), numChunks, fp); - if (bSwap) - { - for (size_t ci = 0, cc = m_chunks.size(); ci != cc; ++ci) - { - m_chunks[ci].SwapEndian(); - } - } - - uint32 numUnused; - fread(&numUnused, sizeof(numUnused), 1, fp); - SwapEndian(numUnused, bSwap); - - m_unusedChunks.resize(numUnused); - fread(&m_unusedChunks[0], sizeof(m_unusedChunks[0]), numUnused, fp); - SwapEndian(&m_unusedChunks[0], m_unusedChunks.size(), bSwap); - - uint32 numPending; - fread(&numPending, sizeof(numPending), 1, fp); - SwapEndian(numPending, bSwap); - - m_pendingMoves.resize(numPending); - fread(&m_pendingMoves[0], sizeof(m_pendingMoves[0]), numPending, fp); - if (bSwap) - { - for (size_t pi = 0, pc = m_pendingMoves.size(); pi != pc; ++pi) - { - m_pendingMoves[pi].SwapEndian(); - } - } - - uint32 numSegs; - fread(&numSegs, sizeof(numSegs), 1, fp); - SwapEndian(numSegs, bSwap); - - m_segments.resize(numSegs); - fread(&m_segments[0], sizeof(m_segments[0]), numSegs, fp); - if (bSwap) - { - for (size_t si = 0, sc = m_segments.size(); si != sc; ++si) - { - m_segments[si].SwapEndian(); - } - } - - fclose(fp); - - RebuildFreeLists(); - -#ifdef CDBA_MORE_DEBUG - ValidateAddressChain(); - ValidateFreeLists(); -#endif - } -} -#endif - -bool CDefragAllocator::AppendSegment(UINT_PTR capacity) -{ - CDBA_ASSERT((capacity & (m_minAlignment - 1)) == 0); - - bool bSuccessful = false; - - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - - capacity >>= m_logMinAlignment; - - // Create a sentinal chunk for the head of the new segment. - Index headSentinalIdx = AllocateChunk(); - if (headSentinalIdx != InvalidChunkIdx) - { - // And a free block. - Index freeBlockIdx = AllocateChunk(); - if (freeBlockIdx != InvalidChunkIdx) - { - SDefragAllocChunk& headSentinalChunk = m_chunks[headSentinalIdx]; - SDefragAllocChunk& freeChunk = m_chunks[freeBlockIdx]; - SDefragAllocChunk& addrEndSentinal = m_chunks[AddrEndSentinal]; - - uint32 allocCapacity = m_capacity; - - headSentinalChunk.ptr = allocCapacity; -#ifndef _RELEASE - headSentinalChunk.source = "Segment Sentinal"; -#endif - headSentinalChunk.attr.SetBusy(true); - headSentinalChunk.attr.SetMoving(false); - headSentinalChunk.attr.SetPinCount(1); - headSentinalChunk.attr.SetSize(0); - - freeChunk.ptr = allocCapacity; - freeChunk.attr.SetBusy(false); - freeChunk.attr.SetMoving(false); - freeChunk.attr.SetPinCount(0); - freeChunk.attr.SetSize((unsigned int)capacity); - - LinkAddrChunk(headSentinalIdx, addrEndSentinal.addrPrevIdx); - LinkAddrChunk(freeBlockIdx, headSentinalIdx); - LinkFreeChunk(freeBlockIdx); - addrEndSentinal.ptr = allocCapacity + (uint32)capacity; - - SDefragAllocSegment seg; - seg.address = allocCapacity; - seg.capacity = (uint32)capacity; - seg.headSentinalChunkIdx = headSentinalIdx; - m_segments.push_back(seg); - - m_capacity = allocCapacity + (uint32)capacity; - m_available += (uint32)capacity; - bSuccessful = true; - -#ifdef CDBA_MORE_DEBUG - ValidateAddressChain(); -#endif - } - else - { - ReleaseChunk(headSentinalIdx); - } - } - - return bSuccessful; -} - -void CDefragAllocator::UnAppendSegment() -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - - // Can't remove the last segment! - CDBA_ASSERT(m_segments.size() > 1); - - [[maybe_unused]] bool bHasMoves = Defrag_CompletePendingMoves(); - - // All outstanding moves should be completed. - CDBA_ASSERT(!bHasMoves); - - // Move all live chunks from this segment into another. - SyncMoveSegment((uint32)m_segments.size() - 1); - - SDefragAllocSegment& segment = m_segments.back(); - SDefragAllocChunk& headSentinalChunk = m_chunks[segment.headSentinalChunkIdx]; - - // Assert that the segment is empty, and release all chunks within it. - uint32 endAddress = m_capacity; - Index chunkIdx = headSentinalChunk.addrNextIdx; - - UnlinkAddrChunk(segment.headSentinalChunkIdx); - ReleaseChunk(segment.headSentinalChunkIdx); - - SDefragAllocChunk* pChunk = &m_chunks[chunkIdx]; - - while (pChunk->ptr != endAddress) - { - CDBA_ASSERT(!pChunk->attr.IsBusy()); - - Index nextChunkIdx = pChunk->addrNextIdx; - - UnlinkFreeChunk(chunkIdx); - UnlinkAddrChunk(chunkIdx); - ReleaseChunk(chunkIdx); - - chunkIdx = nextChunkIdx; - pChunk = &m_chunks[chunkIdx]; - } - - // chunkIdx/pChunk should be the end of memory sentinal. - CDBA_ASSERT(chunkIdx == AddrEndSentinal && pChunk->attr.IsBusy() && !pChunk->attr.GetSize()); - - pChunk->ptr -= segment.capacity; - - m_capacity -= segment.capacity; - m_available -= segment.capacity; - m_segments.pop_back(); -} - -IDefragAllocator::Hdl CDefragAllocator::Allocate(size_t sz, const char* source, void* pContext) -{ - CDBA_ASSERT((IntegerLog2(NextPower2(Align(sz, m_minAlignment))) - m_logMinAlignment) < (1u << SDefragAllocChunkAttr::SizeWidth)); - - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - return Allocate_Locked(sz, m_minAlignment, source, pContext); -} - -IDefragAllocator::Hdl CDefragAllocator::AllocateAligned(size_t sz, size_t alignment, const char* source, void* pContext) -{ - alignment = max((size_t)m_minAlignment, alignment); - - // Just to check the alignment can be stored - CDBA_ASSERT((IntegerLog2(alignment) - m_logMinAlignment) < (1u << SDefragAllocChunk::AlignBitCount)); - CDBA_ASSERT((IntegerLog2(NextPower2(Align(sz, alignment))) - m_logMinAlignment) < (1u << SDefragAllocChunkAttr::SizeWidth)); - - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - return Allocate_Locked(sz, alignment, source, pContext); -} - -IDefragAllocator::AllocatePinnedResult CDefragAllocator::AllocatePinned(size_t sz, const char* source, void* pContext /* = NULL */) -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - AllocatePinnedResult apr = {0}; - apr.hdl = Allocate_Locked(sz, m_minAlignment, source, pContext); - if (apr.hdl != InvalidHdl) - { - apr.offs = Pin(apr.hdl); - apr.usableSize = CDefragAllocator::UsableSize(apr.hdl); - } - - return apr; -} - -bool CDefragAllocator::Free(Hdl hdl) -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - - if (hdl != InvalidHdl) - { - // Assume that the allocator now has exclusive ownership of hdl - that is, - // that the caller won't be modifying it externally. - - Index hdlIdx = ChunkIdxFromHdl(hdl); - CDBA_ASSERT(hdlIdx < m_chunks.size()); - - SDefragAllocChunk* chunk = &m_chunks[hdlIdx]; - CDBA_ASSERT(chunk->attr.IsBusy()); - - // Moving state can only be acquired by defrag and released by CancelMove, both own lock as well as Free. - if (chunk->attr.IsMoving()) - { - CancelMove_Locked(hdlIdx, false); - CDBA_ASSERT(!chunk->attr.IsMoving()); - } - - MarkAsFree(*chunk); - MergeFreeBlock(hdlIdx); - - return true; - } - - return false; -} - -void CDefragAllocator::ChangeContext(Hdl hdl, void* pNewContext) -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - CDBA_ASSERT(hdl != InvalidHdl); - - Index hdlIdx = ChunkIdxFromHdl(hdl); - SDefragAllocChunk& chunk = m_chunks[hdlIdx]; - CDBA_ASSERT(chunk.attr.IsBusy()); - chunk.pContext = pNewContext; -} - -IDefragAllocatorStats CDefragAllocator::GetStats() -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - - IDefragAllocatorStats stats = {0}; - - stats.nCapacity = static_cast(m_capacity) << m_logMinAlignment; - stats.nInUseSize = static_cast(m_capacity - m_available) << m_logMinAlignment; - stats.nInUseBlocks = m_numAllocs; - - uint32 numFreeBlocks = 0; - uint32 numPinnedBlocks = 0; - uint32 numMovingBlocks = 0; - uint32 maxFreeBlockSize = 0; - uint32 minFreeBlockSize = (uint32) - 1; - - SDefragAllocChunk* pChunks = &m_chunks[0]; - for (Index idx = pChunks[AddrStartSentinal].addrNextIdx; idx != AddrEndSentinal; idx = pChunks[idx].addrNextIdx) - { - SDefragAllocChunk& c = pChunks[idx]; - SDefragAllocChunkAttr ca = c.attr; - - if (ca.IsBusy()) - { - if (ca.IsPinned()) - { - ++numPinnedBlocks; - } - if (ca.IsMoving()) - { - ++numMovingBlocks; - } - } - else - { - maxFreeBlockSize = max(maxFreeBlockSize, ca.GetSize()); - minFreeBlockSize = min(minFreeBlockSize, ca.GetSize()); - ++numFreeBlocks; - } - } - - stats.nFreeBlocks = numFreeBlocks; - stats.nPinnedBlocks = numPinnedBlocks - numMovingBlocks - (int)(m_segments.size() - 1); // Each moving block pins a block for the destination - stats.nMovingBlocks = numMovingBlocks; - stats.nLargestFreeBlockSize = maxFreeBlockSize << m_logMinAlignment; - stats.nSmallestFreeBlockSize = minFreeBlockSize << m_logMinAlignment; - stats.nMeanFreeBlockSize = (numFreeBlocks > 0) - ? ((m_available << m_logMinAlignment) / numFreeBlocks) - : 0; - stats.nCancelledMoveCount = (uint32)m_nCancelledMoves; - - return stats; -} - -size_t CDefragAllocator::DefragmentTick(size_t maxMoves, size_t maxAmount, bool bForce) -{ - if (m_isThreadSafe) - { - if (bForce) - { - m_lock.Lock(); - } - else if (!m_lock.TryLock()) - { - return 0; - } - } - - Defrag_CompletePendingMoves(); - - maxMoves = min(maxMoves, (size_t)MaxPendingMoves); - maxMoves = min(maxMoves, m_unusedChunks.size()); // Assume that each move requires a split - maxAmount >>= m_logMinAlignment; - - PendingMove* moves[MaxPendingMoves]; - size_t numMoves = 0; - size_t curAmount = 0; - -#ifdef CDBA_MORE_DEBUG - Defrag_ValidateFreeBlockIteration(); -#endif - - if (maxMoves > 0) - { - numMoves = Defrag_FindMovesBwd(moves + numMoves, maxMoves - numMoves, curAmount, maxAmount); - if (numMoves < maxMoves) - { - numMoves += Defrag_FindMovesFwd(moves + numMoves, maxMoves - numMoves, curAmount, maxAmount); - } - -#ifdef CDBA_DEBUG - for (size_t moveIdx = 0; moveIdx < numMoves; ++moveIdx) - { - PendingMove& pm = *moves[moveIdx]; - - SDefragAllocChunk& srcChunk = m_chunks[pm.srcChunkIdx]; - SDefragAllocChunk& dstChunk = m_chunks[pm.dstChunkIdx]; - SDefragAllocChunkAttr srcChunkAttr = srcChunk.attr; - SDefragAllocChunkAttr dstChunkAttr = dstChunk.attr; - - CDBA_ASSERT(srcChunkAttr.IsMoving()); - CDBA_ASSERT(dstChunkAttr.IsPinned()); - CDBA_ASSERT(dstChunkAttr.IsBusy()); - CDBA_ASSERT(dstChunkAttr.GetSize() == srcChunkAttr.GetSize()); - } -#endif - } - - if (m_isThreadSafe) - { - m_lock.Unlock(); - } - - return curAmount; -} - -CDefragAllocator::Index CDefragAllocator::AllocateChunk() -{ - Index result = InvalidChunkIdx; - - if (!m_unusedChunks.empty()) - { - result = m_unusedChunks.back(); - m_unusedChunks.pop_back(); - } - else if (!m_chunksAreFixed) - { - m_chunks.push_back(SDefragAllocChunk()); - result = (Index) (m_chunks.size() - 1); - CDBA_ASSERT(result == (m_chunks.size() - 1)); - } - - IF_LIKELY (result != InvalidChunkIdx) - { - SDefragAllocChunk& chunk = m_chunks[result]; - chunk.attr.SetBusy(false); - chunk.attr.SetPinCount(0); - chunk.attr.SetMoving(false); - chunk.pContext = NULL; -#ifndef _RELEASE - chunk.source = ""; -#endif - } - - return result; -} - -void CDefragAllocator::DisplayMemoryUsage([[maybe_unused]] const char* title, [[maybe_unused]] unsigned int allocatorDisplayOffset) -{ -#if !defined(_RELEASE) || defined(PERFORMANCE_BUILD) // We want this vis in Performance builds - if (IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom()) - { - int width = gEnv->pRenderer->GetWidth(); - int height = gEnv->pRenderer->GetHeight(); - - // The height of the bar is 40 pixels, but DrawTriangles is in screen UV coords - const float c_barHeight = 40.0f / height; - - unsigned int currentSize = 0; - unsigned int chunkCount = m_chunks.size(); - AZStd::vector chunkVerts; - chunkVerts.reserve(chunkCount * 4); - AZStd::vector chunkIndices; - chunkIndices.reserve(chunkCount * 6); - AZStd::vector chunkColors; - chunkColors.reserve(chunkCount * 4); - - // Chunks use banded colors to show delineations between adjacent allocations - const ColorB usedColor[2] = { ColorB(255, 0, 0), ColorB(200, 0, 0) }; - const ColorB freeColor[2] = { ColorB(0, 255, 0), ColorB(0, 200, 0) }; - - uint32 i = 0; - float minBarY = 1.0f - allocatorDisplayOffset * c_barHeight; - float maxBarY = 1.0f - (allocatorDisplayOffset + 1) * c_barHeight; - for (size_t idx = m_chunks[0].addrNextIdx; idx != 0; idx = m_chunks[idx].addrNextIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - unsigned int chunkSize = chunk.attr.GetSize(); - if (chunkSize != 0) - { - // Start and end x locations in screen UV coords - float startX = static_cast(currentSize) / m_capacity; - float endX = static_cast(currentSize + chunkSize) / m_capacity; - - // Ensure a valid size is at least one pixel wide - endX = AZStd::max(endX, startX + 1.0f / width); - - chunkVerts.push_back(Vec3(startX, minBarY, 0.0f)); - chunkVerts.push_back(Vec3(endX, minBarY, 0.0f)); - chunkVerts.push_back(Vec3(endX, maxBarY, 0.0f)); - chunkVerts.push_back(Vec3(startX, maxBarY, 0.0f)); - - chunkIndices.push_back(i * 4 + 0); - chunkIndices.push_back(i * 4 + 1); - chunkIndices.push_back(i * 4 + 2); - chunkIndices.push_back(i * 4 + 0); - chunkIndices.push_back(i * 4 + 2); - chunkIndices.push_back(i * 4 + 3); - - if (chunk.attr.IsPinned()) - { - chunkColors.push_back(usedColor[i & 1]); - chunkColors.push_back(usedColor[i & 1]); - chunkColors.push_back(usedColor[i & 1]); - chunkColors.push_back(usedColor[i & 1]); - } - else - { - chunkColors.push_back(freeColor[i & 1]); - chunkColors.push_back(freeColor[i & 1]); - chunkColors.push_back(freeColor[i & 1]); - chunkColors.push_back(freeColor[i & 1]); - } - - currentSize += chunkSize; - i++; - } - } - - SAuxGeomRenderFlags savedFlags = pAuxGeom->GetRenderFlags(); - SAuxGeomRenderFlags tempFlags; - tempFlags.SetMode2D3DFlag(e_Mode2D); - pAuxGeom->SetRenderFlags(tempFlags); - pAuxGeom->DrawTriangles(chunkVerts.data(), chunkVerts.size(), chunkIndices.data(), chunkIndices.size(), chunkColors.data()); - pAuxGeom->SetRenderFlags(savedFlags); - - // Draw other stats about the system - const float statisticsWidth = 384.0f; - float statsXOffset = allocatorDisplayOffset * statisticsWidth; - IDefragAllocatorStats stats = GetStats(); - ColorF statsTextColor(1.0f, 1.0f, 0.5f, 1.0f); - pAuxGeom->Draw2dLabel(10 + statsXOffset, 85, 1.7f, statsTextColor, false, title); - pAuxGeom->Draw2dLabel(20 + statsXOffset, 110, 1.5f, statsTextColor, false, "Capacity (MB): %.2f", stats.nCapacity / 1024.0f / 1024.0f); - pAuxGeom->Draw2dLabel(20 + statsXOffset, 130, 1.5f, statsTextColor, false, "In Use (MB): %.2f", stats.nInUseSize / 1024.0f / 1024.0f); - pAuxGeom->Draw2dLabel(20 + statsXOffset, 150, 1.5f, statsTextColor, false, "In Use Blocks: %u", stats.nInUseBlocks); - pAuxGeom->Draw2dLabel(20 + statsXOffset, 170, 1.5f, statsTextColor, false, "Free Blocks: %u", stats.nFreeBlocks); - pAuxGeom->Draw2dLabel(20 + statsXOffset, 190, 1.5f, statsTextColor, false, "Largest Free Block (B): %u", stats.nLargestFreeBlockSize); - pAuxGeom->Draw2dLabel(20 + statsXOffset, 210, 1.5f, statsTextColor, false, "Smallest Free Block (B): %u", stats.nSmallestFreeBlockSize); - pAuxGeom->Draw2dLabel(20 + statsXOffset, 230, 1.5f, statsTextColor, false, "Mean Free Block (B): %u", stats.nMeanFreeBlockSize); - } -#endif -} - -void CDefragAllocator::ReleaseChunk(Index idx) -{ - m_unusedChunks.push_back(idx); -} - -void CDefragAllocator::LinkFreeChunk(Index idx) -{ - SDefragAllocChunk* pChunks = &m_chunks[0]; - SDefragAllocChunk& chunk = pChunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - - int bucket = BucketForSize(chunk.attr.GetSize()); - - Index rootIdx = m_freeBuckets[bucket]; - Index beforeIdx; - - // Search for the position in the list to insert the new block, maintaining address order - for (beforeIdx = pChunks[rootIdx].freeNextIdx; beforeIdx != rootIdx; beforeIdx = pChunks[beforeIdx].freeNextIdx) - { - if (pChunks[beforeIdx].ptr > chunk.ptr) - { - break; - } - } - - Index afterIdx = pChunks[beforeIdx].freePrevIdx; - SDefragAllocChunk& after = pChunks[afterIdx]; - - chunk.freeNextIdx = after.freeNextIdx; - chunk.freePrevIdx = afterIdx; - pChunks[after.freeNextIdx].freePrevIdx = idx; - after.freeNextIdx = idx; -} - -IDefragAllocator::Hdl CDefragAllocator::Allocate_Locked(size_t sz, size_t alignment, [[maybe_unused]] const char* source, void* pContext) -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64 - CDBA_ASSERT(sz <= (BIT64(NumBuckets))); -#else - CDBA_ASSERT(sz <= (BIT(NumBuckets))); -#endif - - sz = Align(sz, alignment) >> m_logMinAlignment; - alignment >>= m_logMinAlignment; - - if (sz > m_available) - { - return InvalidHdl; - } - - Index bestChunkIdx = InvalidChunkIdx; - switch (m_policy.blockSearchKind) - { - case eBSK_BestFit: - bestChunkIdx = BestFit_FindFreeBlockFor(sz, alignment, 0, ~(uint32)0, true); - break; - case eBSK_FirstFit: - bestChunkIdx = FirstFit_FindFreeBlockFor(sz, alignment, 0, ~(uint32)0, true); - break; - default: - __debugbreak(); - break; - } - - if (bestChunkIdx != InvalidChunkIdx) - { - SplitResult sr = SplitFreeBlock(bestChunkIdx, sz, alignment, true); - - IF_LIKELY (sr.bSuccessful) - { - SDefragAllocChunk& bestChunk = m_chunks[bestChunkIdx]; - CDBA_ASSERT(bestChunk.attr.GetSize() == sz); - - MarkAsInUse(bestChunk); - bestChunk.pContext = pContext; -#ifndef _RELEASE - bestChunk.source = source; -#endif - bestChunk.attr.SetPinCount(0); - bestChunk.attr.SetMoving(false); - - return ChunkHdlFromIdx(bestChunkIdx); - } - } - - return InvalidHdl; -} - -CDefragAllocator::SplitResult CDefragAllocator::SplitFreeBlock(Index fbId, size_t sz, size_t alignment, bool allocateInLowHalf) -{ - CDefragAllocator::SplitResult res; - res.bSuccessful = false; - res.nLeftSplitChunkIdx = InvalidChunkIdx; - res.nRightSplitChunkIdx = InvalidChunkIdx; - - SDefragAllocChunk* allocChunk = &m_chunks[fbId]; - - CDBA_ASSERT(!allocChunk->attr.IsBusy()); - CDBA_ASSERT(sz <= allocChunk->attr.GetSize()); - - if ((allocChunk->ptr & (alignment - 1)) != 0 || allocChunk->attr.GetSize() != sz) - { - // Determine the sizes of the new chunks - UINT_PTR baseAddress = allocChunk->ptr; - UINT_PTR endAddress = allocChunk->ptr + allocChunk->attr.GetSize(); - UINT_PTR allocAddress = allocateInLowHalf - ? Align(baseAddress, alignment) - : ((endAddress - sz) & ~(alignment - 1)); - UINT_PTR allocEndAddress = allocAddress + sz; - - // Allocate split chunks - Index nLeftSplitChunkIdx = InvalidChunkIdx; - if (baseAddress != allocAddress) - { - nLeftSplitChunkIdx = AllocateChunk(); - if (nLeftSplitChunkIdx == InvalidChunkIdx) - { - return res; - } - } - - Index nRightSplitChunkIdx = InvalidChunkIdx; - if (allocEndAddress != endAddress) - { - nRightSplitChunkIdx = AllocateChunk(); - if (nRightSplitChunkIdx == InvalidChunkIdx) - { - if (nLeftSplitChunkIdx != InvalidChunkIdx) - { - ReleaseChunk(nLeftSplitChunkIdx); - } - return res; - } - } - - // Split - UnlinkFreeChunk(fbId); - - allocChunk = &m_chunks[fbId]; - - if (nLeftSplitChunkIdx != InvalidChunkIdx) - { - SDefragAllocChunk& splitChunk = m_chunks[nLeftSplitChunkIdx]; - - splitChunk.ptr = baseAddress; - splitChunk.attr.SetSize((int)(allocAddress - baseAddress)); - LinkAddrChunk(nLeftSplitChunkIdx, allocChunk->addrPrevIdx); - } - - if (nRightSplitChunkIdx != InvalidChunkIdx) - { - SDefragAllocChunk& splitChunk = m_chunks[nRightSplitChunkIdx]; - - splitChunk.ptr = allocEndAddress; - splitChunk.attr.SetSize((int)(endAddress - allocEndAddress)); - LinkAddrChunk(nRightSplitChunkIdx, fbId); - } - - allocChunk->ptr = allocAddress; - allocChunk->attr.SetSize((int)(allocEndAddress - allocAddress)); - allocChunk->logAlign = IntegerLog2(alignment); - - if (nLeftSplitChunkIdx != InvalidChunkIdx) - { - LinkFreeChunk(nLeftSplitChunkIdx); - } - if (nRightSplitChunkIdx != InvalidChunkIdx) - { - LinkFreeChunk(nRightSplitChunkIdx); - } - - res.bSuccessful = true; - res.nLeftSplitChunkIdx = nLeftSplitChunkIdx; - res.nRightSplitChunkIdx = nRightSplitChunkIdx; - } - else - { - // Perfect fit. - UnlinkFreeChunk(fbId); - - res.bSuccessful = true; - } - -#ifdef CDBA_MORE_DEBUG - ValidateFreeLists(); -#endif - - return res; -} - -CDefragAllocator::Index CDefragAllocator::MergeFreeBlock(Index fbId) -{ - SDefragAllocChunk* pChunks = &m_chunks[0]; - - SDefragAllocChunk* chunk = &pChunks[fbId]; - - CDBA_ASSERT(m_available <= m_capacity); - CDBA_ASSERT(!chunk->attr.IsBusy()); - - LinkFreeChunk(fbId); - - Index prevChunkIdx = chunk->addrPrevIdx; - SDefragAllocChunk& prevChunk = pChunks[prevChunkIdx]; - if (!prevChunk.attr.IsBusy()) - { - // Merge with previous chunk - - UnlinkFreeChunk(fbId); - UnlinkFreeChunk(prevChunkIdx); - - prevChunk.attr.AddSize(chunk->attr.GetSize()); - prevChunk.addrNextIdx = chunk->addrNextIdx; - pChunks[chunk->addrNextIdx].addrPrevIdx = prevChunkIdx; - - CDBA_ASSERT(pChunks[prevChunk.addrPrevIdx].ptr + pChunks[prevChunk.addrPrevIdx].attr.GetSize() == prevChunk.ptr); - CDBA_ASSERT(prevChunk.ptr + prevChunk.attr.GetSize() == pChunks[prevChunk.addrNextIdx].ptr); - CDBA_ASSERT(pChunks[prevChunk.addrPrevIdx].addrNextIdx == prevChunkIdx); - CDBA_ASSERT(pChunks[prevChunk.addrNextIdx].addrPrevIdx == prevChunkIdx); - - LinkFreeChunk(prevChunkIdx); - ReleaseChunk(fbId); - - // Pretend the released chunk is the previous one, so the next merge can happen - - fbId = prevChunkIdx; - chunk = &prevChunk; - } - - Index nextChunkIdx = chunk->addrNextIdx; - SDefragAllocChunk& nextChunk = pChunks[nextChunkIdx]; - if (!nextChunk.attr.IsBusy()) - { - // Merge with next chunk - - UnlinkFreeChunk(fbId); - UnlinkFreeChunk(nextChunkIdx); - - chunk->attr.AddSize(nextChunk.attr.GetSize()); - chunk->addrNextIdx = nextChunk.addrNextIdx; - pChunks[chunk->addrNextIdx].addrPrevIdx = fbId; - - CDBA_ASSERT(pChunks[chunk->addrPrevIdx].ptr + pChunks[chunk->addrPrevIdx].attr.GetSize() == chunk->ptr); - CDBA_ASSERT(chunk->ptr + chunk->attr.GetSize() == pChunks[chunk->addrNextIdx].ptr); - CDBA_ASSERT(pChunks[chunk->addrPrevIdx].addrNextIdx == fbId); - CDBA_ASSERT(pChunks[chunk->addrNextIdx].addrPrevIdx == fbId); - - LinkFreeChunk(fbId); - ReleaseChunk(nextChunkIdx); - } - - return fbId; -} - -#ifdef CDBA_MORE_DEBUG -void CDefragAllocator::Defrag_ValidateFreeBlockIteration() -{ - Index freeLists[NumBuckets]; - size_t numFreeLists = 0; - - { - PrepareMergePopPrev(freeLists); - UINT_PTR addr = (UINT_PTR)-1; - - if (numFreeLists) - { - do - { - size_t list = MergePeekPrevChunk(freeLists); - Index chk = freeLists[list]; - UINT_PTR chkAddr = m_chunks[chk].ptr; - CDBA_ASSERT(chkAddr < addr); - addr = chkAddr; - MergePopPrevChunk(freeLists, list); - } while (numFreeLists > 0); - } - } - { - PrepareMergePopNext(freeLists); - UINT_PTR addr = 0; - - if (numFreeLists) - { - do - { - size_t list = MergePeekNextChunk(freeLists); - Index chk = freeLists[list]; - UINT_PTR chkAddr = m_chunks[chk].ptr; - CDBA_ASSERT(chkAddr > addr); - addr = chkAddr; - MergePopNextChunk(freeLists, list); - } while (numFreeLists > 0); - } - } -} -#endif - -CDefragAllocator::Index CDefragAllocator::BestFit_FindFreeBlockForSegment(size_t sz, size_t alignment, uint32 seg) -{ - SDefragAllocSegment& segment = m_segments[seg]; - return BestFit_FindFreeBlockFor(sz, alignment, segment.address, segment.address + segment.capacity, true); -} - -CDefragAllocator::Index CDefragAllocator::BestFit_FindFreeBlockFor(size_t sz, size_t alignment, [[maybe_unused]] UINT_PTR addressMin, UINT_PTR addressMax, bool allocateInLowHalf) -{ - Index bestChunkIdx = InvalidChunkIdx; - UINT_PTR bestWastage = (UINT_PTR)-1; - - for (int bucket = BucketForSize(sz); (bestChunkIdx == InvalidChunkIdx) && (bucket < NumBuckets); ++bucket) - { - size_t rootIdx = m_freeBuckets[bucket]; - SDefragAllocChunk& root = m_chunks[rootIdx]; - - for (size_t idx = root.freeNextIdx; idx != rootIdx; idx = m_chunks[idx].freeNextIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max(1U, chunk.attr.GetSize()) >= (1U << bucket)); - - if (chunk.ptr < addressMax) - { - UINT_PTR chunkStart = chunk.ptr; - UINT_PTR chunkSize = chunk.attr.GetSize(); - UINT_PTR chunkEnd = chunkStart + chunkSize; - UINT_PTR allocStart = allocateInLowHalf - ? Align(chunkStart, alignment) - : ((chunkEnd - sz) & ~(alignment - 1)); - UINT_PTR allocEnd = allocStart + sz; - - if (chunkStart <= allocStart && allocEnd <= chunkEnd) - { - if (allocStart == chunkStart && chunkSize == sz) - { - bestChunkIdx = idx; - bestWastage = 0; - - break; - } - - UINT_PTR wastage = (allocStart - chunkStart) + (chunkEnd - allocEnd); - if (wastage < bestWastage) - { - bestChunkIdx = idx; - bestWastage = wastage; - } - } - } - else - { - break; - } - } - } - - return bestChunkIdx; -} - -CDefragAllocator::Index CDefragAllocator::FirstFit_FindFreeBlockFor(size_t sz, size_t alignment, [[maybe_unused]] UINT_PTR addressMin, UINT_PTR addressMax, bool allocateInLowHalf) -{ - for (int bucket = BucketForSize(sz); bucket < NumBuckets; ++bucket) - { - size_t rootIdx = m_freeBuckets[bucket]; - SDefragAllocChunk& root = m_chunks[rootIdx]; - for (size_t idx = root.freeNextIdx; idx != rootIdx; idx = m_chunks[idx].freeNextIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max(1U, chunk.attr.GetSize()) >= (1U << bucket)); - if (chunk.ptr < addressMax) - { - UINT_PTR chunkStart = chunk.ptr; - UINT_PTR chunkSize = chunk.attr.GetSize(); - UINT_PTR chunkEnd = chunkStart + chunkSize; - UINT_PTR allocStart = allocateInLowHalf - ? Align(chunkStart, alignment) - : ((chunkEnd - sz) & ~(alignment - 1)); - UINT_PTR allocEnd = allocStart + sz; - if (chunkStart <= allocStart && allocEnd <= chunkEnd) - { - return idx; - } - } - else - { - break; - } - } - } - return InvalidChunkIdx; -} -size_t CDefragAllocator::Defrag_FindMovesBwd(PendingMove** pMoves, size_t maxMoves, size_t& curAmount, size_t maxAmount) -{ - Index freeLists[NumBuckets]; - - size_t numMoves = 0; - bool bIsLast = true; - - PrepareMergePopPrev(freeLists); - - int nSegmentIdx = (int)m_segments.size() - 1; - - // Try and copy a block from the back to the front - do - { - size_t freeChunkList = MergePeekPrevChunk(freeLists); - if (freeChunkList == (size_t)-1) - { - break; - } - - assert(freeChunkList < sizeof(freeLists) / sizeof(freeLists[0])); - Index freeChunkIdx = freeLists[freeChunkList]; - MergePopPrevChunk(freeLists, freeChunkList); - - // Keep track of the last free block in each segment, by watching free blocks - // crossing segment boundaries. - if (nSegmentIdx >= 0) - { - if (m_chunks[freeChunkIdx].ptr < m_segments[nSegmentIdx].address) - { - bIsLast = true; - --nSegmentIdx; - } - } - - // Don't move free block->next blocks if they're at the end of a segment - they're defragged enough. - // TODO - could allow this (and self moves below) if defragging stalls in a bad state - if (!bIsLast) - { - for (Index candidateIdx = m_chunks[freeChunkIdx].addrNextIdx; freeChunkIdx != InvalidChunkIdx && numMoves < maxMoves && curAmount < maxAmount; ) - { - SDefragAllocChunk& freeChunk = m_chunks[freeChunkIdx]; - SDefragAllocChunk& candidateChunk = m_chunks[candidateIdx]; - SDefragAllocChunkAttr candidateChunkAttr = candidateChunk.attr; - - CDBA_ASSERT(!freeChunk.attr.IsBusy()); - - if (IsMoveableCandidate(candidateChunkAttr, 0xffffffff)) - { -#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64 - size_t candidateChunkAlign = BIT64(candidateChunk.logAlign); -#else - size_t candidateChunkAlign = BIT(candidateChunk.logAlign); -#endif - - // Try and reallocate this chunk. For the time being, assume that it's going to remain in a valid moveable state. - Index dstChunkIdx = Defrag_Bwd_FindFreeBlockFor(candidateChunkAttr.GetSize(), candidateChunkAlign, freeChunk.ptr);// + freeChunk.attr.GetSize()); - - if (dstChunkIdx != InvalidChunkIdx) - { - PendingMove* pPM = AllocPendingMove(); - IF_UNLIKELY (!pPM) - { - return numMoves; - } - - // Found a possible move, so try and mark the chunk as moveable - as long as it's still a valid candidate. - if (TryMarkAsMoving(candidateChunk, 0xffffffff)) - { - // Chunk has been marked as moveable - can now split the dest chunk and set up the move state. - // If the chunk gets pinned in the meantime, it'll sync (through CancelMove) on the allocator lock. - - if (TryScheduleCopy(candidateChunk, m_chunks[dstChunkIdx], pPM, true)) - { - SplitResult sr = SplitFreeBlock(dstChunkIdx, candidateChunkAttr.GetSize(), candidateChunkAlign, true); - CDBA_ASSERT(sr.bSuccessful); - - MergePatchPrevRemove(freeLists, dstChunkIdx); - - if (sr.nRightSplitChunkIdx != InvalidChunkIdx) - { - MergePatchPrevInsert(freeLists, sr.nRightSplitChunkIdx); - } - - pPM->srcChunkIdx = candidateIdx; - pPM->dstChunkIdx = dstChunkIdx; - - // dstChunk is owned by the allocator, so we don't need to be atomic when changing it's state. - SDefragAllocChunk& dstChunk = m_chunks[dstChunkIdx]; - MarkAsInUse(dstChunk); - dstChunk.attr.SetPinCount(1); - - CDBA_ASSERT(sr.nRightSplitChunkIdx == InvalidChunkIdx || (m_chunks[sr.nRightSplitChunkIdx].ptr > dstChunk.ptr)); - CDBA_ASSERT(dstChunk.ptr < candidateChunk.ptr); - -#ifdef CDBA_MORE_DEBUG - ValidateAddressChain(); -#endif - - pMoves[numMoves++] = pPM; - curAmount += dstChunk.attr.GetSize(); - - candidateIdx = m_chunks[candidateIdx].addrNextIdx; - if (dstChunkIdx == freeChunkIdx) - { - freeChunkIdx = sr.nRightSplitChunkIdx; - } - continue; - } - else - { - MarkAsNotMoving(candidateChunk); - } - } - - // Candidate (probably) got pinned whilst finding a free block, or the copy schedule failed. Nevermind - undo what we need to. - FreePendingMove(pPM); - pPM = NULL; - } - } - - break; - } - } - - if (freeChunkIdx != InvalidChunkIdx) - { - for (Index candidateIdx = m_chunks[freeChunkIdx].addrPrevIdx; numMoves < maxMoves && curAmount < maxAmount; ) - { - SDefragAllocChunk& candidateChunk = m_chunks[candidateIdx]; - SDefragAllocChunkAttr candidateChunkAttr = candidateChunk.attr; - - if (IsMoveableCandidate(candidateChunkAttr, 0xffffffff)) - { -#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64 - size_t candidateChunkAlign = BIT64(candidateChunk.logAlign); -#else - size_t candidateChunkAlign = BIT(candidateChunk.logAlign); -#endif - - // Try and reallocate this chunk. For the time being, assume that it's going to remain in a valid moveable state. - Index dstChunkIdx = Defrag_Bwd_FindFreeBlockFor(candidateChunkAttr.GetSize(), candidateChunkAlign, candidateChunk.ptr); - CDBA_ASSERT(dstChunkIdx != freeChunkIdx); - - if (dstChunkIdx != InvalidChunkIdx) - { - PendingMove* pPM = AllocPendingMove(); - IF_UNLIKELY (!pPM) - { - return numMoves; - } - - // Found a possible move, so try and mark the chunk as moveable - as long as it's still a valid candidate. - if (TryMarkAsMoving(candidateChunk, 0xffffffff)) - { - // Chunk has been marked as moveable - can now split the chunk and set up the move state. - // If the chunk gets pinned in the meantime, it'll sync (through CancelMove) on the allocator lock. - - if (TryScheduleCopy(candidateChunk, m_chunks[dstChunkIdx], pPM, true)) - { - SplitResult sr = SplitFreeBlock(dstChunkIdx, candidateChunkAttr.GetSize(), candidateChunkAlign, true); - CDBA_ASSERT(sr.bSuccessful); - - MergePatchPrevRemove(freeLists, dstChunkIdx); - - if (sr.nRightSplitChunkIdx != InvalidChunkIdx) - { - MergePatchPrevInsert(freeLists, sr.nRightSplitChunkIdx); - } - - pPM->srcChunkIdx = candidateIdx; - pPM->dstChunkIdx = dstChunkIdx; - - // dstChunk is owned by the allocator, so don't need to be atomic when changing it's state. - SDefragAllocChunk& dstChunk = m_chunks[dstChunkIdx]; - MarkAsInUse(dstChunk); - dstChunk.attr.SetPinCount(1); - - CDBA_ASSERT(sr.nRightSplitChunkIdx == InvalidChunkIdx || (m_chunks[sr.nRightSplitChunkIdx].ptr > dstChunk.ptr)); - CDBA_ASSERT(dstChunk.ptr < candidateChunk.ptr); - -#ifdef CDBA_MORE_DEBUG - ValidateAddressChain(); -#endif - - pMoves[numMoves++] = pPM; - curAmount += dstChunk.attr.GetSize(); - - candidateIdx = m_chunks[candidateIdx].addrPrevIdx; - continue; - } - else - { - MarkAsNotMoving(candidateChunk); - } - } - - // Candidate (probably) got pinned whilst finding a free block, or the copy schedule failed. Nevermind - undo what we need to. - FreePendingMove(pPM); - pPM = NULL; - } - } - - break; - } - } - bIsLast = false; - } - while (numMoves < maxMoves); - - return numMoves; -} - -size_t CDefragAllocator::Defrag_FindMovesFwd(PendingMove** pMoves, size_t maxMoves, size_t& curAmount, size_t maxAmount) -{ - Index freeLists[NumBuckets]; - - size_t numMoves = 0; - - PrepareMergePopNext(freeLists); - - // Try and copy a block from the front to the back - do - { - size_t freeChunkList = MergePeekNextChunk(freeLists); - if (freeChunkList == (size_t)-1) - { - break; - } - - assert(freeChunkList < sizeof(freeLists) / sizeof(freeLists[0])); - - Index freeChunkIdx = freeLists[freeChunkList]; - MergePopNextChunk(freeLists, freeChunkList); - - CDBA_ASSERT(!m_chunks[freeChunkIdx].attr.IsBusy()); - - for (Index candidateIdx = m_chunks[freeChunkIdx].addrNextIdx; numMoves < maxMoves && curAmount < maxAmount; ) - { - SDefragAllocChunk& freeChunk = m_chunks[freeChunkIdx]; - SDefragAllocChunk& candidateChunk = m_chunks[candidateIdx]; - SDefragAllocChunkAttr candidateChunkAttr = candidateChunk.attr; - - if (IsMoveableCandidate(candidateChunkAttr, 0xffffffff)) - { -#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64 - size_t candidateChunkAlign = BIT64(candidateChunk.logAlign); -#else - size_t candidateChunkAlign = BIT(candidateChunk.logAlign); -#endif - - // Try and reallocate this chunk. For the time being, assume that it's going to remain in a valid moveable state. - Index dstChunkIdx = Defrag_Fwd_FindFreeBlockFor(candidateChunkAttr.GetSize(), candidateChunkAlign, freeChunk.ptr + freeChunk.attr.GetSize()); - - CDBA_ASSERT(dstChunkIdx != freeChunkIdx); - - if (dstChunkIdx != InvalidChunkIdx) - { - PendingMove* pPM = AllocPendingMove(); - IF_UNLIKELY (!pPM) - { - return numMoves; - } - - CDBA_ASSERT(!m_chunks[dstChunkIdx].attr.IsBusy()); - CDBA_ASSERT(m_chunks[dstChunkIdx].attr.GetSize() >= candidateChunkAttr.GetSize()); - - // Found a possible move, so try and mark the chunk as moveable - as long as it's still a valid candidate. - if (TryMarkAsMoving(candidateChunk, 0xffffffff)) - { - // Chunk has been marked as moveable - can now split the dest chunk and set up the move state. - // If the chunk gets pinned in the meantime, it'll sync (through CancelMove) on the allocator lock. - - if (TryScheduleCopy(candidateChunk, m_chunks[dstChunkIdx], pPM, false)) - { - SplitResult sr = SplitFreeBlock(dstChunkIdx, candidateChunkAttr.GetSize(), candidateChunkAlign, false); - CDBA_ASSERT(sr.bSuccessful); - - MergePatchNextRemove(freeLists, dstChunkIdx); - - if (sr.nLeftSplitChunkIdx != InvalidChunkIdx) - { - MergePatchNextInsert(freeLists, sr.nLeftSplitChunkIdx); - } - - pPM->srcChunkIdx = candidateIdx; - pPM->dstChunkIdx = dstChunkIdx; - - // dstChunk is owned by the allocator, so we don't need to be atomic when changing it's state. - SDefragAllocChunk& dstChunk = m_chunks[dstChunkIdx]; - MarkAsInUse(dstChunk); - dstChunk.attr.SetPinCount(1); - - CDBA_ASSERT(sr.nLeftSplitChunkIdx == InvalidChunkIdx || (m_chunks[sr.nLeftSplitChunkIdx].ptr < dstChunk.ptr)); - CDBA_ASSERT(dstChunk.ptr > candidateChunk.ptr); - -#ifdef CDBA_MORE_DEBUG - ValidateAddressChain(); -#endif - - pMoves[numMoves++] = pPM; - curAmount += dstChunk.attr.GetSize(); - - candidateIdx = m_chunks[candidateIdx].addrNextIdx; - continue; - } - else - { - MarkAsNotMoving(candidateChunk); - } - } - - // Candidate (probably) got pinned whilst finding a free block, or the copy schedule failed. Nevermind - undo what we need to. - FreePendingMove(pPM); - pPM = NULL; - } - } - - break; - } - } - while (numMoves < maxMoves); - - return numMoves; -} - -bool CDefragAllocator::Defrag_CompletePendingMoves() -{ - CDBA_ASSERT(m_policy.pDefragPolicy); - - bool bHasMoves = false; - - for (DynArray::iterator it = m_pendingMoves.begin(), itEnd = m_pendingMoves.end(); it != itEnd; ++it) - { - if (it->notify.bCancel) - { - // Currently only support cancelling before a move has really begun - // Also assume that there is no copy in flight - the policy has requested it, so it's their responsibility to - // make sure that this is the case - CDBA_ASSERT(!it->relocated); - - MarkAsFree(m_chunks[it->dstChunkIdx]); - MergeFreeBlock(it->dstChunkIdx); - - MarkAsNotMoving(m_chunks[it->srcChunkIdx]); - - FreePendingMove(&*it); - } - else - { - if (it->notify.bDstIsValid) - { - if (!it->relocated) - { - CDBA_ASSERT(it->dstChunkIdx != InvalidChunkIdx); - - if (!it->cancelled) - { - Relocate(it->userMoveId, it->srcChunkIdx, it->dstChunkIdx); - } - - it->relocated = true; - } - - if (it->notify.bSrcIsUnneeded) - { - SDefragAllocChunk& dst = m_chunks[it->dstChunkIdx]; - MarkAsFree(dst); - MergeFreeBlock(it->dstChunkIdx); - - if (!it->cancelled) - { - CDBA_ASSERT(it->srcChunkIdx != InvalidChunkIdx); - - SDefragAllocChunk& src = m_chunks[it->srcChunkIdx]; - - // Should be the last thing to occur during move - MarkAsNotMoving(src); - } - else - { - // Only the destination chunk is now valid - just free it. - CDBA_ASSERT(it->srcChunkIdx == InvalidChunkIdx); - } - - FreePendingMove(&*it); - } - } - - if (it->dstChunkIdx != InvalidChunkIdx) - { - bHasMoves = true; - } - } - } - - return bHasMoves; -} - -CDefragAllocator::Index CDefragAllocator::Defrag_Bwd_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressLimit) -{ - Index bestChunkIdx = InvalidChunkIdx; - UINT_PTR maxAddress = addressLimit; - - int minBucket = BucketForSize(sz); - - // Search for an exact fit - { - size_t rootIdx = m_freeBuckets[minBucket]; - SDefragAllocChunk& root = m_chunks[rootIdx]; - - for (size_t idx = root.freeNextIdx; idx != rootIdx; idx = m_chunks[idx].freeNextIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max((uint32)1, (uint32)chunk.attr.GetSize()) >= (1U << minBucket)); - - UINT_PTR chunkBase = chunk.ptr; - UINT_PTR chunkEnd = chunkBase + chunk.attr.GetSize(); - UINT_PTR allocBase = Align(chunkBase, alignment); - UINT_PTR allocEnd = allocBase + sz; - - if (chunk.ptr < maxAddress) - { - if (chunkBase == allocBase && chunkEnd == allocEnd) - { - bestChunkIdx = idx; - maxAddress = chunk.ptr; - break; - } - } - else - { - break; - } - } - } - - for (size_t bucket = minBucket; (bestChunkIdx == InvalidChunkIdx) && (bucket < NumBuckets); ++bucket) - { - size_t rootIdx = m_freeBuckets[bucket]; - SDefragAllocChunk& root = m_chunks[rootIdx]; - - for (size_t idx = root.freeNextIdx; idx != rootIdx; idx = m_chunks[idx].freeNextIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max((uint32)1, (uint32)chunk.attr.GetSize()) >= (1U << bucket)); - - UINT_PTR chunkBase = chunk.ptr; - UINT_PTR chunkEnd = chunkBase + chunk.attr.GetSize(); - UINT_PTR allocBase = Align(chunkBase, alignment); - UINT_PTR allocEnd = allocBase + sz; - - if (allocEnd <= maxAddress) - { - if (chunkBase <= allocBase && allocEnd <= chunkEnd) - { - bestChunkIdx = idx; - maxAddress = chunkBase; - break; - } - } - else - { - // Chunks are ordered by address. If the maxAddress has been exceeded, there's no point in searching the rest of the list. - break; - } - } - } - - return bestChunkIdx; -} - -CDefragAllocator::Index CDefragAllocator::Defrag_Fwd_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressLimit) -{ - Index bestChunkIdx = InvalidChunkIdx; - UINT_PTR minAddress = addressLimit; - - int minBucket = BucketForSize(sz); - - // Search for an exact fit - { - size_t rootIdx = m_freeBuckets[minBucket]; - SDefragAllocChunk& root = m_chunks[rootIdx]; - - for (size_t idx = root.freePrevIdx; idx != rootIdx; idx = m_chunks[idx].freePrevIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max((uint32)1, (uint32)chunk.attr.GetSize()) >= (1U << minBucket)); - - UINT_PTR chunkBase = chunk.ptr; - UINT_PTR chunkEnd = chunkBase + chunk.attr.GetSize(); - UINT_PTR allocBase = (chunkEnd - sz) & ~(alignment - 1); - UINT_PTR allocEnd = allocBase + sz; - - if (chunkBase >= minAddress) - { - if (allocBase == chunkBase && allocEnd == chunkEnd) - { - bestChunkIdx = idx; - minAddress = chunk.ptr; - break; - } - } - else - { - break; - } - } - } - - for (size_t bucket = minBucket; (bestChunkIdx == InvalidChunkIdx) && (bucket < NumBuckets); ++bucket) - { - size_t rootIdx = m_freeBuckets[bucket]; - SDefragAllocChunk& root = m_chunks[rootIdx]; - - for (size_t idx = root.freePrevIdx; idx != rootIdx; idx = m_chunks[idx].freePrevIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max((uint32)1, (uint32)chunk.attr.GetSize()) >= (1U << bucket)); - - UINT_PTR chunkBase = chunk.ptr; - UINT_PTR chunkEnd = chunkBase + chunk.attr.GetSize(); - UINT_PTR allocBase = (chunkEnd - sz) & ~(alignment - 1); - UINT_PTR allocEnd = allocBase + sz; - - if (chunkBase > minAddress) - { - if (chunkBase <= allocBase && allocEnd <= chunkEnd) - { - bestChunkIdx = idx; - minAddress = chunkBase; - break; - } - } - else - { - // Chunks are ordered by address. If the minAddress has been exceeded, there's no point in searching the rest of the list. - break; - } - } - } - - return bestChunkIdx; -} - -CDefragAllocator::PendingMove* CDefragAllocator::AllocPendingMove() -{ - // Naive - just search for a free slot. - for (PendingMoveVec::iterator it = m_pendingMoves.begin(), itEnd = m_pendingMoves.end(); it != itEnd; ++it) - { - if (it->dstChunkIdx == InvalidChunkIdx) - { - return &*it; - } - } - - return NULL; -} - -void CDefragAllocator::FreePendingMove(PendingMove* pMove) -{ - stl::reconstruct(*pMove); -} - -void CDefragAllocator::CancelMove(Index srcChunkIdx, bool bIsContentNeeded) -{ - CryOptionalAutoLock lock(m_lock, m_isThreadSafe); - CancelMove_Locked(srcChunkIdx, bIsContentNeeded); -} - -void CDefragAllocator::CancelMove_Locked(Index srcChunkIdx, [[maybe_unused]] bool bIsContentNeeded) -{ - SDefragAllocChunk* pChunk = &m_chunks[srcChunkIdx]; - - // In theory CancelMove could get called twice for the same chunk - make sure that - // redundant cancels are ignored - if (pChunk->attr.IsMoving()) - { - // Chunk is being moved. Find the job responsible and cancel it (if it's not complete). - PendingMoveVec::iterator it = std::find_if(m_pendingMoves.begin(), m_pendingMoves.end(), PendingMoveSrcChunkPredicate(srcChunkIdx)); - CDBA_ASSERT(it != m_pendingMoves.end()); - CDBA_ASSERT(it->srcChunkIdx != InvalidChunkIdx); - - if (it->notify.bDstIsValid && it->notify.bSrcIsUnneeded) - { - // Chunk has actually completed, just not finalised. Discard the destination chunk. - MarkAsFree(m_chunks[it->dstChunkIdx]); - MergeFreeBlock(it->dstChunkIdx); - FreePendingMove(&*it); - } - else - { - // Chunk is still in flight. - - // If the content is important, then we can either cancel the copy (if not overlapped), or - // sync and wait for it complete. TODO. - - m_policy.pDefragPolicy->CancelCopy(it->userMoveId, pChunk->pContext, false); - it->srcChunkIdx = InvalidChunkIdx; - it->cancelled = true; - } - - MarkAsNotMoving(*pChunk); - ++m_nCancelledMoves; - } -} - -void CDefragAllocator::Relocate(uint32 userMoveId, Index srcChunkIdx, Index dstChunkIdx) -{ - using std::swap; - - SDefragAllocChunk* pChunks = &m_chunks[0]; - uint32 logAlignment = m_logMinAlignment; - - SDefragAllocChunk& src = pChunks[srcChunkIdx]; - SDefragAllocChunk& dst = pChunks[dstChunkIdx]; - SDefragAllocChunkAttr srcAttr = src.attr; - SDefragAllocChunkAttr dstAttr = dst.attr; - - CDBA_ASSERT(srcAttr.IsMoving()); - CDBA_ASSERT(dstAttr.IsPinned()); - CDBA_ASSERT(!dstAttr.IsMoving()); - CDBA_ASSERT(srcAttr.GetSize() == dstAttr.GetSize()); - - UINT_PTR oldPtr = src.ptr; - UINT_PTR newPtr = dst.ptr; - - // src and dst are linked in the addr chain only - src needs to move where dst is (so user handles remain consistent) - // and the src block be freed. - - SDefragAllocChunk* pA = &dst; - SDefragAllocChunk* pB = &src; - - CDBA_ASSERT(pChunks[pA->addrPrevIdx].ptr + pChunks[pA->addrPrevIdx].attr.GetSize() == pA->ptr); - CDBA_ASSERT(pA->ptr + pA->attr.GetSize() == pChunks[pA->addrNextIdx].ptr); - CDBA_ASSERT(pChunks[pB->addrPrevIdx].ptr + pChunks[pB->addrPrevIdx].attr.GetSize() == pB->ptr); - CDBA_ASSERT(pB->ptr + pB->attr.GetSize() == pChunks[pB->addrNextIdx].ptr); - CDBA_ASSERT(&pChunks[pChunks[pA->addrNextIdx].addrPrevIdx] == pA); - CDBA_ASSERT(&pChunks[pChunks[pA->addrPrevIdx].addrNextIdx] == pA); - CDBA_ASSERT(&pChunks[pChunks[pB->addrNextIdx].addrPrevIdx] == pB); - CDBA_ASSERT(&pChunks[pChunks[pB->addrPrevIdx].addrNextIdx] == pB); - - Index nA = dstChunkIdx; - Index nB = srcChunkIdx; - - if (pA->addrNextIdx == nB) - { - // Neighbours - pB->addrPrevIdx = pA->addrPrevIdx; - pA->addrNextIdx = pB->addrNextIdx; - pA->addrPrevIdx = nB; - pB->addrNextIdx = nA; - pChunks[pB->addrPrevIdx].addrNextIdx = nB; - pChunks[pA->addrNextIdx].addrPrevIdx = nA; - } - else if (pA->addrPrevIdx == nB) - { - // Neighbours - pB->addrNextIdx = pA->addrNextIdx; - pA->addrPrevIdx = pB->addrPrevIdx; - pB->addrPrevIdx = nA; - pA->addrNextIdx = nB; - pChunks[pA->addrPrevIdx].addrNextIdx = nA; - pChunks[pB->addrNextIdx].addrPrevIdx = nB; - } - else - { - swap(pB->addrNextIdx, pA->addrNextIdx); - swap(pA->addrPrevIdx, pB->addrPrevIdx); - pChunks[pA->addrPrevIdx].addrNextIdx = nA; - pChunks[pA->addrNextIdx].addrPrevIdx = nA; - pChunks[pB->addrNextIdx].addrPrevIdx = nB; - pChunks[pB->addrPrevIdx].addrNextIdx = nB; - } - - swap(src.packedPtr, dst.packedPtr); - -#ifdef CDBA_MORE_DEBUG - ValidateAddressChain(); -#endif - - CDBA_ASSERT(pChunks[pA->addrPrevIdx].ptr + pChunks[pA->addrPrevIdx].attr.GetSize() == pA->ptr); - CDBA_ASSERT(pA->ptr + pA->attr.GetSize() == pChunks[pA->addrNextIdx].ptr); - CDBA_ASSERT(pChunks[pB->addrPrevIdx].ptr + pChunks[pB->addrPrevIdx].attr.GetSize() == pB->ptr); - CDBA_ASSERT(pB->ptr + pB->attr.GetSize() == pChunks[pB->addrNextIdx].ptr); - CDBA_ASSERT(&pChunks[pChunks[pA->addrNextIdx].addrPrevIdx] == pA); - CDBA_ASSERT(&pChunks[pChunks[pA->addrPrevIdx].addrNextIdx] == pA); - CDBA_ASSERT(&pChunks[pChunks[pB->addrNextIdx].addrPrevIdx] == pB); - CDBA_ASSERT(&pChunks[pChunks[pB->addrPrevIdx].addrNextIdx] == pB); - - if (userMoveId != IDefragAllocatorPolicy::InvalidUserMoveId) - { - m_policy.pDefragPolicy->Relocate(userMoveId, src.pContext, newPtr << logAlignment, oldPtr << logAlignment, (UINT_PTR)srcAttr.GetSize() << logAlignment); - } -} - -void CDefragAllocator::SyncMoveSegment(uint32 seg) -{ - SDefragAllocSegment& segment = m_segments[seg]; - SDefragAllocChunk& headSentinalChunk = m_chunks[segment.headSentinalChunkIdx]; - - // Assert that the segment is empty. - uint32 endAddress = segment.address + segment.capacity; - - Index chunkIdx = headSentinalChunk.addrNextIdx; - SDefragAllocChunk* pChunk = &m_chunks[chunkIdx]; - - int numValidSegs = seg; - - while (pChunk->ptr != endAddress) - { - if (pChunk->attr.IsBusy()) - { - CDBA_ASSERT(!pChunk->attr.IsMoving()); - CDBA_ASSERT(!pChunk->attr.IsPinned()); - CDBA_ASSERT(m_policy.pDefragPolicy != NULL); - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64 - size_t chunkAlign = BIT64(pChunk->logAlign); -#else - size_t chunkAlign = BIT(pChunk->logAlign); -#endif - - // Try and synchronously move the allocation - Index destinationChunkIdx = InvalidChunkIdx; - for (int segIdx = 0; destinationChunkIdx == InvalidChunkIdx && segIdx < numValidSegs; ++segIdx) - { - destinationChunkIdx = BestFit_FindFreeBlockForSegment(pChunk->attr.GetSize(), chunkAlign, segIdx); - } - - CDBA_ASSERT(destinationChunkIdx != InvalidChunkIdx); - - SplitResult sr = SplitFreeBlock(destinationChunkIdx, pChunk->attr.GetSize(), chunkAlign, true); - CDBA_ASSERT(sr.bSuccessful); - - SDefragAllocChunk& destinationChunk = m_chunks[destinationChunkIdx]; - MarkAsInUse(destinationChunk); - - Pin(ChunkHdlFromIdx(destinationChunkIdx)); - MarkAsMoving(*pChunk); - - m_policy.pDefragPolicy->SyncCopy(pChunk->pContext, destinationChunk.ptr << m_logMinAlignment, pChunk->ptr << m_logMinAlignment, (UINT_PTR)pChunk->attr.GetSize() << m_logMinAlignment); - Relocate(IDefragAllocatorPolicy::InvalidUserMoveId, chunkIdx, destinationChunkIdx); - - MarkAsNotMoving(*pChunk); - Unpin(ChunkHdlFromIdx(destinationChunkIdx)); - - MarkAsFree(destinationChunk); - destinationChunkIdx = MergeFreeBlock(destinationChunkIdx); - pChunk = &m_chunks[destinationChunkIdx]; - } - - chunkIdx = pChunk->addrNextIdx; - pChunk = &m_chunks[chunkIdx]; - } -} - -void CDefragAllocator::RebuildFreeLists() -{ - for (int bi = 0; bi < NumBuckets; ++bi) - { - Index ci = m_freeBuckets[bi]; - m_chunks[ci].freeNextIdx = ci; - m_chunks[ci].freePrevIdx = ci; - } - - for (Index ci = m_chunks[AddrStartSentinal].addrNextIdx; ci != AddrEndSentinal; ci = m_chunks[ci].addrNextIdx) - { - SDefragAllocChunk& ch = m_chunks[ci]; - if (!ch.attr.IsBusy()) - { - LinkFreeChunk(ci); - } - } - -#ifdef CDBA_MORE_DEBUG - ValidateFreeLists(); -#endif -} - -void CDefragAllocator::ValidateAddressChain() -{ - UINT_PTR p = 0; - - Index hdr = 0; - for (Index ci = m_chunks[hdr].addrNextIdx; ci != hdr; ) - { - SDefragAllocChunk& c = m_chunks[ci]; - - CDBA_ASSERT(p == c.ptr); - p += c.attr.GetSize(); - - ci = c.addrNextIdx; - } - - for (int bi = 0; bi < NumBuckets; ++bi) - { - hdr = m_freeBuckets[bi]; - - for (Index ci = m_chunks[hdr].freeNextIdx; ci != hdr; ) - { - SDefragAllocChunk& c = m_chunks[ci]; - - CDBA_ASSERT(!c.attr.IsBusy()); - - ci = c.freeNextIdx; - } - } -} - -void CDefragAllocator::ValidateFreeLists() -{ -#if defined(CDBA_DEBUG) - for (size_t bucket = 0; bucket < NumBuckets; ++bucket) - { - size_t rootIdx = m_freeBuckets[bucket]; - SDefragAllocChunk& root = m_chunks[rootIdx]; - - for (size_t idx = root.freeNextIdx; idx != rootIdx; idx = m_chunks[idx].freeNextIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max((uint32)1, (uint32)chunk.attr.GetSize()) >= (1U << bucket)); - CDBA_ASSERT(idx >= NumBuckets + 2); - - CDBA_ASSERT(m_chunks[chunk.freeNextIdx].freePrevIdx == idx); - CDBA_ASSERT(m_chunks[chunk.freePrevIdx].freeNextIdx == idx); - } - - for (size_t idx = root.freePrevIdx; idx != rootIdx; idx = m_chunks[idx].freePrevIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - - CDBA_ASSERT(!chunk.attr.IsBusy()); - CDBA_ASSERT(max((uint32)1, (uint32)chunk.attr.GetSize()) >= (1U << bucket)); - CDBA_ASSERT(idx >= NumBuckets + 2); - - CDBA_ASSERT(m_chunks[chunk.freeNextIdx].freePrevIdx == idx); - CDBA_ASSERT(m_chunks[chunk.freePrevIdx].freeNextIdx == idx); - } - } -#endif -} diff --git a/Code/CryEngine/CrySystem/DefragAllocator.h b/Code/CryEngine/CrySystem/DefragAllocator.h deleted file mode 100644 index 183b10bb7f..0000000000 --- a/Code/CryEngine/CrySystem/DefragAllocator.h +++ /dev/null @@ -1,712 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_DEFRAGALLOCATOR_H -#define CRYINCLUDE_CRYSYSTEM_DEFRAGALLOCATOR_H -#pragma once - - -#include "IDefragAllocator.h" - -#include "System.h" - -#ifndef _RELEASE -#define CDBA_DEBUG -#endif - -//#define CDBA_MORE_DEBUG - -#ifdef CDBA_DEBUG -#define CDBA_ASSERT(x) do { assert(x); if (!(x)) {__debugbreak(); } \ -} while (0) -#else -#define CDBA_ASSERT(x) assert(x) -#endif - -union SDefragAllocChunkAttr -{ - enum - { - SizeWidth = 27, - SizeMask = (1 << SizeWidth) - 1, - BusyMask = 1 << 27, - MovingMask = 1 << 28, - MaxPinCount = 7, - PinnedCountShift = 29, - PinnedIncMask = 1 << PinnedCountShift, - PinnedCountMask = MaxPinCount << PinnedCountShift, - }; - - uint32 ui; - - ILINE unsigned int GetSize() const { return ui & SizeMask; } - ILINE void SetSize(unsigned int size) { ui = (ui & ~SizeMask) | size; } - ILINE void AddSize(int size) { ui += size; } - ILINE bool IsBusy() const { return (ui & BusyMask) != 0; } - ILINE void SetBusy(bool b) { ui = b ? (ui | BusyMask) : (ui & ~BusyMask); } - ILINE bool IsMoving() const { return (ui & MovingMask) != 0; } - ILINE void SetMoving(bool m) { ui = m ? (ui | MovingMask) : (ui & ~MovingMask); } - ILINE void IncPinCount() { ui += PinnedIncMask; } - ILINE void DecPinCount() { ui -= PinnedIncMask; } - ILINE bool IsPinned() const { return (ui & PinnedCountMask) != 0; } - ILINE unsigned int GetPinCount() const { return (ui & PinnedCountMask) >> PinnedCountShift; } - ILINE void SetPinCount(unsigned int p) { ui = (ui & ~PinnedCountMask) | (p << PinnedCountShift); } -}; - -struct SDefragAllocChunk -{ - enum - { - AlignBitCount = 4, - }; - typedef IDefragAllocator::Hdl Index; - - Index addrPrevIdx; - Index addrNextIdx; - - union - { - struct - { - UINT_PTR ptr : sizeof(UINT_PTR) * 8 - AlignBitCount; - UINT_PTR logAlign: AlignBitCount; - }; - UINT_PTR packedPtr; - }; - SDefragAllocChunkAttr attr; - - union - { - void* pContext; - struct - { - Index freePrevIdx; - Index freeNextIdx; - }; - }; - -#ifndef _RELEASE - const char* source; -#endif - - void SwapEndian() - { - ::SwapEndian(addrPrevIdx, true); - ::SwapEndian(addrNextIdx, true); - ::SwapEndian(packedPtr, true); - ::SwapEndian(attr.ui, true); - - if (attr.IsBusy()) - { - ::SwapEndian(pContext, true); - } - else - { - ::SwapEndian(freePrevIdx, true); - ::SwapEndian(freeNextIdx, true); - } - -#ifndef _RELEASE - ::SwapEndian(source, true); -#endif - } -}; - -struct SDefragAllocSegment -{ - uint32 address; - uint32 capacity; - SDefragAllocChunk::Index headSentinalChunkIdx; - - void SwapEndian() - { - ::SwapEndian(address, true); - ::SwapEndian(capacity, true); - ::SwapEndian(headSentinalChunkIdx, true); - } -}; - -class CDefragAllocator; - -class CDefragAllocatorWalker -{ -public: - explicit CDefragAllocatorWalker(CDefragAllocator& alloc); - ~CDefragAllocatorWalker(); - - const SDefragAllocChunk* Next(); - -private: - CDefragAllocatorWalker(const CDefragAllocatorWalker&); - CDefragAllocatorWalker& operator = (const CDefragAllocatorWalker&); - -private: - CDefragAllocator* m_pAlloc; - SDefragAllocChunk::Index m_nChunkIdx; -}; - -class CDefragAllocator - : public IDefragAllocator -{ - friend class CDefragAllocatorWalker; - typedef SDefragAllocChunk::Index Index; - -public: - CDefragAllocator(); - - void Release(bool bDiscard); - - void Init(UINT_PTR capacity, UINT_PTR minAlignment, const Policy& policy); - -#ifndef _RELEASE - void DumpState(const char* filename); - void RestoreState(const char* filename); -#endif - - // allocatorDisplayOffset will offset the statistics for the allocator depending on the index. - // 0 means no offset and default location, 1 means bar will be rendered above the 0th bar and stats to the right of the 0th stats - void DisplayMemoryUsage(const char* title, unsigned int allocatorDisplayOffset = 0); - - bool AppendSegment(UINT_PTR capacity); - void UnAppendSegment(); - - Hdl Allocate(size_t sz, const char* source, void* pContext = NULL); - Hdl AllocateAligned(size_t sz, size_t alignment, const char* source, void* pContext = NULL); - AllocatePinnedResult AllocatePinned(size_t sz, const char* source, void* pContext = NULL); - bool Free(Hdl hdl); - - void ChangeContext(Hdl hdl, void* pNewContext); - - size_t GetAllocated() const { return (size_t)(m_capacity - m_available) << m_logMinAlignment; } - IDefragAllocatorStats GetStats(); - - size_t DefragmentTick(size_t maxMoves, size_t maxAmount, bool bForce); - - ILINE UINT_PTR UsableSize(Hdl hdl) - { - Index chunkIdx = ChunkIdxFromHdl(hdl); - CDBA_ASSERT(chunkIdx < m_chunks.size()); - - SDefragAllocChunk& chunk = m_chunks[chunkIdx]; - SDefragAllocChunkAttr attr = chunk.attr; - - CDBA_ASSERT(attr.IsBusy()); - return (UINT_PTR)attr.GetSize() << m_logMinAlignment; - } - - // Pin the chunk until the next defrag tick, when it will be automatically unpinned - ILINE UINT_PTR WeakPin(Hdl hdl) - { - Index chunkIdx = ChunkIdxFromHdl(hdl); - CDBA_ASSERT(chunkIdx < m_chunks.size()); - - SDefragAllocChunk& chunk = m_chunks[chunkIdx]; - SDefragAllocChunkAttr attr = chunk.attr; - CDBA_ASSERT(attr.IsBusy()); - - if (attr.IsMoving()) - { - CancelMove(chunkIdx, true); - } - - return chunk.ptr << m_logMinAlignment; - } - - // Pin the chunk until Unpin is called - ILINE UINT_PTR Pin(Hdl hdl) - { - Index chunkIdx = ChunkIdxFromHdl(hdl); - - SDefragAllocChunk& chunk = m_chunks[chunkIdx]; - SDefragAllocChunkAttr attr; - SDefragAllocChunkAttr newAttr; - - do - { - attr.ui = const_cast(chunk.attr.ui); - newAttr.ui = attr.ui; - - CDBA_ASSERT(attr.GetPinCount() < SDefragAllocChunkAttr::MaxPinCount); - CDBA_ASSERT(attr.IsBusy()); - - newAttr.IncPinCount(); - } - while (CryInterlockedCompareExchange(alias_cast(&chunk.attr.ui), newAttr.ui, attr.ui) != attr.ui); - - // Potentially a Relocate could be in progress here. Either the Relocate is mid-way, in which case 'IsMoving()' will - // still be set, and CancelMove will sync and all is well. - - // If 'IsMoving()' is not set, the Relocate should have just completed, in which case ptr should validly point - // to the new location. - - if (attr.IsMoving()) - { - CancelMove(chunkIdx, true); - } - - return chunk.ptr << m_logMinAlignment; - } - - ILINE void Unpin(Hdl hdl) - { - SDefragAllocChunk& chunk = m_chunks[ChunkIdxFromHdl(hdl)]; - SDefragAllocChunkAttr attr; - SDefragAllocChunkAttr newAttr; - do - { - attr.ui = const_cast(chunk.attr.ui); - newAttr.ui = attr.ui; - - CDBA_ASSERT(attr.IsPinned()); - CDBA_ASSERT(attr.IsBusy()); - - newAttr.DecPinCount(); - } - while (CryInterlockedCompareExchange(alias_cast(&chunk.attr.ui), newAttr.ui, attr.ui) != attr.ui); - } - - ILINE const char* GetSourceOf([[maybe_unused]] Hdl hdl) - { -#ifndef _RELEASE - return m_chunks[ChunkIdxFromHdl(hdl)].source; -#else - return ""; -#endif - } - -private: - enum - { - NumBuckets = 31, // 2GB - MaxPendingMoves = 64, - - AddrStartSentinal = 0, - AddrEndSentinal = 1, - }; - - struct SplitResult - { - bool bSuccessful; - Index nLeftSplitChunkIdx; - Index nRightSplitChunkIdx; - }; - - struct PendingMove - { - PendingMove() - : srcChunkIdx(InvalidChunkIdx) - , dstChunkIdx(InvalidChunkIdx) - , userMoveId(0) - , relocated(false) - , cancelled(false) - { - } - - Index srcChunkIdx; - Index dstChunkIdx; - uint32 userMoveId; - IDefragAllocatorCopyNotification notify; - bool relocated; - bool cancelled; - - void SwapEndian() - { - ::SwapEndian(srcChunkIdx, true); - ::SwapEndian(dstChunkIdx, true); - ::SwapEndian(userMoveId, true); - } - }; - - struct PendingMoveSrcChunkPredicate - { - PendingMoveSrcChunkPredicate(Index ci) - : m_ci(ci) {} - bool operator () (const PendingMove& pm) const { return pm.srcChunkIdx == m_ci; } - Index m_ci; - }; - - typedef DynArray PendingMoveVec; - typedef std::vector SegmentVec; - - static const Index InvalidChunkIdx = (Index) - 1; - -private: - static ILINE Index ChunkIdxFromHdl(Hdl id) { return id - 1; } - static ILINE Hdl ChunkHdlFromIdx(Index idx) { return idx + 1; } - -private: - ~CDefragAllocator(); - - Index AllocateChunk(); - void ReleaseChunk(Index idx); - - ILINE void MarkAsInUse(SDefragAllocChunk& chunk) - { - CDBA_ASSERT(!chunk.attr.IsBusy()); - - chunk.attr.SetBusy(true); - m_available -= chunk.attr.GetSize(); - ++m_numAllocs; - - // m_available is unsigned, so check for underflow - CDBA_ASSERT(m_available <= m_capacity); - } - - ILINE void MarkAsFree(SDefragAllocChunk& chunk) - { - CDBA_ASSERT(chunk.attr.IsBusy()); - - chunk.attr.SetPinCount(0); - chunk.attr.SetMoving(false); - chunk.attr.SetBusy(0); - m_available += chunk.attr.GetSize(); - --m_numAllocs; - - // m_available is unsigned, so check for underflow - CDBA_ASSERT(m_available <= m_capacity); - } - - void LinkFreeChunk(Index idx); - void UnlinkFreeChunk(Index idx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - m_chunks[chunk.freePrevIdx].freeNextIdx = chunk.freeNextIdx; - m_chunks[chunk.freeNextIdx].freePrevIdx = chunk.freePrevIdx; - } - - void LinkAddrChunk(Index idx, Index afterIdx) - { - SDefragAllocChunk& chunk = m_chunks[idx]; - SDefragAllocChunk& afterChunk = m_chunks[afterIdx]; - - chunk.addrNextIdx = afterChunk.addrNextIdx; - chunk.addrPrevIdx = afterIdx; - m_chunks[chunk.addrNextIdx].addrPrevIdx = idx; - afterChunk.addrNextIdx = idx; - } - - void UnlinkAddrChunk(Index id) - { - SDefragAllocChunk& chunk = m_chunks[id]; - - m_chunks[chunk.addrPrevIdx].addrNextIdx = chunk.addrNextIdx; - m_chunks[chunk.addrNextIdx].addrPrevIdx = chunk.addrPrevIdx; - } - - void PrepareMergePopNext(Index* pLists) - { - for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx) - { - Index hdrChunkId = m_freeBuckets[bucketIdx]; - Index nextId = m_chunks[hdrChunkId].freeNextIdx; - if (nextId != hdrChunkId) - { - pLists[bucketIdx] = nextId; - } - else - { - pLists[bucketIdx] = InvalidChunkIdx; - } - } - } - - size_t MergePeekNextChunk(Index* pLists) - { - size_t farList = (size_t)-1; - UINT_PTR farPtr = (UINT_PTR)-1; - - for (size_t listIdx = 0; listIdx < NumBuckets; ++listIdx) - { - Index chunkIdx = pLists[listIdx]; - if (chunkIdx != InvalidChunkIdx) - { - SDefragAllocChunk& chunk = m_chunks[chunkIdx]; - if (chunk.ptr < farPtr) - { - farPtr = chunk.ptr; - farList = listIdx; - } - } - } - - return farList; - } - - void MergePopNextChunk(Index* pLists, size_t list) - { - using std::swap; - - Index fni = m_chunks[pLists[list]].freeNextIdx; - pLists[list] = fni; - if (m_chunks[fni].attr.IsBusy()) - { - // End of the list - pLists[list] = InvalidChunkIdx; - } - } - - void MergePatchNextRemove(Index* pLists, Index removeIdx) - { - for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx) - { - if (pLists[bucketIdx] == removeIdx) - { - Index nextIdx = m_chunks[removeIdx].freeNextIdx; - if (!m_chunks[nextIdx].attr.IsBusy()) - { - pLists[bucketIdx] = nextIdx; - } - else - { - pLists[bucketIdx] = InvalidChunkIdx; - } - } - } - } - - void MergePatchNextInsert(Index* pLists, Index insertIdx) - { - SDefragAllocChunk& insertChunk = m_chunks[insertIdx]; - int bucket = BucketForSize(insertChunk.attr.GetSize()); - - if (pLists[bucket] != InvalidChunkIdx) - { - SDefragAllocChunk& listChunk = m_chunks[pLists[bucket]]; - if (listChunk.ptr > insertChunk.ptr) - { - pLists[bucket] = insertIdx; - } - } - } - - void PrepareMergePopPrev(Index* pLists) - { - for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx) - { - Index hdrChunkId = m_freeBuckets[bucketIdx]; - Index prevIdx = m_chunks[hdrChunkId].freePrevIdx; - if (prevIdx != hdrChunkId) - { - pLists[bucketIdx] = prevIdx; - } - else - { - pLists[bucketIdx] = InvalidChunkIdx; - } - } - } - - size_t MergePeekPrevChunk(Index* pLists) - { - size_t farList = (size_t)-1; - UINT_PTR farPtr = 0; - - for (size_t listIdx = 0; listIdx < NumBuckets; ++listIdx) - { - Index chunkIdx = pLists[listIdx]; - if (chunkIdx != InvalidChunkIdx) - { - SDefragAllocChunk& chunk = m_chunks[chunkIdx]; - if (chunk.ptr >= farPtr) - { - farPtr = chunk.ptr; - farList = listIdx; - } - } - } - - return farList; - } - - void MergePopPrevChunk(Index* pLists, size_t list) - { - using std::swap; - - Index fpi = m_chunks[pLists[list]].freePrevIdx; - pLists[list] = fpi; - if (m_chunks[fpi].attr.IsBusy()) - { - // End of the list - pLists[list] = InvalidChunkIdx; - } - } - - void MergePatchPrevInsert(Index* pLists, Index insertIdx) - { - SDefragAllocChunk& insertChunk = m_chunks[insertIdx]; - int bucket = BucketForSize(insertChunk.attr.GetSize()); - - if (pLists[bucket] != InvalidChunkIdx) - { - SDefragAllocChunk& listChunk = m_chunks[pLists[bucket]]; - if (listChunk.ptr < insertChunk.ptr) - { - pLists[bucket] = insertIdx; - } - } - } - - void MergePatchPrevRemove(Index* pLists, Index removeIdx) - { - for (int bucketIdx = 0; bucketIdx < NumBuckets; ++bucketIdx) - { - if (pLists[bucketIdx] == removeIdx) - { - Index nextIdx = m_chunks[removeIdx].freePrevIdx; - if (!m_chunks[nextIdx].attr.IsBusy()) - { - pLists[bucketIdx] = nextIdx; - } - else - { - pLists[bucketIdx] = InvalidChunkIdx; - } - } - } - } - - void MarkAsMoving(SDefragAllocChunk& src) - { - SDefragAllocChunkAttr srcAttr, srcNewAttr; - do - { - srcAttr.ui = const_cast(src.attr.ui); - srcNewAttr.ui = srcAttr.ui; - srcNewAttr.SetMoving(true); - } - while (CryInterlockedCompareExchange(alias_cast(&src.attr.ui), srcNewAttr.ui, srcAttr.ui) != srcAttr.ui); - } - - void MarkAsNotMoving(SDefragAllocChunk& src) - { - SDefragAllocChunkAttr srcAttr, srcNewAttr; - do - { - srcAttr.ui = const_cast(src.attr.ui); - srcNewAttr.ui = srcAttr.ui; - srcNewAttr.SetMoving(false); - } - while (CryInterlockedCompareExchange(alias_cast(&src.attr.ui), srcNewAttr.ui, srcAttr.ui) != srcAttr.ui); - } - - ILINE bool IsMoveableCandidate(const SDefragAllocChunkAttr& a, uint32 sizeUpperBound) - { - return a.IsBusy() && !a.IsPinned() && !a.IsMoving() && (0 < a.GetSize()) && (a.GetSize() <= sizeUpperBound); - } - - bool TryMarkAsMoving(SDefragAllocChunk& src, uint32 sizeUpperBound) - { - SDefragAllocChunkAttr srcAttr, srcNewAttr; - do - { - srcAttr.ui = const_cast(src.attr.ui); - srcNewAttr.ui = srcAttr.ui; - if (!IsMoveableCandidate(srcAttr, sizeUpperBound)) - { - return false; - } - srcNewAttr.SetMoving(true); - } - while (CryInterlockedCompareExchange(alias_cast(&src.attr.ui), srcNewAttr.ui, srcAttr.ui) != srcAttr.ui); - return true; - } - - bool TryScheduleCopy(SDefragAllocChunk& srcChunk, SDefragAllocChunk& dstChunk, PendingMove* pPM, bool bLowHalf) - { - UINT_PTR dstChunkBase = dstChunk.ptr; - UINT_PTR dstChunkEnd = dstChunkBase + dstChunk.attr.GetSize(); -#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_BIT64 - UINT_PTR allocAlign = BIT64(srcChunk.logAlign); -#else - UINT_PTR allocAlign = BIT(srcChunk.logAlign); -#endif - UINT_PTR allocSize = srcChunk.attr.GetSize(); - UINT_PTR dstAllocBase = bLowHalf - ? Align(dstChunkBase, allocAlign) - : ((dstChunkEnd - allocSize) & ~(allocAlign - 1)); - - uint32 userId = m_policy.pDefragPolicy->BeginCopy( - srcChunk.pContext, - dstAllocBase << m_logMinAlignment, - srcChunk.ptr << m_logMinAlignment, - allocSize << m_logMinAlignment, - &pPM->notify); - pPM->userMoveId = userId; - - return userId != 0; - } - - Hdl Allocate_Locked(size_t sz, size_t alignment, const char* source, void* pContext); - SplitResult SplitFreeBlock(Index fbId, size_t sz, size_t alignment, bool allocateInLowHalf); - Index MergeFreeBlock(Index fbId); - -#ifdef CDBA_MORE_DEBUG - void Defrag_ValidateFreeBlockIteration(); -#endif - - Index BestFit_FindFreeBlockForSegment(size_t sz, size_t alignment, uint32 nSegment); - Index BestFit_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressMin, UINT_PTR addressMax, bool allocateInLowHalf); - Index FirstFit_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressMin, UINT_PTR addressMax, bool allocateInLowHalf); - - size_t Defrag_FindMovesBwd(PendingMove** pMoves, size_t maxMoves, size_t& curAmount, size_t maxAmount); - size_t Defrag_FindMovesFwd(PendingMove** pMoves, size_t maxMoves, size_t& curAmount, size_t maxAmount); - bool Defrag_CompletePendingMoves(); - Index Defrag_Bwd_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressLimit); - Index Defrag_Fwd_FindFreeBlockFor(size_t sz, size_t alignment, UINT_PTR addressLimit); - - PendingMove* AllocPendingMove(); - void FreePendingMove(PendingMove* pMove); - - void CancelMove(Index srcChunkIdx, bool bIsContentNeeded); - void CancelMove_Locked(Index srcChunkIdx, bool bIsContentNeeded); - void Relocate(uint32 userMoveId, Index srcChunkIdx, Index dstChunkIdx); - - void SyncMoveSegment(uint32 seg); - - void RebuildFreeLists(); - void ValidateAddressChain(); - void ValidateFreeLists(); - - int BucketForSize(size_t sz) const - { - return sz > 0 - ? static_cast(IntegerLog2(sz)) - : 0; - } - -private: - bool m_isThreadSafe; - bool m_chunksAreFixed; - - CryCriticalSection m_lock; - - uint32 m_capacity; - uint32 m_available; - Index m_numAllocs; - - uint16 m_minAlignment; - uint16 m_logMinAlignment; - - Index m_freeBuckets[NumBuckets]; - - std::vector m_chunks; - std::vector m_unusedChunks; - PendingMoveVec m_pendingMoves; - SegmentVec m_segments; - - uint32 m_nCancelledMoves; - - Policy m_policy; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_DEFRAGALLOCATOR_H diff --git a/Code/CryEngine/CrySystem/DllMain.cpp b/Code/CryEngine/CrySystem/DllMain.cpp index aba39fb9fb..53593821d9 100644 --- a/Code/CryEngine/CrySystem/DllMain.cpp +++ b/Code/CryEngine/CrySystem/DllMain.cpp @@ -15,10 +15,6 @@ #include "System.h" #include #include "DebugCallStack.h" -#if defined(AZ_MONOLITHIC_BUILD) -#include -#include -#endif #if defined(AZ_RESTRICTED_PLATFORM) #undef AZ_RESTRICTED_SECTION @@ -67,51 +63,6 @@ AZ_POP_DISABLE_WARNING } #endif -////////////////////////////////////////////////////////////////////////// -struct CSystemEventListner_System - : public ISystemEventListener -{ -public: - virtual void OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) - { - switch (event) - { - case ESYSTEM_EVENT_LEVEL_UNLOAD: - gEnv->pSystem->SetThreadState(ESubsys_Physics, false); - break; - - case ESYSTEM_EVENT_LEVEL_LOAD_START: - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - CryCleanup(); - break; - } - - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - CryCleanup(); - STLALLOCATOR_CLEANUP; - gEnv->pSystem->SetThreadState(ESubsys_Physics, true); - break; - } - } - } -}; - -static CSystemEventListner_System g_system_event_listener_system; - -static AZ::EnvironmentVariable s_cryMemoryManager; - - -// Force the CryMemoryManager into the AZ::Environment for exposure to other DLLs -void ExportCryMemoryManager() -{ - IMemoryManager* cryMemoryManager = nullptr; - CryGetIMemoryManagerInterface((void**)&cryMemoryManager); - AZ_Assert(cryMemoryManager, "Unable to resolve CryMemoryManager"); - s_cryMemoryManager = AZ::Environment::CreateVariable("CryIMemoryManagerInterface", cryMemoryManager); -} - extern "C" { CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupParams) @@ -123,8 +74,6 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar // Environment should have been attached via InjectEnvironment AZ_Assert(AZ::Environment::IsReady(), "Environment is not attached, must be attached before CreateSystemInterface can be called"); - ExportCryMemoryManager(); - pSystem = new CSystem(startupParams.pSharedEnvironment); ModuleInitISystem(pSystem, "CrySystem"); @@ -132,30 +81,22 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar #define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_2 #include AZ_RESTRICTED_FILE(DllMain_cpp) #endif -#if defined(AZ_MONOLITHIC_BUILD) - ICryFactoryRegistryImpl* pCryFactoryImpl = static_cast(pSystem->GetCryFactoryRegistry()); - pCryFactoryImpl->RegisterFactories(g_pHeadToRegFactories); -#endif // AZ_MONOLITHIC_BUILD + // the earliest point the system exists - w2e tell the callback if (startupParams.pUserCallback) { startupParams.pUserCallback->OnSystemConnect(pSystem); } +#if defined(WIN32) // Environment Variable to signal we don't want to override our exception handler - our crash report system will set this auto envVar = AZ::Environment::FindVariable("ExceptionHandlerIsSet"); - bool handlerIsSet = (envVar && *envVar); - - if (!startupParams.bMinimal && !handlerIsSet) // in minimal mode, we want to crash when we crash! + const bool handlerIsSet = (envVar && *envVar); + if (!handlerIsSet) { -#if defined(WIN32) - // Install exception handler in Release modes. ((DebugCallStack*)IDebugCallStack::instance())->installErrorHandler(pSystem); -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE(DllMain_cpp) -#endif } +#endif bool retVal = false; { @@ -174,24 +115,7 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar return 0; } - pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_system); - return pSystem; } - -CRYSYSTEM_API void WINAPI CryInstallUnhandledExceptionHandler() -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_4 -#include AZ_RESTRICTED_FILE(DllMain_cpp) -#endif -} - -#if defined(ENABLE_PROFILING_CODE) && !defined(LINUX) && !defined(APPLE) -CRYSYSTEM_API void CryInstallPostExceptionHandler(void (* PostExceptionHandlerCallback)()) -{ - return IDebugCallStack::instance()->FileCreationCallback(PostExceptionHandlerCallback); -} -#endif }; diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.cpp b/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.cpp deleted file mode 100644 index 26c13a070d..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.cpp +++ /dev/null @@ -1,359 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#include "CrySystem_precompiled.h" -#include "CryFactoryRegistryImpl.h" -#include "../System.h" - -#include -#include -#include - -#include - - -CCryFactoryRegistryImpl::CCryFactoryRegistryImpl() - : m_guard() - , m_byCName() - , m_byCID() - , m_byIID() - , m_callbacks() -{ -} - - -CCryFactoryRegistryImpl::~CCryFactoryRegistryImpl() -{ -} - - -CCryFactoryRegistryImpl& CCryFactoryRegistryImpl::Access() -{ - static StaticInstance> s_registry; - return s_registry; -} - - -ICryFactory* CCryFactoryRegistryImpl::GetFactory(const char* cname) const -{ - AUTO_READLOCK(m_guard); - - if (!cname) - { - return 0; - } - - const FactoryByCName search(cname); - FactoriesByCNameConstIt it = std::lower_bound(m_byCName.begin(), m_byCName.end(), search); - return it != m_byCName.end() && !(search < *it) ? (*it).m_ptr : 0; -} - - -ICryFactory* CCryFactoryRegistryImpl::GetFactory(const CryClassID& cid) const -{ - AUTO_READLOCK(m_guard); - - const FactoryByCID search(cid); - FactoriesByCIDConstIt it = std::lower_bound(m_byCID.begin(), m_byCID.end(), search); - return it != m_byCID.end() && !(search < *it) ? (*it).m_ptr : 0; -} - - -void CCryFactoryRegistryImpl::IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const -{ - AUTO_READLOCK(m_guard); - - typedef std::pair SearchResult; - SearchResult res = std::equal_range(m_byIID.begin(), m_byIID.end(), FactoryByIID(iid, 0), LessPredFactoryByIIDOnly()); - - const size_t numFactoriesFound = std::distance(res.first, res.second); - if (pFactories) - { - numFactories = min(numFactories, numFactoriesFound); - FactoriesByIIDConstIt it = res.first; - for (size_t i = 0; i < numFactories; ++i, ++it) - { - pFactories[i] = (*it).m_ptr; - } - } - else - { - numFactories = numFactoriesFound; - } -} - - -void CCryFactoryRegistryImpl::RegisterCallback(ICryFactoryRegistryCallback* pCallback) -{ - if (!pCallback) - { - return; - } - - { - AUTO_MODIFYLOCK(m_guard); - - Callbacks::iterator it = std::lower_bound(m_callbacks.begin(), m_callbacks.end(), pCallback); - if (it == m_callbacks.end() || pCallback < *it) - { - m_callbacks.insert(it, pCallback); - } - else - { - assert(0 && "CCryFactoryRegistryImpl::RegisterCallback() -- pCallback already registered!"); - } - } - { - AUTO_READLOCK(m_guard); - - typedef std::pair SearchResult; - SearchResult res = std::equal_range(m_byIID.begin(), m_byIID.end(), FactoryByIID(cryiidof(), 0), LessPredFactoryByIIDOnly()); - - for (; res.first != res.second; ++res.first) - { - pCallback->OnNotifyFactoryRegistered((*res.first).m_ptr); - } - } -} - - -void CCryFactoryRegistryImpl::UnregisterCallback(ICryFactoryRegistryCallback* pCallback) -{ - if (!pCallback) - { - return; - } - - AUTO_MODIFYLOCK(m_guard); - - Callbacks::iterator it = std::lower_bound(m_callbacks.begin(), m_callbacks.end(), pCallback); - if (it != m_callbacks.end() && !(pCallback < *it)) - { - m_callbacks.erase(it); - } -} - - -bool CCryFactoryRegistryImpl::GetInsertionPos(ICryFactory* pFactory, FactoriesByCNameIt& itPosForCName, FactoriesByCIDIt& itPosForCID) -{ - assert(pFactory); - - struct FatalError - { - static void Report(ICryFactory* pKnownFactory, ICryFactory* pNewFactory) - { - char err[1024]; - sprintf_s(err, sizeof(err), "Conflicting factories...\n" - "Factory (0x%p): ClassID = %s, ClassName = \"%s\"\n" - "Factory (0x%p): ClassID = %s, ClassName = \"%s\"", - pKnownFactory, pKnownFactory ? CryGUIDHelper::Print(pKnownFactory->GetClassID()).c_str() : "$unknown$", pKnownFactory ? pKnownFactory->GetName() : "$unknown$", - pNewFactory, pNewFactory ? CryGUIDHelper::Print(pNewFactory->GetClassID()).c_str() : "$unknown$", pNewFactory ? pNewFactory->GetName() : "$unknown$"); - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_FACTORY_REGISTRY_USE_PRINTF_FOR_FATAL - printf("\n!!! Fatal error !!!\n"); - printf(err); - printf("\n"); -#elif defined(WIN32) || defined(WIN64) - OutputDebugStringA("\n!!! Fatal error !!!\n"); - OutputDebugStringA(err); - OutputDebugStringA("\n"); - MessageBoxA(0, err, "!!! Fatal error !!!", MB_OK | MB_ICONERROR); -#endif - - assert(0); - exit(0); - } - }; - - FactoryByCName searchByCName(pFactory); - FactoriesByCNameIt itForCName = std::lower_bound(m_byCName.begin(), m_byCName.end(), searchByCName); - if (itForCName != m_byCName.end()) - { - // If the addresses match, then this factory is already registered. It's not really worth error-ing about, - // as double registration will not cause any harm. - if (itForCName->m_ptr == pFactory) - { - return false; - } - - if (!(searchByCName < *itForCName)) - { - FatalError::Report((*itForCName).m_ptr, pFactory); - } - } - - FactoryByCID searchByCID(pFactory); - FactoriesByCIDIt itForCID = std::lower_bound(m_byCID.begin(), m_byCID.end(), searchByCID); - if (itForCID != m_byCID.end() && !(searchByCID < *itForCID)) - { - FatalError::Report((*itForCID).m_ptr, pFactory); - } - - itPosForCName = itForCName; - itPosForCID = itForCID; - - return true; -} - - -void CCryFactoryRegistryImpl::RegisterFactories(const SRegFactoryNode* pFactories) -{ - size_t numFactoriesToAdd = 0; - size_t numInterfacesSupported = 0; - { - const SRegFactoryNode* p = pFactories; - while (p) - { - ICryFactory* pFactory = p->m_pFactory; - assert(pFactory); - if (pFactory) - { - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - pFactory->ClassSupports(pIIDs, numIIDs); - - numInterfacesSupported += numIIDs; - ++numFactoriesToAdd; - } - - p = p->m_pNext; - } - } - - { - AUTO_MODIFYLOCK(m_guard); - - m_byCName.reserve(m_byCName.size() + numFactoriesToAdd); - m_byCID.reserve(m_byCID.size() + numFactoriesToAdd); - m_byIID.reserve(m_byIID.size() + numInterfacesSupported); - - size_t numFactoriesAdded = 0; - const SRegFactoryNode* p = pFactories; - while (p) - { - ICryFactory* pFactory = p->m_pFactory; - if (pFactory) - { - FactoriesByCNameIt itPosForCName; - FactoriesByCIDIt itPosForCID; - if (GetInsertionPos(pFactory, itPosForCName, itPosForCID)) - { - m_byCName.insert(itPosForCName, FactoryByCName(pFactory)); - m_byCID.insert(itPosForCID, FactoryByCID(pFactory)); - - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - pFactory->ClassSupports(pIIDs, numIIDs); - - for (size_t i = 0; i < numIIDs; ++i) - { - const FactoryByIID newFactory(pIIDs[i], pFactory); - m_byIID.push_back(newFactory); - } - - for (size_t i = 0, s = m_callbacks.size(); i < s; ++i) - { - m_callbacks[i]->OnNotifyFactoryRegistered(pFactory); - } - - ++numFactoriesAdded; - } - } - - p = p->m_pNext; - } - - if (numFactoriesAdded) - { - std::sort(m_byIID.begin(), m_byIID.end()); - } - } -} - - -void CCryFactoryRegistryImpl::UnregisterFactories(const SRegFactoryNode* pFactories) -{ - AUTO_MODIFYLOCK(m_guard); - - const SRegFactoryNode* p = pFactories; - while (p) - { - ICryFactory* pFactory = p->m_pFactory; - UnregisterFactoryInternal(pFactory); - p = p->m_pNext; - } -} - - -void CCryFactoryRegistryImpl::UnregisterFactory(ICryFactory* const pFactory) -{ - AUTO_MODIFYLOCK(m_guard); - - UnregisterFactoryInternal(pFactory); -} - - -void CCryFactoryRegistryImpl::UnregisterFactoryInternal(ICryFactory* const pFactory) -{ - if (pFactory) - { - FactoryByCName searchByCName(pFactory); - FactoriesByCNameIt itForCName = std::lower_bound(m_byCName.begin(), m_byCName.end(), searchByCName); - if (itForCName != m_byCName.end() && !(searchByCName < *itForCName)) - { - assert((*itForCName).m_ptr == pFactory); - if ((*itForCName).m_ptr == pFactory) - { - m_byCName.erase(itForCName); - } - } - - FactoryByCID searchByCID(pFactory); - FactoriesByCIDIt itForCID = std::lower_bound(m_byCID.begin(), m_byCID.end(), searchByCID); - if (itForCID != m_byCID.end() && !(searchByCID < *itForCID)) - { - assert((*itForCID).m_ptr == pFactory); - if ((*itForCID).m_ptr == pFactory) - { - m_byCID.erase(itForCID); - } - } - - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - pFactory->ClassSupports(pIIDs, numIIDs); - - for (size_t i = 0; i < numIIDs; ++i) - { - FactoryByIID searchByIID(pIIDs[i], pFactory); - FactoriesByIIDIt itForIID = std::lower_bound(m_byIID.begin(), m_byIID.end(), searchByIID); - if (itForIID != m_byIID.end() && !(searchByIID < *itForIID)) - { - m_byIID.erase(itForIID); - } - } - - for (size_t i = 0, s = m_callbacks.size(); i < s; ++i) - { - m_callbacks[i]->OnNotifyFactoryUnregistered(pFactory); - } - } -} - -ICryFactoryRegistry* CSystem::GetCryFactoryRegistry() const -{ - return &CCryFactoryRegistryImpl::Access(); -} diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.h b/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.h deleted file mode 100644 index a75ddf782f..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/CryFactoryRegistryImpl.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_CRYFACTORYREGISTRYIMPL_H -#define CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_CRYFACTORYREGISTRYIMPL_H -#pragma once - - - -#include -#include - -#include - - -class CCryFactoryRegistryImpl - : public ICryFactoryRegistryImpl -{ -public: - virtual ICryFactory* GetFactory(const char* cname) const; - virtual ICryFactory* GetFactory(const CryClassID& cid) const; - virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const; - - virtual void RegisterCallback(ICryFactoryRegistryCallback* pCallback); - virtual void UnregisterCallback(ICryFactoryRegistryCallback* pCallback); - - virtual void RegisterFactories(const SRegFactoryNode* pFactories); - virtual void UnregisterFactories(const SRegFactoryNode* pFactories); - - virtual void UnregisterFactory(ICryFactory* const pFactory); - -public: - static CCryFactoryRegistryImpl& Access(); - CCryFactoryRegistryImpl(); - ~CCryFactoryRegistryImpl(); - -private: - struct FactoryByCName - { - const char* m_cname; - ICryFactory* m_ptr; - - FactoryByCName(const char* cname) - : m_cname(cname) - , m_ptr(0) {assert(m_cname); } - FactoryByCName(ICryFactory* ptr) - : m_cname(ptr ? ptr->GetName() : 0) - , m_ptr(ptr) {assert(m_cname && m_ptr); } - bool operator <(const FactoryByCName& rhs) const {return strcmp(m_cname, rhs.m_cname) < 0; } - }; - typedef std::vector FactoriesByCName; - typedef FactoriesByCName::iterator FactoriesByCNameIt; - typedef FactoriesByCName::const_iterator FactoriesByCNameConstIt; - - struct FactoryByCID - { - CryClassID m_cid; - ICryFactory* m_ptr; - - FactoryByCID(const CryClassID& cid) - : m_cid(cid) - , m_ptr(0) {} - FactoryByCID(ICryFactory* ptr) - : m_cid(ptr ? ptr->GetClassID() : MAKE_CRYGUID(0, 0)) - , m_ptr(ptr) {assert(m_ptr); } - bool operator <(const FactoryByCID& rhs) const {return m_cid < rhs.m_cid; } - }; - typedef std::vector FactoriesByCID; - typedef FactoriesByCID::iterator FactoriesByCIDIt; - typedef FactoriesByCID::const_iterator FactoriesByCIDConstIt; - - struct FactoryByIID - { - CryInterfaceID m_iid; - ICryFactory* m_ptr; - - FactoryByIID(CryInterfaceID iid, ICryFactory* pFactory) - : m_iid(iid) - , m_ptr(pFactory) {} - bool operator <(const FactoryByIID& rhs) const - { - if (m_iid != rhs.m_iid) - { - return m_iid < rhs.m_iid; - } - return m_ptr < rhs.m_ptr; - } - }; - typedef std::vector FactoriesByIID; - typedef FactoriesByIID::iterator FactoriesByIIDIt; - typedef FactoriesByIID::const_iterator FactoriesByIIDConstIt; - struct LessPredFactoryByIIDOnly - { - bool operator ()(const FactoryByIID& lhs, const FactoryByIID& rhs) const {return lhs.m_iid < rhs.m_iid; } - }; - - typedef std::vector Callbacks; - typedef Callbacks::iterator CallbacksIt; - typedef Callbacks::const_iterator CallbacksConstIt; - -private: - bool GetInsertionPos(ICryFactory* pFactory, FactoriesByCNameIt& itPosForCName, FactoriesByCIDIt& itPosForCID); - void UnregisterFactoryInternal(ICryFactory* const pFactory); - -private: - mutable CryReadModifyLock m_guard; - - FactoriesByCName m_byCName; - FactoriesByCID m_byCID; - FactoriesByIID m_byIID; - - Callbacks m_callbacks; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_CRYFACTORYREGISTRYIMPL_H diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.cpp b/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.cpp deleted file mode 100644 index f87643d4f0..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.cpp +++ /dev/null @@ -1,955 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#include "CrySystem_precompiled.h" -#include "TestExtensions.h" - -#ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#include -#include -#include - - -////////////////////////////////////////////////////////////////////////// - - -namespace TestComposition -{ - struct ITestExt1 - : public ICryUnknown - { - CRYINTERFACE_DECLARE(ITestExt1, 0x9d9e0dcfa5764cb0, 0xa73701595f75bd32) - - virtual void Call1() const = 0; - }; - - DECLARE_SMART_POINTERS(ITestExt1); - - - class CTestExt1 - : public ITestExt1 - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt1) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CTestExt1, "TestExt1", 0x43b04e7cc1be45ca, 0x9df6ccb1c0dc1ad8) - - public: - virtual void Call1() const; - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt1) - - CTestExt1::CTestExt1() - { - i = 1; - } - - CTestExt1::~CTestExt1() - { - printf("Inside CTestExt1 dtor\n"); - } - - void CTestExt1::Call1() const - { - printf("Inside CTestExt1::Call1()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - struct ITestExt2 - : public ICryUnknown - { - CRYINTERFACE_DECLARE(ITestExt2, 0x8eb7a4b399874b9c, 0xb96bd6da7a8c72f9) - - virtual void Call2() = 0; - }; - - DECLARE_SMART_POINTERS(ITestExt2); - - - class CTestExt2 - : public ITestExt2 - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt2) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CTestExt2, "TestExt2", 0x25b3ebf8f1754b9a, 0xb5494e3da7cdd80f) - - public: - virtual void Call2(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt2) - - CTestExt2::CTestExt2() - { - i = 2; - } - - CTestExt2::~CTestExt2() - { - printf("Inside CTestExt2 dtor\n"); - } - - void CTestExt2::Call2() - { - printf("Inside CTestExt2::Call2()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CComposed - : public ICryUnknown - { - CRYGENERATE_CLASS(CComposed, "Composed", 0x0439d74b8dcd4b7f, 0x9287dcdf7e26a3a5) - - CRYCOMPOSITE_BEGIN() - CRYCOMPOSITE_ADD(m_pTestExt1, "Ext1") - CRYCOMPOSITE_ADD(m_pTestExt2, "Ext2") - CRYCOMPOSITE_END(CComposed) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_END() - - private: - ITestExt1Ptr m_pTestExt1; - ITestExt2Ptr m_pTestExt2; - }; - - CRYREGISTER_CLASS(CComposed) - - CComposed::CComposed() - : m_pTestExt1() - , m_pTestExt2() - { - CryCreateClassInstance("TestExt1", m_pTestExt1); - CryCreateClassInstance("TestExt2", m_pTestExt2); - } - - CComposed::~CComposed() - { - } - - ////////////////////////////////////////////////////////////////////////// - - struct ITestExt3 - : public ICryUnknown - { - CRYINTERFACE_DECLARE(ITestExt3, 0xdd017935a2134898, 0xbd2fffa145551876) - - virtual void Call3() = 0; - }; - - DECLARE_SMART_POINTERS(ITestExt3); - - class CTestExt3 - : public ITestExt3 - { - CRYGENERATE_CLASS(CTestExt3, "TestExt3", 0xeceab40bc4bb4988, 0xa9f63c1db85a69b1) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt3) - CRYINTERFACE_END() - - public: - virtual void Call3(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt3) - - CTestExt3::CTestExt3() - { - i = 3; - } - - CTestExt3::~CTestExt3() - { - printf("Inside CTestExt3 dtor\n"); - } - - void CTestExt3::Call3() - { - printf("Inside CTestExt3::Call3()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CComposed2 - : public ICryUnknown - { - CRYGENERATE_CLASS(CComposed2, "Composed2", 0x0439d74b8dcd4b7e, 0x9287dcdf7e26a3a6) - - CRYCOMPOSITE_BEGIN() - CRYCOMPOSITE_ADD(m_pTestExt3, "Ext3") - CRYCOMPOSITE_END(CComposed2) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_END() - - private: - ITestExt3Ptr m_pTestExt3; - }; - - CRYREGISTER_CLASS(CComposed2) - - CComposed2::CComposed2() - : m_pTestExt3() - { - CryCreateClassInstance("TestExt3", m_pTestExt3); - } - - CComposed2::~CComposed2() - { - } - - ////////////////////////////////////////////////////////////////////////// - - class CTestExt4 - : public ITestExt1 - , public ITestExt2 - , public ITestExt3 - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ITestExt1) - CRYINTERFACE_ADD(ITestExt2) - CRYINTERFACE_ADD(ITestExt3) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CTestExt4, "TestExt4", 0x43204e7cc1be45ca, 0x9df4ccb1c0dc1ad8) - - public: - virtual void Call1() const; - virtual void Call2(); - virtual void Call3(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CTestExt4) - - CTestExt4::CTestExt4() - { - i = 4; - } - - CTestExt4::~CTestExt4() - { - printf("Inside CTestExt4 dtor\n"); - } - - void CTestExt4::Call1() const - { - printf("Inside CTestExt4::Call1()\n"); - } - - void CTestExt4::Call2() - { - printf("Inside CTestExt4::Call2()\n"); - } - - void CTestExt4::Call3() - { - printf("Inside CTestExt4::Call3()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CMegaComposed - : public CComposed - , public CComposed2 - { - CRYGENERATE_CLASS(CMegaComposed, "MegaComposed", 0x512787559f84503, 0x421ac1af66f2fb6f) - - CRYCOMPOSITE_BEGIN() - CRYCOMPOSITE_ADD(m_pTestExt4, "Ext4") - CRYCOMPOSITE_ENDWITHBASE2(CMegaComposed, CComposed, CComposed2) - - CRYINTERFACE_BEGIN() - CRYINTERFACE_END() - - private: - AZStd::shared_ptr m_pTestExt4; - }; - - CRYREGISTER_CLASS(CMegaComposed) - - CMegaComposed::CMegaComposed() - : m_pTestExt4() - { - printf("Inside CMegaComposed ctor\n"); - m_pTestExt4 = CTestExt4::CreateClassInstance(); - } - - CMegaComposed::~CMegaComposed() - { - printf("Inside CMegaComposed dtor\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - static void TestComposition() - { - printf("\nTest composition:\n"); - - ICryUnknownPtr p; - if (CryCreateClassInstance("MegaComposed", p)) - { - ITestExt1Ptr p1 = cryinterface_cast(crycomposite_query(p, "Ext1")); - if (p1) - { - p1->Call1(); // calls CTestExt1::Call1() - } - ITestExt2Ptr p2 = cryinterface_cast(crycomposite_query(p, "Ext2")); - if (p2) - { - p2->Call2(); // calls CTestExt2::Call2() - } - ITestExt3Ptr p3 = cryinterface_cast(crycomposite_query(p, "Ext3")); - if (p3) - { - p3->Call3(); // calls CTestExt3::Call3() - } - p3 = cryinterface_cast(crycomposite_query(p, "Ext4")); - if (p3) - { - p3->Call3(); // calls CTestExt4::Call3() - } - p1 = cryinterface_cast(crycomposite_query(p.get(), "Ext4")); - p2 = cryinterface_cast(crycomposite_query(p.get(), "Ext4")); - - bool b = CryIsSameClassInstance(p1, p2); // true - } - - { - ICryUnknownConstPtr pCUnk = p; - ICryUnknownConstPtr pComp1 = crycomposite_query(pCUnk.get(), "Ext1"); - //ICryUnknownPtr pComp1 = crycomposite_query(pCUnk, "Ext1"); // must fail to compile due to const rules - - ITestExt1ConstPtr p1 = cryinterface_cast(pComp1); - if (p1) - { - p1->Call1(); - } - } - } -} // namespace TestComposition - - -////////////////////////////////////////////////////////////////////////// - - -namespace TestExtension -{ - class CFoobar - : public IFoobar - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IFoobar) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CFoobar, "Foobar", 0x76c8dd6d16634531, 0x95d3b1cfabcf7ef4) - - public: - virtual void Foo(); - }; - - CRYREGISTER_CLASS(CFoobar) - - CFoobar::CFoobar() - { - } - - CFoobar::~CFoobar() - { - } - - void CFoobar::Foo() - { - printf("Inside CFoobar::Foo()\n"); - } - - static void TestFoobar() - { - AZStd::shared_ptr p = CFoobar::CreateClassInstance(); - { - CryInterfaceID iid = cryiidof(); - CryClassID clsid = p->GetFactory()->GetClassID(); - int t = 0; - } - - { - IAPtr sp_ = cryinterface_cast(p); // sp_ == NULL - - ICryUnknownPtr sp1 = cryinterface_cast(p); - IFoobarPtr sp = cryinterface_cast(sp1); - sp->Foo(); - } - - { - CFoobar* pF = p.get(); - pF->Foo(); - ICryUnknown* p1 = cryinterface_cast(pF); - } - - IFoobar* pFoo = cryinterface_cast(p.get()); - ICryFactory* pF1 = pFoo->GetFactory(); - pFoo->Foo(); - - int t = 0; - } - - ////////////////////////////////////////////////////////////////////////// - - class CRaboof - : public IRaboof - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IRaboof) - CRYINTERFACE_END() - - CRYGENERATE_SINGLETONCLASS(CRaboof, "Raabof", 0xba482ce12b2e4309, 0x8238ed8b52cb1f1e) - - public: - virtual void Rab(); - }; - - CRYREGISTER_SINGLETON_CLASS(CRaboof) - - CRaboof::CRaboof() - { - } - - CRaboof::~CRaboof() - { - } - - void CRaboof::Rab() - { - printf("Inside CRaboof::Rab()\n"); - } - - static void TestRaboof() - { - AZStd::shared_ptr pFoo0_ = CRaboof::CreateClassInstance(); - IRaboofPtr pFoo0 = cryinterface_cast(pFoo0_); - ICryUnknownPtr p0 = cryinterface_cast(pFoo0); - - CryInterfaceID iid = cryiidof(); - CryClassID clsid = p0->GetFactory()->GetClassID(); - - AZStd::shared_ptr pFoo1 = CRaboof::CreateClassInstance(); - - pFoo0->Rab(); - pFoo1->Rab(); - } - - ////////////////////////////////////////////////////////////////////////// - - class CAB - : public IA - , public IB - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IA) - CRYINTERFACE_ADD(IB) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CAB, "AB", 0xb9e54711a64448c0, 0xa4819b4ed3024d04) - - public: - virtual void A(); - virtual void B(); - - private: - int i; - }; - - CRYREGISTER_CLASS(CAB) - - CAB::CAB() - { - i = 0x12345678; - } - - CAB::~CAB() - { - } - - void CAB::A() - { - printf("Inside CAB::A()\n"); - } - - void CAB::B() - { - printf("Inside CAB::B()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CABC - : public CAB - , public IC - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IC) - CRYINTERFACE_ENDWITHBASE(CAB) - - CRYGENERATE_CLASS(CABC, "ABC", 0x4e61feae11854be7, 0xa16157c5f8baadd9) - - public: - virtual void C(); - - private: - int a; - }; - - CRYREGISTER_CLASS(CABC) - - CABC::CABC() - //: CAB() - { - a = 0x87654321; - } - - CABC::~CABC() - { - } - - void CABC::C() - { - printf("Inside CABC::C()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CCustomC - : public ICustomC - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IC) - CRYINTERFACE_ADD(ICustomC) - CRYINTERFACE_END() - - CRYGENERATE_CLASS(CCustomC, "CustomC", 0xee61760b98a44b71, 0xa05e7372b44bd0fd) - - public: - virtual void C(); - virtual void C1(); - - private: - int a; - }; - - CRYREGISTER_CLASS(CCustomC) - - CCustomC::CCustomC() - { - a = 0x87654321; - } - - CCustomC::~CCustomC() - { - } - - void CCustomC::C() - { - printf("Inside CCustomC::C()\n"); - } - - void CCustomC::C1() - { - printf("Inside CCustomC::C1()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - class CMultiBase - : public CAB - , public CCustomC - { - CRYINTERFACE_BEGIN() - CRYINTERFACE_ENDWITHBASE2(CAB, CCustomC) - - CRYGENERATE_CLASS(CMultiBase, "MultiBase", 0x75966b8f98644d42, 0x8fbdd489e94cc29e) - - public: - virtual void A(); - virtual void C1(); - - int i; - }; - - CRYREGISTER_CLASS(CMultiBase) - - CMultiBase::CMultiBase() - { - i = 0x87654321; - } - - CMultiBase::~CMultiBase() - { - } - - void CMultiBase::C1() - { - printf("Inside CMultiBase::C1()\n"); - } - - void CMultiBase::A() - { - printf("Inside CMultiBase::A()\n"); - } - - ////////////////////////////////////////////////////////////////////////// - - static void TestComplex() - { - { - ICPtr p; - if (CryCreateClassInstance(MAKE_CRYGUID(0x75966b8f98644d42, 0x8fbdd489e94cc29e), p)) - { - p->C(); - } - } - - { - ICustomCPtr p; - if (CryCreateClassInstance("MultiBase", p)) - { - p->C(); - } - } - - { - IFoobarPtr p; - if (CryCreateClassInstance(MAKE_CRYGUID(0x75966b8f98644d42, 0x8fbdd489e94cc29e), p)) - { - p->Foo(); - } - } - - { - AZStd::shared_ptr p = CMultiBase::CreateClassInstance(); - AZStd::shared_ptr pc = p; - - { - ICryUnknownPtr pUnk = cryinterface_cast(p); - ICryUnknownConstPtr pCUnk0 = cryinterface_cast(p); - ICryUnknownConstPtr pCUnk1 = cryinterface_cast(pc); - //ICryUnknownPtr pUnkF = cryinterface_cast(pc); // must fail to compile due to const rules - - ICryFactory* pF = pUnk->GetFactory(); - - int t = 0; - } - - ICPtr pC = cryinterface_cast(p); - ICustomCPtr pCC = cryinterface_cast(pC); - - p->C(); - p->C1(); - - pC->C(); - pCC->C1(); - - IAPtr pA = cryinterface_cast(p); - pA->A(); - p->A(); - } - - { - AZStd::shared_ptr p = CCustomC::CreateClassInstance(); - - ICPtr pC = cryinterface_cast(p); - ICustomCPtr pCC = cryinterface_cast(pC); - - p->C(); - p->C1(); - - pC->C(); - pCC->C1(); - } - { - CryInterfaceID ia = cryiidof(); - CryInterfaceID ib = cryiidof(); - CryInterfaceID ic = cryiidof(); - CryInterfaceID ico = cryiidof(); - } - - { - AZStd::shared_ptr p = CAB::CreateClassInstance(); - CryClassID clsid = p->GetFactory()->GetClassID(); - - IAPtr pA = cryinterface_cast(p); - IBPtr pB = cryinterface_cast(p); - - IBPtr pB1 = cryinterface_cast(pA); - IAPtr pA1 = cryinterface_cast(pB); - - pA->A(); - pB->B(); - - ICryUnknownPtr p1 = cryinterface_cast(pA); - ICryUnknownPtr p2 = cryinterface_cast(pB); - const ICryUnknown* p3 = cryinterface_cast(pB.get()); - - int t = 0; - } - - { - AZStd::shared_ptr pABC = CABC::CreateClassInstance(); - CryClassID clsid = pABC->GetFactory()->GetClassID(); - - ICryFactory* pFac = pABC->GetFactory(); - pFac->ClassSupports(cryiidof()); - pFac->ClassSupports(cryiidof()); - - IAPtr pABC0 = cryinterface_cast(pABC); - IBPtr pABC1 = cryinterface_cast(pABC0); - ICPtr pABC2 = cryinterface_cast(pABC1); - - pABC2->C(); - pABC1->B(); - - pABC2->GetFactory(); - - const IC* pCconst = pABC2.get(); - const ICryUnknown* pOconst = cryinterface_cast(pCconst); - const IA* pAconst = cryinterface_cast(pOconst); - const IB* pBconst = cryinterface_cast(pAconst); - - //const IA* pA11 = cryinterface_cast(pOconst); - - pCconst = cryinterface_cast(pBconst); - - IC* pC = static_cast(static_cast(pABC1.get())); - pC->C(); // calls IB::B() - - int t = 0; - } - } - - ////////////////////////////////////////////////////////////////////////// - // use of extension system without any of the helper macros/templates - - class CDontLikeMacrosFactory - : public ICryFactory - { - // ICryFactory - public: - virtual const char* GetClassName() const - { - return "DontLikeMacros"; - } - virtual const CryClassID& GetClassID() const - { - static const CryClassID cid = {0x73c3ab0042e6488aull, 0x89ca1a3763365565ull}; - return cid; - } - virtual bool ClassSupports(const CryInterfaceID& iid) const - { - return iid == cryiidof() || iid == cryiidof(); - } - virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const - { - static const CryInterfaceID iids[2] = {cryiidof(), cryiidof()}; - pIIDs = iids; - numIIDs = 2; - } - virtual ICryUnknownPtr CreateClassInstance() const; - - public: - static CDontLikeMacrosFactory& Access() - { - return s_factory; - } - - private: - CDontLikeMacrosFactory() {} - ~CDontLikeMacrosFactory() {} - - private: - static CDontLikeMacrosFactory s_factory; - }; - - CDontLikeMacrosFactory CDontLikeMacrosFactory::s_factory; - - class CDontLikeMacros - : public IDontLikeMacros - { - // ICryUnknown - public: - virtual ICryFactory* GetFactory() const - { - return &CDontLikeMacrosFactory::Access(); - }; - - // only needed to be able to create initial shared_ptr so we don't lose type info for debugging (i.e. inspecting shared_ptr<>) - template - friend void AZStd::Internal::sp_ms_deleter::destroy(); - template - friend AZStd::shared_ptr AZStd::make_shared(); - - protected: - virtual void* QueryInterface(const CryInterfaceID& iid) const - { - if (iid == cryiidof()) - { - return (void*) (ICryUnknown*) this; - } - else if (iid == cryiidof()) - { - return (void*) (IDontLikeMacros*) this; - } - else - { - return 0; - } - } - - virtual void* QueryComposite(const char*) const - { - return 0; - } - - // IDontLikeMacros - public: - virtual void CallMe() - { - printf("Yey, no macros...\n"); - } - - CDontLikeMacros() {} - - protected: - virtual ~CDontLikeMacros() {} - }; - - ICryUnknownPtr CDontLikeMacrosFactory::CreateClassInstance() const - { - AZStd::shared_ptr p = AZStd::make_shared(); - return ICryUnknownPtr(*static_cast*>(static_cast(&p))); - } - - static SRegFactoryNode g_dontLikeMacrosFactory(&CDontLikeMacrosFactory::Access()); - - ////////////////////////////////////////////////////////////////////////// - - static void TestDontLikeMacros() - { - ICryFactory* f = &CDontLikeMacrosFactory::Access(); - - f->ClassSupports(cryiidof()); - f->ClassSupports(cryiidof()); - - const CryInterfaceID* pIIDs = 0; - size_t numIIDs = 0; - f->ClassSupports(pIIDs, numIIDs); - - ICryUnknownPtr p = f->CreateClassInstance(); - IDontLikeMacrosPtr pp = cryinterface_cast(p); - - ICryUnknownPtr pq = crycomposite_query(p, "blah"); - - pp->CallMe(); - } -} // namespace TestExtension - - -////////////////////////////////////////////////////////////////////////// - - -void TestExtensions(ICryFactoryRegistryImpl* pReg) -{ - printf("Test extensions:\n"); - - struct MyCallback - : public ICryFactoryRegistryCallback - { - virtual void OnNotifyFactoryRegistered(ICryFactory* pFactory) - { - int test = 0; - } - virtual void OnNotifyFactoryUnregistered(ICryFactory* pFactory) - { - int test = 0; - } - }; - - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x4); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x1); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x3); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x3); - //pReg->RegisterCallback((ICryFactoryRegistryCallback*) 0x2); - - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x2); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x2); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x4); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x3); - //pReg->UnregisterCallback((ICryFactoryRegistryCallback*) 0x1); - - //MyCallback callback0; - //pReg->RegisterCallback(&callback0); - //pReg->RegisterFactories(g_pHeadToRegFactories); - - //pReg->RegisterFactories(g_pHeadToRegFactories); - //pReg->UnregisterFactories(g_pHeadToRegFactories); - - ICryFactory* pF[4]; - size_t numFactories = 4; - pReg->IterateFactories(cryiidof(), pF, numFactories); - pReg->IterateFactories(MAKE_CRYGUID(-1, -1), pF, numFactories); - - numFactories = (size_t) -1; - pReg->IterateFactories(cryiidof(), 0, numFactories); - - MyCallback callback1; - pReg->RegisterCallback(&callback1); - pReg->UnregisterCallback(&callback1); - - ICryFactory* p; - p = pReg->GetFactory(MAKE_CRYGUID(0xee61760b98a44b71, 0xa05e7372b44bd0fd)); - p = pReg->GetFactory("CustomC"); - p = pReg->GetFactory("ABC"); - p = pReg->GetFactory((const char*)0); - - p = pReg->GetFactory("DontLikeMacros"); - p = pReg->GetFactory(MAKE_CRYGUID(0x73c3ab0042e6488a, 0x89ca1a3763365565)); - - TestExtension::TestFoobar(); - TestExtension::TestRaboof(); - TestExtension::TestComplex(); - TestExtension::TestDontLikeMacros(); - - TestComposition::TestComposition(); -} - -#endif // #ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES diff --git a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.h b/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.h deleted file mode 100644 index ac9ad04dc7..0000000000 --- a/Code/CryEngine/CrySystem/ExtensionSystem/TestCases/TestExtensions.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Part of CryEngine's extension framework. - - -#ifndef CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_TESTCASES_TESTEXTENSIONS_H -#define CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_TESTCASES_TESTEXTENSIONS_H -#pragma once - - -//#define EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#include - -struct ICryFactoryRegistryImpl; - -void TestExtensions(ICryFactoryRegistryImpl* pReg); - -struct IFoobar - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IFoobar, 0x539e9c672cad4a03, 0x9ecd8069c99a846b) - - virtual void Foo() = 0; -}; - -DECLARE_SMART_POINTERS(IFoobar); - -struct IRaboof - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IRaboof, 0x135ca25e634b4d13, 0x9e4467968a708822) - - virtual void Rab() = 0; -}; - -DECLARE_SMART_POINTERS(IRaboof); - -struct IA - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IA, 0xd93aaceb35ec427e, 0xb64bf8dec4997e67) - - virtual void A() = 0; -}; - -DECLARE_SMART_POINTERS(IA); - -struct IB - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IB, 0xe0d830c826424e11, 0x9eacfa19eaf31ffb) - - virtual void B() = 0; -}; - -DECLARE_SMART_POINTERS(IB); - -struct IC - : public ICryUnknown -{ - CRYINTERFACE_DECLARE(IC, 0x577509a20fc5477c, 0x893757c9ca88b27b) - - virtual void C() = 0; -}; - -DECLARE_SMART_POINTERS(IC); - -struct ICustomC - : public IC -{ - CRYINTERFACE_DECLARE(ICustomC, 0x2ac769da4c7443bf, 0x80911033e21dfbcf) - - virtual void C1() = 0; -}; - -DECLARE_SMART_POINTERS(ICustomC); - -////////////////////////////////////////////////////////////////////////// -// use of extension system without any of the helper macros/templates - -struct IDontLikeMacros - : public ICryUnknown -{ - template - friend const CryInterfaceID& InterfaceCastSemantics::cryiidof(); - template - friend void AZStd::Internal::sp_ms_deleter::destroy(); - template - friend AZStd::shared_ptr AZStd::make_shared(); -protected: - virtual ~IDontLikeMacros() {} - -private: - // It's very important that this static function is implemented for each interface! - // Otherwise the consistency of cryinterface_cast() is compromised because - // cryiidof() = cryiidof>() {baseof = ICryUnknown in most cases} - static const CryInterfaceID& IID() - { - static const CryInterfaceID iid = {0x0f43b7e3f1364af0ull, 0xb4a16a975bea3ec4ull}; - return iid; - } - -public: - virtual void CallMe() = 0; -}; - -DECLARE_SMART_POINTERS(IDontLikeMacros); - - -#endif // #ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - -#endif // CRYINCLUDE_CRYSYSTEM_EXTENSIONSYSTEM_TESTCASES_TESTEXTENSIONS_H diff --git a/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp b/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp deleted file mode 100644 index 22a9fa1793..0000000000 --- a/Code/CryEngine/CrySystem/GeneralMemoryHeap.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "GeneralMemoryHeap.h" - -#include -#include - -class GeneralMemoryHeapAllocator - : public AZ::SimpleSchemaAllocator -{ - using Base = AZ::SimpleSchemaAllocator; -public: - static const size_t DEFAULT_ALIGNMENT = sizeof(void*); - - GeneralMemoryHeapAllocator(const char* desc) - : Base("GeneralMemoryHeapAllocator", desc) - { - } - - void Reserve(size_t size) - { - // Allocate a block, then free it, forcing it into the page tree/cache - void* block = m_schema->Allocate(size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, "GeneralMemoryHeapAllocator Reserve", __FILE__, __LINE__); - m_schema->DeAllocate(block); - } -}; - -CGeneralMemoryHeap::CGeneralMemoryHeap([[maybe_unused]] UINT_PTR base, [[maybe_unused]] size_t upperLimit, size_t reserveSize, const char* sUsage) - : m_refCount(0) - , m_block(nullptr) - , m_blockSize(0) -{ - AZ::HphaSchema::Descriptor desc; - desc.m_subAllocator = &AZ::AllocatorInstance::Get(); - m_allocator.reset(new AZ::AllocatorWrapper); - m_allocator->Create(desc, sUsage); - if (reserveSize) - { - (*m_allocator)->Reserve(reserveSize); - } -} - -CGeneralMemoryHeap::CGeneralMemoryHeap(void* base, size_t size, const char* sUsage) - : m_refCount(0) - , m_block(base) - , m_blockSize(size) -{ - AZ::HphaSchema::Descriptor desc; - desc.m_fixedMemoryBlock = base; - desc.m_fixedMemoryBlockByteSize = size; - desc.m_fixedMemoryBlockAlignment = GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT; - m_allocator.reset(new AZ::AllocatorWrapper); - m_allocator->Create(desc, sUsage); -} - -CGeneralMemoryHeap::~CGeneralMemoryHeap() -{ -} - -bool CGeneralMemoryHeap::Cleanup() -{ - (*m_allocator)->GarbageCollect(); - return true; -} - -int CGeneralMemoryHeap::AddRef() -{ - return m_refCount.fetch_add(1); -} - -int CGeneralMemoryHeap::Release() -{ - int nRef = m_refCount.fetch_sub(1); - - if (nRef <= 1) - { - delete this; - } - - return nRef; -} - -void CGeneralMemoryHeap::RecordAlloc(void* ptr, size_t size) -{ - if (m_block == nullptr) - { - m_allocs.emplace(ptr, size); - } -} - -void CGeneralMemoryHeap::RecordFree(void* ptr, size_t size) -{ - if (m_block == nullptr) - { - m_allocs.erase(Alloc(ptr, size)); - } -} - -bool CGeneralMemoryHeap::IsInAddressRange(void* ptr) const -{ - if (m_block) - { - return (static_cast(ptr) - static_cast(m_block)) <= m_blockSize; - } - auto it = m_allocs.find(Alloc(ptr)); - return it != m_allocs.end(); -} - -void* CGeneralMemoryHeap::Calloc(size_t numElements, size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(numElements * size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, sUsage, __FILE__, __LINE__); - memset(ptr, 0, numElements * size); - RecordAlloc(ptr, numElements * size); - return ptr; -} - -void* CGeneralMemoryHeap::Malloc(size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT, 0, sUsage, __FILE__, __LINE__); - RecordAlloc(ptr, size); - return ptr; -} - -size_t CGeneralMemoryHeap::Free(void* ptr) -{ - // The client code using these heaps tend to use a guesswork algorithm to freeing - // which involves handing the pointer to every known heap until it frees, so - // it's necessary to validate that the ptr belongs to this heap before attempting to free - if (IsInAddressRange(ptr)) - { - size_t size = (*m_allocator)->AllocationSize(ptr); - RecordFree(ptr, size); - (*m_allocator)->DeAllocate(ptr); - return size; - } - return 0; -} - -void* CGeneralMemoryHeap::Realloc(void* ptr, size_t size, const char* /*sUsage*/) -{ - RecordFree(ptr, (*m_allocator)->AllocationSize(ptr)); - void* newPtr = (*m_allocator)->ReAllocate(ptr, size, GeneralMemoryHeapAllocator::DEFAULT_ALIGNMENT); - RecordAlloc(newPtr, size); - return newPtr; -} - -void* CGeneralMemoryHeap::ReallocAlign(void* ptr, size_t size, size_t alignment, const char* /*sUsage*/) -{ - RecordFree(ptr, (*m_allocator)->AllocationSize(ptr)); - void* newPtr = (*m_allocator)->ReAllocate(ptr, size, alignment); - RecordAlloc(newPtr, size); - return newPtr; -} - -void* CGeneralMemoryHeap::Memalign(size_t boundary, size_t size, const char* sUsage) -{ - void* ptr = (*m_allocator)->Allocate(size, boundary, 0, sUsage, __FILE__, __LINE__); - RecordAlloc(ptr, size); - return ptr; -} - -size_t CGeneralMemoryHeap::UsableSize(void* ptr) const -{ - // The client code using these heaps tend to use a guesswork algorithm to determine - // which heap owns the pointer. Calls to UsableSize() are a part of this guesswork. - // The overrun detector doesn't play nicely on AllocationSize() lookups for pointers that - // don't belong to the heap, so validate that we're in the correct address range before trying - // to look up the size. - return IsInAddressRange(ptr) ? (*m_allocator)->AllocationSize(ptr) : 0; -} - -AZ::IAllocator* CGeneralMemoryHeap::GetAllocator() const -{ - return m_allocator->Get(); -} diff --git a/Code/CryEngine/CrySystem/GeneralMemoryHeap.h b/Code/CryEngine/CrySystem/GeneralMemoryHeap.h deleted file mode 100644 index a09556055d..0000000000 --- a/Code/CryEngine/CrySystem/GeneralMemoryHeap.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H -#define CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H -#pragma once - - -#include "IMemory.h" -#include -#include -#include - -class GeneralMemoryHeapAllocator; - -class CGeneralMemoryHeap - : public IGeneralMemoryHeap -{ - struct Alloc - { - void* m_base; - size_t m_size; - - Alloc(void* base = nullptr, size_t size = 0) - : m_base(base) - , m_size(size) - {} - - bool operator==(const Alloc& rhs) const - { - // size doesn't matter - return m_base == rhs.m_base; - } - - bool operator<(const Alloc& rhs) const - { - // this will cause allocs to be sorted by address - return m_base < rhs.m_base; - } - }; - -public: - // Create a heap that will map/unmap pages in the range [baseAddress, baseAddress + upperLimit). - CGeneralMemoryHeap(UINT_PTR baseAddress, size_t upperLimit, size_t reserveSize, const char* sUsage); - - // Create a heap that will assumes all memory in the range [base, base + size) is already mapped. - CGeneralMemoryHeap(void* base, size_t size, const char* sUsage); - - ~CGeneralMemoryHeap(); - -public: // IGeneralMemoryHeap Members - bool Cleanup(); - - int AddRef(); - int Release(); - - bool IsInAddressRange(void* ptr) const; - - void* Calloc(size_t nmemb, size_t size, const char* sUsage = NULL); - void* Malloc(size_t sz, const char* sUsage = NULL); - size_t Free(void* ptr); - void* Realloc(void* ptr, size_t sz, const char* sUsage = NULL); - void* ReallocAlign(void* ptr, size_t size, size_t alignment, const char* sUsage = NULL); - void* Memalign(size_t boundary, size_t size, const char* sUsage = NULL); - size_t UsableSize(void* ptr) const; - - AZ::IAllocator* GetAllocator() const override; - -private: - CGeneralMemoryHeap(const CGeneralMemoryHeap&) = delete; - CGeneralMemoryHeap& operator = (const CGeneralMemoryHeap&) = delete; - - void RecordAlloc(void* ptr, size_t size); - void RecordFree(void* ptr, size_t size); - -private: - AZStd::unique_ptr> m_allocator; - AZStd::atomic_int m_refCount; - void* m_block; - size_t m_blockSize; - AZStd::set, AZ::AZStdAlloc> m_allocs; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_GENERALMEMORYHEAP_H diff --git a/Code/CryEngine/CrySystem/HMDCVars.cpp b/Code/CryEngine/CrySystem/HMDCVars.cpp deleted file mode 100644 index 4ef08db729..0000000000 --- a/Code/CryEngine/CrySystem/HMDCVars.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "HMDCVars.h" -#include -#include - -namespace AZ -{ -namespace VR -{ - -void HMDCVars::OnHMDRecenter([[maybe_unused]] IConsoleCmdArgs* args) -{ - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, RecenterPose); -} - -void HMDCVars::OnHMDTrackingLevelChange(IConsoleCmdArgs* args) -{ - if (args->GetArgCount() != 2) - { - // First arg should be the command itself, second arg should be the requested tracking level. - return; - } - - // Read the new tracking level. - int argVal = 0; - std::stringstream stream(args->GetArg(1)); - stream >> argVal; - - AZ::VR::HMDTrackingLevel level = static_cast(argVal); - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, SetTrackingLevel, level); -} - -void HMDCVars::OnOutputToHMDChanged(ICVar* var) -{ - // Set the necessary cvars for turning on/off output to an HMD. - ICVar* mode = gEnv->pConsole->GetCVar("r_StereoMode"); - ICVar* output = gEnv->pConsole->GetCVar("r_StereoOutput"); - ICVar* height = gEnv->pConsole->GetCVar("r_height"); - ICVar* width = gEnv->pConsole->GetCVar("r_width"); - - if (!mode || !output || !height || !width) - { - return; - } - - bool enable = (var->GetIVal() == 1); - if (enable) - { - // Auto-set the resolution. - { - const AZ::VR::HMDDeviceInfo* deviceInfo = nullptr; - EBUS_EVENT_RESULT(deviceInfo, AZ::VR::HMDDeviceRequestBus, GetDeviceInfo); - - // If the device info exists then there is a VR device connected and working. - if (deviceInfo) - { - mode->Set(EStereoMode::STEREO_MODE_DUAL_RENDERING); - output->Set(EStereoOutput::STEREO_OUTPUT_HMD); - - width->Set(static_cast(deviceInfo->renderWidth)); - height->Set(static_cast(deviceInfo->renderHeight)); - } - } - } - else - { - mode->Set(EStereoMode::STEREO_MODE_NO_STEREO); - output->Set(EStereoOutput::STEREO_OUTPUT_STANDARD); - } -} - -void HMDCVars::OnHMDDebugInfo(ICVar* var) -{ - bool enable = (var->GetIVal() == 1); - EBUS_EVENT(AZ::VR::HMDDebuggerRequestBus, EnableInfo, enable); -} - -void HMDCVars::OnHMDDebugCamera(ICVar* var) -{ - bool enable = (var->GetIVal() == 1); - EBUS_EVENT(AZ::VR::HMDDebuggerRequestBus, EnableCamera, enable); -} - -int HMDCVars::hmd_social_screen = static_cast(HMDSocialScreen::UndistortedLeftEye); -int HMDCVars::hmd_debug_info = 0; -int HMDCVars::hmd_debug_camera = 0; - -} // namespace VR -} // namespace AZ diff --git a/Code/CryEngine/CrySystem/HMDCVars.h b/Code/CryEngine/CrySystem/HMDCVars.h deleted file mode 100644 index f449bb0725..0000000000 --- a/Code/CryEngine/CrySystem/HMDCVars.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - - -#pragma once - -#include -#include - -namespace AZ -{ - namespace VR - { - class HMDCVars - { - public: - - static int hmd_social_screen; - static int hmd_debug_info; - static int hmd_debug_camera; - - static void Register() - { - REGISTER_CVAR2("hmd_social_screen", &hmd_social_screen, hmd_social_screen, - VF_NULL, "Selects the social screen mode: \n" - "-1- Off\n" - "0 - Undistorted left eye\n" - "1 - Undistorted right eye\n" - ); - - REGISTER_INT_CB("hmd_debug_info", 0, VF_ALWAYSONCHANGE, - "Enable/disable HMD and VR controller debug info/rendering", - OnHMDDebugInfo); - - REGISTER_INT_CB("hmd_debug_camera", 0, VF_ALWAYSONCHANGE, - "Enable/disable HMD debug camera", - OnHMDDebugCamera); - - REGISTER_COMMAND("hmd_tracking_level", &OnHMDTrackingLevelChange, - VF_NULL, "Set the HMD center reference point.\n" - "0 - Camera (Actor's head)\n" - "1 - Actor's feet (floor)\n"); - - REGISTER_COMMAND("hmd_recenter_pose", &OnHMDRecenter, - VF_NULL, "Re-centers sensor orientation of the HMD."); - - REGISTER_INT_CB("output_to_hmd", 0, VF_ALWAYSONCHANGE, - "Enable/disable output to any connected HMD (for VR)", - OnOutputToHMDChanged); - } - - private: - - static void OnHMDRecenter(IConsoleCmdArgs* args); - static void OnHMDTrackingLevelChange(IConsoleCmdArgs* args); - static void OnOutputToHMDChanged(ICVar* var); - static void OnHMDDebugInfo(ICVar* var); - static void OnHMDDebugCamera(ICVar* var); - }; - } // namespace VR -} // namespace AZ diff --git a/Code/CryEngine/CrySystem/HandlerBase.cpp b/Code/CryEngine/CrySystem/HandlerBase.cpp deleted file mode 100644 index 6e1b7fdc77..0000000000 --- a/Code/CryEngine/CrySystem/HandlerBase.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "HandlerBase.h" - -const char* SERVER_LOCK_NAME = "SynchronizeGameServer"; -const char* CLIENT_LOCK_NAME = "SynchronizeGameClient"; - -HandlerBase::HandlerBase(const char* bucket, int affinity) -{ - m_serverLockName.Format("%s_%s", SERVER_LOCK_NAME, bucket); - m_clientLockName.Format("%s_%s", CLIENT_LOCK_NAME, bucket); - if (affinity != 0) - { - m_affinity = uint32(1) << (affinity - 1); - } - else - { - m_affinity = -1; - } - m_prevAffinity = 0; -} - -HandlerBase::~HandlerBase() -{ - if (m_prevAffinity) - { - if (SyncSetAffinity(m_prevAffinity)) - { - CryLogAlways("Restored affinity to %d", m_prevAffinity); - } - else - { - CryLogAlways("Failed to restore affinity to %d", m_prevAffinity); - } - } -} - -void HandlerBase::SetAffinity() -{ - if (m_prevAffinity) //already set - { - return; - } - if (uint32 p = SyncSetAffinity(m_affinity)) - { - CryLogAlways("Changed affinity to %d", m_affinity); - m_prevAffinity = p; - } - else - { - CryLogAlways("Failed to change affinity to %d", m_affinity); - } -} - -#if defined(LINUX) - -uint32 HandlerBase::SyncSetAffinity(uint32 cpuMask)//put -1 -{ - if (cpuMask != 0) - { - cpu_set_t cpuSet; - uint32 affinity = 0; - if (!sched_getaffinity(getpid(), sizeof cpuSet, &cpuSet)) - { - for (int cpu = 0; cpu < sizeof(cpuMask) * 8; ++cpu) - { - if (CPU_ISSET(cpu, &cpuSet)) - { - affinity |= 1 << cpu; - } - } - } - if (affinity) - { - CPU_ZERO(&cpuSet); - for (int cpu = 0; cpu < sizeof(cpuMask) * 8; ++cpu) - { - if (cpuMask & (1 << cpu)) - { - CPU_SET(cpu, &cpuSet); - } - } - - if (!sched_setaffinity(getpid(), sizeof(cpuSet), &cpuSet)) - { - return affinity; - } - } - } - return 0; -} - -#elif AZ_LEGACY_CRYSYSTEM_TRAIT_USE_HANDLER_SYNC_AFFINITY - -uint32 HandlerBase::SyncSetAffinity(uint32 cpuMask)//put -1 -{ - uint32 p = (uint32)SetThreadAffinityMask(GetCurrentThread(), cpuMask); - if (p == 0) - { - CryLogAlways("Error updating affinity mask to %d", cpuMask); - } - return p; -} - -#else - -uint32 HandlerBase::SyncSetAffinity(uint32 cpuMask)//put -1 -{ - CryLogAlways("Updating thread affinity not supported on this platform"); - return 0; -} - -#endif - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/HandlerBase.h b/Code/CryEngine/CrySystem/HandlerBase.h deleted file mode 100644 index 67e7a828a6..0000000000 --- a/Code/CryEngine/CrySystem/HandlerBase.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_HANDLERBASE_H -#define CRYINCLUDE_CRYSYSTEM_HANDLERBASE_H - -#pragma once - -const int MAX_CLIENTS_NUM = 100; - -struct HandlerBase -{ - HandlerBase(const char* bucket, int affinity); - ~HandlerBase(); - - void SetAffinity(); - uint32 SyncSetAffinity(uint32 cpuMask); - - string m_serverLockName; - string m_clientLockName; - uint32 m_affinity; - uint32 m_prevAffinity; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_HANDLERBASE_H diff --git a/Code/CryEngine/CrySystem/IDebugCallStack.cpp b/Code/CryEngine/CrySystem/IDebugCallStack.cpp index d73d70ab8b..c14dd2b0da 100644 --- a/Code/CryEngine/CrySystem/IDebugCallStack.cpp +++ b/Code/CryEngine/CrySystem/IDebugCallStack.cpp @@ -16,7 +16,6 @@ #include "CrySystem_precompiled.h" #include "IDebugCallStack.h" -#include #include "System.h" #include #include @@ -238,8 +237,6 @@ void IDebugCallStack::FatalError(const char* description) void IDebugCallStack::WriteLineToLog(const char* format, ...) { - CDebugAllowFileAccess allowFileAccess; - va_list ArgList; char szBuffer[MAX_WARNING_LENGTH]; va_start(ArgList, format); @@ -258,28 +255,6 @@ void IDebugCallStack::WriteLineToLog(const char* format, ...) } } -void IDebugCallStack::Screenshot(const char* szFileName) -{ - WriteLineToLog("Attempting to create error screenshot \"%s\"", szFileName); - - static int g_numScreenshots = 0; - if (gEnv->pRenderer && !g_numScreenshots++) - { - if (gEnv->pRenderer->ScreenShot(szFileName)) - { - WriteLineToLog("Successfully created screenshot."); - } - else - { - WriteLineToLog("Error creating screenshot."); - } - } - else - { - WriteLineToLog("Ignoring multiple calls to Screenshot"); - } -} - ////////////////////////////////////////////////////////////////////////// void IDebugCallStack::StartMemLog() { diff --git a/Code/CryEngine/CrySystem/IDebugCallStack.h b/Code/CryEngine/CrySystem/IDebugCallStack.h index 7b54c0cac0..f181b73913 100644 --- a/Code/CryEngine/CrySystem/IDebugCallStack.h +++ b/Code/CryEngine/CrySystem/IDebugCallStack.h @@ -77,8 +77,6 @@ protected: static const char* TranslateExceptionCode(DWORD dwExcept); static void PutVersion(char* str, size_t length); - static void Screenshot(const char* szFileName); - bool m_bIsFatalError; static const char* const s_szFatalErrorCode; diff --git a/Code/CryEngine/CrySystem/IOSConsole.h b/Code/CryEngine/CrySystem/IOSConsole.h deleted file mode 100644 index 8bd2a8779e..0000000000 --- a/Code/CryEngine/CrySystem/IOSConsole.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for iOS, reports back to the main interface - -#pragma once - -#include -#include - -class CIOSConsole - : public ISystemUserCallback - , public IOutputPrintSink - , public ITextModeConsole -{ - CIOSConsole(const CIOSConsole&); - CIOSConsole& operator = (const CIOSConsole&); - - bool m_isInitialized; -public: - static CryCriticalSectionNonRecursive s_lock; -public: - CIOSConsole(); - ~CIOSConsole(); - - // Interface IOutputPrintSink ///////////////////////////////////////////// - DLL_EXPORT virtual void Print(const char* line); - - // Interface ISystemUserCallback ////////////////////////////////////////// - virtual bool OnError(const char* errorString); - virtual bool OnSaveDocument() { return false; } - virtual void OnProcessSwitch() { } - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem*); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - void SetRequireDedicatedServer(bool) {} - void SetHeader(const char*) {} - // Interface ITextModeConsole ///////////////////////////////////////////// - virtual Vec2_tpl BeginDraw(); - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw(); -}; diff --git a/Code/CryEngine/CrySystem/IOSConsole.mm b/Code/CryEngine/CrySystem/IOSConsole.mm deleted file mode 100644 index 6058ea8a44..0000000000 --- a/Code/CryEngine/CrySystem/IOSConsole.mm +++ /dev/null @@ -1,94 +0,0 @@ -/* -* 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. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#if defined(IOS) -#include "IOSConsole.h" - - - -CIOSConsole::CIOSConsole(): -m_isInitialized(false) -{ - -} - -CIOSConsole::~CIOSConsole() -{ - -} - -// Interface IOutputPrintSink ///////////////////////////////////////////// -void CIOSConsole::Print(const char *line) -{ - printf("MSG: %s\n", line); -} -// Interface ISystemUserCallback ////////////////////////////////////////// -bool CIOSConsole::OnError(const char *errorString) -{ - printf("ERR: %s\n", errorString); - return true; -} - -void CIOSConsole::OnInitProgress(const char *sProgressMsg) -{ - (void) sProgressMsg; - // Do Nothing -} -void CIOSConsole::OnInit(ISystem *pSystem) -{ - if (!m_isInitialized) - { - IConsole* pConsole = pSystem->GetIConsole(); - if (pConsole != 0) - { - pConsole->AddOutputPrintSink(this); - } - m_isInitialized = true; - } -} -void CIOSConsole::OnShutdown() -{ - if (m_isInitialized) - { - // remove outputprintsink - m_isInitialized = false; - } -} -void CIOSConsole::OnUpdate() -{ - // Do Nothing -} -void CIOSConsole::GetMemoryUsage(ICrySizer *pSizer) -{ - size_t size = sizeof(*this); - - - - pSizer->AddObject(this, size); -} - -// Interface ITextModeConsole ///////////////////////////////////////////// -Vec2_tpl CIOSConsole::BeginDraw() -{ - return Vec2_tpl(0,0); -} -void CIOSConsole::PutText( int x, int y, const char * msg ) -{ - printf("PUT: %s\n", msg); -} -void CIOSConsole::EndDraw() { - // Do Nothing -} -#endif // IOS diff --git a/Code/CryEngine/CrySystem/IThreadConfigManager.h b/Code/CryEngine/CrySystem/IThreadConfigManager.h deleted file mode 100644 index 97c4d7237b..0000000000 --- a/Code/CryEngine/CrySystem/IThreadConfigManager.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -struct SThreadConfig -{ - enum eThreadParamFlag - { - eThreadParamFlag_ThreadName = BIT(0), - eThreadParamFlag_StackSize = BIT(1), - eThreadParamFlag_Affinity = BIT(2), - eThreadParamFlag_Priority = BIT(3), - eThreadParamFlag_PriorityBoost = BIT(4), - }; - - typedef uint32 TThreadParamFlag; - - const char* szThreadName; - uint32 stackSizeBytes; - uint32 affinityFlag; - int32 priority; - bool bDisablePriorityBoost; - - TThreadParamFlag paramActivityFlag; -}; - -class IThreadConfigManager -{ -public: - virtual ~IThreadConfigManager() - { - } - - //! Called once during System startup. - //! Loads the thread configuration for the executing platform from file. - virtual bool LoadConfig(const char* pcPath) = 0; - - //! Returns true if a config has been loaded. - virtual bool ConfigLoaded() const = 0; - - //! Gets the thread configuration for the specified thread on the active platform. - //! If no matching config is found a default configuration is returned (which does not have the same name as the search string). - virtual const SThreadConfig* GetThreadConfig(const char* sThreadName, ...) = 0; - virtual const SThreadConfig* GetDefaultThreadConfig() const = 0; - - //! Dump a detailed description of the thread startup configurations for this platform to the log file. - virtual void DumpThreadConfigurationsToLog() = 0; -}; diff --git a/Code/CryEngine/CrySystem/ImageHandler.cpp b/Code/CryEngine/CrySystem/ImageHandler.cpp deleted file mode 100644 index 7444aebdc0..0000000000 --- a/Code/CryEngine/CrySystem/ImageHandler.cpp +++ /dev/null @@ -1,280 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include "ImageHandler.h" -#include -#include "ScopeGuard.h" -#include "Algorithm.h" -#include "System.h" - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ImageHandler_cpp) -#endif - -#if !(defined(ANDROID) || defined(IOS) || defined(LINUX)) && AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO // Rally US1050 - Compile libtiff for Android and IOS - #include - -static_assert(sizeof(thandle_t) >= sizeof(AZ::IO::HandleType), "Platform defines thandle_t to be smaller than required"); -#endif - -namespace -{ - class Image - : public IImageHandler::IImage - { - public: - Image(std::vector&& data, int width, int height) - { - CRY_ASSERT(data.size() == width * height * ImageHandler::c_BytesPerPixel); - m_data = std::move(data); - m_width = width; - m_height = height; - } - private: - virtual const std::vector& GetData() const override { return m_data; } - virtual int GetWidth() const override { return m_width; } - virtual int GetHeight() const override { return m_height; } - - unsigned int m_width; - unsigned int m_height; - std::vector m_data; - }; -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - struct TiffIO - { - static tsize_t Read(thandle_t handle, tdata_t buffer, tsize_t size) - { - AZ::u64 bytesRead = 0; - AZ::IO::FileIOBase::GetDirectInstance()->Read(static_cast(reinterpret_cast(handle)), buffer, size, false, &bytesRead); - return static_cast(bytesRead); - }; - - static tsize_t Write(thandle_t handle, tdata_t buffer, tsize_t size) - { - AZ::u64 sizeWritten; - if (AZ::IO::FileIOBase::GetDirectInstance()->Write(static_cast(reinterpret_cast(handle)), buffer, size, &sizeWritten)) - { - return static_cast(sizeWritten); - } - else - { - return 0; - } - }; - - static int Close(thandle_t handle) - { - AZ::IO::FileIOBase::GetDirectInstance()->Close(static_cast(reinterpret_cast(handle))); - return 0; - }; - - static toff_t Seek(thandle_t handle, toff_t pos, int mode) - { - if (AZ::IO::FileIOBase::GetDirectInstance()->Seek(static_cast(reinterpret_cast(handle)), static_cast(pos), AZ::IO::GetSeekTypeFromFSeekMode(mode))) - { - if (mode == SEEK_SET) - { - return pos; - } - else - { - AZ::u64 offsetFromBegin; - if (AZ::IO::FileIOBase::GetDirectInstance()->Tell(static_cast(reinterpret_cast(handle)), offsetFromBegin)) - { - return static_cast(offsetFromBegin); - } - else - { - return -1; - } - } - } - return -1; - }; - - static toff_t Size(thandle_t handle) - { - AZ::u64 fileSize = 0; - AZ::IO::FileIOBase::GetDirectInstance()->Size(static_cast(reinterpret_cast(handle)), fileSize); - return static_cast(fileSize); - }; - - static int Map(thandle_t, tdata_t*, toff_t*) - { - return 0; - }; - - static void Unmap(thandle_t, tdata_t, toff_t) - { - return; - }; - }; -#endif -} - -std::unique_ptr ImageHandler::CreateImage(std::vector&& data, int width, int height) const -{ - return std::make_unique(std::move(data), width, height); -} - -std::unique_ptr ImageHandler::LoadImage([[maybe_unused]] const char* filename) const -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - - AZ::IO::HandleType fileHandle; - AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode("rb"), fileHandle); - - if (fileHandle == AZ::IO::InvalidHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to open image file %s", filename); - return nullptr; - } - - auto tifHandle = std17::unique_resource_checked(TIFFClientOpen(filename, "rb", reinterpret_cast(static_cast(fileHandle)), TiffIO::Read, TiffIO::Write, TiffIO::Seek, TiffIO::Close, &TiffIO::Size, TiffIO::Map, TiffIO::Unmap), (TIFF*)nullptr, TIFFClose); - if (!tifHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load image %s", filename); - return nullptr; - } - - int width = 0; - int height = 0; - TIFFGetField(tifHandle, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tifHandle, TIFFTAG_IMAGELENGTH, &height); - std::vector data(4 * width * height); - if (!TIFFReadRGBAImageOriented(tifHandle, width, height, reinterpret_cast(data.data()), ORIENTATION_TOPLEFT)) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load image %s", filename); - return nullptr; - } - - //strip alpha - int every4th = 0; - data.erase(std::remove_if(begin(data), end(data), [&](unsigned char) - { - return (every4th++ & 3) == 3; - }), end(data)); - - return std::make_unique(std::move(data), width, height); -#else - CRY_ASSERT(0); // UNIMPLEMENTED - return nullptr; -#endif -} - -bool ImageHandler::SaveImage([[maybe_unused]] IImageHandler::IImage* image, [[maybe_unused]] const char* filename) const -{ -#if AZ_LEGACY_CRYSYSTEM_TRAIT_IMAGEHANDLER_TIFFIO - - AZ::IO::HandleType fileHandle; - AZ::IO::FileIOBase::GetDirectInstance()->Open(filename, AZ::IO::GetOpenModeFromStringMode("wb"), fileHandle); - - if (fileHandle == AZ::IO::InvalidHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to open image file for write %s", filename); - return false; - } - - auto tifHandle = std17::unique_resource_checked(TIFFClientOpen(filename, "wb", reinterpret_cast(static_cast(fileHandle)), TiffIO::Read, TiffIO::Write, TiffIO::Seek, TiffIO::Close, &TiffIO::Size, TiffIO::Map, TiffIO::Unmap), (TIFF*)nullptr, TIFFClose); - if (!tifHandle) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to save image %s", filename); - return false; - } - - TIFFSetField(tifHandle, TIFFTAG_IMAGEWIDTH, image->GetWidth()); - TIFFSetField(tifHandle, TIFFTAG_IMAGELENGTH, image->GetHeight()); - TIFFSetField(tifHandle, TIFFTAG_SAMPLESPERPIXEL, c_BytesPerPixel); - TIFFSetField(tifHandle, TIFFTAG_BITSPERSAMPLE, 8); - TIFFSetField(tifHandle, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(tifHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(tifHandle, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - TIFFSetField(tifHandle, TIFFTAG_COMPRESSION, COMPRESSION_LZW); - - tsize_t bytesPerLine = c_BytesPerPixel * image->GetWidth(); - std::vector lineBuffer; - if (TIFFScanlineSize(tifHandle) != bytesPerLine) - { - lineBuffer.resize(bytesPerLine); - } - else - { - lineBuffer.resize(TIFFScanlineSize(tifHandle)); - } - TIFFSetField(tifHandle, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tifHandle, image->GetWidth() * c_BytesPerPixel)); - auto srcData = image->GetData().data(); - - for (uint32 row = 0; row < image->GetHeight(); row++) - { - memcpy(lineBuffer.data(), &srcData[row * bytesPerLine], bytesPerLine); - if (TIFFWriteScanline(tifHandle, lineBuffer.data(), row, 0) < 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Failed to write part of image %s", filename); - return false; - } - } - - return true; -#else - CRY_ASSERT(0); // UNIMPLEMENTED - return false; -#endif -} - -std::unique_ptr ImageHandler::CreateDiffImage(IImageHandler::IImage* image1, IImageHandler::IImage* image2) const -{ - if (!image1 || !image2) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, null arguments"); - return nullptr; - } - if (image1->GetWidth() != image2->GetWidth() || image1->GetHeight() != image2->GetHeight()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, 2 images were not the same size"); - return nullptr; - } - CRY_ASSERT(image1->GetData().size() == image1->GetWidth() * image1->GetHeight() * ImageHandler::c_BytesPerPixel); - CRY_ASSERT(image2->GetData().size() == image2->GetWidth() * image2->GetHeight() * ImageHandler::c_BytesPerPixel); - - std::vector resultRGBData; - - auto iter1 = image1->GetData().data(); - auto iter2 = image2->GetData().data(); - for (int i = 0; i < image1->GetWidth() * image1->GetHeight() * c_BytesPerPixel; ++i) - { - resultRGBData.push_back(static_cast(abs(static_cast(iter1[i]) - static_cast(iter2[i])))); - } - - return std::make_unique(std::move(resultRGBData), image1->GetWidth(), image1->GetHeight()); -} - -float ImageHandler::CalculatePSNR(IImageHandler::IImage* diffIimage) const -{ - if (!diffIimage) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not create diff image, null arguments"); - return 0; - } - CRY_ASSERT(diffIimage->GetData().size() == diffIimage->GetWidth() * diffIimage->GetHeight() * ImageHandler::c_BytesPerPixel); - - auto mse = std17::accumulate(diffIimage->GetData(), 0.0, [](double result, unsigned char value) -> double { return result += (double)value * (double)value; }); - mse /= (c_BytesPerPixel * diffIimage->GetWidth() * diffIimage->GetHeight()); - - if (mse <= 0) - { - return std::numeric_limits::max(); - } - - // see http://en.wikipedia.org/wiki/Peak_signal-to-noise_ratio for a derivation of this formula and source for magic numbers - return static_cast(20 * log10(255) - 10 * log10(mse)); -} diff --git a/Code/CryEngine/CrySystem/ImageHandler.h b/Code/CryEngine/CrySystem/ImageHandler.h deleted file mode 100644 index bba596a266..0000000000 --- a/Code/CryEngine/CrySystem/ImageHandler.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* 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. -* -*/ -#pragma once -#ifndef CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H -#define CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H - -#include "IImageHandler.h" - -class ImageHandler - : public IImageHandler -{ -public: - static const int c_BytesPerPixel = 3; //This only deals with RGB data for now, no alpha -private: - virtual std::unique_ptr CreateImage(std::vector&& rgbData, int width, int height) const override; - virtual std::unique_ptr LoadImage(const char* filename) const override; - virtual bool SaveImage(IImageHandler::IImage* image, const char* filename) const override; - virtual std::unique_ptr CreateDiffImage(IImageHandler::IImage* image1, IImageHandler::IImage* image2) const override; - virtual float CalculatePSNR(IImageHandler::IImage* diffIimage) const override; -}; -#endif // CRYINCLUDE_CRYSYSTEM_IMAGEHANDLER_H diff --git a/Code/CryEngine/CrySystem/LZ4Decompressor.cpp b/Code/CryEngine/CrySystem/LZ4Decompressor.cpp deleted file mode 100644 index a4b8a2b8e6..0000000000 --- a/Code/CryEngine/CrySystem/LZ4Decompressor.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : lz4 hc decompress wrapper - - -#include "CrySystem_precompiled.h" -#include -#include "LZ4Decompressor.h" - -bool CLZ4Decompressor::DecompressData(const char* pIn, char* pOut, const uint outputSize) const -{ - return LZ4_decompress_fast(pIn, pOut, outputSize) >= 0; -} - -void CLZ4Decompressor::Release() -{ - delete this; -} diff --git a/Code/CryEngine/CrySystem/LZ4Decompressor.h b/Code/CryEngine/CrySystem/LZ4Decompressor.h deleted file mode 100644 index 20652a8e78..0000000000 --- a/Code/CryEngine/CrySystem/LZ4Decompressor.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : lz4 hc decompress wrapper - - -#ifndef CRYINCLUDE_CRYSYSTEM_LZ4DECOMPRESSOR_H -#define CRYINCLUDE_CRYSYSTEM_LZ4DECOMPRESSOR_H -#pragma once - - -#include "ILZ4Decompressor.h" - -class CLZ4Decompressor - : public ILZ4Decompressor -{ -public: - virtual bool DecompressData(const char* pIn, char* pOut, const uint outputSize) const; - virtual void Release(); - -private: - virtual ~CLZ4Decompressor() {} -}; - -#endif // CRYINCLUDE_CRYSYSTEM_LZ4DECOMPRESSOR_H diff --git a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp index d31f122d9b..c36b9bcee7 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/LevelSystem.cpp @@ -17,12 +17,8 @@ #include "LevelSystem.h" #include #include "IMovieSystem.h" -#include "IMaterialEffects.h" -#include #include -#include "IDeferredCollisionEvent.h" #include "CryPath.h" -#include #include @@ -108,10 +104,11 @@ bool CLevelInfo::ReadInfo() AzFramework::ApplicationRequests::Bus::BroadcastResult( usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); + // Set up a default game type for legacy code. + m_defaultGameTypeName = "Mission0"; + if (usePrefabSystemForLevels) { - // Set up a default game type for legacy code. - m_defaultGameTypeName = "Mission0"; return true; } @@ -262,16 +259,6 @@ void CLevelSystem::Rescan(const char* levelsFolder) { if (levelsFolder) { - if (const ICmdLineArg* pModArg = m_pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "MOD")) - { - if (m_pSystem->IsMODValid(pModArg->GetValue())) - { - m_levelsFolder.format("Mods/%s/%s", pModArg->GetValue(), levelsFolder); - m_levelInfos.clear(); - ScanFolder(0, true); - } - } - m_levelsFolder = levelsFolder; } @@ -648,20 +635,6 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName) AZStd::string levelPath(pLevelInfo->GetPath()); - /* - ICVar *pFileCache = gEnv->pConsole->GetCVar("sys_FileCache"); CRY_ASSERT(pFileCache); - - if(pFileCache->GetIVal()) - { - if(pPak->OpenPack("",pLevelInfo->GetPath()+string("/FileCache.dat"))) - gEnv->pLog->Log("FileCache.dat loaded"); - else - gEnv->pLog->Log("FileCache.dat not loaded"); - } - */ - - m_pSystem->SetThreadState(ESubsys_Physics, false); - ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay"); float spamDelay = 0.0f; if (pSpamDelay) @@ -768,8 +741,6 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName) gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0); - m_pSystem->SetThreadState(ESubsys_Physics, true); - return m_pCurrentLevel; } @@ -795,9 +766,6 @@ void CLevelSystem::PrepareNextLevel(const char* levelName) // switched to level heap, so now imm start the loading screen (renderer will be reinitialized in the levelheap) gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START_LOADINGSCREEN, 0, 0); gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_PREPARE); - - // Inform resource manager about loading of the new level. - GetISystem()->GetIResourceManager()->PrepareLevel(pLevelInfo->GetPath(), pLevelInfo->GetName()); } for (AZStd::vector::const_iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) @@ -845,11 +813,6 @@ void CLevelSystem::OnLoadingError(const char* levelName, const char* error) return; } - if (gEnv->pRenderer) - { - gEnv->pRenderer->SetTexturePrecaching(false); - } - for (AZStd::vector::const_iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) { (*it)->OnLoadingError(levelName, error); @@ -967,33 +930,6 @@ void CLevelSystem::UnloadLevel() CTimeValue tBegin = gEnv->pTimer->GetAsyncTime(); - //AM: Flush render thread (Flush is not exposed - using EndFrame()) - //We are about to delete resources that could be in use - if (gEnv->pRenderer) - { - gEnv->pRenderer->EndFrame(); - - - bool isLoadScreenPlaying = false; -#if AZ_LOADSCREENCOMPONENT_ENABLED - LoadScreenBus::BroadcastResult(isLoadScreenPlaying, &LoadScreenBus::Events::IsPlaying); -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - - // force a black screen as last render command. - //if load screen is playing do not call this draw as it may lead to a crash due to UI loading code getting - //pumped while loading the shaders for this draw. - if (!isLoadScreenPlaying) - { - gEnv->pRenderer->BeginFrame(); - gEnv->pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST); - gEnv->pRenderer->Draw2dImage(0, 0, 800, 600, -1, 0.0f, 0.0f, 1.0f, 1.0f, 0.f, 0.0f, 0.0f, 0.0f, 1.0, 0.f); - gEnv->pRenderer->EndFrame(); - } - - //flush any outstanding texture requests - gEnv->pRenderer->FlushPendingTextureTasks(); - } - // Clear level entities and prefab instances. EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext); @@ -1036,35 +972,12 @@ void CLevelSystem::UnloadLevel() m_lastLevelName.clear(); - GetISystem()->GetIResourceManager()->UnloadLevel(); - SAFE_RELEASE(m_pCurrentLevel); // Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed). // Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event). EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect); - // Force to clean render resources left after deleting all objects and materials. - IRenderer* pRenderer = gEnv->pRenderer; - if (pRenderer) - { - pRenderer->FlushRTCommands(true, true, true); - - CryComment("Deleting Render meshes, render resources and flush texture streaming"); - // This may also release some of the materials. - int flags = FRR_DELETED_MESHES | FRR_FLUSH_TEXTURESTREAMING | FRR_OBJECTS | FRR_RENDERELEMENTS | FRR_RP_BUFFERS | FRR_POST_EFFECTS; - - // Always keep the system resources around in the editor. - // If a level load fails for any reason, then do not unload the system resources, otherwise we will not have any system resources to continue rendering the console and debug output text. - if (!gEnv->IsEditor() && !GetLevelLoadFailed()) - { - flags |= FRR_SYSTEM_RESOURCES; - } - - pRenderer->FreeResources(flags); - CryComment("done"); - } - // Perform level unload procedures for the LyShine UI system if (gEnv && gEnv->pLyShine) { diff --git a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp index 4b6e210522..31d1540d77 100644 --- a/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp +++ b/Code/CryEngine/CrySystem/LevelSystem/SpawnableLevelSystem.cpp @@ -14,8 +14,6 @@ #include "SpawnableLevelSystem.h" #include #include "IMovieSystem.h" -#include -#include "IDeferredCollisionEvent.h" #include @@ -38,8 +36,8 @@ namespace LegacyLevelSystem //------------------------------------------------------------------------ static void LoadLevel(const AZ::ConsoleCommandContainer& arguments) { - AZ_Error("SpawnableLevelSystem", arguments.empty(), "LoadLevel requires a level file name to be provided."); - AZ_Error("SpawnableLevelSystem", arguments.size() > 1, "LoadLevel requires a single level file name to be provided."); + AZ_Error("SpawnableLevelSystem", !arguments.empty(), "LoadLevel requires a level file name to be provided."); + AZ_Error("SpawnableLevelSystem", arguments.size() == 1, "LoadLevel requires a single level file name to be provided."); if (!arguments.empty() && gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor()) { @@ -248,8 +246,6 @@ namespace LegacyLevelSystem auto pPak = gEnv->pCryPak; - m_pSystem->SetThreadState(ESubsys_Physics, false); - ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay"); float spamDelay = 0.0f; if (pSpamDelay) @@ -344,8 +340,6 @@ namespace LegacyLevelSystem gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0); - m_pSystem->SetThreadState(ESubsys_Physics, true); - return true; } @@ -423,11 +417,6 @@ namespace LegacyLevelSystem { AZ_Error("LevelSystem", false, "Error loading level '%s': %s\n", levelName, error); - if (gEnv->pRenderer) - { - gEnv->pRenderer->SetTexturePrecaching(false); - } - for (auto& listener : m_listeners) { listener->OnLoadingError(levelName, error); @@ -541,32 +530,6 @@ namespace LegacyLevelSystem CTimeValue tBegin = gEnv->pTimer->GetAsyncTime(); - // AM: Flush render thread (Flush is not exposed - using EndFrame()) - // We are about to delete resources that could be in use - if (gEnv->pRenderer) - { - gEnv->pRenderer->EndFrame(); - - bool isLoadScreenPlaying = false; - #if AZ_LOADSCREENCOMPONENT_ENABLED - LoadScreenBus::BroadcastResult(isLoadScreenPlaying, &LoadScreenBus::Events::IsPlaying); - #endif // if AZ_LOADSCREENCOMPONENT_ENABLED - - // force a black screen as last render command. - // if load screen is playing do not call this draw as it may lead to a crash due to UI loading code getting - // pumped while loading the shaders for this draw. - if (!isLoadScreenPlaying) - { - gEnv->pRenderer->BeginFrame(); - gEnv->pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST); - gEnv->pRenderer->Draw2dImage(0, 0, 800, 600, -1, 0.0f, 0.0f, 1.0f, 1.0f, 0.f, 0.0f, 0.0f, 0.0f, 1.0, 0.f); - gEnv->pRenderer->EndFrame(); - } - - // flush any outstanding texture requests - gEnv->pRenderer->FlushPendingTextureTasks(); - } - // Clear level entities and prefab instances. EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext); @@ -602,34 +565,10 @@ namespace LegacyLevelSystem m_lastLevelName.clear(); - GetISystem()->GetIResourceManager()->UnloadLevel(); - // Force Lua garbage collection (may no longer be needed now the legacy renderer has been removed). // Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event). EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect); - // Force to clean render resources left after deleting all objects and materials. - IRenderer* pRenderer = gEnv->pRenderer; - if (pRenderer) - { - pRenderer->FlushRTCommands(true, true, true); - - CryComment("Deleting Render meshes, render resources and flush texture streaming"); - // This may also release some of the materials. - int flags = FRR_DELETED_MESHES | FRR_FLUSH_TEXTURESTREAMING | FRR_OBJECTS | FRR_RENDERELEMENTS | FRR_RP_BUFFERS | FRR_POST_EFFECTS; - - // Always keep the system resources around in the editor. - // If a level load fails for any reason, then do not unload the system resources, otherwise we will not have any system resources to - // continue rendering the console and debug output text. - if (!gEnv->IsEditor() && !GetLevelLoadFailed()) - { - flags |= FRR_SYSTEM_RESOURCES; - } - - pRenderer->FreeResources(flags); - CryComment("done"); - } - // Perform level unload procedures for the LyShine UI system if (gEnv && gEnv->pLyShine) { diff --git a/Code/CryEngine/CrySystem/LocalizedStringManager.cpp b/Code/CryEngine/CrySystem/LocalizedStringManager.cpp index a11e068a9b..572ef9a957 100644 --- a/Code/CryEngine/CrySystem/LocalizedStringManager.cpp +++ b/Code/CryEngine/CrySystem/LocalizedStringManager.cpp @@ -28,13 +28,8 @@ #include #include -#include "CryZlib.h" - #include #include -#if !defined(_RELEASE) -#include "CrySizerImpl.h" -#endif //#if !defined(_RELEASE) #define MAX_CELL_COUNT 32 @@ -165,52 +160,6 @@ static void TestFormatMessage ([[maybe_unused]] IConsoleCmdArgs* pArgs) } #endif //#if !defined(_RELEASE) - -////////////////////////////////////////////////////////////////////////// -#if !defined(_RELEASE) -void CLocalizedStringsManager::LocalizationDumpLoadedInfo([[maybe_unused]] IConsoleCmdArgs* pArgs) -{ - CLocalizedStringsManager* pLoca = (CLocalizedStringsManager*) gEnv->pSystem->GetLocalizationManager(); - - for (TTagFileNames::iterator tagit = pLoca->m_tagFileNames.begin(); tagit != pLoca->m_tagFileNames.end(); ++tagit) - { - CryLogAlways("Tag %s (%d)", tagit->first.c_str(), tagit->second.id); - - int entries = 0; - CrySizerImpl* pSizer = new CrySizerImpl(); - - for (tmapFilenames::iterator it = pLoca->m_loadedTables.begin(); it != pLoca->m_loadedTables.end(); it++) - { - if (tagit->second.id == it->second.nTagID) - { - CryLogAlways("\t%s", it->first.c_str()); - } - - if (pLoca->m_pLanguage) - { - const uint32 numEntries = pLoca->m_pLanguage->m_vLocalizedStrings.size(); - for (int32 i = numEntries - 1; i >= 0; i--) - { - SLocalizedStringEntry* entry = pLoca->m_pLanguage->m_vLocalizedStrings[i]; - if (tagit->second.id == entry->nTagID) - { - entries++; - entry->GetMemoryUsage((ICrySizer*) pSizer); - } - } - } - } - - // This line messes up Uncrustify so turn it off: *INDENT-OFF* - CryLogAlways("\t\tEntries %d, Approx Size %" PRISIZE_T "Kb", entries, pSizer->GetTotalSize() / 1024); - // turn it back on again: *INDENT-ON* - - SAFE_RELEASE(pSizer); - } -} - -#endif //#if !defined(_RELEASE) - ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -249,9 +198,6 @@ CLocalizedStringsManager::CLocalizedStringsManager(ISystem* pSystem) "0: No encoding, store as wide strings\n" "1: Huffman encode translated text, saves approx 30% with a small runtime performance cost\n" "Default is 1."); - - - REGISTER_COMMAND("LocalizationDumpLoadedInfo", LocalizationDumpLoadedInfo, VF_NULL, "Dump out into about the loaded localization files"); #endif //#if !defined(_RELEASE) REGISTER_CVAR2(c_sys_localization_format, &m_cvarLocalizationFormat, 1, VF_NULL, diff --git a/Code/CryEngine/CrySystem/LocalizedStringManager.h b/Code/CryEngine/CrySystem/LocalizedStringManager.h index 6b7ef6060b..1f18ba5c4a 100644 --- a/Code/CryEngine/CrySystem/LocalizedStringManager.h +++ b/Code/CryEngine/CrySystem/LocalizedStringManager.h @@ -96,10 +96,6 @@ public: void GetLoadedTags(TLocalizationTagVec& tagVec); void FreeLocalizationData(); -#if !defined(_RELEASE) - static void LocalizationDumpLoadedInfo(IConsoleCmdArgs* pArgs); -#endif //#if !defined(_RELEASE) - private: void SetAvailableLocalizationsBitfield(const ILocalizationManager::TLocalizationBitfield availableLocalizations); diff --git a/Code/CryEngine/CrySystem/Log.cpp b/Code/CryEngine/CrySystem/Log.cpp index cdf145e4be..b8241ee865 100644 --- a/Code/CryEngine/CrySystem/Log.cpp +++ b/Code/CryEngine/CrySystem/Log.cpp @@ -20,10 +20,8 @@ //this should not be included here #include #include -#include #include "System.h" #include "CryPath.h" // PathUtil::ReplaceExtension() -#include #include "UnicodeFunctions.h" #include @@ -51,7 +49,7 @@ #define LOG_BACKUP_PATH "@log@/LogBackups" #if defined(IOS) -#include "SystemUtilsApple.h" +#include #endif ////////////////////////////////////////////////////////////////////// @@ -238,7 +236,6 @@ void CLog::CloseLogFile([[maybe_unused]] bool forceClose) ////////////////////////////////////////////////////////////////////////// AZ::IO::HandleType CLog::OpenLogFile(const char* filename, const char* mode) { - CDebugAllowFileAccess ignoreInvalidFileAccess; using namespace AZ::IO; AZ_Assert(m_logFileHandle == AZ::IO::InvalidHandle, "Attempt to open log file when one is already open. This would lead to a handle leak."); @@ -418,7 +415,7 @@ void CLog::LogV(const ELogType type, const char* szFormat, va_list args) LogV(type, 0, szFormat, args); } -void CLog::LogV(const ELogType type, int flags, const char* szFormat, va_list args) +void CLog::LogV(const ELogType type, [[maybe_unused]]int flags, const char* szFormat, va_list args) { // this is here in case someone called LogV directly, with an invalid formatter. if (!CheckLogFormatter(szFormat)) @@ -596,28 +593,6 @@ void CLog::LogV(const ELogType type, int flags, const char* szFormat, va_list ar GetISystem()->GetIRemoteConsole()->AddLogError(szString); break; } - - ////////////////////////////////////////////////////////////////////////// - if (type == eWarningAlways || type == eWarning || type == eError || type == eErrorAlways) - { - IValidator* pValidator = m_pSystem->GetIValidator(); - if (pValidator && (flags & VALIDATOR_FLAG_SKIP_VALIDATOR) == 0) - { - CryAutoCriticalSection scope_lock(m_logCriticalSection); - - SValidatorRecord record; - record.text = szBuffer; - record.module = VALIDATOR_MODULE_SYSTEM; - record.severity = VALIDATOR_WARNING; - record.assetScope = GetAssetScopeString(); - record.flags = flags; - if (type == eError || type == eErrorAlways) - { - record.severity = VALIDATOR_ERROR; - } - pValidator->Report(record); - } - } } //will log the text both to the end of file and console @@ -920,13 +895,7 @@ bool CLog::LogToMainThread(const char* szString, ELogType logType, bool bAdd, SL msg.bAdd = bAdd; msg.destination = destination; msg.logType = logType; - // don't try to store the log message for later in case of out of memory, since then its very likely that this allocation - // also fails and results in a stack overflow. This way we should at least get a out of memory on-screen message instead of - // a not obvious crash - if ((gEnv) && (gEnv->bIsOutOfMemory == false)) - { - m_threadSafeMsgQueue.push(msg); - } + m_threadSafeMsgQueue.push(msg); return true; } return false; @@ -1145,8 +1114,6 @@ void CLog::LogStringToFile(const char* szString, ELogType logType, bool bAdd, [[ if (logToFile) { - CDebugAllowFileAccess dafa; - if (m_logFileHandle == AZ::IO::InvalidHandle) { OpenLogFile(m_szFilename, "w+t"); @@ -1445,24 +1412,6 @@ void CLog::UpdateLoadingScreen(const char* szFormat, ...) va_end(args); } #endif - - if (CryGetCurrentThreadId() == m_nMainThreadId) - { - ((CSystem*)m_pSystem)->UpdateLoadingScreen(); - -#ifndef LINUX - // Take this opportunity to update streaming engine. - if (IStreamEngine* pStreamEngine = GetISystem()->GetStreamEngine()) - { - const float curTime = m_pSystem->GetITimer()->GetAsyncCurTime(); - if (curTime - m_fLastLoadingUpdateTime > .1f) // not frequent than once in 100ms - { - m_fLastLoadingUpdateTime = curTime; - pStreamEngine->Update(); - } - } -#endif - } } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/MTSafeAllocator.cpp b/Code/CryEngine/CrySystem/MTSafeAllocator.cpp deleted file mode 100644 index 7d9c08d3c4..0000000000 --- a/Code/CryEngine/CrySystem/MTSafeAllocator.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "MTSafeAllocator.h" -#include - -extern CMTSafeHeap* g_pPakHeap; - -// Uncomment this define to enable time tracing of the MTSAFE heap -#define MTSAFE_PROFILE 1 -//#undef MTSAFE_PROFILE - -namespace -{ - class CSimpleTimer - { - LARGE_INTEGER& m_result; - LARGE_INTEGER m_start; - public: - - CSimpleTimer(LARGE_INTEGER& li) - : m_result(li) - { QueryPerformanceCounter(&m_start); } - - ~CSimpleTimer() - { - LARGE_INTEGER end; - QueryPerformanceCounter(&end); - m_result.QuadPart = end.QuadPart - m_start.QuadPart; - } - }; -}; - -////////////////////////////////////////////////////////////////////////// -CMTSafeHeap::CMTSafeHeap() - : m_LiveTempAllocations() - , m_TotalAllocations() - , m_TempAllocationsFailed() - , m_TempAllocationsTime() -{ - size_t allocated = 0; - m_pGeneralHeapStorage = (char*)CryMalloc(MTSAFE_GENERAL_HEAP_SIZE, allocated, MTSAFE_DEFAULT_ALIGNMENT); - m_pGeneralHeapStorageEnd = m_pGeneralHeapStorage + MTSAFE_GENERAL_HEAP_SIZE; - m_pGeneralHeap = CryGetIMemoryManager()->CreateGeneralMemoryHeap(m_pGeneralHeapStorage, MTSAFE_GENERAL_HEAP_SIZE, "MTSafeHeap"); -} - -////////////////////////////////////////////////////////////////////////// -CMTSafeHeap::~CMTSafeHeap() -{ - SAFE_RELEASE(m_pGeneralHeap); - CryFree(m_pGeneralHeapStorage, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -size_t CMTSafeHeap::PersistentAllocSize(size_t nSize) -{ - return nSize; -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::PersistentAlloc(size_t nSize) -{ - size_t allocated = 0; - return CryMalloc(nSize, allocated, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::FreePersistent(void* p) -{ - CryFree(p, MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::TempAlloc(size_t nSize, const char* szDbgSource, bool& bFallBackToMalloc, uint32 align) -{ -# if MTSAFE_PROFILE - CSimpleTimer timer(m_TempAllocationsTime); -# endif - - void* ptr = NULL; - if (align) - { - ptr = m_pGeneralHeap->Memalign(align, nSize, szDbgSource); - } - else - { - ptr = m_pGeneralHeap->Malloc(nSize, szDbgSource); - } - - //explicit alignment not supported beyond this point, safer to return NULL - if (ptr || !bFallBackToMalloc) - { - bFallBackToMalloc = false; - return ptr; - } - - bFallBackToMalloc = true; - -# if MTSAFE_PROFILE - CryInterlockedAdd((volatile int*)&m_TempAllocationsFailed, (int)nSize); -# endif - - return CryModuleMemalign(nSize, align > 0 ? align : MTSAFE_DEFAULT_ALIGNMENT); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::FreeTemporary(void* p) -{ -# if MTSAFE_PROFILE - CSimpleTimer timer(m_TempAllocationsTime); -# endif - - if (m_pGeneralHeap->IsInAddressRange(p)) - { - m_pGeneralHeap->Free(p); - return; - } - - // Fallback to free - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -void* CMTSafeHeap::StaticAlloc([[maybe_unused]] void* pOpaque, unsigned nItems, unsigned nSize) -{ - return g_pPakHeap->TempAlloc(nItems * nSize, "StaticAlloc"); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::StaticFree ([[maybe_unused]] void* pOpaque, void* pAddress) -{ - g_pPakHeap->FreeTemporary(pAddress); -} - -////////////////////////////////////////////////////////////////////////// -void CMTSafeHeap::GetMemoryUsage(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "FileSystem Pool"); -} - -void CMTSafeHeap::PrintStats() -{ -# if MTSAFE_PROFILE - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - const double rFreq = 1. / static_cast(freq.QuadPart); - - CryLogAlways("mtsafe temporary pool failed for %" PRISIZE_T " bytes, time spent in allocations %3.08f seconds", - m_TempAllocationsFailed, static_cast(m_TempAllocationsTime.QuadPart) * rFreq); -# endif -} - diff --git a/Code/CryEngine/CrySystem/MTSafeAllocator.h b/Code/CryEngine/CrySystem/MTSafeAllocator.h deleted file mode 100644 index eeee5ff501..0000000000 --- a/Code/CryEngine/CrySystem/MTSafeAllocator.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - - -#if defined(LINUX) -# include "Linux_Win32Wrapper.h" -#endif -#include - -//////////////////////////////////////////////////////////////////////////////// -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(MTSafeAllocator_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(MOBILE) // IOS/Android -# define MTSAFE_DEFAULT_ALIGNMENT 8 -# define MTSAFE_GENERAL_HEAP_SIZE ((1U << 20) + (1U << 19)) -#elif defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(MAC) -# define MTSAFE_GENERAL_HEAP_SIZE (12U << 20) -# define MTSAFE_DEFAULT_ALIGNMENT 8 -#else -# error Unknown target platform -#endif - -class CMTSafeHeap -{ -public: - // Constructor - CMTSafeHeap(); - - // Destructor - ~CMTSafeHeap(); - - // Performs a persisistent (in other words, non-temporary) allocation. - void* PersistentAlloc(size_t nSize); - - // Retrieves system memory allocation size for any call to PersistentAlloc. - // Required to not count virtual memory usage inside CrySizer - size_t PersistentAllocSize(size_t nSize); - - // Frees memory allocation - void FreePersistent(void* p); - - // Perform a allocation that is considered temporary and will be handled by - // the pool itself. - // Note: It is important that these temporary allocations are actually - // temporary and do not persist for a long persiod of time. - void* TempAlloc (size_t nSize, const char* szDbgSource, uint32 align = 0) - { - bool bFallbackToMalloc = true; - return TempAlloc(nSize, szDbgSource, bFallbackToMalloc, align); - } - - void* TempAlloc (size_t nSize, const char* szDbgSource, bool& bFallBackToMalloc, uint32 align = 0); - - bool IsInGeneralHeap(const void* p) - { - return m_pGeneralHeapStorage <= p && p < m_pGeneralHeapStorageEnd; - } - - // Free a temporary allocaton. - void FreeTemporary(void* p); - - // The number of live allocations allocation within the temporary pool - size_t NumAllocations() const { return m_LiveTempAllocations; } - - // The memory usage of the mtsafe allocator - void GetMemoryUsage(ICrySizer* pSizer); - - // zlib-compatible stubs - static void* StaticAlloc (void* pOpaque, unsigned nItems, unsigned nSize); - static void StaticFree (void* pOpaque, void* pAddress); - - // Dump some statistics to the cry log - void PrintStats(); - - -private: - friend class CSystem; - - IGeneralMemoryHeap* m_pGeneralHeap; - char* m_pGeneralHeapStorage; - char* m_pGeneralHeapStorageEnd; - - // The number of temporary allocations currently active within the pool - size_t m_LiveTempAllocations; - - // The total number of allocations performed in the pool - size_t m_TotalAllocations; - - // The total bytes that weren't temporarily allocated - size_t m_TempAllocationsFailed; - // The total number of temporary allocations that fell back to global system memory - LARGE_INTEGER m_TempAllocationsTime; -}; diff --git a/Code/CryEngine/CrySystem/MemoryAddressRange.cpp b/Code/CryEngine/CrySystem/MemoryAddressRange.cpp deleted file mode 100644 index bb547d80cc..0000000000 --- a/Code/CryEngine/CrySystem/MemoryAddressRange.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "MemoryAddressRange.h" -#include "System.h" - -#if defined(APPLE) || defined(LINUX) -#include -#endif - -CMemoryAddressRange::CMemoryAddressRange(char* pBaseAddress, size_t nPageSize, size_t nPageCount, [[maybe_unused]] const char* sName) - : m_pBaseAddress(pBaseAddress) - , m_nPageSize(nPageSize) - , m_nPageCount(nPageCount) -{ -} - -void CMemoryAddressRange::Release() -{ - delete this; -} - -char* CMemoryAddressRange::GetBaseAddress() const -{ - return m_pBaseAddress; -} - -size_t CMemoryAddressRange::GetPageCount() const -{ - return m_nPageCount; -} - -size_t CMemoryAddressRange::GetPageSize() const -{ - return m_nPageSize; -} - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_MEMADDRESSRANGE_WINDOWS_STYLE - -void* CMemoryAddressRange::ReserveSpace(size_t capacity) -{ - return VirtualAlloc(NULL, capacity, MEM_RESERVE, PAGE_READWRITE); -} - -size_t CMemoryAddressRange::GetSystemPageSize() -{ - SYSTEM_INFO si; - GetSystemInfo(&si); - return si.dwPageSize; -} - -CMemoryAddressRange::CMemoryAddressRange(size_t capacity, [[maybe_unused]] const char* name) -{ - m_nPageSize = GetSystemPageSize(); - - size_t algnCap = Align(capacity, m_nPageSize); - m_pBaseAddress = (char*)ReserveSpace(algnCap); - m_nPageCount = algnCap / m_nPageSize; -} - -CMemoryAddressRange::~CMemoryAddressRange() -{ - VirtualFree(m_pBaseAddress, 0, MEM_RELEASE); -} - -void* CMemoryAddressRange::MapPage(size_t pageIdx) -{ - void* pRet = VirtualAlloc(m_pBaseAddress + pageIdx * m_nPageSize, m_nPageSize, MEM_COMMIT, PAGE_READWRITE); - return pRet; -} - -void CMemoryAddressRange::UnmapPage(size_t pageIdx) -{ - char* pBase = m_pBaseAddress + pageIdx * m_nPageSize; - - // Disable warning about only decommitting pages, and not releasing them - VirtualFree(pBase, m_nPageSize, MEM_DECOMMIT); -} - -#elif defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(MemoryAddressRange_cpp) -#elif defined(APPLE) || defined(LINUX) - -void* CMemoryAddressRange::ReserveSpace(size_t capacity) -{ - return mmap(0, capacity, PROT_NONE, MAP_ANON | MAP_NORESERVE | MAP_PRIVATE, -1, 0); -} - -size_t CMemoryAddressRange::GetSystemPageSize() -{ - return sysconf(_SC_PAGESIZE); -} - -CMemoryAddressRange::CMemoryAddressRange(size_t capacity, const char* name) -{ - m_nPageSize = GetSystemPageSize(); - - m_allocatedSpace = Align(capacity, m_nPageSize); - m_pBaseAddress = (char*)ReserveSpace(m_allocatedSpace); - assert(m_pBaseAddress != MAP_FAILED); - m_nPageCount = m_allocatedSpace / m_nPageSize; -} - -CMemoryAddressRange::~CMemoryAddressRange() -{ - int ret = munmap(m_pBaseAddress, m_allocatedSpace); - (void) ret; - assert(ret == 0); -} - -void* CMemoryAddressRange::MapPage(size_t pageIdx) -{ - // There is no equivalent to this function with mmap, this - // happens automatically in the OS. We just return the - // correct address. - void* pRet = NULL; - if (0 == mprotect(m_pBaseAddress + (pageIdx * m_nPageSize), m_nPageSize, PROT_READ | PROT_WRITE)) - { - pRet = m_pBaseAddress + (pageIdx * m_nPageSize); - } - - return pRet; -} - -void CMemoryAddressRange::UnmapPage(size_t pageIdx) -{ - char* pBase = m_pBaseAddress + pageIdx * m_nPageSize; - int ret = mprotect(pBase, m_nPageSize, PROT_NONE); - (void) ret; - assert(ret == 0); -} - - -#endif diff --git a/Code/CryEngine/CrySystem/MemoryAddressRange.h b/Code/CryEngine/CrySystem/MemoryAddressRange.h deleted file mode 100644 index b2679f6667..0000000000 --- a/Code/CryEngine/CrySystem/MemoryAddressRange.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H -#define CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H -#pragma once - - -#include "IMemory.h" - -class CMemoryAddressRange - : public IMemoryAddressRange -{ -public: - static void* ReserveSpace(size_t sz); - static size_t GetSystemPageSize(); - -public: - CMemoryAddressRange(char* pBaseAddress, size_t nPageSize, size_t nPageCount, const char* sName); - CMemoryAddressRange(size_t capacity, const char* name); - ~CMemoryAddressRange(); - - ILINE bool IsInRange(void* p) const - { - return m_pBaseAddress <= p && p < (m_pBaseAddress + m_nPageSize * m_nPageCount); - } - -public: - void Release(); - - char* GetBaseAddress() const; - size_t GetPageCount() const; - size_t GetPageSize() const; - - void* MapPage(size_t pageIdx); - void UnmapPage(size_t pageIdx); - -private: - CMemoryAddressRange(const CMemoryAddressRange&); - CMemoryAddressRange& operator = (const CMemoryAddressRange&); - -private: - char* m_pBaseAddress; - size_t m_nPageSize; - size_t m_nPageCount; -#if defined(APPLE) || defined(LINUX) - size_t m_allocatedSpace; // Required to unmap latter on -#endif -}; - -#endif // CRYINCLUDE_CRYSYSTEM_MEMORYADDRESSRANGE_H diff --git a/Code/CryEngine/CrySystem/MemoryFragmentationProfiler.h b/Code/CryEngine/CrySystem/MemoryFragmentationProfiler.h deleted file mode 100644 index 7d373bb472..0000000000 --- a/Code/CryEngine/CrySystem/MemoryFragmentationProfiler.h +++ /dev/null @@ -1,325 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_MEMORYFRAGMENTATIONPROFILER_H -#define CRYINCLUDE_CRYSYSTEM_MEMORYFRAGMENTATIONPROFILER_H -#pragma once - - -// useful class to investigate memory fragmentation -// every time you call this from the console: -// -// #System.DumpMemoryCoverage() -// -// it adds a line to "MemoryCoverage.bmp" (generated the first time, there is a max line count) -// blue stripes mark some special positions (DLL positions) - -// Dependencies: only CryLog() - - -#include // STL vector<> - - -#if defined(WIN32) || defined(WIN64) - -class CMemoryFragmentationProfiler -{ -public: - - // constructor - clean file - CMemoryFragmentationProfiler() - : m_dwLine(0xffffffff) // 0xffffffff means not initialized yet - { - } - - // call this if you want to add one line (on first call the file is generated) - void DumpMemoryCoverage() - { - if (m_dwLine == 0xffffffff) - { - Init(); - } - - const size_t nMinMemoryPerUnit = 4 * 1024; // down to a few KB - const size_t nUnitsPerLine = 1024 * 8; // amount of bits, should only occupy a few KB memory - - const size_t nMaxMemoryPerUnit = 0x100000000 / nUnitsPerLine; // 4GB in total - - static std::vector vCoverage; - - vCoverage.clear(); - vCoverage.resize(nUnitsPerLine, 0); // should occupy nUnitsPerLine/8 bytes (vector is specialized) - - size_t nAvailableMem = 0, nUsedMem = 0; - - const size_t nMallocOverhead = 24; // depends on used runtime (debug:32, release:24) - - size_t nCurrentUnitSize = 256 * 1024 * 1024; // start with 256 MB blocks - - void** pMemoryBlocks = 0; // linked list of memory blocks (to free them) - - size_t nUnits = 0; - uint32 dwAllocCnt = 0, dwFreeCnt = 0; - - while (nCurrentUnitSize >= nMinMemoryPerUnit) - { - size_t nLocalUnits = 0; - - for (;; ) - { - void** pMem = (void**)::malloc(nCurrentUnitSize - nMallocOverhead); - - if (!pMem) - { - break; - } - - ++dwAllocCnt; - - // update coverage (conservative) - { - size_t nStartUnit = ((size_t)pMem + nMaxMemoryPerUnit - 1) / (nMaxMemoryPerUnit); - size_t nEndUnit = ((size_t)pMem + nCurrentUnitSize) / (nMaxMemoryPerUnit); - - if (nStartUnit > nUnitsPerLine) - { - nStartUnit = nUnitsPerLine; - } - - if (nEndUnit > nUnitsPerLine) - { - nEndUnit = nUnitsPerLine; - } - - for (size_t i = nStartUnit; i < nEndUnit; ++i) - { - vCoverage[i] = 1; - } - } - - ++nLocalUnits; - - // insert in linked list - *pMem = pMemoryBlocks; - pMemoryBlocks = pMem; - } - - nUnits += nLocalUnits; - nAvailableMem += nLocalUnits * nCurrentUnitSize; - - nCurrentUnitSize /= 2; - nUnits *= 2; - } - - // free all memory blocks allocated - while (pMemoryBlocks) - { - void* pNext = *pMemoryBlocks; - - ::free(pMemoryBlocks); - ++dwFreeCnt; - - pMemoryBlocks = (void**)pNext; - } - - - // _heapmin(); - - CryLog("CMemoryFragmentationProfiler Y=%d, available memory=%d MB, used memory=%d MB", - m_dwLine, (nAvailableMem + 1024 * 1024 - 1) / (1024 * 1024), (nUsedMem + 1024 * 1024 - 1) / (1024 * 1024)); - - LogCoverage(vCoverage); - - DumpToRAWCoverage(vCoverage); - } - -private: // ------------------------------------------------------------------ - - void Init() - { - FILE* out = nullptr; - azfopen(&out, "MemoryCoverage.bmp", "wb"); - - if (out) - { - BITMAPFILEHEADER pHeader; - BITMAPINFOHEADER pInfoHeader; - - memset(&pHeader, 0, sizeof(BITMAPFILEHEADER)); - memset(&pInfoHeader, 0, sizeof(BITMAPINFOHEADER)); - - pHeader.bfType = 0x4D42; - pHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_nPixelsPerLine * m_nLineCount * 3; - pHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); - - pInfoHeader.biSize = sizeof(BITMAPINFOHEADER); - pInfoHeader.biWidth = m_nPixelsPerLine; - pInfoHeader.biHeight = m_nLineCount; - pInfoHeader.biPlanes = 1; - pInfoHeader.biBitCount = 24; - pInfoHeader.biCompression = 0; - pInfoHeader.biSizeImage = m_nPixelsPerLine * m_nLineCount; - - fwrite(&pHeader, 1, sizeof(BITMAPFILEHEADER), out); - fwrite(&pInfoHeader, 1, sizeof(BITMAPINFOHEADER), out); - - for (int y = 0; y < m_nLineCount; y++) // amount of lines - { - for (int x = 0; x < m_nPixelsPerLine; x++) - { - size_t nAddress = x * (0x100000000 / m_nPixelsPerLine); - - if (nAddress == 0x30000000 - || nAddress == 0x30500000 - || nAddress == 0x31000000 - || nAddress == 0x31500000 - || nAddress == 0x32000000 - || nAddress == 0x32500000 - || nAddress == 0x33500000 - || nAddress == 0x34000000 - || nAddress == 0x35000000 - || nAddress == 0x35500000 - || nAddress == 0x36000000 - || nAddress == 0x36500000 - || nAddress == 0x38000000 - || nAddress == 0x39000000) - { - putc((unsigned char)100, out); // blue DLL start - } - else - { - putc((unsigned char)0, out); // black - } - putc((unsigned char)0, out); - putc((unsigned char)0, out); - } - } - - fclose(out); - m_dwLine = 0; - } - } - - void LogCoverage(std::vector& vCov) - { - const size_t nCharPerLine = 128; // readable amount - - char szResult[nCharPerLine + 1], * pCursor = szResult; - - szResult[nCharPerLine] = 0; // zero termination - - size_t nSize = vCov.size(); - size_t nUnitsPerChar = nSize / nCharPerLine; - - for (size_t i = 0; i < nSize; ) - { - unsigned int nLocalCov = 0; - - for (size_t e = 0; e < nUnitsPerChar; ++e, ++i) - { - if (vCov[i]) - { - ++nLocalCov; - } - } - - if (nLocalCov == 0) - { - *pCursor++ = '#'; // occupied - } - else if (nLocalCov == nUnitsPerChar) - { - *pCursor++ = '.'; // free - } - else - { - *pCursor++ = '+'; // partly - } - } - - CryLog(" Coverage=%s", szResult); - } - - - void DumpToRAWCoverage(std::vector& vCov) - { - FILE* out = nullptr; - azfopen(&out, "MemoryCoverage.bmp", "rb+"); - - if (!out) - { - return; - } - - if (fseek(out, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 3 * (m_nLineCount - 1 - m_dwLine) * m_nPixelsPerLine, SEEK_SET) != 0) - { - fclose(out); - return; - } - - size_t nSize = vCov.size(); - size_t nUnitsPerChar = nSize / m_nPixelsPerLine; - - for (size_t i = 0; i < nSize; ) - { - unsigned int nLocalCov = 0; - - for (size_t e = 0; e < nUnitsPerChar; ++e, ++i) - { - if (vCov[i]) - { - ++nLocalCov; - } - } - - size_t Val = 256 - (256 * nLocalCov) / nUnitsPerChar; - - if (Val > 0) - { - Val = 127 + Val / 2; - } - - putc((unsigned char)Val, out); - putc((unsigned char)Val, out); - putc((unsigned char)Val, out); // grey - } - - fclose(out); - - ++m_dwLine; - } - - - - unsigned int m_dwLine; // [0..m_nLineCount-1], m_nLineCount means bitmap is full, 0xffffffff means not initialized yet - static const size_t m_nPixelsPerLine = 1024; // bitmap width - static const size_t m_nLineCount = 128; // -}; - - -#else // defined(WIN32) || defined(WIN64) - - -class CMemoryFragmentationProfiler -{ -public: - void DumpMemoryCoverage() {} -}; - -#endif // defined(WIN32) || defined(WIN64) - - - -#endif // CRYINCLUDE_CRYSYSTEM_MEMORYFRAGMENTATIONPROFILER_H - - diff --git a/Code/CryEngine/CrySystem/MemoryManager.cpp b/Code/CryEngine/CrySystem/MemoryManager.cpp deleted file mode 100644 index 4704d2f5fe..0000000000 --- a/Code/CryEngine/CrySystem/MemoryManager.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "MemoryManager.h" -#include "platform.h" -#include "CustomMemoryHeap.h" -#include "GeneralMemoryHeap.h" -#include "PageMappingHeap.h" -#include "DefragAllocator.h" - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define MEMORYMANAGER_CPP_SECTION_1 1 -#endif - -#if defined(WIN32) - #define WIN32_LEAN_AND_MEAN - #include - #include -#endif - -#if defined(APPLE) -#include // task_info -#endif - -#if defined(APPLE) || defined(LINUX) -#include // required by mman.h -#include //mmap - virtual memory manager -#endif - -#ifdef MEMMAN_STATIC -CCryMemoryManager g_memoryManager; -#endif - -////////////////////////////////////////////////////////////////////////// -CCryMemoryManager* CCryMemoryManager::GetInstance() -{ -#ifdef MEMMAN_STATIC - return &g_memoryManager; -#else - static CCryMemoryManager memman; - return &memman; -#endif -} - -////////////////////////////////////////////////////////////////////////// -bool CCryMemoryManager::GetProcessMemInfo(SProcessMemInfo& minfo) -{ - ZeroStruct(minfo); -#if defined(WIN32) - - MEMORYSTATUSEX mem; - mem.dwLength = sizeof(mem); - GlobalMemoryStatusEx (&mem); - - minfo.TotalPhysicalMemory = mem.ullTotalPhys; - minfo.FreePhysicalMemory = mem.ullAvailPhys; - - ////////////////////////////////////////////////////////////////////////// - typedef BOOL (WINAPI * GetProcessMemoryInfoProc)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD); - - PROCESS_MEMORY_COUNTERS pc; - ZeroStruct(pc); - pc.cb = sizeof(pc); - static HMODULE hPSAPI = LoadLibraryA("psapi.dll"); - if (hPSAPI) - { - static GetProcessMemoryInfoProc pGetProcessMemoryInfo = (GetProcessMemoryInfoProc)GetProcAddress(hPSAPI, "GetProcessMemoryInfo"); - if (pGetProcessMemoryInfo) - { - if (pGetProcessMemoryInfo(GetCurrentProcess(), &pc, sizeof(pc))) - { - minfo.PageFaultCount = pc.PageFaultCount; - minfo.PeakWorkingSetSize = pc.PeakWorkingSetSize; - minfo.WorkingSetSize = pc.WorkingSetSize; - minfo.QuotaPeakPagedPoolUsage = pc.QuotaPeakPagedPoolUsage; - minfo.QuotaPagedPoolUsage = pc.QuotaPagedPoolUsage; - minfo.QuotaPeakNonPagedPoolUsage = pc.QuotaPeakNonPagedPoolUsage; - minfo.QuotaNonPagedPoolUsage = pc.QuotaNonPagedPoolUsage; - minfo.PagefileUsage = pc.PagefileUsage; - minfo.PeakPagefileUsage = pc.PeakPagefileUsage; - - return true; - } - } - } - return false; - -#else - -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION MEMORYMANAGER_CPP_SECTION_1 - #include AZ_RESTRICTED_FILE(MemoryManager_cpp) -#endif - - bool retVal = true; - -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) - #undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(LINUX) - - MEMORYSTATUS MemoryStatus; - GlobalMemoryStatus(&MemoryStatus); - minfo.PagefileUsage = minfo.PeakPagefileUsage = MemoryStatus.dwTotalPhys - MemoryStatus.dwAvailPhys; - - minfo.FreePhysicalMemory = MemoryStatus.dwAvailPhys; - minfo.TotalPhysicalMemory = MemoryStatus.dwTotalPhys; - -#if defined(ANDROID) - // On Android, mallinfo() is an EXTREMELY time consuming operation. Nearly 80% CPU time will be spent - // on this operation once -memreplay is given. Since WorkingSetSize is only used for statistics and - // debugging purpose, it's simply ignored. - minfo.WorkingSetSize = 0; -#else - struct mallinfo meminfo = mallinfo(); - minfo.WorkingSetSize = meminfo.usmblks + meminfo.uordblks; -#endif - -#elif defined(APPLE) - - MEMORYSTATUS MemoryStatus; - GlobalMemoryStatus(&MemoryStatus); - minfo.PagefileUsage = minfo.PeakPagefileUsage = MemoryStatus.dwTotalPhys - MemoryStatus.dwAvailPhys; - - minfo.FreePhysicalMemory = MemoryStatus.dwAvailPhys; - minfo.TotalPhysicalMemory = MemoryStatus.dwTotalPhys; - - // Retrieve WorkingSetSize from task_info - task_basic_info kTaskInfo; - mach_msg_type_number_t uInfoCount(sizeof(kTaskInfo) / sizeof(natural_t)); - if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&kTaskInfo, &uInfoCount) != 0) - { - gEnv->pLog->LogError("task_info failed\n"); - return false; - } - minfo.WorkingSetSize = kTaskInfo.resident_size; - -#else - - retVal = false; - -#endif - - return retVal; -#endif -} - -////////////////////////////////////////////////////////////////////////// -CCryMemoryManager::HeapHandle CCryMemoryManager::TraceDefineHeap([[maybe_unused]] const char* heapName, [[maybe_unused]] size_t size, [[maybe_unused]] const void* pBase) -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapAlloc([[maybe_unused]] HeapHandle heap, [[maybe_unused]] void* mem, [[maybe_unused]] size_t size, [[maybe_unused]] size_t blockSize, [[maybe_unused]] const char* sUsage, [[maybe_unused]] const char* sNameHint) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapFree([[maybe_unused]] HeapHandle heap, [[maybe_unused]] void* mem, [[maybe_unused]] size_t blockSize) -{ -} - - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapSetColor([[maybe_unused]] uint32 color) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CCryMemoryManager::TraceHeapSetLabel([[maybe_unused]] const char* sLabel) -{ -} - -////////////////////////////////////////////////////////////////////////// -uint32 CCryMemoryManager::TraceHeapGetColor() -{ - return 0; -} - -////////////////////////////////////////////////////////////////////////// -ICustomMemoryHeap* const CCryMemoryManager::CreateCustomMemoryHeapInstance(IMemoryManager::EAllocPolicy const eAllocPolicy) -{ - return new CCustomMemoryHeap(eAllocPolicy); -} - -IGeneralMemoryHeap* CCryMemoryManager::CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage) -{ - return new CGeneralMemoryHeap(static_cast(0), upperLimit, reserveSize, sUsage); -} - -IGeneralMemoryHeap* CCryMemoryManager::CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage) -{ - return new CGeneralMemoryHeap(base, sz, sUsage); -} - -IMemoryAddressRange* CCryMemoryManager::ReserveAddressRange(size_t capacity, const char* sName) -{ - return new CMemoryAddressRange(capacity, sName); -} - -IPageMappingHeap* CCryMemoryManager::CreatePageMappingHeap(size_t addressSpace, const char* sName) -{ - return new CPageMappingHeap(addressSpace, sName); -} - -IDefragAllocator* CCryMemoryManager::CreateDefragAllocator() -{ - return new CDefragAllocator(); -} - -extern "C" -{ - CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager) - { - // Static instance of the memory manager - *pIMemoryManager = CCryMemoryManager::GetInstance(); - } -}; diff --git a/Code/CryEngine/CrySystem/MemoryManager.h b/Code/CryEngine/CrySystem/MemoryManager.h deleted file mode 100644 index e9d748e481..0000000000 --- a/Code/CryEngine/CrySystem/MemoryManager.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H -#pragma once - -#include "ISystem.h" - -////////////////////////////////////////////////////////////////////////// -// Class that implements IMemoryManager interface. -////////////////////////////////////////////////////////////////////////// -#ifndef MEMMAN_STATIC -class CCryMemoryManager - : public IMemoryManager -{ -public: - // Singleton - static CCryMemoryManager* GetInstance(); - - ////////////////////////////////////////////////////////////////////////// - virtual bool GetProcessMemInfo(SProcessMemInfo& minfo); - - virtual HeapHandle TraceDefineHeap(const char* heapName, size_t size, const void* pBase); - virtual void TraceHeapAlloc(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint = 0); - virtual void TraceHeapFree(HeapHandle heap, void* mem, size_t blockSize); - virtual void TraceHeapSetColor(uint32 color); - virtual uint32 TraceHeapGetColor(); - virtual void TraceHeapSetLabel(const char* sLabel); - - virtual ICustomMemoryHeap* const CreateCustomMemoryHeapInstance(IMemoryManager::EAllocPolicy const eAllocPolicy); - virtual IGeneralMemoryHeap* CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage); - virtual IGeneralMemoryHeap* CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage); - - virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName); - virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName); - - virtual IDefragAllocator* CreateDefragAllocator(); -}; -#else -typedef IMemoryManager CCryMemoryManager; -#endif - -#endif // CRYINCLUDE_CRYSYSTEM_MEMORYMANAGER_H diff --git a/Code/CryEngine/CrySystem/MiniGUI/DrawContext.cpp b/Code/CryEngine/CrySystem/MiniGUI/DrawContext.cpp deleted file mode 100644 index a45fde272b..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/DrawContext.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "DrawContext.h" -#include -#include -#include - -MINIGUI_BEGIN - -////////////////////////////////////////////////////////////////////////// -CDrawContext::CDrawContext(SMetrics* pMetrics) -{ - m_currentStackLevel = 0; - m_x = 0; - m_y = 0; - m_pMetrics = pMetrics; - m_color = ColorB(0, 0, 0, 0); - m_defaultZ = 0.0f; - m_pAuxRender = gEnv->pRenderer->GetIRenderAuxGeom(); - - m_frameWidth = (float)gEnv->pRenderer->GetWidth(); - m_frameHeight = (float)gEnv->pRenderer->GetHeight(); -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::SetColor(ColorB color) -{ - m_color = color; -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::DrawLine(float x0, float y0, float x1, float y1, float thickness /*= 1.0f */) -{ - m_pAuxRender->DrawLine(Vec3(m_x + x0, m_y + y0, m_defaultZ), m_color, Vec3(m_x + x1, m_y + y1, m_defaultZ), m_color, thickness); -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::DrawTriangle(float x0, float y0, float x1, float y1, float x2, float y2) -{ - m_pAuxRender->DrawTriangle(Vec3(m_x + x0, m_y + y0, m_defaultZ), m_color, Vec3(m_x + x1, m_y + y1, m_defaultZ), m_color, Vec3(m_x + x2, m_y + y2, m_defaultZ), m_color); -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::DrawRect(const Rect& rc) -{ - m_pAuxRender->DrawTriangle(Vec3(m_x + rc.left, m_y + rc.top, m_defaultZ), m_color, Vec3(m_x + rc.left, m_y + rc.bottom, m_defaultZ), m_color, Vec3(m_x + rc.right, m_y + rc.top, m_defaultZ), m_color); - m_pAuxRender->DrawTriangle(Vec3(m_x + rc.left, m_y + rc.bottom, m_defaultZ), m_color, Vec3(m_x + rc.right, m_y + rc.bottom, m_defaultZ), m_color, Vec3(m_x + rc.right, m_y + rc.top, m_defaultZ), m_color); -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::DrawFrame(const Rect& rc, ColorB lineColor, ColorB solidColor, float thickness) -{ - ColorB prevColor = m_color; - - SetColor(solidColor); - DrawRect(rc); - - SetColor(lineColor); - - uint32 curFlags = m_pAuxRender->GetRenderFlags().m_renderFlags; - m_pAuxRender->SetRenderFlags(curFlags | e_DrawInFrontOn); - DrawLine(rc.left, rc.top, rc.right, rc.top, thickness); - DrawLine(rc.right, rc.top, rc.right, rc.bottom, thickness); - DrawLine(rc.left, rc.top, rc.left, rc.bottom, thickness); - DrawLine(rc.left, rc.bottom, rc.right, rc.bottom, thickness); - m_pAuxRender->SetRenderFlags(curFlags); - - m_color = prevColor; -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::StartDrawing() -{ - uint32 width = gEnv->pRenderer->GetWidth(); - uint32 height = gEnv->pRenderer->GetHeight(); - - gEnv->pRenderer->Set2DMode(width, height, m_backupSceneMatrices); - - m_prevRenderFlags = m_pAuxRender->GetRenderFlags().m_renderFlags; - m_pAuxRender->SetRenderFlags(e_Mode3D | e_AlphaBlended | e_FillModeSolid | e_CullModeBack | e_DepthWriteOff | e_DepthTestOff); -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::StopDrawing() -{ - // Restore old flags that where set before our draw context. - m_pAuxRender->SetRenderFlags(m_prevRenderFlags); - - gEnv->pRenderer->Unset2DMode(m_backupSceneMatrices); -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::DrawString(float x, float y, float font_size, ETextAlign align, const char* format, ...) -{ - //text will be off screen - if (y > m_frameHeight || x > m_frameWidth) - { - return; - } - - va_list args; - va_start(args, format); - SDrawTextInfo ti; - ti.xscale = ti.yscale = font_size / 12.0f; // font size in pixels to text scale. - - ti.flags = eDrawText_Monospace | eDrawText_2D | eDrawText_FixedSize | eDrawText_IgnoreOverscan; - if (align == eTextAlign_Left) - { - } - else if (align == eTextAlign_Right) - { - ti.flags |= eDrawText_Right; - } - else if (align == eTextAlign_Center) - { - ti.flags |= eDrawText_Center; - } - ti.color[0] = (float)m_color.r / 255.0f; - ti.color[1] = (float)m_color.g / 255.0f; - ti.color[2] = (float)m_color.b / 255.0f; - ti.color[3] = (float)m_color.a / 255.0f; - gEnv->pRenderer->DrawTextQueued(Vec3(m_x + x, m_y + y, m_defaultZ), ti, format, args); - va_end(args); -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::PushClientRect(const Rect& rc) -{ - m_currentStackLevel++; - assert(m_currentStackLevel < MAX_ORIGIN_STACK); - m_clientRectStack[m_currentStackLevel] = rc; - m_x += rc.left; - m_y += rc.top; -} - -////////////////////////////////////////////////////////////////////////// -void CDrawContext::PopClientRect() -{ - if (m_currentStackLevel > 0) - { - Rect& rc = m_clientRectStack[m_currentStackLevel]; - m_x -= rc.left; - m_y -= rc.top; - - m_currentStackLevel--; - } -} -MINIGUI_END diff --git a/Code/CryEngine/CrySystem/MiniGUI/DrawContext.h b/Code/CryEngine/CrySystem/MiniGUI/DrawContext.h deleted file mode 100644 index 6b1b8000ae..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/DrawContext.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : DrawContext helper class for MiniGUI - - -#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_DRAWCONTEXT_H -#define CRYINCLUDE_CRYSYSTEM_MINIGUI_DRAWCONTEXT_H -#pragma once - - -#include "ICryMiniGUI.h" -#include - -struct IRenderAuxGeom; - -MINIGUI_BEGIN - -enum ETextAlign -{ - eTextAlign_Left, - eTextAlign_Right, - eTextAlign_Center -}; - -////////////////////////////////////////////////////////////////////////// -// Context of MiniGUI drawing. -////////////////////////////////////////////////////////////////////////// -class CDrawContext -{ -public: - CDrawContext(SMetrics* pMetrics); - - // Must be called before any drawing happens - void StartDrawing(); - // Must be called after all drawing have been complete. - void StopDrawing(); - - void PushClientRect(const Rect& rc); - void PopClientRect(); - - SMetrics& Metrics() { return *m_pMetrics; } - void SetColor(ColorB color); - - void DrawLine(float x0, float y0, float x1, float y1, float thickness = 1.0f); - void DrawTriangle(float x0, float y0, float x1, float y1, float x2, float y2); - void DrawRect(const Rect& rc); - void DrawFrame(const Rect& rc, ColorB lineColor, ColorB solidColor, float thickness = 1.0f); - - void DrawString(float x, float y, float font_size, ETextAlign align, const char* format, ...); - - -protected: - SMetrics* m_pMetrics; - - ColorB m_color; - float m_defaultZ; - IRenderAuxGeom* m_pAuxRender; - uint32 m_prevRenderFlags; - - enum - { - MAX_ORIGIN_STACK = 16 - }; - - int m_currentStackLevel; - float m_x, m_y; // Reference X,Y positions - Rect m_clientRectStack[MAX_ORIGIN_STACK]; - - float m_frameWidth; - float m_frameHeight; - -private: - TransformationMatrices m_backupSceneMatrices; -}; - -MINIGUI_END - -#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_DRAWCONTEXT_H diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniButton.cpp b/Code/CryEngine/CrySystem/MiniGUI/MiniButton.cpp deleted file mode 100644 index cbedfe1eae..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniButton.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - - -#include "CrySystem_precompiled.h" -#include "MiniButton.h" -#include "DrawContext.h" -#include -#include - -MINIGUI_BEGIN - - -CMiniButton::CMiniButton() -{ - m_pCVar = NULL; - m_fCVarValue[0] = 0; - m_fCVarValue[1] = 1; - m_saveStateOn = false; - m_clickCallback = NULL; - m_pCallbackData = NULL; - m_pConnectedCtrl = NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniButton::Reset() -{ - /*if (m_pCVar) - { - pCVar->Set( m_fCVarValue[0] ); - }*/ - - /*if(m_pConnectedCtrl) - { - m_pConnectedCtrl->SetVisible(false); - }*/ - - clear_flag(eCtrl_Checked); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniButton::SaveState() -{ - if (is_flag(eCtrl_Checked)) - { - if (m_pConnectedCtrl && m_pConnectedCtrl->CheckFlag(eCtrl_Hidden)) - { - m_saveStateOn = false; - } - else - { - m_saveStateOn = true; - } - } - else - { - m_saveStateOn = false; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniButton::RestoreState() -{ - if (m_pCVar) - { - if (m_pCVar->GetFVal() == m_fCVarValue[1]) - { - set_flag(eCtrl_Checked); - - - //Restoring CVars has caused a few issues, especially when the user is changing - //CVars through the console while perfHud is active, removing for now - //pCVar->Set( m_saveStateOn ? m_fCVarValue[1] : m_fCVarValue[0] ); - } - else - { - clear_flag(eCtrl_Checked); - } - } - else - { - //connected controls (tables / info boxes etc) now look after themselves - /*if(m_pConnectedCtrl) - { - m_pConnectedCtrl->SetVisible(m_saveStateOn); - }*/ - - if (CheckFlag(eCtrl_CheckButton)) - { - if (m_saveStateOn) - { - set_flag(eCtrl_Checked); - } - else - { - clear_flag(eCtrl_Checked); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniButton::OnPaint(CDrawContext& dc) -{ - ColorB bkgColor = dc.Metrics().clrBackground; - - if (is_flag(eCtrl_Highlight)) - { - bkgColor = dc.Metrics().clrBackgroundHighlight; - } - else if (is_flag(eCtrl_Checked)) - { - //if connected control has been hidden, this button should not be checked - if (m_pConnectedCtrl && m_pConnectedCtrl->CheckFlag(eCtrl_Hidden)) - { - clear_flag(eCtrl_Checked); - } - else - { - bkgColor = dc.Metrics().clrBackgroundSelected; - } - } - - float borderThickness = 1.0f; - - if (is_flag(eCtrl_Focus)) - { - borderThickness = 3.0f; - } - - ColorB borderCol = dc.Metrics().clrFrameBorder; - - if (!m_pGUI->InFocus()) - { - borderCol = dc.Metrics().clrFrameBorderOutOfFocus; - bkgColor.a = dc.Metrics().outOfFocusAlpha; - } - - dc.DrawFrame(m_rect, borderCol, bkgColor, borderThickness); - - ColorB textColor = dc.Metrics().clrText; - - if (is_flag(eCtrl_Checked | eCtrl_Highlight)) - { - textColor = dc.Metrics().clrTextSelected; - } - - dc.SetColor(textColor); - - ETextAlign align; - float startX; - - if (is_flag(eCtrl_TextAlignCentre)) - { - startX = (m_rect.left + m_rect.right) / 2.f; - align = eTextAlign_Center; - } - else - { - startX = m_rect.left + 5.f; - align = eTextAlign_Left; - } - - dc.DrawString(startX, m_rect.top, dc.Metrics().fTitleSize, align, GetTitle()); - - //Check not very obvious -#if 0 - if (is_flag(eCtrl_Checked)) - { - // Draw checked mark. - float checkX = m_rect.left + 4; - float checkY = (m_rect.bottom + m_rect.top) * 0.5f; - dc.SetColor(dc.Metrics().clrChecked); - dc.DrawLine(checkX, checkY, checkX + 3, checkY + 3); - dc.DrawLine(checkX + 3, checkY + 3, checkX + 7, checkY - 6); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -void CMiniButton::SetRect(const Rect& rc) -{ - Rect newrc = rc; - newrc.bottom = newrc.top + m_pGUI->Metrics().fTitleSize + 2; - CMiniCtrl::SetRect(newrc); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniButton::OnEvent(float x, float y, EMiniCtrlEvent event) -{ - switch (event) - { - case eCtrlEvent_LButtonDown: - { - SCommand cmd; - - if (CheckFlag(eCtrl_CheckButton)) - { - if (!CheckFlag(eCtrl_Checked)) - { - cmd.command = eCommand_ButtonChecked; - } - else - { - cmd.command = eCommand_ButtonUnchecked; - } - } - else - { - cmd.command = eCommand_ButtonPress; - } - - cmd.nCtrlID = GetId(); - cmd.pCtrl = this; - GetGUI()->OnCommand(cmd); - - if (CheckFlag(eCtrl_CheckButton)) - { - bool bOn = false; - - if (CheckFlag(eCtrl_Checked)) - { - bOn = false; - ClearFlag(eCtrl_Checked); - } - else - { - bOn = true; - SetFlag(eCtrl_Checked); - } - - if (m_pCVar) - { - m_pCVar->Set(m_fCVarValue[bOn ? 1 : 0]); - } - - if (m_pConnectedCtrl) - { - m_pConnectedCtrl->SetVisible(bOn); - } - } - else - { - //cross button behavior - if (m_pConnectedCtrl) - { - m_pConnectedCtrl->SetVisible(false); - } - } - - if (m_clickCallback) - { - m_clickCallback(m_pCallbackData, true); - } - } - break; - case eCtrlEvent_MouseOff: - { - if (m_pParent) - { - m_pParent->OnEvent(x, y, eCtrlEvent_MouseOff); - } - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CMiniButton::SetControlCVar(const char* sCVarName, float fOffValue, float fOnValue) -{ - m_pCVar = GetISystem()->GetIConsole()->GetCVar(sCVarName); - - if (!m_pCVar) - { - CryLogAlways("failed to find CVar: %s\n", sCVarName); - } - - m_fCVarValue[0] = fOffValue; - m_fCVarValue[1] = fOnValue; - - if (m_pCVar && m_pCVar->GetFVal() == fOnValue) - { - set_flag(eCtrl_Checked); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CMiniButton::SetClickCallback(ClickCallback callback, void* pCallbackData) -{ - m_clickCallback = callback; - m_pCallbackData = pCallbackData; - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CMiniButton::SetConnectedCtrl(IMiniCtrl* pConnectedCtrl) -{ - m_pConnectedCtrl = pConnectedCtrl; - return true; -} - -MINIGUI_END diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniButton.h b/Code/CryEngine/CrySystem/MiniGUI/MiniButton.h deleted file mode 100644 index 3e45f6b4e4..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniButton.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - - -#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIBUTTON_H -#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIBUTTON_H -#pragma once - - -#include "MiniGUI.h" - -MINIGUI_BEGIN - -////////////////////////////////////////////////////////////////////////// -// Root window all other controls derive from -class CMiniButton - : public CMiniCtrl -{ -public: - CMiniButton(); - - ////////////////////////////////////////////////////////////////////////// - // CMiniCtrl interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual EMiniCtrlType GetType() const { return eCtrlType_Button; } - virtual void SetRect(const Rect& rc); - virtual void OnPaint(CDrawContext& dc); - virtual void OnEvent(float x, float y, EMiniCtrlEvent event); - virtual void Reset(); - virtual void SaveState(); - virtual void RestoreState(); - ////////////////////////////////////////////////////////////////////////// - - virtual bool SetControlCVar(const char* sCVarName, float fOffValue, float fOnValue); - virtual bool SetClickCallback(ClickCallback callback, void* pCallbackData); - virtual bool SetConnectedCtrl(IMiniCtrl* pConnectedCtrl); - -protected: - ICVar* m_pCVar; - float m_fCVarValue[2]; - ClickCallback m_clickCallback; - void* m_pCallbackData; - IMiniCtrl* m_pConnectedCtrl; -}; - -MINIGUI_END - -#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIBUTTON_H diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniGUI.cpp b/Code/CryEngine/CrySystem/MiniGUI/MiniGUI.cpp deleted file mode 100644 index 9b074ce537..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniGUI.cpp +++ /dev/null @@ -1,862 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of the MiniGUI class - - -#include "CrySystem_precompiled.h" -#include "MiniGUI.h" -#include "DrawContext.h" - -#include "MiniButton.h" -#include "MiniMenu.h" -#include "MiniInfoBox.h" -#include "MiniTable.h" - -#include -#include - -#include -#include -#include - -namespace minigui -{ - CRYREGISTER_SINGLETON_CLASS(CMiniGUI) -} - - -MINIGUI_BEGIN - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::InitMetrics() -{ - m_metrics.clrText = ColorB(255, 255, 255, 255); - m_metrics.clrTextSelected = ColorB(0, 255, 0, 255); - m_metrics.fTextSize = 12.0f; - - m_metrics.clrTitle = ColorB(255, 255, 255, 255); - - m_metrics.fTitleSize = 14.0f; - - const int backgroundAlpha = 255; - - m_metrics.clrBackground = ColorB(20, 20, 20, backgroundAlpha); - m_metrics.clrBackgroundHighlight = ColorB(10, 10, 150, backgroundAlpha); - m_metrics.clrBackgroundSelected = ColorB(10, 120, 10, backgroundAlpha); - - m_metrics.clrFrameBorder = ColorB(255, 0, 0, 255); - m_metrics.clrFrameBorderHighlight = ColorB(255, 255, 0, 255); - m_metrics.clrFrameBorderOutOfFocus = ColorB(0, 0, 0, 255); - - m_metrics.clrChecked = ColorB(0, 0, 0, 255); - m_metrics.outOfFocusAlpha = 32; -} - -class CMiniCtrlRoot - : public CMiniCtrl -{ -public: - CMiniCtrlRoot() {}; - virtual EMiniCtrlType GetType() const { return eCtrlType_Unknown; }; - virtual void OnPaint([[maybe_unused]] class CDrawContext& dc) {}; -}; - -////////////////////////////////////////////////////////////////////////// -CMiniGUI::CMiniGUI() - : m_enabled(false) - , m_inFocus(true) - , m_pDPadMenu(NULL) - , m_pMovingCtrl(NULL) -{ -} - -////////////////////////////////////////////////////////////////////////// -CMiniGUI::~CMiniGUI() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::Init() -{ - m_pEventListener = NULL; - InitMetrics(); - - AzFramework::InputChannelEventListener::Connect(); - - m_pRootCtrl = new CMiniCtrlRoot; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::Reset() -{ - m_pRootCtrl->Reset(); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::SaveState() -{ - m_pRootCtrl->SaveState(); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::RestoreState() -{ - m_pRootCtrl->RestoreState(); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::SetEnabled(bool status) -{ - m_enabled = status; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::SetInFocus(bool status) -{ - if (status) - { - m_inFocus = true; - } - else - { - CloseDPadMenu(); - m_inFocus = false; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::Done() -{ - AzFramework::InputChannelEventListener::Disconnect(); -} - - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::Draw() -{ - FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_SYSTEM, g_bProfilerEnabled); - - // When console opened hide MiniGui - bool bConsoleOpened = gEnv->pConsole->IsOpened(); - if (m_enabled && !bConsoleOpened) - { - ProcessInput(); - - CDrawContext dc(&m_metrics); - dc.StartDrawing(); - { - // Draw all controls. - m_pRootCtrl->DrawCtrl(dc); - } - dc.StopDrawing(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::ProcessInput() -{ - //check we are not in digital selection mode - if (!m_pDPadMenu) - { - float mx(0), my(0); - AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero(); - AzFramework::InputSystemCursorRequestBus::EventResult(systemCursorPositionNormalized, - AzFramework::InputDeviceMouse::Id, - &AzFramework::InputSystemCursorRequests::GetSystemCursorPositionNormalized); - mx = systemCursorPositionNormalized.GetX() * gEnv->pRenderer->GetWidth(); - my = systemCursorPositionNormalized.GetY() * gEnv->pRenderer->GetHeight(); - - //update moving control - if (m_pMovingCtrl) - { - m_pMovingCtrl->Move(mx, my); - } - - IMiniCtrl* pCtrl = GetCtrlFromPoint(mx, my); - if (pCtrl) - { - SetHighlight(pCtrl, true, mx, my); - } - else - { - SetHighlight(m_highlightedCtrl, false, mx, my); - } - } -} - -////////////////////////////////////////////////////////////////////////// -IMiniCtrl* CMiniGUI::GetCtrlFromPoint(float x, float y) const -{ - // Draw all controls. - return m_pRootCtrl->GetCtrlFromPoint(x, y); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::SetHighlight(IMiniCtrl* pCtrl, bool bEnable, float x, float y) -{ - if (pCtrl) - { - if (m_highlightedCtrl && m_highlightedCtrl != pCtrl) - { - m_highlightedCtrl->OnEvent(x, y, eCtrlEvent_MouseOff); - m_highlightedCtrl->ClearFlag(eCtrl_Highlight); - } - - if (bEnable) - { - pCtrl->OnEvent(x, y, eCtrlEvent_MouseOver); - pCtrl->SetFlag(eCtrl_Highlight); - - m_highlightedCtrl = pCtrl; - } - else - { - pCtrl->OnEvent(x, y, eCtrlEvent_MouseOff); - pCtrl->ClearFlag(eCtrl_Highlight); - m_highlightedCtrl = NULL; - } - } - else - { - assert(bEnable == false); - - if (m_highlightedCtrl) - { - m_highlightedCtrl->OnEvent(x, y, eCtrlEvent_MouseOff); - m_highlightedCtrl->ClearFlag(eCtrl_Highlight); - m_highlightedCtrl = NULL; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::SetFocus(IMiniCtrl* pCtrl, bool bEnable) -{ - if (m_focusCtrl) - { - m_focusCtrl->ClearFlag(eCtrl_Focus); - } - m_focusCtrl = pCtrl; - if (m_focusCtrl) - { - if (bEnable) - { - m_focusCtrl->SetFlag(eCtrl_Focus); - } - else - { - m_focusCtrl->ClearFlag(eCtrl_Focus); - } - } -} - -////////////////////////////////////////////////////////////////////////// -SMetrics& CMiniGUI::Metrics() -{ - return m_metrics; -} - -////////////////////////////////////////////////////////////////////////// -IMiniCtrl* CMiniGUI::CreateCtrl(IMiniCtrl* pParentCtrl, int nCtrlID, EMiniCtrlType type, int nCtrlFlags, const Rect& rc, const char* title) -{ - CMiniCtrl* pCtrl = 0; - // Test code. - switch (type) - { - case eCtrlType_Button: - pCtrl = new CMiniButton; - break; - case eCtrlType_Menu: - pCtrl = new CMiniMenu; - break; - case eCtrlType_InfoBox: - pCtrl = new CMiniInfoBox; - break; - case eCtrlType_Table: - pCtrl = new CMiniTable; - break; - default: - assert(0 && "Unknown MiniGUI control type"); - break; - } - ; - if (pCtrl) - { - pCtrl->SetGUI(this); - pCtrl->SetFlag(nCtrlFlags); - pCtrl->SetTitle(title); - pCtrl->SetRect(rc); - pCtrl->SetId(nCtrlID); - - if (pCtrl->CheckFlag(eCtrl_AutoResize)) - { - pCtrl->AutoResize(); - } - - if (pCtrl->CheckFlag(eCtrl_CloseButton)) - { - pCtrl->CreateCloseButton(); - } - - if (pParentCtrl) - { - pParentCtrl->AddSubCtrl(pCtrl); - } - else - { - m_pRootCtrl->AddSubCtrl(pCtrl); - } - - if (type == eCtrlType_Menu && pParentCtrl == NULL) - { - m_rootMenus.push_back(pCtrl); - } - } - return pCtrl; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::OnCommand(SCommand& cmd) -{ - if (m_pEventListener) - { - m_pEventListener->OnCommand(cmd); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::OnMouseInputEvent(const AzFramework::InputChannel& inputChannel) -{ - if (!m_inFocus || !m_enabled) - { - return; - } - - const AzFramework::InputChannel::PositionData2D* positionData2D = inputChannel.GetCustomData(); - if (!positionData2D) - { - return; - } - const float mx = positionData2D->m_normalizedPosition.GetX() * gEnv->pRenderer->GetWidth(); - const float my = positionData2D->m_normalizedPosition.GetY() * gEnv->pRenderer->GetHeight(); - IMiniCtrl* pCtrl = GetCtrlFromPoint(mx, my); - if (pCtrl) - { - const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId(); - if (channelId == AzFramework::InputDeviceMouse::Button::Left) - { - if (inputChannel.IsStateBegan()) - { - pCtrl->OnEvent(mx, my, eCtrlEvent_LButtonDown); - } - else if (inputChannel.IsStateEnded()) - { - pCtrl->OnEvent(mx, my, eCtrlEvent_LButtonUp); - } - } - } -} - -void CMiniGUI::SetDPadMenu(IMiniCtrl* pMenu) -{ - m_pDPadMenu = (CMiniMenu*)pMenu; - UiCursorBus::Broadcast(&UiCursorInterface::DecrementVisibleCounter); -} - -void CMiniGUI::CloseDPadMenu() -{ - if (m_pDPadMenu) - { - CMiniMenu* closeMenu = m_pDPadMenu; - - //close menu and all parent menus - do - { - closeMenu->Close(); - closeMenu = (CMiniMenu*)closeMenu->GetParent(); - } while (closeMenu->GetType() == eCtrlType_Menu); - - m_pDPadMenu->ClearFlag(eCtrl_Highlight); - m_pDPadMenu = NULL; - UiCursorBus::Broadcast(&UiCursorInterface::IncrementVisibleCounter); - } -} - -void CMiniGUI::UpdateDPadMenu(const AzFramework::InputChannel& inputChannel) -{ - const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId(); - const bool isPressed = inputChannel.IsStateBegan(); - - if (m_pDPadMenu) - { - if (channelId == AzFramework::InputDeviceGamepad::Button::B) - { - CloseDPadMenu(); - return; - } - - if (isPressed) - { - if (channelId == AzFramework::InputDeviceGamepad::Button::DD || - channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LD) - { - m_pDPadMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadDown); - } - else if (channelId == AzFramework::InputDeviceGamepad::Button::DU || - channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LU) - { - m_pDPadMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadUp); - } - else if (channelId == AzFramework::InputDeviceGamepad::Button::DL || - channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LL) - { - CMiniMenu* pNewMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadLeft); - - //get previous root menu - if (pNewMenu == NULL) - { - int i = 0, nRootMenus = m_rootMenus.size(); - - for (i = 0; i < nRootMenus; i++) - { - if (m_rootMenus[i] == m_pDPadMenu) - { - break; - } - } - - if (i > 0) - { - m_pDPadMenu->Close(); - m_pDPadMenu->ClearFlag(eCtrl_Highlight); - - m_pDPadMenu = (CMiniMenu*)m_rootMenus[i - 1]; - m_pDPadMenu->Open(); - m_pDPadMenu->SetFlag(eCtrl_Highlight); - } - //else selected menu remains the same - } - else - { - m_pDPadMenu = pNewMenu; - } - } - else if (channelId == AzFramework::InputDeviceGamepad::Button::DR || - channelId == AzFramework::InputDeviceGamepad::ThumbStickDirection::LR) - { - CMiniMenu* pNewMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_DPadRight); - - //get next root menu - if (pNewMenu == NULL) - { - int i = 0, nRootMenus = m_rootMenus.size(); - - for (i = 0; i < nRootMenus; i++) - { - if (m_rootMenus[i] == m_pDPadMenu) - { - break; - } - } - - if (i < nRootMenus - 1) - { - m_pDPadMenu->Close(); - m_pDPadMenu->ClearFlag(eCtrl_Highlight); - - m_pDPadMenu = (CMiniMenu*)m_rootMenus[i + 1]; - m_pDPadMenu->Open(); - m_pDPadMenu->SetFlag(eCtrl_Highlight); - } - //else selected menu remains the same - } - else - { - m_pDPadMenu = pNewMenu; - } - } - else if (channelId == AzFramework::InputDeviceGamepad::Button::A) - { - m_pDPadMenu = m_pDPadMenu->UpdateSelection(eCtrlEvent_LButtonDown); - } - } - } -} - -bool CMiniGUI::OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) -{ - const AzFramework::InputDeviceId& deviceId = inputChannel.GetInputDevice().GetInputDeviceId(); - if (AzFramework::InputDeviceMouse::IsMouseDevice(deviceId)) - { - OnMouseInputEvent(inputChannel); - return false; - } - - if (!m_inFocus) - { - return false; - } - - if (!AzFramework::InputDeviceGamepad::IsGamepadDevice(deviceId)) - { - return false; - } - - if (m_pDPadMenu) - { - UpdateDPadMenu(inputChannel); - } - else - { - float posX = 0.0f; - float posY = 0.0f; - const AzFramework::InputChannel::PositionData2D* positionData2D = inputChannel.GetCustomData(); - if (positionData2D) - { - posX = positionData2D->m_normalizedPosition.GetX() * gEnv->pRenderer->GetWidth(); - posY = positionData2D->m_normalizedPosition.GetY() * gEnv->pRenderer->GetHeight(); - } - - IMiniCtrl* pCtrl = GetCtrlFromPoint(posX, posY); - - if (pCtrl) - { - const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId(); - if (channelId == AzFramework::InputDeviceGamepad::Button::A) - { - switch (inputChannel.GetState()) - { - case AzFramework::InputChannel::State::Began: - pCtrl->OnEvent(posX, posY, eCtrlEvent_LButtonDown); - break; - - case AzFramework::InputChannel::State::Ended: - pCtrl->OnEvent(posX, posY, eCtrlEvent_LButtonUp); - break; - - case AzFramework::InputChannel::State::Updated: - pCtrl->OnEvent(posX, posY, eCtrlEvent_LButtonPressed); - - //if we've clicked on a menu, enter menu selection mode, disable mouse - if (pCtrl->GetType() == eCtrlType_Menu) - { - SetDPadMenu(pCtrl); - } - - break; - } - } - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::SetEventListener(IMiniGUIEventListener* pListener) -{ - m_pEventListener = pListener; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniGUI::RemoveAllCtrl() -{ - m_highlightedCtrl = NULL; - - //reset all console variables to default state - Reset(); - - m_pRootCtrl->RemoveAllSubCtrl(); -} - -////////////////////////////////////////////////////////////////////////// -//CMiniCtrl -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::Reset() -{ - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->Reset(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::SaveState() -{ - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->SaveState(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::RestoreState() -{ - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->RestoreState(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::AddSubCtrl(IMiniCtrl* pCtrl) -{ - assert(pCtrl); - _smart_ptr pTempCtrl(pCtrl); - IMiniCtrl* pParent = pCtrl->GetParent(); - if (pParent) - { - pParent->RemoveSubCtrl(pCtrl); - } - - static_cast(pCtrl)->m_pParent = this; - m_subCtrls.push_back(pCtrl); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::RemoveSubCtrl(IMiniCtrl* pCtrl) -{ - assert(pCtrl); - _smart_ptr pTempCtrl(pCtrl); - IMiniCtrl* pParent = pCtrl->GetParent(); - if (pParent == this) - { - static_cast(pCtrl)->m_pParent = 0; - for (int i = 0, num = (int)m_subCtrls.size(); i < num; i++) - { - if (m_subCtrls[i] == pCtrl) - { - m_subCtrls.erase(m_subCtrls.begin() + i); - break; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::RemoveAllSubCtrl() -{ - int nSubCtrls = m_subCtrls.size(); - - if (nSubCtrls) - { - for (int i = 0; i < nSubCtrls; i++) - { - IMiniCtrl* pSubCtrl = m_subCtrls[i].get(); - pSubCtrl->RemoveAllSubCtrl(); - } - - m_subCtrls.clear(); - } -} - -////////////////////////////////////////////////////////////////////////// -IMiniCtrl* CMiniCtrl::GetCtrlFromPoint(float x, float y) -{ - if (is_flag(eCtrl_Hidden)) - { - return 0; - } - - for (int i = 0, num = (int)m_subCtrls.size(); i < num; i++) - { - float lx = x - m_rect.left; - float ly = y - m_rect.top; - IMiniCtrl* pHit = m_subCtrls[i]->GetCtrlFromPoint(lx, ly); - if (pHit) - { - return pHit; - } - } - if (m_rect.IsPointInside(x, y)) - { - return this; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::DrawCtrl(CDrawContext& dc) -{ - OnPaint(dc); - - dc.PushClientRect(m_rect); - - for (int i = 0, num = (int)m_subCtrls.size(); i < num; i++) - { - CMiniCtrl* pCtrl = static_cast((IMiniCtrl*)m_subCtrls[i]); - if (!pCtrl->is_flag(eCtrl_Hidden)) - { - pCtrl->DrawCtrl(dc); - } - } - - dc.PopClientRect(); -} - -////////////////////////////////////////////////////////////////////////// -int CMiniCtrl::GetSubCtrlCount() const -{ - return (int)m_subCtrls.size(); -} - -////////////////////////////////////////////////////////////////////////// -IMiniCtrl* CMiniCtrl::GetSubCtrl(int nIndex) const -{ - assert(nIndex >= 0 && nIndex < (int)m_subCtrls.size()); - return m_subCtrls[nIndex]; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::SetRect(const Rect& rc) -{ - m_rect = rc; - - if (m_pCloseButton) - { - float width = rc.Width(); - - //relative position of cross box - Rect closeRect(width - 20.f, 0.f, width, 20.f); - m_pCloseButton->SetRect(closeRect); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::SetVisible(bool state) -{ - if (state) - { - clear_flag(eCtrl_Hidden); - } - else - { - set_flag(eCtrl_Hidden); - } - - if (m_pCloseButton) - { - m_pCloseButton->SetVisible(state); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::AutoResize() -{ - uint32 stringLen = m_title.length(); - - if (stringLen) - { - //just an approximation for now - should take into account font size / kerning - m_rect.right = m_rect.left + (8.5f * stringLen); - } - - m_requiresResize = false; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::StartMoving(float x, float y) -{ - if (!m_moving) - { - m_prevX = x; - m_prevY = y; - m_moving = true; - - m_pGUI->SetMovingCtrl(this); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::StopMoving() -{ - if (m_moving) - { - m_moving = false; - m_pGUI->SetMovingCtrl(NULL); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::Move(float x, float y) -{ - if (m_moving) - { - float moveX = x - m_prevX; - float moveY = y - m_prevY; - - m_rect.top += moveY; - m_rect.bottom += moveY; - - m_rect.left += moveX; - m_rect.right += moveX; - - m_prevX = x; - m_prevY = y; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::OnEvent(float x, float y, EMiniCtrlEvent event) -{ - switch (event) - { - case eCtrlEvent_LButtonDown: - { - if (is_flag(eCtrl_Highlight | eCtrl_Moveable)) - { - StartMoving(x, y); - } - } - break; - - case eCtrlEvent_LButtonUp: - if (m_moving) - { - StopMoving(); - } - break; - - case eCtrlEvent_MouseOver: - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniCtrl::CreateCloseButton() -{ - if (m_pGUI) - { - m_pCloseButton = m_pGUI->CreateCtrl(this, 100, eCtrlType_Button, 0, Rect(0, 0, 100, 20), "X"); - - if (m_pCloseButton) - { - m_pCloseButton->SetConnectedCtrl(this); - - float width = m_rect.Width(); - - //relative position of cross box - Rect closeRect(width - 20.f, 0.f, width, 20.f); - m_pCloseButton->SetRect(closeRect); - } - } -} - -MINIGUI_END diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniGUI.h b/Code/CryEngine/CrySystem/MiniGUI/MiniGUI.h deleted file mode 100644 index a4db53070f..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniGUI.h +++ /dev/null @@ -1,219 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Mini GUI subsystem - - -#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIGUI_H -#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIGUI_H -#pragma once - - -#include "ICryMiniGUI.h" -#include - -#include - -#include - -MINIGUI_BEGIN - -class CMiniMenu; - -////////////////////////////////////////////////////////////////////////// -// Root window all other controls derive from -class CMiniCtrl - : public IMiniCtrl -{ -public: - - CMiniCtrl() - : m_nFlags(0) - , m_id(0) - , m_renderCallback(NULL) - , m_fTextSize(12.f) - , m_prevX(0.f) - , m_prevY(0.f) - , m_moving(false) - , m_requiresResize(false) - , m_pCloseButton(NULL) - , m_saveStateOn(false) - {}; - - ////////////////////////////////////////////////////////////////////////// - // IMiniCtrl interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void Reset(); - virtual void SaveState(); - virtual void RestoreState(); - - virtual void SetGUI(IMiniGUI* pGUI) { m_pGUI = pGUI; }; - virtual IMiniGUI* GetGUI() const { return m_pGUI; }; - - virtual int GetId() const { return m_id; }; - virtual void SetId(int id) { m_id = id; }; - - virtual const char* GetTitle() const { return m_title; }; - virtual void SetTitle(const char* title) { m_title = title; }; - - virtual Rect GetRect() const { return m_rect; } - virtual void SetRect(const Rect& rc); - - virtual void SetFlag(uint32 flag) { set_flag(flag); } - virtual void ClearFlag(uint32 flag) { clear_flag(flag); }; - virtual bool CheckFlag(uint32 flag) const { return is_flag(flag); } - - virtual void AddSubCtrl(IMiniCtrl* pCtrl); - virtual void RemoveSubCtrl(IMiniCtrl* pCtrl); - virtual void RemoveAllSubCtrl(); - virtual int GetSubCtrlCount() const; - virtual IMiniCtrl* GetSubCtrl(int nIndex) const; - virtual IMiniCtrl* GetParent() const { return m_pParent; }; - - virtual IMiniCtrl* GetCtrlFromPoint(float x, float y); - - virtual void SetVisible(bool state); - - virtual void OnEvent(float x, float y, EMiniCtrlEvent); - - virtual bool SetRenderCallback(RenderCallback callback) { m_renderCallback = callback; return true; }; - - - // Not implemented in base control - virtual bool SetControlCVar([[maybe_unused]] const char* sCVarName, [[maybe_unused]] float fOffValue, [[maybe_unused]] float fOnValue) { assert(0); return false; }; - virtual bool SetClickCallback([[maybe_unused]] ClickCallback callback, [[maybe_unused]] void* pCallbackData) { assert(0); return false; }; - virtual bool SetConnectedCtrl([[maybe_unused]] IMiniCtrl* pConnectedCtrl) { assert(0); return false; }; - - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - virtual void AutoResize(); - - ////////////////////////////////////////////////////////////////////////// - virtual void CreateCloseButton(); - - void DrawCtrl(CDrawContext& dc); - - virtual void Move(float x, float y); - -protected: - void set_flag(uint32 flag) { m_nFlags |= flag; } - void clear_flag(uint32 flag) { m_nFlags &= ~flag; }; - bool is_flag(uint32 flag) const { return (m_nFlags & flag) == flag; } - - //dynamic movement - void StartMoving(float x, float y); - void StopMoving(); - -protected: - int m_id; - IMiniGUI* m_pGUI; - uint32 m_nFlags; - CryFixedStringT<32> m_title; - Rect m_rect; - _smart_ptr m_pParent; - std::vector m_subCtrls; - RenderCallback m_renderCallback; - float m_fTextSize; - - //optional close 'X' button on controls, ref counted by m_subCtrls - IMiniCtrl* m_pCloseButton; - - //dynamic movement - float m_prevX; - float m_prevY; - bool m_moving; - bool m_requiresResize; - bool m_saveStateOn; -}; - -////////////////////////////////////////////////////////////////////////// -class CMiniGUI - : public IMiniGUI - , public AzFramework::InputChannelEventListener -{ -public: - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(IMiniGUI) - CRYINTERFACE_END() - CRYGENERATE_SINGLETONCLASS(CMiniGUI, "MiniGUI", 0x1a049b879a4e4b58, 0xac14026e17e6255e) - -public: - void InitMetrics(); - void ProcessInput(); - - ////////////////////////////////////////////////////////////////////////// - // IMiniGUI interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void Init(); - virtual void Done(); - virtual void Draw(); - virtual void Reset(); - virtual void SaveState(); - virtual void RestoreState(); - virtual void SetEnabled(bool status); - virtual void SetInFocus(bool status); - virtual bool InFocus() {return m_inFocus; } - - virtual void SetEventListener(IMiniGUIEventListener* pListener); - - virtual SMetrics& Metrics(); - - virtual void OnCommand(SCommand& cmd); - - virtual void RemoveAllCtrl(); - virtual IMiniCtrl* CreateCtrl(IMiniCtrl* pParentCtrl, int nCtrlID, EMiniCtrlType type, int nCtrlFlags, const Rect& rc, const char* title); - - virtual IMiniCtrl* GetCtrlFromPoint(float x, float y) const; - - void SetHighlight(IMiniCtrl* pCtrl, bool bEnable, float x, float y); - void SetFocus(IMiniCtrl* pCtrl, bool bEnable); - - // AzFramework::InputChannelEventListener - bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override; - AZ::s32 GetPriority() const override { return AzFramework::InputChannelEventListener::GetPriorityUI(); } - - virtual void SetMovingCtrl(IMiniCtrl* pCtrl) - { - m_pMovingCtrl = pCtrl; - } - -protected: - void OnMouseInputEvent(const AzFramework::InputChannel& inputChannel); - - //DPad menu navigation - void UpdateDPadMenu(const AzFramework::InputChannel& inputChannel); - void SetDPadMenu(IMiniCtrl* pMenu); - void CloseDPadMenu(); - -protected: - bool m_enabled; - bool m_inFocus; - - SMetrics m_metrics; - - _smart_ptr m_pRootCtrl; - - _smart_ptr m_highlightedCtrl; - _smart_ptr m_focusCtrl; - - IMiniGUIEventListener* m_pEventListener; - - CMiniMenu* m_pDPadMenu; - IMiniCtrl* m_pMovingCtrl; - std::vector m_rootMenus; -}; - -MINIGUI_END - -#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIGUI_H diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniInfoBox.cpp b/Code/CryEngine/CrySystem/MiniGUI/MiniInfoBox.cpp deleted file mode 100644 index 74114b9156..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniInfoBox.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - - -#include "CrySystem_precompiled.h" -#include "MiniInfoBox.h" -#include "DrawContext.h" -#include - -MINIGUI_BEGIN - - -CMiniInfoBox::CMiniInfoBox() - : m_fTextIndent(4) -{ -} - -////////////////////////////////////////////////////////////////////////// -void CMiniInfoBox::SaveState() -{ - if (CheckFlag(eCtrl_Hidden)) - { - m_saveStateOn = false; - } - else - { - m_saveStateOn = true; - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniInfoBox::Reset() -{ - SetFlag(eCtrl_Hidden); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniInfoBox::RestoreState() -{ - if (m_saveStateOn) - { - ClearFlag(eCtrl_Hidden); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniInfoBox::OnPaint(CDrawContext& dc) -{ - if (m_requiresResize) - { - AutoResize(); - } - - ColorB borderCol = dc.Metrics().clrFrameBorder; - ColorB backgroundCol = dc.Metrics().clrBackground; - - if (!m_pGUI->InFocus()) - { - borderCol = dc.Metrics().clrFrameBorderOutOfFocus; - backgroundCol.a = dc.Metrics().outOfFocusAlpha; - } - else if (m_moving) - { - borderCol = dc.Metrics().clrFrameBorderHighlight; - } - - dc.DrawFrame(m_rect, borderCol, backgroundCol); - - dc.SetColor(dc.Metrics().clrTitle); - dc.DrawString(m_rect.left + 4, m_rect.top, dc.Metrics().fTitleSize, eTextAlign_Left, GetTitle()); - - float fTextSize = m_fTextSize; - if (fTextSize == 0) - { - fTextSize = dc.Metrics().fTextSize; - } - - float x = m_fTextIndent + m_rect.left + 8; - float y = m_rect.top + fTextSize + fTextSize; - // Draw entries. - for (int i = 0, num = (int)m_entries.size(); i < num; i++) - { - SInfoEntry& info = m_entries[i]; - dc.SetColor(info.color); - dc.DrawString(x, y, info.textSize, eTextAlign_Left, info.text); - y += info.textSize * 0.8f; - if (y + info.textSize > m_rect.bottom) - { - break; - } - } - - if (m_renderCallback) - { - m_renderCallback(m_rect.left, m_rect.top); - } -} - - -////////////////////////////////////////////////////////////////////////// -void CMiniInfoBox::OnEvent(float x, float y, EMiniCtrlEvent event) -{ - CMiniCtrl::OnEvent(x, y, event); -} - -void CMiniInfoBox::AddEntry(const char* str, ColorB col, float textSize) -{ - SInfoEntry info; - - info.color = col; - info.textSize = textSize; - cry_strcpy(info.text, str); - - m_entries.push_back(info); - - if (CheckFlag(eCtrl_AutoResize)) - { - //set dirty flag instead of resizing for every elem - m_requiresResize = true; //AutoResize(); - } -} - -void CMiniInfoBox::ClearEntries() -{ - m_entries.clear(); - m_requiresResize = true; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniInfoBox::AutoResize() -{ - float width = 0.f; - float height = 32.f; - - //must be at least the size of title and cross box - width = m_fTextIndent + ((float)m_title.size() * 14.f) + 30.f; - - for (int i = 0, num = (int)m_entries.size(); i < num; i++) - { - SInfoEntry& info = m_entries[i]; - - uint32 strLength = strlen(info.text); - - float strSize = info.textSize * strLength; - - width = max(strSize, width); - height += info.textSize * 0.8f; - } - - //scale width, could do with kerning info - width *= 0.6f; - - Rect newRect = m_rect; - newRect.right = newRect.left + width; - newRect.bottom = newRect.top + height; - - SetRect(newRect); - - m_requiresResize = false; -} - -MINIGUI_END diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniInfoBox.h b/Code/CryEngine/CrySystem/MiniGUI/MiniInfoBox.h deleted file mode 100644 index dbe8a668d6..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniInfoBox.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - -#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIINFOBOX_H -#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIINFOBOX_H -#pragma once - - -#include "MiniGUI.h" - -MINIGUI_BEGIN - -////////////////////////////////////////////////////////////////////////// -// Root window all other controls derive from -class CMiniInfoBox - : public CMiniCtrl - , public IMiniInfoBox -{ -public: - CMiniInfoBox(); - - ////////////////////////////////////////////////////////////////////////// - // CMiniCtrl interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual EMiniCtrlType GetType() const { return eCtrlType_InfoBox; } - virtual void OnPaint(CDrawContext& dc); - virtual void OnEvent(float x, float y, EMiniCtrlEvent event); - virtual void Reset(); - virtual void SaveState(); - virtual void RestoreState(); - virtual void AutoResize(); - ////////////////////////////////////////////////////////////////////////// - - virtual void SetTextIndent(float x) { m_fTextIndent = x; } - virtual void SetTextSize(float sz) { m_fTextSize = sz; } - virtual void ClearEntries(); - virtual void AddEntry(const char* str, ColorB col, float textSize); - - ////////////////////////////////////////////////////////////////////////// - // IMiniTable interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual bool IsHidden() { return CheckFlag(eCtrl_Hidden); } - virtual void Hide(bool stat) { SetVisible(!stat); } - -public: - - ////////////////////////////////////////////////////////////////////////// - - static const int MAX_TEXT_LENGTH = 64; - - struct SInfoEntry - { - char text[MAX_TEXT_LENGTH]; - ColorB color; - float textSize; - }; - ////////////////////////////////////////////////////////////////////////// - -protected: - - std::vector m_entries; - float m_fTextIndent; -}; - -MINIGUI_END - -#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIINFOBOX_H diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniMenu.cpp b/Code/CryEngine/CrySystem/MiniGUI/MiniMenu.cpp deleted file mode 100644 index f905f0f998..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniMenu.cpp +++ /dev/null @@ -1,364 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - - -#include "CrySystem_precompiled.h" -#include "MiniMenu.h" -#include "DrawContext.h" - -MINIGUI_BEGIN - - -CMiniMenu::CMiniMenu() -{ - m_bVisible = false; - m_bSubMenu = false; - m_menuWidth = 0.f; - m_selectionIndex = -1; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::OnPaint(CDrawContext& dc) -{ - CMiniButton::OnPaint(dc); - - if (m_bSubMenu) - { - // Draw checked mark. - float x1 = m_rect.right - 12; - float y1 = m_rect.top + 3; - - float x2 = m_rect.right - 3; - float y2 = (m_rect.bottom + m_rect.top) / 2; - - float x3 = m_rect.right - 12; - float y3 = m_rect.bottom - 3; - - dc.SetColor(ColorB(0, 0, 0, 255)); - - dc.DrawLine(x1, y1, x2, y2, 2.f); - dc.DrawLine(x2, y2, x3, y3, 2.f); - - x1 -= 1; - x2 -= 1; - x3 -= 1; - y1 -= 1; - y2 -= 1; - y3 -= 1; - - dc.SetColor(ColorB(255, 255, 255, 255)); - - dc.DrawLine(x1, y1, x2, y2, 2.f); - dc.DrawLine(x2, y2, x3, y3, 2.f); - } - - - //dc.DrawFrame( m_rect,dc.Metrics().clrFrameBorder,dc.Metrics().clrBackground ); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::SetRect(const Rect& rc) -{ - Rect newrc = rc; - newrc.bottom = newrc.top + m_pGUI->Metrics().fTitleSize + 2; - CMiniCtrl::SetRect(newrc); -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::OnEvent(float x, float y, EMiniCtrlEvent event) -{ - switch (event) - { - case eCtrlEvent_LButtonDown: - { - if (m_bVisible) - { - Close(); - } - else - { - Open(); - } - } - break; - case eCtrlEvent_MouseOff: - { - bool closeMenu = true; - IMiniCtrl* pCtrl = m_pGUI->GetCtrlFromPoint(x, y); - - //check if the cursor is still in one of the menu's children - if (pCtrl) - { - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - if (pCtrl == GetSubCtrl(i)) - { - closeMenu = false; - break; - } - } - } - - if (closeMenu) - { - Close(); - - if (m_pParent) - { - m_pParent->OnEvent(x, y, eCtrlEvent_MouseOff); - } - } - } - break; - } -} - -CMiniMenu* CMiniMenu::UpdateSelection(EMiniCtrlEvent event) -{ - CMiniMenu* pNewMenu = this; - IMiniCtrl* pCurrentSelection = NULL; - - if (m_selectionIndex != -1) - { - pCurrentSelection = m_subCtrls[m_selectionIndex]; - } - - switch (event) - { - case eCtrlEvent_DPadLeft: //move to parent - if (!pCurrentSelection) - { - //move to previous root menu - pNewMenu = NULL; - } - else if (m_bSubMenu) - { - Close(); - pNewMenu = (CMiniMenu*)m_pParent.get(); - //pNewMenu->SetFlag(eCtrl_Highlight); - } - break; - - case eCtrlEvent_DPadRight: //move to child - if (!pCurrentSelection) - { - //move to next root menu - pNewMenu = NULL; - } - else if (pCurrentSelection->GetType() == eCtrlType_Menu) - { - pNewMenu = (CMiniMenu*)pCurrentSelection; - pNewMenu->Open(); - pNewMenu->ClearFlag(eCtrl_Highlight); - } - break; - - case eCtrlEvent_DPadUp: //move up list - if (m_bSubMenu) - { - if (m_selectionIndex > 0) - { - m_selectionIndex--; - } - } - else - { - if (m_selectionIndex >= 0) - { - m_selectionIndex--; - - if (m_selectionIndex == -1) - { - SetFlag(eCtrl_Highlight); - } - } - } - break; - - case eCtrlEvent_DPadDown: //move down the list - if (m_selectionIndex < (int)(m_subCtrls.size() - 1)) - { - if (m_selectionIndex == -1) - { - ClearFlag(eCtrl_Highlight); - } - m_selectionIndex++; - } - break; - - case eCtrlEvent_LButtonDown: //pass on button press - { - if (pCurrentSelection) - { - if (pCurrentSelection->GetType() == eCtrlType_Menu) - { - pNewMenu = (CMiniMenu*)pCurrentSelection; - } - pCurrentSelection->OnEvent(0, 0, eCtrlEvent_LButtonDown); - } - else - { - OnEvent(0, 0, eCtrlEvent_LButtonDown); - } - } - break; - } - - if (pCurrentSelection) - { - pCurrentSelection->ClearFlag(eCtrl_Highlight); - } - - if (m_selectionIndex >= 0) - { - m_subCtrls[m_selectionIndex]->SetFlag(eCtrl_Highlight); - } - - return pNewMenu; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::Open() -{ - m_bVisible = true; - - Rect rc(0, 0, m_menuWidth, 1); - - //render sub menu to the right - if (m_bSubMenu) - { - CMiniMenu* pParent = static_cast(m_pParent.get()); - rc.left = pParent->m_menuWidth; //rcParent.right; - rc.right = rc.left + m_menuWidth; - } - else - { - Rect rcThis = GetRect(); - rc.top = rcThis.Height(); - } - - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->ClearFlag(eCtrl_Hidden); - float h = pSubCtrl->GetRect().Height(); - Rect rcCtrl = rc; - rcCtrl.top = rc.top; - rcCtrl.bottom = rcCtrl.top + h; - pSubCtrl->SetRect(rcCtrl); - rc.top += h; - } - - //highlight first item when opened - if (m_bSubMenu) - { - m_selectionIndex = 0; - m_subCtrls[m_selectionIndex]->SetFlag(eCtrl_Highlight); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::Close() -{ - m_bVisible = false; - - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->SetFlag(eCtrl_Hidden); - } - - if (m_selectionIndex != -1) - { - m_subCtrls[m_selectionIndex]->ClearFlag(eCtrl_Highlight); - } - m_selectionIndex = -1; -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::Reset() -{ - m_bVisible = false; - - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->Reset(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::SaveState() -{ - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->SaveState(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::RestoreState() -{ - for (int i = 0, num = GetSubCtrlCount(); i < num; i++) - { - IMiniCtrl* pSubCtrl = GetSubCtrl(i); - pSubCtrl->RestoreState(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CMiniMenu::AddSubCtrl(IMiniCtrl* pCtrl) -{ - assert(pCtrl); - pCtrl->SetFlag(eCtrl_Hidden); - pCtrl->SetFlag(eCtrl_NoBorder); - - bool bSubMenu = false; - - if (pCtrl->GetType() == eCtrlType_Menu) - { - CMiniMenu* pSubMenu = static_cast(pCtrl); - pSubMenu->m_bSubMenu = true; - bSubMenu = true; - } - - if (!m_bSubMenu) - { - //menu is at least the size of title bar - m_menuWidth = max(m_menuWidth, strlen(GetTitle()) * 8.5f); - } - - const char* title = pCtrl->GetTitle(); - - if (title) - { - uint32 titleLen = strlen(title); - - float width = (float)titleLen * 8.5f; - - if (bSubMenu) - { - //increase width for submenu arrow - width += 10.f; - } - - m_menuWidth = max(m_menuWidth, width); - } - - // Call parent - CMiniButton::AddSubCtrl(pCtrl); -} -MINIGUI_END diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniMenu.h b/Code/CryEngine/CrySystem/MiniGUI/MiniMenu.h deleted file mode 100644 index c288d840df..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniMenu.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - - -#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIMENU_H -#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIMENU_H -#pragma once - - -#include "MiniGUI.h" -#include "MiniButton.h" - -MINIGUI_BEGIN - -////////////////////////////////////////////////////////////////////////// -// Root window all other controls derive from -class CMiniMenu - : public CMiniButton -{ -public: - CMiniMenu(); - - ////////////////////////////////////////////////////////////////////////// - // CMiniCtrl interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual EMiniCtrlType GetType() const { return eCtrlType_Menu; } - virtual void SetRect(const Rect& rc); - virtual void OnPaint(CDrawContext& dc); - virtual void OnEvent(float x, float y, EMiniCtrlEvent event); - virtual void AddSubCtrl(IMiniCtrl* pCtrl); - virtual void Reset(); - virtual void SaveState(); - virtual void RestoreState(); - ////////////////////////////////////////////////////////////////////////// - - //digital selection funcs - CMiniMenu* UpdateSelection(EMiniCtrlEvent event); - - void Open(); - void Close(); - -protected: - -protected: - bool m_bVisible; - bool m_bSubMenu; - float m_menuWidth; - - int m_selectionIndex; -}; - -MINIGUI_END - -#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINIMENU_H diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniTable.cpp b/Code/CryEngine/CrySystem/MiniGUI/MiniTable.cpp deleted file mode 100644 index 6a306a2f9e..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniTable.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Table implementation in the MiniGUI - - -#include "CrySystem_precompiled.h" -#include "MiniTable.h" -#include "DrawContext.h" - -#include - -MINIGUI_BEGIN - -CMiniTable::CMiniTable() -{ - m_fTextSize = 15.f; - m_pageNum = 0; - m_pageSize = 35; -} - -void CMiniTable::OnPaint(CDrawContext& dc) -{ - if (m_requiresResize) - { - AutoResize(); - } - - ColorB borderCol; - ColorB backgroundCol = dc.Metrics().clrBackground; - - if (m_pGUI->InFocus()) - { - if (m_moving) - { - borderCol = dc.Metrics().clrFrameBorderHighlight; - } - else - { - borderCol = dc.Metrics().clrFrameBorder; - } - } - else - { - borderCol = dc.Metrics().clrFrameBorderOutOfFocus; - backgroundCol.a = dc.Metrics().outOfFocusAlpha; - } - - dc.DrawFrame(m_rect, borderCol, backgroundCol); - - float fTextSize = m_fTextSize; - if (fTextSize == 0) - { - fTextSize = dc.Metrics().fTextSize; - } - - float indent = 4.f; - - float x = m_rect.left + indent; - float y = m_rect.top + indent; - - const int nColumns = m_columns.size(); - int numEntries = nColumns > 0 ? m_columns[0].cells.size() : 0; - - int startIdx = 0; - int endIdx = numEntries; - - //Page number - if (nColumns) - { - int numPages = numEntries / m_pageSize; - - if (numPages) - { - startIdx = m_pageNum * m_pageSize; - endIdx = min(startIdx + m_pageSize, numEntries); - dc.SetColor(ColorB(255, 255, 255, 255)); - - //print page details (adjust for zero indexed) - dc.DrawString(x, y, fTextSize, eTextAlign_Left, "Page %d of %d (Page Up / Page Down)", m_pageNum + 1, numPages + 1); - y += fTextSize; - } - } - - float topOfTable = y; - - for (int i = 0; i < nColumns; i++) - { - SColumn& column = m_columns[i]; - - y = topOfTable; - - dc.SetColor(ColorB(32, 32, 255, 255)); - - dc.DrawString(x, y, fTextSize, eTextAlign_Left, column.name); - y += fTextSize + indent; - - ColorB currentCol(255, 255, 255, 255); - - dc.SetColor(currentCol); - - const int nCells = column.cells.size(); - - for (int j = startIdx; j < endIdx && j < nCells; j++) - { - if (column.cells[j].col != currentCol) - { - dc.SetColor(column.cells[j].col); - currentCol = column.cells[j].col; - } - - dc.DrawString(x, y, fTextSize, eTextAlign_Left, column.cells[j].text); - y += fTextSize; - } - - x += column.width; - } -} - -void CMiniTable::OnEvent(float x, float y, EMiniCtrlEvent event) -{ - //movement - CMiniCtrl::OnEvent(x, y, event); -} - -void CMiniTable::AutoResize() -{ - //must be at least the size of cross box - float tableWidth = 30.f; - - float tableHeight = 0.f; - const float widthScale = 0.6f; - const int nColumns = m_columns.size(); - - int startIdx = 0; - int endIdx = 0; - - bool bPageHeader = false; - - //Update Page index - if (nColumns) - { - int numEntries = m_columns[0].cells.size(); - - //page index is now invalid, cap at max - if ((m_pageNum * m_pageSize) > numEntries) - { - m_pageNum = (numEntries / m_pageSize); - } - - startIdx = m_pageNum * m_pageSize; - endIdx = min(startIdx + m_pageSize, numEntries); - - if (numEntries > m_pageSize) - { - bPageHeader = true; - } - } - - for (int i = 0; i < nColumns; i++) - { - SColumn& column = m_columns[i]; - - float width = strlen(column.name) * m_fTextSize; - - int nCells = column.cells.size(); - - for (int j = startIdx; j < endIdx && j < nCells; j++) - { - width = max(width, strlen(column.cells[j].text) * m_fTextSize); - } - - width *= widthScale; - - column.width = width; - tableWidth += width; - tableHeight = max(tableHeight, min(endIdx - startIdx, m_pageSize) * m_fTextSize); - } - - tableHeight += m_fTextSize * 2.f; - - //Page index - if (bPageHeader) - { - tableHeight += m_fTextSize; - } - - Rect newRect = m_rect; - - newRect.right = newRect.left + tableWidth; - newRect.bottom = newRect.top + tableHeight; - - SetRect(newRect); - - m_requiresResize = false; -} - -void CMiniTable::Reset() -{ - SetFlag(eCtrl_Hidden); - - m_pageNum = 0; -} - -void CMiniTable::SaveState() -{ - if (CheckFlag(eCtrl_Hidden)) - { - m_saveStateOn = false; - } - else - { - m_saveStateOn = true; - } -} - -void CMiniTable::RestoreState() -{ - if (m_saveStateOn) - { - ClearFlag(eCtrl_Hidden); - } -} - -int CMiniTable::AddColumn(const char* name) -{ - assert(name); - - SColumn col; - - cry_strcpy(col.name, name); - col.width = strlen(col.name) * 8.f; - - m_columns.push_back(col); - - m_requiresResize = true; - - return m_columns.size() - 1; -} - -void CMiniTable::RemoveColumns() -{ - m_columns.clear(); -} - -int CMiniTable::AddData(int columnIndex, ColorB col, const char* format, ...) -{ - assert(columnIndex < (int)m_columns.size()); - - SCell cell; - - va_list args; - va_start(args, format); - int written = vsnprintf_s(cell.text, MAX_TEXT_LENGTH, MAX_TEXT_LENGTH - 1, format, args); - va_end(args); - - if (written == -1) - { - cell.text[MAX_TEXT_LENGTH - 1] = '\0'; - } - - cell.col = col; - - m_columns[columnIndex].cells.push_back(cell); - - m_requiresResize = true; - - return m_columns[columnIndex].cells.size() - 1; -} - -void CMiniTable::ClearTable() -{ - const int nColumns = m_columns.size(); - - for (int i = 0; i < nColumns; i++) - { - m_columns[i].cells.clear(); - } -} - -void CMiniTable::SetVisible(bool state) -{ - if (state) - { - clear_flag(eCtrl_Hidden); - AzFramework::InputChannelEventListener::Connect(); - } - else - { - set_flag(eCtrl_Hidden); - AzFramework::InputChannelEventListener::Disconnect(); - } - - if (m_pCloseButton) - { - m_pCloseButton->SetVisible(state); - } -} - -void CMiniTable::Hide(bool stat) -{ - SetVisible(!stat); -} - -bool CMiniTable::OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) -{ - if (!IsHidden() && inputChannel.IsStateBegan()) - { - const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId(); - if (channelId == AzFramework::InputDeviceKeyboard::Key::NavigationPageUp) - { - m_pageNum++; - m_requiresResize = true; - } - else if (channelId == AzFramework::InputDeviceKeyboard::Key::NavigationPageDown) - { - if (m_pageNum > 0) - { - m_pageNum--; - m_requiresResize = true; - } - } - } - return false; -} -MINIGUI_END diff --git a/Code/CryEngine/CrySystem/MiniGUI/MiniTable.h b/Code/CryEngine/CrySystem/MiniGUI/MiniTable.h deleted file mode 100644 index fb89aca2dc..0000000000 --- a/Code/CryEngine/CrySystem/MiniGUI/MiniTable.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Table implementation in the MiniGUI - - -#ifndef CRYINCLUDE_CRYSYSTEM_MINIGUI_MINITABLE_H -#define CRYINCLUDE_CRYSYSTEM_MINIGUI_MINITABLE_H -#pragma once - - -#include "MiniGUI.h" - -MINIGUI_BEGIN - -class CMiniTable - : public CMiniCtrl - , public IMiniTable - , public AzFramework::InputChannelEventListener -{ -public: - CMiniTable(); - - ////////////////////////////////////////////////////////////////////////// - // CMiniCtrl interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual EMiniCtrlType GetType() const { return eCtrlType_Table; } - virtual void OnPaint(CDrawContext& dc); - virtual void OnEvent(float x, float y, EMiniCtrlEvent event); - virtual void Reset(); - virtual void SaveState(); - virtual void RestoreState(); - virtual void AutoResize(); - virtual void SetVisible(bool state); - - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // IMiniTable interface implementation. - ////////////////////////////////////////////////////////////////////////// - - //Add a new column to the table, return column index - virtual int AddColumn(const char* name); - - //Remove all columns an associated data - virtual void RemoveColumns(); - - //Add data to specified column (add onto the end), return row index - virtual int AddData(int columnIndex, ColorB col, const char* format, ...); - - //Clear all data from table - virtual void ClearTable(); - - virtual bool IsHidden() { return CheckFlag(eCtrl_Hidden); } - - virtual void Hide(bool stat); - - // AzFramework::InputChannelEventListener - bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override; - AZ::s32 GetPriority() const override { return AzFramework::InputChannelEventListener::GetPriorityUI(); } - - static const int MAX_TEXT_LENGTH = 64; - -protected: - - struct SCell - { - char text[MAX_TEXT_LENGTH]; - ColorB col; - }; - - struct SColumn - { - char name[MAX_TEXT_LENGTH]; - float width; - std::vector cells; - }; - - std::vector m_columns; - int m_pageSize; - int m_pageNum; -}; - -MINIGUI_END - -#endif // CRYINCLUDE_CRYSYSTEM_MINIGUI_MINITABLE_H diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec.cpp b/Code/CryEngine/CrySystem/MobileDetectSpec.cpp deleted file mode 100644 index 342537daeb..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include -#include - -#include "MobileDetectSpec.h" - -namespace MobileSysInspect -{ - struct GpuApiPair - { - AZStd::string gpuDescription; - AZStd::string apiDescription; - }; - - AZStd::vector> deviceSpecMapping; - AZStd::vector> gpuSpecMapping; - const float LOW_SPEC_RAM = 1.0f; - const float MEDIUM_SPEC_RAM = 2.0f; - const float HIGH_SPEC_RAM = 3.0f; - - bool GetSpecForGPUAndAPI(const AZStd::string& gpuName, const AZStd::string& apiDescription, AZStd::string& specName) - { - for (const auto& descriptionSpecPair : gpuSpecMapping) - { - const GpuApiPair& currentPair = descriptionSpecPair.first; - AZStd::regex currentRegex(currentPair.gpuDescription.c_str()); - if (!AZStd::regex_search(gpuName, currentRegex)) - { - continue; - } - - currentRegex.assign(currentPair.apiDescription.c_str()); - if (!currentRegex.Empty() && !AZStd::regex_search(apiDescription, currentRegex)) - { - continue; - } - - specName = descriptionSpecPair.second; - return true; - } - - return false; - } - - namespace Internal - { - void LoadDeviceSpecMapping_impl(const char* filename) - { - XmlNodeRef xmlNode = GetISystem()->LoadXmlFromFile(filename); - - if (!xmlNode) - { - return; - } - - const int fileCount = xmlNode->getChildCount(); - - for (int i = 0; i < fileCount; ++i) - { - XmlNodeRef fileNode = xmlNode->getChild(i); - AZStd::string file = fileNode->getAttr("file"); - - if (!file.empty()) - { - const int mappingCount = fileNode->getChildCount(); - - deviceSpecMapping.reserve(mappingCount); - - for (int j = 0; j < mappingCount; ++j) - { - XmlNodeRef modelNode = fileNode->getChild(j); - AZStd::string model = modelNode->getAttr("model"); - - if (!model.empty()) - { - deviceSpecMapping.push_back(AZStd::make_pair(model, file)); - } - } - } - } - } - - void LoadGpuSpecMapping_impl(const char* filename) - { - XmlNodeRef xmlNode = GetISystem()->LoadXmlFromFile(filename); - - if (!xmlNode) - { - return; - } - - const int fileCount = xmlNode->getChildCount(); - - for (int i = 0; i < fileCount; ++i) - { - XmlNodeRef fileNode = xmlNode->getChild(i); - AZStd::string file = fileNode->getAttr("file"); - - if (!file.empty()) - { - const int mappingCount = fileNode->getChildCount(); - - gpuSpecMapping.reserve(mappingCount); - - for (int j = 0; j < mappingCount; ++j) - { - XmlNodeRef modelNode = fileNode->getChild(j); - GpuApiPair gpuApiPair; - gpuApiPair.gpuDescription = modelNode->getAttr("gpuName"); - gpuApiPair.apiDescription = modelNode->getAttr("apiVersion"); - - if (!gpuApiPair.gpuDescription.empty() || !gpuApiPair.apiDescription.empty()) - { - gpuSpecMapping.push_back(AZStd::make_pair(gpuApiPair, file)); - } - } - } - } - } - - bool GetSpecForModelName(const AZStd::string& modelName, AZStd::string& specName) - { - for (const auto& descriptionSpecPair : deviceSpecMapping) - { - AZStd::regex currentRegex(descriptionSpecPair.first.c_str()); - if (AZStd::regex_search(modelName, currentRegex)) - { - specName = descriptionSpecPair.second; - return true; - } - } - - return false; - } - - } // namespace Internal -} // namespace MobileSysInspect diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec.h b/Code/CryEngine/CrySystem/MobileDetectSpec.h deleted file mode 100644 index bbb15d301a..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "AzCore/std/containers/unordered_map.h" - -namespace MobileSysInspect -{ - extern const float LOW_SPEC_RAM; - extern const float MEDIUM_SPEC_RAM; - extern const float HIGH_SPEC_RAM; - - void LoadDeviceSpecMapping(); - bool GetAutoDetectedSpecName(AZStd::string &buffer); - bool GetSpecForGPUAndAPI(const AZStd::string& gpuName, const AZStd::string& apiDescription, AZStd::string& specName); - const float GetDeviceRamInGB(); - - namespace Internal - { - void LoadDeviceSpecMapping_impl(const char* fileName); - void LoadGpuSpecMapping_impl(const char* filename); - bool GetSpecForModelName(const AZStd::string& modelName, AZStd::string& specName); - } -} diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec_Android.cpp b/Code/CryEngine/CrySystem/MobileDetectSpec_Android.cpp deleted file mode 100644 index 181200d383..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec_Android.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include -#include - -#include "MobileDetectSpec.h" - -namespace MobileSysInspect -{ - void LoadDeviceSpecMapping() - { - Internal::LoadDeviceSpecMapping_impl("@assets@/config/gpu/android_models.xml"); - Internal::LoadGpuSpecMapping_impl("@assets@/config/gpu/android_gpus.xml"); - } - - // Returns true if device is found in the device spec mapping - bool GetAutoDetectedSpecName(AZStd::string &buffer) - { - static constexpr const char* s_javaFieldName = "MODEL"; - AZ::Android::JNI::Object obj("android/os/Build"); - obj.RegisterStaticField(s_javaFieldName, "Ljava/lang/String;"); - AZStd::string name = obj.GetStaticStringField(s_javaFieldName); - - return Internal::GetSpecForModelName(name, buffer); - } - - const float GetDeviceRamInGB() - { - static constexpr const char* s_javaFuntionNameGetDeviceRamInGB = "GetDeviceRamInGB"; - AZ::Android::JNI::Object obj("com/amazon/lumberyard/AndroidDeviceManager"); - obj.RegisterStaticMethod(s_javaFuntionNameGetDeviceRamInGB, "()F"); - return obj.InvokeStaticFloatMethod(s_javaFuntionNameGetDeviceRamInGB); - } -} diff --git a/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp b/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp deleted file mode 100644 index 1f3275f1c6..0000000000 --- a/Code/CryEngine/CrySystem/MobileDetectSpec_Ios.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include - -#include "MobileDetectSpec.h" -#include "SystemUtilsApple.h" - -namespace MobileSysInspect -{ - void LoadDeviceSpecMapping() - { - Internal::LoadDeviceSpecMapping_impl("@assets@/config/gpu/ios_models.xml"); - } - - // Returns true if device is found in the device spec mapping - bool GetAutoDetectedSpecName(AZStd::string &buffer) - { - AZStd::string name = SystemUtilsApple::GetMachineName(); - - return Internal::GetSpecForModelName(name, buffer); - } - - const float GetDeviceRamInGB() - { - // not supported on this platform - return 0.0f; - } -} diff --git a/Code/CryEngine/CrySystem/NotificationNetwork.cpp b/Code/CryEngine/CrySystem/NotificationNetwork.cpp deleted file mode 100644 index a0bd3fb9e6..0000000000 --- a/Code/CryEngine/CrySystem/NotificationNetwork.cpp +++ /dev/null @@ -1,1345 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "NotificationNetwork.h" -#include - -#include -#include - -#undef LockDebug -//#define LockDebug(str1,str2) {string strMessage;strMessage.Format(str1,str2);if (m_clients.size()) OutputDebugString(strMessage.c_str());} -#define LockDebug(str1, str2) - -// - -extern bool RCON_IsRemoteAllowedToConnect(const AZ::AzSock::AzSocketAddress& connectee); - -using namespace NotificationNetwork; - -// - -#include -class CQueryNotification - : public INotificationNetworkListener -{ - // INotificationNetworkListener -public: - virtual void OnNotificationNetworkReceive([[maybe_unused]] const void* pBuffer, [[maybe_unused]] size_t length) - { - INotificationNetwork* pNotificationNetwork = - gEnv->pSystem->GetINotificationNetwork(); - if (!pNotificationNetwork) - { - return; - } - - AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath(); - if (projectPath.empty()) - { - return; - } - - pNotificationNetwork->Send("SystemInfo", projectPath.c_str(), projectPath.size()); - } -} g_queryNotification; - -AZSOCKET CConnectionBase::CreateSocket() -{ - AZSOCKET sock = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - CryLog("CNotificationNetworkClient::Create: Failed to create socket."); - return AZ_SOCKET_INVALID; - } - - if (AZ::AzSock::SetSocketOption(sock, AZ::AzSock::AzSocketOption::REUSEADDR, true)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Create: Failed to set SO_REUSEADDR option."); - return AZ_SOCKET_INVALID; - } - -#if defined (WIN32) || defined(WIN64) //MS Platforms - if (AZ::AzSock::SetSocketBlockingMode(sock, false)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Connect: Failed to set socket to asynchronous operation."); - return AZ_SOCKET_INVALID; - } - -#endif - - // TCP_NODELAY required for win32 because of high latency connection otherwise -#if defined(WIN32) - if (AZ::AzSock::EnableTCPNoDelay(sock, true)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Create: Failed to set TCP_NODELAY option."); - return AZ_SOCKET_INVALID; - } -#endif - - return sock; -} - -bool CConnectionBase::Connect(const char* address, uint16 port) -{ - AZ::AzSock::AzSocketAddress socketAddress; - socketAddress.SetAddress(address, port); - - int result = AZ::AzSock::Connect(m_socket, socketAddress); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ::AzSock::AzSockError err = AZ::AzSock::AzSockError(result); - if (err == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK_CONN) - { - return true; - } - - if (err == AZ::AzSock::AzSockError::eASE_EISCONN) - { - if (!m_boIsConnected) - { - m_boIsConnected = true; - m_boIsFailedToConnect = false; - OnConnect(true); - } - return true; - } - - if (err == AZ::AzSock::AzSockError::eASE_EALREADY) - { - // It will happen, in case of DNS problems, or if the console is not - // reachable or turned off. - //CryLog("CNotificationNetworkClient::Connect: Failed to connect. Reason: already conencted."); - return true; - } - - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - CryLog("CNotificationNetworkClient::Connect: Failed to connect. Reason: %d ", result); - return false; - } - - return true; -} - -/* - - CChannel - -*/ - -bool CChannel::IsNameValid(const char* name) -{ - if (!name) - { - return false; - } - if (!*name) - { - return false; - } - - if (::strlen(name) > NN_CHANNEL_NAME_LENGTH_MAX) - { - return false; - } - - return true; -} - -// - -CChannel::CChannel() -{ -} - -CChannel::CChannel(const char* name) -{ - if (!name) - { - return; - } - - if (!*name) - { - return; - } - - size_t length = MIN(::strlen(name), NN_CHANNEL_NAME_LENGTH_MAX); - ::memset(m_name, 0, NN_CHANNEL_NAME_LENGTH_MAX); - ::memcpy(m_name, name, length); -} - -CChannel::~CChannel() -{ -} - -// - -void CChannel::WriteToPacketHeader(void* pPacket) const -{ - ::memcpy((uint8*)pPacket + NN_PACKET_HEADER_OFFSET_CHANNEL, - m_name, NN_CHANNEL_NAME_LENGTH_MAX); -} - -void CChannel::ReadFromPacketHeader(void* pPacket) -{ - ::memcpy(m_name, (uint8*)pPacket + NN_PACKET_HEADER_OFFSET_CHANNEL, - NN_CHANNEL_NAME_LENGTH_MAX); -} - -// - -bool CChannel::operator ==(const CChannel& channel) const -{ - return ::strncmp(m_name, channel.m_name, NN_CHANNEL_NAME_LENGTH_MAX) == 0; -} - -bool CChannel::operator !=(const CChannel& channel) const -{ - return ::strncmp(m_name, channel.m_name, NN_CHANNEL_NAME_LENGTH_MAX) != 0; -} - -/* - - CListeners - -*/ - -CListeners::CListeners() -{ - m_pNotificationWrite = &m_notifications[0]; - m_pNotificationRead = &m_notifications[1]; -} - -CListeners::~CListeners() -{ - while (!m_pNotificationRead->empty()) - { - SBuffer buffer = m_pNotificationRead->front(); - m_pNotificationRead->pop(); - delete[] buffer.pData; - } - - while (!m_pNotificationWrite->empty()) - { - SBuffer buffer = m_pNotificationWrite->front(); - m_pNotificationWrite->pop(); - delete[] buffer.pData; - } -} - -// - -size_t CListeners::Count(const CChannel& channel) -{ - size_t count = 0; - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].second != channel) - { - continue; - } - - ++count; - } - - return count; -} - -CChannel* CListeners::Channel(INotificationNetworkListener* pListener) -{ - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].first != pListener) - { - continue; - } - - return &m_listeners[i].second; - } - - return nullptr; -} - -bool CListeners::Bind(const CChannel& channel, INotificationNetworkListener* pListener) -{ - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].first == pListener) - { - m_listeners[i].second = channel; - return true; - } - } - - m_listeners.push_back(std::pair()); - m_listeners.back().first = pListener; - m_listeners.back().second = channel; - return true; -} - -bool CListeners::Remove(INotificationNetworkListener* pListener) -{ - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].first != pListener) - { - continue; - } - - m_listeners[i] = m_listeners.back(); - m_listeners.pop_back(); - return true; - } - - return false; -} - -void CListeners::NotificationPush(const SBuffer& buffer) -{ - // TODO: Use auto lock. - m_notificationCriticalSection.Lock(); - m_pNotificationWrite->push(buffer); - m_notificationCriticalSection.Unlock(); -} - -void CListeners::NotificationsProcess() -{ - m_notificationCriticalSection.Lock(); - std::swap(m_pNotificationWrite, m_pNotificationRead); - m_notificationCriticalSection.Unlock(); - - while (!m_pNotificationRead->empty()) - { - SBuffer buffer = m_pNotificationRead->front(); - m_pNotificationRead->pop(); - - for (size_t i = 0; i < m_listeners.size(); ++i) - { - if (m_listeners[i].second != buffer.channel) - { - continue; - } - - m_listeners[i].first->OnNotificationNetworkReceive( - buffer.pData, buffer.length); - } - - delete[] buffer.pData; - } -} - -/* - - CConnectionBase - -*/ - -CConnectionBase::CConnectionBase(CNotificationNetwork* pNotificationNetwork) -{ - m_pNotificationNetwork = pNotificationNetwork; - - m_port = 0; - - m_socket = AZ_SOCKET_INVALID; - - m_buffer.pData = nullptr; - m_buffer.length = 0; - m_dataLeft = 0; - - m_boIsConnected = false; - m_boIsFailedToConnect = false; -} - -CConnectionBase::~CConnectionBase() -{ - if (m_buffer.pData) - { - delete[] m_buffer.pData; - } - - if (m_socket != AZ_SOCKET_INVALID) - { - CloseSocket_Internal(); - } -} - -// - -void CConnectionBase::SetAddress(const char* address, uint16 port) -{ - size_t length = MIN(::strlen(address), 15); - ::memset(m_address, 0, sizeof(m_address)); - ::memcpy(m_address, address, length); - m_port = port; -} - -bool CConnectionBase::Validate() -{ - if (m_socket != AZ_SOCKET_INVALID) - { - if (!m_port) - { - AZ::AzSock::AzSocketAddress socketAddress; - int result = AZ::AzSock::GetSockName(m_socket, socketAddress); - if (AZ::AzSock::SocketErrorOccured(result)) - { - return false; - } - } - - return Select_Internal(); - } - - if (!m_port) // If port is not set we don't want to try to reconnect. - { - return false; - } - - m_socket = CreateSocket(); - // If the create sockect will fail, it is likely that we will never be able to connect, - // we might want to signal that. - - Connect(m_address, m_port); - - return false; -} - -bool CConnectionBase::Send(const void* pBuffer, size_t length) -{ - if (!Validate()) - { - return false; - } - - size_t sent = 0; - while (sent < length) - { - int r = AZ::AzSock::Send(m_socket, (const char*)pBuffer + sent, length - sent, 0); - if (AZ::AzSock::SocketErrorOccured(r)) - { - AZ::AzSock::AzSockError nCurrentError = AZ::AzSock::AzSockError(r); - if (nCurrentError == AZ::AzSock::AzSockError::eASE_ENOTCONN) - { - r = 0; - break; - } - else if (nCurrentError == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK) - { - r = 0; - } - else - { - CryLog("CNotificationNetworkClient::Send: Failed to send package. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - return false; - } - } - - sent += r; - } - - return true; -} - -bool CConnectionBase::SendMessage(EMessage eMessage, const CChannel& channel, uint32 data) -{ - char header[NN_PACKET_HEADER_LENGTH]; - ::memset(header, 0, NN_PACKET_HEADER_LENGTH); - *(uint32*)&header[NN_PACKET_HEADER_OFFSET_MESSAGE] = AZ::AzSock::HostToNetLong(eMessage); - *(uint32*)&header[NN_PACKET_HEADER_OFFSET_DATA_LENGTH] = AZ::AzSock::HostToNetLong(data); - channel.WriteToPacketHeader(header); - - if (!Send(header, NN_PACKET_HEADER_LENGTH)) - { - return false; - } - - return true; -} - -bool CConnectionBase::Select_Internal() -{ - if (m_socket == AZ_SOCKET_INVALID) - { - return false; - } - - AZFD_SET stExceptions; - AZFD_SET stWriteSockets; - - FD_ZERO(&stExceptions); - FD_SET(m_socket, &stExceptions); - - FD_ZERO(&stWriteSockets); - FD_SET(m_socket, &stWriteSockets); - - AZTIMEVAL timeOut = { 0, 0 }; - - int r = AZ::AzSock::Select(m_socket, nullptr, &stWriteSockets, &stExceptions, &timeOut); - if (AZ::AzSock::SocketErrorOccured(r)) - { - CryLog("CNotificationNetworkClient:: Failed to select socket. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - m_boIsFailedToConnect = true; - return false; - } - else if (!r) - { - return m_boIsConnected; - } - - if (FD_ISSET(m_socket, &stExceptions)) - { - CloseSocket_Internal(); - m_boIsFailedToConnect = true; - OnConnect(m_boIsConnected); // Handles failed attempt to connect. - return false; - } - else if (FD_ISSET(m_socket, &stWriteSockets)) // In Windows a socket can be in both lists. - { - if (!m_boIsConnected) - { - m_boIsConnected = true; - m_boIsFailedToConnect = false; - OnConnect(m_boIsConnected); // Handles successful attempt to connect. - } - return true; - } - - return false; -} - -void CConnectionBase::CloseSocket_Internal() -{ - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - if (m_boIsConnected) - { - OnDisconnect(); - } - m_boIsConnected = false; -} - -bool CConnectionBase::SendNotification(const CChannel& channel, const void* pBuffer, size_t length) -{ - if (!SendMessage(eMessage_DataTransfer, channel, length)) - { - return false; - } - if (!length) - { - return true; - } - - if (!Send(pBuffer, length)) - { - return false; - } - - return true; -} - -bool CConnectionBase::ReceiveMessage(CListeners& listeners) -{ - if (!Validate()) - { - return false; - } - - if (!m_dataLeft) - { - m_dataLeft = NN_PACKET_HEADER_LENGTH; - } - int r = AZ::AzSock::Recv(m_socket, (char*)&m_bufferHeader[NN_PACKET_HEADER_LENGTH - m_dataLeft], m_dataLeft, 0); - if (!r) - { - // Connection terminated. - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - if (AZ::AzSock::SocketErrorOccured(r)) - { - m_dataLeft = 0; - - CryLog("CNotificationNetworkClient::ReceiveMessage: Failed to receive package. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - return false; - } - - if (m_dataLeft -= r) - { - return true; - } - - // The whole message was received, process it... - - EMessage eMessage = (EMessage)AZ::AzSock::NetToHostLong( - *(uint32*)&m_bufferHeader[NN_PACKET_HEADER_OFFSET_MESSAGE]); - const CChannel& channel = *(CChannel*)&m_bufferHeader[NN_PACKET_HEADER_OFFSET_CHANNEL]; - - if (eMessage == eMessage_DataTransfer) - { - m_dataLeft = AZ::AzSock::NetToHostLong(*(uint32*)&m_bufferHeader[NN_PACKET_HEADER_OFFSET_DATA_LENGTH]); - if (!m_dataLeft) - { - SBuffer buffer; - buffer.channel = channel; - buffer.pData = nullptr; - buffer.length = 0; - listeners.NotificationPush(buffer); - return true; - } - - m_buffer.pData = new uint8[m_buffer.length = m_dataLeft]; - if (!m_buffer.pData) - { - CryLog("CNotificationNetwork::CConnection::Receive: Failed to allocate buffer.\n"); - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - - m_buffer.channel.ReadFromPacketHeader(m_bufferHeader); - return +1; - } - - if (!OnMessage(eMessage, channel)) - { - CryLog("NotificationNetwork::CConnectionBase::ReceiveMessage: " - "Unknown message received, terminating Connection...\n"); - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - - return true; -} - -bool CConnectionBase::ReceiveNotification(CListeners& listeners) -{ - int r = AZ::AzSock::Recv(m_socket, (char*)&m_buffer.pData[m_buffer.length - m_dataLeft], m_dataLeft, 0); - if (!r) - { - CryLog("CNotificationNetworkClient::ReceiveNotification: Failed to receive package. Reason: Connection terminated."); - // Connection terminated. - m_dataLeft = 0; - - CloseSocket_Internal(); - return false; - } - - if (AZ::AzSock::SocketErrorOccured(r)) - { - m_dataLeft = 0; - - CryLog("CNotificationNetworkClient::ReceiveNotification: Failed to receive package. Reason: %s", AZ::AzSock::GetStringForError(r)); - CloseSocket_Internal(); - return false; - } - - if (m_dataLeft -= r) - { - return true; - } - - listeners.NotificationPush(m_buffer); - m_buffer.pData = nullptr; - m_buffer.length = 0; - m_dataLeft = 0; - return true; -} - -bool CConnectionBase::Receive(CListeners& listeners) -{ - if (m_buffer.pData) - { - return ReceiveNotification(listeners); - } - - return ReceiveMessage(listeners); -} - -bool CConnectionBase::GetIsConnectedFlag() -{ - return Select_Internal() || m_boIsConnected; -} - -bool CConnectionBase::GetIsFailedToConnectFlag() const -{ - return m_boIsFailedToConnect; -} - -/* - - CClient - -*/ - -CClient* CClient::Create(CNotificationNetwork* pNotificationNetwork, const char* address, uint16 port) -{ - CClient* pClient = new CClient(pNotificationNetwork); - AZSOCKET sock = pClient->CreateSocket(); - // In the current implementation, this is REALLY UNLIKELY to happen. - if (sock == AZ_SOCKET_INVALID) - { - delete pClient; - return nullptr; - } - - // - pClient->SetSocket(sock); - pClient->Connect(address, port); - - pClient->SetAddress(address, port); - pClient->SetSocket(sock); - return pClient; -} - -CClient* CClient::Create(CNotificationNetwork* pNotificationNetwork) -{ - CClient* pClient = new CClient(pNotificationNetwork); - return pClient; -} - -// - -CClient::CClient(CNotificationNetwork* pNotificationNetwork) - : CConnectionBase(pNotificationNetwork) -{ -} - -CClient::~CClient() -{ - GetNotificationNetwork()->ReleaseClients(this); -} - -// - -void CClient::Update() -{ - m_listeners.NotificationsProcess(); -} - -// CConnectionBase - -bool CClient::OnConnect(bool boConnected) -{ - if (boConnected) - { - for (size_t i = 0; i < m_listeners.Count(); ++i) - { - if (!SendMessage(eMessage_ChannelRegister, m_listeners.Channel(i), 0)) - { - return false; - } - } - } - - CryAutoLock lock(m_stConnectionCallbacksLock); - for (size_t nCount = 0; nCount < m_cNotificationNetworkConnectionCallbacks.size(); ++nCount) - { - m_cNotificationNetworkConnectionCallbacks[nCount]->OnConnect(this, boConnected); - } - - return boConnected; -} - -bool CClient::OnDisconnect() -{ - CryAutoLock lock(m_stConnectionCallbacksLock); - for (size_t nCount = 0; nCount < m_cNotificationNetworkConnectionCallbacks.size(); ++nCount) - { - m_cNotificationNetworkConnectionCallbacks[nCount]->OnDisconnected(this); - } - - return true; -} - -bool CClient::OnMessage([[maybe_unused]] EMessage eMessage, [[maybe_unused]] const CChannel& channel) -{ - return false; -} - -// INotificationNetworkClient - -bool CClient::Connect(const char* address, uint16 port) -{ - bool bReturnValue(false); - - if (m_socket == AZ_SOCKET_INVALID) - { - m_socket = CreateSocket(); - } - - bReturnValue = CConnectionBase::Connect(address, port); - if (bReturnValue) - { - SetAddress(address, port); - } - - return bReturnValue; -} - -bool CClient::ListenerBind(const char* channelName, INotificationNetworkListener* pListener) -{ - if (!CChannel::IsNameValid(channelName)) - { - return false; - } - - if (!m_listeners.Bind(CChannel(channelName), pListener)) - { - return false; - } - - if (!SendMessage(eMessage_ChannelRegister, CChannel(channelName), 0)) - { - return false; - } - - return true; -} - -bool CClient::ListenerRemove(INotificationNetworkListener* pListener) -{ - CChannel* pChannel = m_listeners.Channel(pListener); - if (!pChannel) - { - return false; - } - - if (!m_listeners.Remove(pListener)) - { - return false; - } - - if (!SendMessage(eMessage_ChannelUnregister, *pChannel, 0)) - { - return false; - } - - return true; -} - -bool CClient::Send(const char* channelName, const void* pBuffer, size_t length) -{ - CRY_ASSERT(CChannel::IsNameValid(channelName)); - // CRY_ASSERT_MESSAGE(channelLength <= NN_CHANNEL_NAME_LENGTH_MAX, - // "Channel name \"%s\" was passed to a Notification Network method, the name cannot be longer than %d chars.", - // channel, NN_CHANNEL_NAME_LENGTH_MAX); - - if (!CChannel::IsNameValid(channelName)) - { - return false; - } - if (!SendNotification(CChannel(channelName), pBuffer, length)) - { - return false; - } - - return true; -} - -bool CClient::RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) -{ - CryAutoLock lock(m_stConnectionCallbacksLock); - return stl::push_back_unique(m_cNotificationNetworkConnectionCallbacks, pConnectionCallback); -} - -bool CClient::UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) -{ - CryAutoLock lock(m_stConnectionCallbacksLock); - return stl::find_and_erase(m_cNotificationNetworkConnectionCallbacks, pConnectionCallback); -} - -/* - - CNotificationNetwork::CConnection - -*/ - -CNotificationNetwork::CConnection::CConnection(CNotificationNetwork* pNotificationNetwork, AZSOCKET sock) - : CConnectionBase(pNotificationNetwork) -{ - SetSocket(sock); - m_listeningChannels.reserve(8); -} - -CNotificationNetwork::CConnection::~CConnection() -{ -} - -// - -bool CNotificationNetwork::CConnection::IsListening(const CChannel& channel) -{ - for (size_t i = 0; i < m_listeningChannels.size(); ++i) - { - if (m_listeningChannels[i] == channel) - { - return true; - } - } - - return false; -} - -// CConnectionBase - -bool CNotificationNetwork::CConnection::OnMessage(EMessage eMessage, const CChannel& channel) -{ - switch (eMessage) - { - case eMessage_ChannelRegister: - for (size_t i = 0; i < m_listeningChannels.size(); ++i) - { - if (m_listeningChannels[i] == channel) - { - return true; - } - } - m_listeningChannels.push_back(channel); - return true; - - case eMessage_ChannelUnregister: - for (size_t i = 0; i < m_listeningChannels.size(); ++i) - { - if (m_listeningChannels[i] != channel) - { - continue; - } - - m_listeningChannels[i] = m_listeningChannels.back(); - m_listeningChannels.pop_back(); - return true; - } - return true; - } - - return false; -} - -/* - - CNotificationNetwork::CThread - -*/ - -CNotificationNetwork::CThread::CThread() -{ - m_pNotificationNetwork = nullptr; - m_bRun = true; -} - -CNotificationNetwork::CThread::~CThread() -{ -} - -// - -bool CNotificationNetwork::CThread::Begin(CNotificationNetwork* pNotificationNetwork) -{ - m_pNotificationNetwork = pNotificationNetwork; - Start(-1, (char*)NN_THREAD_NAME); - return true; -} - - -void CNotificationNetwork::CThread::End() -{ - m_bRun = false; - // WaitForThread(); - - // TODO: Should properly close! -} - -// CryRunnable - -void CNotificationNetwork::CThread::Run() -{ - CryThreadSetName(threadID(THREADID_NULL), NN_THREAD_NAME); - while (m_bRun) - { - m_pNotificationNetwork->ProcessSockets(); - } -} - -/* - - CNotificationNetwork - -*/ - -CNotificationNetwork* CNotificationNetwork::Create() -{ - AZ::AzSock::Startup(); - - AZSOCKET sock = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - CryLog("CNotificationNetwork::Create: Failed to create socket.\n"); - return nullptr; - } - - // Disable nagling of small blocks to fight high latency connection - int result = AZ::AzSock::EnableTCPNoDelay(sock, true); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Create: Failed to set TCP_NODELAY option."); - return nullptr; - } - - result = AZ::AzSock::SetSocketBlockingMode(sock, false); - if (AZ::AzSock::SocketErrorOccured(result)) - { - AZ::AzSock::CloseSocket(sock); - CryLog("CNotificationNetworkClient::Connect: Failed to set socket to asynchronous operation."); - return nullptr; - } - - // Editor uses a different port to avoid conflicts when running both editor and game on same PC - // But allows the lua remote debugger to connect to the editor - unsigned short port = gEnv && gEnv->IsEditor() ? 9433 : 9432; - - AZ::AzSock::AzSocketAddress addr; - addr.SetAddrPort(port); - - result = AZ::AzSock::Bind(sock, addr); - if (AZ::AzSock::SocketErrorOccured(result)) - { - CryLog("CNotificationNetwork::Create: Failed to bind socket.\n"); - AZ::AzSock::CloseSocket(sock); - return nullptr; - } - - result = AZ::AzSock::Listen(sock, 8); - if (AZ::AzSock::SocketErrorOccured(result)) - { - CryLog("CNotificationNetwork::Create: Failed to listen.\n"); - AZ::AzSock::CloseSocket(sock); - return nullptr; - } - - CNotificationNetwork* pNotificationNetwork = new CNotificationNetwork(); - pNotificationNetwork->m_socket = sock; - - pNotificationNetwork->m_thread.Begin(pNotificationNetwork); - - return pNotificationNetwork; -} - -// - -CNotificationNetwork::CNotificationNetwork() -{ - m_socket = AZ_SOCKET_INVALID; - - m_connections.reserve(4); - - m_listeners.Bind("Query", &g_queryNotification); -} - -CNotificationNetwork::~CNotificationNetwork() -{ - m_thread.End(); - m_thread.Stop(); - m_thread.WaitForThread(); - while (!m_connections.empty()) - { - delete m_connections.back(); - m_connections.pop_back(); - } - - if (m_socket != AZ_SOCKET_INVALID) - { - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - AZ::AzSock::Cleanup(); -} - -// - -void CNotificationNetwork::ReleaseClients(CClient* pClient) -{ - // TODO: Use CryAutoLock - LockDebug("Lock %s\n", "CNotificationNetwork::ReleaseClients()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - if (m_clients[i] != pClient) - { - continue; - } - - m_clients[i] = m_clients.back(); - m_clients.pop_back(); - break; - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::ReleaseClients()"); -} - -void CNotificationNetwork::ProcessSockets() -{ - fd_set read; - FD_ZERO(&read); - AZSOCKET socketMax = 0; - if (m_socket != AZ_SOCKET_INVALID) - { - FD_SET(m_socket, &read); - socketMax = m_socket; - } - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (m_connections[i]->Validate()) - { - AZSOCKET sock = m_connections[i]->GetSocket(); - FD_SET(sock, &read); - - if (socketMax < sock) - { - socketMax = sock; - } - - continue; - } - - // The Connection is invalid, remove it. - CConnection* pConnection = m_connections[i]; - m_connections[i] = m_connections.back(); - m_connections.pop_back(); - delete pConnection; - - // Invalidate the loop increment since we just removed a Connection and - // in the process potentially replaced its slot with an unprocessed one. - --i; - - CryLog("Notification Network Connection terminated, current total: %d\n", - (int)m_connections.size()); - } - - LockDebug("Lock %s\n", "CNotificationNetwork::ProcessSockets()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - if (!m_clients[i]->Validate()) - { - continue; - } - - AZSOCKET sock = m_clients[i]->GetSocket(); - FD_SET(sock, &read); - - if (socketMax < sock) - { - socketMax = sock; - } - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::ProcessSockets()"); - - AZTIMEVAL timeOut = { 1, 0 }; - int r = AZ::AzSock::Select(socketMax, &read, nullptr, nullptr, &timeOut); - if (r == 0) - { - return; - } - - // When we have no sockets, the select statement will fail and not - // block for even 1 second, as it should... - if (AZ::AzSock::SocketErrorOccured(r)) - { - // So we force the sleep here for now. - Sleep(1000); - return; - } - - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (!FD_ISSET(m_connections[i]->GetSocket(), &read)) - { - continue; - } - - m_connections[i]->Receive(m_listeners); - } - - LockDebug("Lock 2 %s\n", "CNotificationNetwork::ProcessSockets()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - if (!FD_ISSET(m_clients[i]->GetSocket(), &read)) - { - continue; - } - - m_clients[i]->Receive(); - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock 2 %s\n", "CNotificationNetwork::ProcessSockets()"); - - if (m_socket == AZ_SOCKET_INVALID) - { - return; - } - if (!FD_ISSET(m_socket, &read)) - { - return; - } - - AZ::AzSock::AzSocketAddress addr; - AZSOCKET sock = AZ::AzSock::Accept(m_socket, addr); - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - return; - } - - if (!RCON_IsRemoteAllowedToConnect(addr)) - { - AZ::AzSock::CloseSocket(sock); - return; - } - - m_connections.push_back(new CConnection(this, sock)); - - CryLog("Notification Network accepted new Connection, current total: %d\n", - (int)m_connections.size()); -} - -// INotificationNetwork - -INotificationNetworkClient* CNotificationNetwork::CreateClient() -{ - CClient* pClient = CClient::Create(this); - - LockDebug("Lock %s\n", "CNotificationNetwork::CreateClient()"); - m_clientsCriticalSection.Lock(); - m_clients.push_back(pClient); - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::CreateClient()"); - - return pClient; -} - -INotificationNetworkClient* CNotificationNetwork::Connect(const char* address, uint16 port) -{ - CClient* pClient = CClient::Create(this, address, port); - if (!pClient) - { - return nullptr; - } - - LockDebug("Lock %s\n", "CNotificationNetwork::Connect()"); - m_clientsCriticalSection.Lock(); - m_clients.push_back(pClient); - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::Connect()"); - - return pClient; -} - -size_t CNotificationNetwork::GetConnectionCount(const char* channelName) -{ - if (!channelName) - { - return m_connections.size(); - } - - if (!CChannel::IsNameValid(channelName)) - { - return 0; - } - - CChannel channel(channelName); - size_t count = 0; - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (!m_connections[i]->IsListening(channel)) - { - continue; - } - - ++count; - } - return count; -} - -bool CNotificationNetwork::ListenerBind(const char* channelName, INotificationNetworkListener* pListener) -{ - if (!CChannel::IsNameValid(channelName)) - { - return false; - } - - return m_listeners.Bind(CChannel(channelName), pListener); -} - -bool CNotificationNetwork::ListenerRemove(INotificationNetworkListener* pListener) -{ - return m_listeners.Remove(pListener); -} - -void CNotificationNetwork::Update() -{ - m_listeners.NotificationsProcess(); - - LockDebug("Lock %s\n", "CNotificationNetwork::Update()"); - m_clientsCriticalSection.Lock(); - for (size_t i = 0; i < m_clients.size(); ++i) - { - m_clients[i]->Update(); - } - m_clientsCriticalSection.Unlock(); - LockDebug("Unlock %s\n", "CNotificationNetwork::Update()"); -} - -uint32 CNotificationNetwork::Send(const char* channelName, const void* pBuffer, size_t length) -{ - if (!CChannel::IsNameValid(channelName)) - { - return 0; - } - - CChannel channel(channelName); - - // TODO: There should be a mutex lock here to ensure thread safety. - - uint32 count = 0; - for (size_t i = 0; i < m_connections.size(); ++i) - { - if (!m_connections[i]->IsListening(channel)) - { - continue; - } - - if (m_connections[i]->SendNotification(channel, pBuffer, length)) - { - ++count; - } - } - - return count; -} diff --git a/Code/CryEngine/CrySystem/NotificationNetwork.h b/Code/CryEngine/CrySystem/NotificationNetwork.h deleted file mode 100644 index ee336dbbb0..0000000000 --- a/Code/CryEngine/CrySystem/NotificationNetwork.h +++ /dev/null @@ -1,293 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H -#define CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H - -#pragma once - -#include -#include -#include - -#include - -class CNotificationNetwork; -namespace NotificationNetwork { - // Constants - - static const uint32 NN_PACKET_HEADER_LENGTH = 2 * sizeof(uint32) + NN_CHANNEL_NAME_LENGTH_MAX; - - static const uint32 NN_PACKET_HEADER_OFFSET_MESSAGE = 0; - static const uint32 NN_PACKET_HEADER_OFFSET_DATA_LENGTH = sizeof(uint32); - static const uint32 NN_PACKET_HEADER_OFFSET_CHANNEL = sizeof(uint32) + sizeof(uint32); - - static const char* NN_THREAD_NAME = "NotificationNetwork"; - - enum EMessage - { - eMessage_DataTransfer = 0xbada2217, - - eMessage_ChannelRegister = 0xab4eda30, - eMessage_ChannelUnregister = 0xfa4e3423, - }; - - // Classes - - struct CChannel - { - public: - static bool IsNameValid(const char* name); - - public: - CChannel(); - CChannel(const char* name); - ~CChannel(); - - public: - void WriteToPacketHeader(void* pPacket) const; - void ReadFromPacketHeader(void* pPacket); - - public: - bool operator ==(const CChannel& channel) const; - bool operator !=(const CChannel& channel) const; - - private: - char m_name[NN_CHANNEL_NAME_LENGTH_MAX]; - }; - - // TEMP - struct SBuffer - { - uint8* pData; - uint32 length; - CChannel channel; - }; - - class CListeners - { - public: - CListeners(); - ~CListeners(); - - public: - size_t Count() { return m_listeners.size(); } - size_t Count(const CChannel& channel); - - CChannel& Channel(size_t index) { return m_listeners[index].second; } - CChannel* Channel(INotificationNetworkListener* pListener); - - bool Bind(const CChannel& channel, INotificationNetworkListener* pListener); - bool Remove(INotificationNetworkListener* pListener); - - void NotificationPush(const SBuffer& buffer); - void NotificationsProcess(); - - private: - std::vector< std::pair > m_listeners; - - std::queue m_notifications[2]; - std::queue* m_pNotificationWrite; - std::queue* m_pNotificationRead; - CryCriticalSection m_notificationCriticalSection; - }; - - class CConnectionBase - { - public: - CConnectionBase(CNotificationNetwork* pNotificationNetwork); - virtual ~CConnectionBase(); - - public: - AZSOCKET CreateSocket(); - - bool Connect(const char* address, uint16 port); - - AZSOCKET GetSocket() { return m_socket; } - - bool Validate(); - - bool SendNotification(const CChannel& channel, const void* pBuffer, size_t length); - - bool Receive(CListeners& listeners); - - bool GetIsConnectedFlag(); - bool GetIsFailedToConnectFlag() const; - - protected: - CNotificationNetwork* GetNotificationNetwork() { return m_pNotificationNetwork; } - - void SetAddress(const char* address, uint16 port); - void SetSocket(AZSOCKET sock) { m_socket = sock; } - - bool Send(const void* pBuffer, size_t length); - bool SendMessage(EMessage eMessage, const CChannel& channel, uint32 data); - - bool Select_Internal(); - void CloseSocket_Internal(); - - virtual bool OnConnect([[maybe_unused]] bool bConnectionResult) { return true; } - virtual bool OnDisconnect() {return true; } - virtual bool OnMessage([[maybe_unused]] EMessage eMessage, [[maybe_unused]] const CChannel& channel) { return false; } - - private: - bool ReceiveMessage(CListeners& listeners); - bool ReceiveNotification(CListeners& listeners); - - protected: - CNotificationNetwork* m_pNotificationNetwork; - - char m_address[16]; - uint16 m_port; - - AZSOCKET m_socket; - - uint8 m_bufferHeader[NN_PACKET_HEADER_LENGTH]; - SBuffer m_buffer; - uint32 m_dataLeft; - - volatile bool m_boIsConnected; - volatile bool m_boIsFailedToConnect; - }; - - class CClient - : public CConnectionBase - , public INotificationNetworkClient - { - public: - typedef std::vector TDNotificationNetworkConnectionCallbacks; - - static CClient* Create(CNotificationNetwork* pNotificationNetwork, const char* address, uint16 port); - static CClient* Create(CNotificationNetwork* pNotificationNetwork); - - private: - CClient(CNotificationNetwork* pNotificationNetwork); - ~CClient(); - - public: - bool Receive() { return CConnectionBase::Receive(m_listeners); } - - void Update(); - - // CConnectionBase - public: - virtual bool OnConnect(bool bConnectionResult); - virtual bool OnDisconnect(); - virtual bool OnMessage(EMessage eMessage, const CChannel& channel); - - // INotificationNetworkClient - public: - bool Connect(const char* address, uint16 port); - - void Release() { delete this; } - - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener); - virtual bool ListenerRemove(INotificationNetworkListener* pListener); - - virtual bool Send(const char* channelName, const void* pBuffer, size_t length); - - virtual bool IsConnected() {return CConnectionBase::GetIsConnectedFlag(); } - virtual bool IsFailedToConnect() const{return CConnectionBase::GetIsFailedToConnectFlag(); } - - virtual bool RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback); - virtual bool UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback); - private: - CListeners m_listeners; - - TDNotificationNetworkConnectionCallbacks m_cNotificationNetworkConnectionCallbacks; - CryCriticalSection m_stConnectionCallbacksLock; - }; -} // namespace NotificationNetwork -class CNotificationNetwork - : public INotificationNetwork -{ -private: - class CConnection - : public NotificationNetwork::CConnectionBase - { - public: - CConnection(CNotificationNetwork* pNotificationNetwork, AZSOCKET sock); - virtual ~CConnection(); - - public: - bool IsListening(const NotificationNetwork::CChannel& channel); - - // CConnectionBase - protected: - virtual bool OnMessage(NotificationNetwork::EMessage eMessage, const NotificationNetwork::CChannel& channel); - - private: - std::vector m_listeningChannels; - }; - - class CThread - : public CryThread - { - public: - CThread(); - ~CThread(); - - public: - bool Begin(CNotificationNetwork* pNotificationNetwork); - void End(); - - // CryRunnable - public: - virtual void Run(); - - private: - CNotificationNetwork* m_pNotificationNetwork; - bool m_bRun; - } m_thread; - -public: - static CNotificationNetwork* Create(); - -public: - CNotificationNetwork(); - ~CNotificationNetwork(); - -public: - void ReleaseClients(NotificationNetwork::CClient* pClient); - -private: - void ProcessSockets(); - - // INotificationNetwork -public: - virtual void Release() { delete this; } - - virtual INotificationNetworkClient* CreateClient(); - - virtual INotificationNetworkClient* Connect(const char* address, uint16 port); - - virtual size_t GetConnectionCount(const char* channelName); - - virtual void Update(); - - virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener); - virtual bool ListenerRemove(INotificationNetworkListener* pListener); - - virtual uint32 Send(const char* channelName, const void* pBuffer, size_t length); - -private: - AZSOCKET m_socket; - - std::vector m_connections; - std::vector m_clients; - NotificationNetwork::CListeners m_listeners; - - CryCriticalSection m_clientsCriticalSection; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H diff --git a/Code/CryEngine/CrySystem/OverloadSceneManager/OverloadSceneManager.cpp b/Code/CryEngine/CrySystem/OverloadSceneManager/OverloadSceneManager.cpp deleted file mode 100644 index 044d44fade..0000000000 --- a/Code/CryEngine/CrySystem/OverloadSceneManager/OverloadSceneManager.cpp +++ /dev/null @@ -1,290 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Manages overload values (eg CPU,GPU etc) -// 1.0="everything is ok" 0.0="very bad frame rate" -// various systems can use this information and control what is currently in the scene - - -#include "CrySystem_precompiled.h" -#include "OverloadSceneManager.h" - -//-------------------------------------------------------------------------------------------------- -// Name: COverloadSceneManager -// Desc: Constructor -//-------------------------------------------------------------------------------------------------- -COverloadSceneManager::COverloadSceneManager() -{ - InitialiseCVars(); - - m_currentFrameStat = 0; - - ResetDefaultValues(); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Desc: static console callback functions -//-------------------------------------------------------------------------------------------------- -static void OnChange_osm_enabled(ICVar* pCVar) -{ - if (pCVar->GetIVal() == 0) - { - gEnv->pOverloadSceneManager->Reset(); - //gEnv->pRenderer->EnablePipelineProfiler(false); // would need push/pop since something else might have enabled it - } - else if (pCVar->GetIVal() == 1) - { - gEnv->pRenderer->EnablePipelineProfiler(true); - } -} - -static void cmd_setFBScale(IConsoleCmdArgs* pParams) -{ - int argCount = pParams->GetArgCount(); - - Vec2 newScale = Vec2(0.0f, 0.0f); - gEnv->pRenderer->EF_Query(EFQ_GetViewportDownscaleFactor, newScale); - - if (argCount > 1) - { - newScale.x = clamp_tpl((float)atof(pParams->GetArg(1)), 0.0f, 1.0f); - - if (argCount > 2) - { - newScale.y = clamp_tpl((float)atof(pParams->GetArg(2)), 0.0f, 1.0f); - } - else - { - newScale.y = newScale.x; - } - - newScale = gEnv->pRenderer->SetViewportDownscale(newScale.x, newScale.y); - } - - int nWidth = gEnv->pRenderer->GetWidth(); - int nHeight = gEnv->pRenderer->GetHeight(); - - gEnv->pLog->LogWithType(ILog::eInputResponse, "Current Viewport Resolution: %dx%d", - int(nWidth * newScale.x), int(nHeight * newScale.y)); -} - -//-------------------------------------------------------------------------------------------------- -// Name: InitialiseCVars -// Desc: Initialises CVars -//-------------------------------------------------------------------------------------------------- -void COverloadSceneManager::InitialiseCVars() -{ - // depending on final requirements, these could be made into const cvars - REGISTER_CVAR_CB(osm_enabled, 0, VF_NULL, "Enables/disables overload scene manager", &OnChange_osm_enabled); - REGISTER_CVAR(osm_historyLength, 5, VF_NULL, "Overload scene manager number of frames to record stats for"); - REGISTER_CVAR(osm_targetFPS, 28.0f, VF_NULL, "Overload scene manager target frame rate"); - REGISTER_CVAR(osm_targetFPSTolerance, 1.0f, VF_NULL, "The overload scene manager will make adjustments if fps is outside targetFPS +/- this value"); - REGISTER_CVAR(osm_fbScaleDeltaDown, 5.0f, VF_NULL, "The speed multiplier for the overload scene manager frame buffer scaling down"); - REGISTER_CVAR(osm_fbScaleDeltaUp, 1.0f, VF_NULL, "The speed multiplier for the overload scene manager frame buffer scaling up"); - REGISTER_CVAR(osm_fbMinScale, 0.66f, VF_NULL, "The minimum scale factor the overload scene manager will drop to"); - - REGISTER_COMMAND("osm_setFBScale", cmd_setFBScale, VF_NULL, "Sets the framebuffer scale to either a single scale on both X and Y, or independent scales.\n" - "NOTE: Will be overridden immediately if Overload scene manager is still enabled - see osm_enabled"); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: Reset -// Desc: Resets overload scene manager outputs to sensible defaults -//-------------------------------------------------------------------------------------------------- -void COverloadSceneManager::Reset() -{ - ResetDefaultValues(); - - gEnv->pRenderer->SetViewportDownscale(m_fbScale, m_fbScale); -} - -void COverloadSceneManager::ResetDefaultValues() -{ - m_fbScale = 1.0f; - m_scaleState = FBSCALE_AUTO; - m_lerpOverride.m_start = m_lerpOverride.m_length = 1.0f; - m_lerpOverride.m_reversed = false; - m_lerpAuto.m_start = m_lerpAuto.m_length = 1.0f; - m_lerpAuto.m_reversed = true; - m_fbAutoScale = m_fbOverrideDestScale = m_fbOverrideCurScale = 1.0f; - - // completely reset history - for (int i = 0; i < osm_historyLength; i++) - { - SScenePerformanceStats& stats = m_sceneStats[i]; - stats.frameRate = stats.gpuFrameRate = osm_targetFPS; - } - - m_smoothedSceneStats.frameRate = m_smoothedSceneStats.gpuFrameRate = osm_targetFPS; -} -//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: Update -// Desc: Updates overload scene manager -//-------------------------------------------------------------------------------------------------- -void COverloadSceneManager::Update() -{ - if (!osm_enabled) - { - return; - } - - UpdateStats(); - ResizeFB(); -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: OverrideScale and ResetScale -// Desc: sets up appropriate members for lerping between automatic framebuffer scale and manual -// overrides. -//-------------------------------------------------------------------------------------------------- -void COverloadSceneManager::OverrideScale(float frameScale, float dt) -{ - dt = max(dt, 1.0f / 1000.0f); - - float curTime = gEnv->pTimer->GetCurrTime(); - - frameScale = clamp_tpl(frameScale, osm_fbMinScale, 1.0f); - - m_fbOverrideDestScale = frameScale; - - if (m_scaleState == FBSCALE_AUTO) - { - // remove any override lerp - we want to lerp straight from auto to the given value. - m_lerpOverride.m_start = m_lerpOverride.m_length = 1.0f; - m_lerpOverride.m_reversed = false; - m_fbOverrideCurScale = frameScale; - - m_lerpAuto.m_start = curTime; - m_lerpAuto.m_length = dt; - m_lerpAuto.m_reversed = false; - } - else if (m_scaleState == FBSCALE_OVERRIDE) - { - m_lerpOverride.m_start = curTime; - m_lerpOverride.m_length = dt; - m_lerpOverride.m_reversed = false; - - m_fbOverrideCurScale = m_fbScale; - } - - m_scaleState = FBSCALE_OVERRIDE; -} - -void COverloadSceneManager::ResetScale(float dt) -{ - dt = max(dt, 1.0f / 1000.0f); - - float curTime = gEnv->pTimer->GetCurrTime(); - - // remove any override lerp - we want to lerp straight to auto - m_lerpOverride.m_start = m_lerpOverride.m_length = 1.0f; - m_lerpOverride.m_reversed = false; - m_fbOverrideCurScale = m_fbOverrideDestScale = m_fbScale; - - m_lerpAuto.m_start = curTime; - m_lerpAuto.m_length = dt; - m_lerpAuto.m_reversed = true; // want to lerp back to auto mode - - m_scaleState = FBSCALE_AUTO; -}//------------------------------------------------------------------------------------------------- - -//-------------------------------------------------------------------------------------------------- -// Name: UpdateStats -// Desc: Updates overload stats -//-------------------------------------------------------------------------------------------------- -void COverloadSceneManager::UpdateStats() -{ - m_currentFrameStat++; - - if (m_currentFrameStat >= osm_historyLength) - { - m_currentFrameStat = 0; - } - - SScenePerformanceStats& currentStats = m_sceneStats[m_currentFrameStat]; - const float frameLength = gEnv->pTimer->GetRealFrameTime() * 1000.0f; - const float gpuFrameLength = gEnv->pRenderer->GetGPUFrameTime() * 1000.0f; - - currentStats.frameRate = frameLength > 0.0f ? 1000.0f / frameLength : 0.0f; - currentStats.gpuFrameRate = gpuFrameLength > 0.0f ? 1000.0f / gpuFrameLength : 0.0f; - - CalculateSmoothedStats(); -}//------------------------------------------------------------------------------------------------- - -void COverloadSceneManager::CalculateSmoothedStats() -{ - m_smoothedSceneStats.Reset(); - - for (int i = 0; i < osm_historyLength; i++) - { - SScenePerformanceStats& stats = m_sceneStats[i]; - m_smoothedSceneStats.frameRate += stats.frameRate; - m_smoothedSceneStats.gpuFrameRate += stats.gpuFrameRate; - } - - m_smoothedSceneStats.frameRate /= osm_historyLength; - m_smoothedSceneStats.gpuFrameRate /= osm_historyLength; -} - -float COverloadSceneManager::CalcFBScale() -{ - float curTime = gEnv->pTimer->GetCurrTime(); - - // first calculate delta of the override lerp - float delta = clamp_tpl((curTime - m_lerpOverride.m_start) / m_lerpOverride.m_length, 0.0f, 1.0f); - if (m_lerpOverride.m_reversed) - { - delta = 1.0f - delta; - } - - // get the current target override - float curOverrideScale = LERP(m_fbOverrideCurScale, m_fbOverrideDestScale, delta); - - // calculate the delta from (or two) automatic scaling - delta = clamp_tpl((curTime - m_lerpAuto.m_start) / m_lerpAuto.m_length, 0.0f, 1.0f); - if (m_lerpAuto.m_reversed) - { - delta = 1.0f - delta; - } - - // final lerp from automatic to current override - return LERP(m_fbAutoScale, curOverrideScale, delta); -} - -void COverloadSceneManager::ResizeFB() -{ - // don't do anything for invalid framerates - if (m_smoothedSceneStats.gpuFrameRate < 5.0f || m_smoothedSceneStats.gpuFrameRate > 100.0f) - { - return; - } - - float fpsDiff = fabsf(m_smoothedSceneStats.gpuFrameRate - osm_targetFPS); - - if (m_smoothedSceneStats.gpuFrameRate < osm_targetFPS - osm_targetFPSTolerance) - { - m_fbAutoScale -= osm_fbScaleDeltaDown / 1000.0f * fpsDiff; - } - else if (m_smoothedSceneStats.gpuFrameRate > osm_targetFPS + osm_targetFPSTolerance) - { - m_fbAutoScale += osm_fbScaleDeltaUp / 1000.0f * fpsDiff; - } - - m_fbAutoScale = clamp_tpl(m_fbAutoScale, osm_fbMinScale, 1.0f); - - m_fbScale = clamp_tpl(CalcFBScale(), osm_fbMinScale, 1.0f); - - gEnv->pRenderer->SetViewportDownscale(m_fbScale, m_fbScale); -} diff --git a/Code/CryEngine/CrySystem/OverloadSceneManager/OverloadSceneManager.h b/Code/CryEngine/CrySystem/OverloadSceneManager/OverloadSceneManager.h deleted file mode 100644 index 06a901b3df..0000000000 --- a/Code/CryEngine/CrySystem/OverloadSceneManager/OverloadSceneManager.h +++ /dev/null @@ -1,127 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_OVERLOADSCENEMANAGER_OVERLOADSCENEMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_OVERLOADSCENEMANAGER_OVERLOADSCENEMANAGER_H -#pragma once - - -// Includes -#include "IOverloadSceneManager.h" - -#define SCENE_PERFORMANCE_FRAME_HISTORY 64 - -//================================================================================================== -// Name: SOverloadSceneStats -// Desc: Overload scene stats -// Author: James Chilvers -//================================================================================================== -struct SScenePerformanceStats -{ - SScenePerformanceStats() - { - Reset(); - } - - void Reset() - { - frameRate = 0.0f; - gpuFrameRate = 0.0f; - } - - float frameRate; - float gpuFrameRate; -};//------------------------------------------------------------------------------------------------ - -//================================================================================================== -// Name: COverloadSceneManager -// Desc: Manages overload values (eg CPU,GPU etc) -// 1.0="everything is ok" 0.0="very bad frame rate" -// various systems can use this information and control what is currently in the scene -// Author: James Chilvers -//================================================================================================== -class COverloadSceneManager - : public IOverloadSceneManager -{ - friend class COverloadDG; - -public: - - COverloadSceneManager(); - ~COverloadSceneManager() override = default; - - virtual void Reset(); - - virtual void Update(); - - virtual void OverrideScale(float frameScale, float dt); - virtual void ResetScale(float dt); - -private: - - void ResetDefaultValues(); - void InitialiseCVars(); - void UpdateStats(); - void CalculateSmoothedStats(); - void ResizeFB(); - - float CalcFBScale(); // performs all lerping and returns final framebuffer scale - - // cvars - int osm_enabled; - int osm_historyLength; - float osm_targetFPS; - float osm_targetFPSTolerance; - float osm_fbScaleDeltaUp, osm_fbScaleDeltaDown; - float osm_fbMinScale; - - SScenePerformanceStats m_smoothedSceneStats; - SScenePerformanceStats m_sceneStats[SCENE_PERFORMANCE_FRAME_HISTORY]; - int m_currentFrameStat; - - // current output scale, set to the renderer - float m_fbScale; - - // Lerping behaviour is to lerp from autoscale to (lerp between cur/dest override) - // - // m_fbOverrideCurScale - // | - // | - // m_fbAutoScale ---- m_lerpAuto ---> m_lerpOverride - // | - // v - // m_fbOverrideDestScale - - // framebuffer scales to support lerping & overriding of calculated scale - float m_fbAutoScale, m_fbOverrideCurScale, m_fbOverrideDestScale; - - struct ScaleLerp - { - bool m_reversed; // Normally lerp is 0 -> 1. If reversed it's 1 -> 0 - float m_start; // time in seconds - float m_length; // time in seconds - }; - - // lerpAuto is the lerp between auto scale and whatever override is. - // lerpOverride is the lerp between m_fbOverrideCurScale and m_fbOverrideDestScale - ScaleLerp m_lerpAuto, m_lerpOverride; - - // State is the current destination of any lerps. - enum ScaleState - { - FBSCALE_AUTO, - FBSCALE_OVERRIDE, - } m_scaleState; -};//------------------------------------------------------------------------------------------------ - -#endif // CRYINCLUDE_CRYSYSTEM_OVERLOADSCENEMANAGER_OVERLOADSCENEMANAGER_H diff --git a/Code/CryEngine/CrySystem/PageMappingHeap.cpp b/Code/CryEngine/CrySystem/PageMappingHeap.cpp deleted file mode 100644 index d42d75db5b..0000000000 --- a/Code/CryEngine/CrySystem/PageMappingHeap.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "PageMappingHeap.h" - -namespace -{ - template - inline void FindZeroRanges(const uint32* str, size_t strLen, Func& yield) - { - size_t carry = 0; - size_t bitIdx = 0; - - for (size_t wordIdx = 0; wordIdx < strLen; ++wordIdx) - { - size_t wordBitIdx = 0; - int64 word = str[wordIdx]; - - // Set up sign extension to insert bits that are the last bit, inverted. - - if (!(word & 0x80000000)) - { - reinterpret_cast(word) |= 0xffffffff00000000ULL; - } - - do - { - size_t wordZeroRunLen = countTrailingZeroes(word); - - wordBitIdx += wordZeroRunLen; - carry += wordZeroRunLen; - - if (wordBitIdx == 32) - { - break; - } - - yield(bitIdx, carry); - word >>= wordZeroRunLen; - bitIdx += carry; - carry = 0; - - size_t wordOneRunLen = countTrailingZeroes(~word); - bitIdx += wordOneRunLen; - wordBitIdx += wordOneRunLen; - - if (wordBitIdx == 32) - { - break; - } - - word >>= wordOneRunLen; - } - while (true); - } - - if (carry) - { - yield(bitIdx, carry); - } - } - - struct DLMMapFindBest - { - DLMMapFindBest(size_t size) - : requiredLength(size) - , bestPosition(-1) - , bestFragmentLength(INT_MAX) - { - } - - bool operator () (size_t position, size_t length) - { - if (length == requiredLength) - { - bestPosition = position; - bestFragmentLength = 0; - return false; - } - else if (length > requiredLength) - { - size_t fragment = length - requiredLength; - if (fragment < bestFragmentLength) - { - bestPosition = position; - bestFragmentLength = fragment; - } - } - - return true; - } - - size_t requiredLength; - ptrdiff_t bestPosition; - size_t bestFragmentLength; - }; - - struct FindLargest - { - FindLargest() - : largest(0) - { - } - bool operator () (size_t, size_t length) - { - largest = max(largest, length); - return true; - } - - size_t largest; - }; -} - -CPageMappingHeap::CPageMappingHeap(char* pAddressSpace, size_t nNumPages, size_t nPageSize, const char* sName) - : m_addrRange(pAddressSpace, nPageSize, nNumPages, sName) -{ - Init(); -} - -CPageMappingHeap::CPageMappingHeap(size_t addressSpace, const char* sName) - : m_addrRange(addressSpace, sName) -{ - Init(); -} - -CPageMappingHeap::~CPageMappingHeap() -{ -} - -void CPageMappingHeap::Release() -{ - delete this; -} - -size_t CPageMappingHeap::GetGranularity() const -{ - return m_addrRange.GetPageSize(); -} - -bool CPageMappingHeap::IsInAddressRange(void* ptr) const -{ - return m_addrRange.IsInRange(ptr); -} - -size_t CPageMappingHeap::FindLargestFreeBlockSize() const -{ - CryAutoLock lock(m_lock); - - const size_t pageSize = m_addrRange.GetPageSize(); - - FindLargest findLargest; - FindZeroRanges(&m_pageBitmap[0], m_pageBitmap.size(), findLargest); - - return findLargest.largest * pageSize; -} - -void* CPageMappingHeap::Map(size_t length) -{ - CryAutoLock lock(m_lock); - - const size_t pageBitmapElemBitSize = (sizeof(uint32) * 8); - const size_t pageSize = m_addrRange.GetPageSize(); - const size_t numPages = m_addrRange.GetPageCount(); - - if (length % pageSize) - { - __debugbreak(); - length = (length + (pageSize - 1)) & ~(pageSize - 1); - } - - DLMMapFindBest findBest(length / pageSize); - FindZeroRanges(&m_pageBitmap[0], m_pageBitmap.size(), findBest); - - if ((findBest.bestPosition == -1) || (findBest.bestPosition >= (int)numPages)) - { - return NULL; - } - - void* mapAddress = m_addrRange.GetBaseAddress() + pageSize * findBest.bestPosition; - - for (size_t pageIdx = findBest.bestPosition, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - if (!m_addrRange.MapPage(pageIdx)) - { - // Unwind the pages we've already mapped. - for (; pageIdx > static_cast(findBest.bestPosition); --pageIdx) - { - m_addrRange.UnmapPage(pageIdx - 1); - } - - return NULL; - } - } - - for (size_t pageIdx = findBest.bestPosition, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - size_t pageSegment = pageIdx / pageBitmapElemBitSize; - uint32 pageMask = 1U << static_cast(pageIdx % pageBitmapElemBitSize); - - m_pageBitmap[pageSegment] |= pageMask; - } - - return mapAddress; -} - -void CPageMappingHeap::Unmap(void* mem, size_t length) -{ - CryAutoLock lock(m_lock); - const size_t pageSize = m_addrRange.GetPageSize(); - - if (length % pageSize) - { - __debugbreak(); - length = (length + (pageSize - 1)) & ~(pageSize - 1); - } - - char* mapAddress = reinterpret_cast(mem); - for (size_t pageIdx = (mapAddress - m_addrRange.GetBaseAddress()) / pageSize, pageIdxEnd = pageIdx + length / pageSize; pageIdx != pageIdxEnd; ++pageIdx) - { - m_addrRange.UnmapPage(pageIdx); - - const size_t pageBitmapElemBitSize = (sizeof(uint32) * 8); - - size_t pageSegment = pageIdx / pageBitmapElemBitSize; - uint32 pageMask = ~(1U << static_cast(pageIdx % pageBitmapElemBitSize)); - - m_pageBitmap[pageSegment] &= pageMask; - } -} - -void CPageMappingHeap::Init() -{ - UINT_PTR start = (UINT_PTR)m_addrRange.GetBaseAddress(); - UINT_PTR end = start + m_addrRange.GetPageCount() * m_addrRange.GetPageSize(); - - size_t addressSpace = end - start; - size_t pageSize = m_addrRange.GetPageSize(); - size_t numPages = (addressSpace + pageSize - 1) / pageSize; - m_pageBitmap.resize((numPages + 31) / 32); - - size_t pageCapacity = m_pageBitmap.size() * 32; - size_t numUnavailablePages = pageCapacity - numPages; - if (numUnavailablePages > 0) - { - m_pageBitmap.back() = ~((1 << (32 - numUnavailablePages)) - 1); - } -} diff --git a/Code/CryEngine/CrySystem/PageMappingHeap.h b/Code/CryEngine/CrySystem/PageMappingHeap.h deleted file mode 100644 index 8cd3a7a315..0000000000 --- a/Code/CryEngine/CrySystem/PageMappingHeap.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H -#define CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H -#pragma once - - -#include "MemoryAddressRange.h" - -#include "IMemory.h" - -class CPageMappingHeap - : public IPageMappingHeap -{ -public: - CPageMappingHeap(char* pAddressSpace, size_t nNumPages, size_t nPageSize, const char* sName); - CPageMappingHeap(size_t addressSpace, const char* sName); - ~CPageMappingHeap(); - -public: // IPageMappingHeap Members - virtual void Release(); - - virtual size_t GetGranularity() const; - virtual bool IsInAddressRange(void* ptr) const; - - virtual size_t FindLargestFreeBlockSize() const; - - virtual void* Map(size_t sz); - virtual void Unmap(void* ptr, size_t sz); - -private: - CPageMappingHeap(const CPageMappingHeap&); - CPageMappingHeap& operator = (const CPageMappingHeap&); - -private: - void Init(); - -private: - mutable CryCriticalSectionNonRecursive m_lock; - CMemoryAddressRange m_addrRange; - std::vector m_pageBitmap; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_PAGEMAPPINGHEAP_H diff --git a/Code/CryEngine/CrySystem/PerfHUD.cpp b/Code/CryEngine/CrySystem/PerfHUD.cpp deleted file mode 100644 index 2aeabe2650..0000000000 --- a/Code/CryEngine/CrySystem/PerfHUD.cpp +++ /dev/null @@ -1,2166 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - -#include "CrySystem_precompiled.h" - -#ifdef USE_PERFHUD - -#include "PerfHUD.h" -#include "MiniGUI/MiniInfoBox.h" -#include "MiniGUI/MiniMenu.h" -#include "MiniGUI/MiniTable.h" -#include -#include -#include "System.h" - -#include - -#include - -#include -#include - -#include - -#define PERFHUD_CONFIG_FILE "Config/PerfHud_PC.xml" - -using namespace minigui; - -const float CPerfHUD::OVERSCAN_X = 15; -const float CPerfHUD::OVERSCAN_Y = 15; - -const ColorB CPerfHUD::COL_NORM = ColorB(255, 255, 255, 255); -const ColorB CPerfHUD::COL_WARN = ColorB(255, 255, 0, 255); -const ColorB CPerfHUD::COL_ERROR = ColorB(255, 0, 0, 255); - -const float CPerfHUD::TEXT_SIZE_NORM = 14.f; -const float CPerfHUD::TEXT_SIZE_WARN = 18.f; -const float CPerfHUD::TEXT_SIZE_ERROR = 26.f; - -const float CPerfHUD::ACTIVATE_TIME_FROM_GAME = 1.f; -const float CPerfHUD::ACTIVATE_TIME_FROM_HUD = 0.1f; - -CRYREGISTER_SINGLETON_CLASS(CPerfHUD) -CPerfHUD::CPerfHUD() - : m_menuStartX(OVERSCAN_X) - , m_menuStartY(OVERSCAN_Y) - , m_hudCreated(false) - , m_L1Pressed(false) - , m_L2Pressed(false) - , m_R1Pressed(false) - , m_R2Pressed(false) - , m_changingState(false) - , m_hwMouseEnabled(false) - , m_triggersDownStartTime(-1.f) - , m_hudState(eHudOff) - , m_hudLastState(eHudOff) -{ - m_widgets.reserve(ICryPerfHUDWidget::eWidget_Num); -} - -CPerfHUD::~CPerfHUD() {} - -void CPerfHUD::Destroy() -{ - m_widgets.clear(); - - m_rootMenus.clear(); - - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - pGUI->RemoveAllCtrl(); - } -} - -// -// CONSOLE COMMAND CALLBACKS -// - -int CPerfHUD::m_sys_perfhud = 0; -int CPerfHUD::m_sys_perfhud_pause = 0; - -void CPerfHUD::CVarChangeCallback(ICVar* pCvar) -{ - ICryPerfHUD* pPerfHud = gEnv->pSystem->GetPerfHUD(); - - if (pPerfHud) - { - int val = pCvar->GetIVal(); - //Check for invalid value - if (val >= 0 && val < eHudNumStates) - { - pPerfHud->SetState((EHudState)val); - } - } -} - -SET_WIDGET_DEF(Warnings, eWidget_Warnings) -SET_WIDGET_DEF(RenderSummary, eWidget_RenderStats) -SET_WIDGET_DEF(RenderBatchStats, eWidget_RenderBatchStats) -SET_WIDGET_DEF(FpsBuckets, eWidget_FpsBuckets) -SET_WIDGET_DEF(Particles, eWidget_Particles) -SET_WIDGET_DEF(PakFile, eWidget_PakFile) - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::Init() -{ - m_sys_perfhud_prev = 0; - - if (gEnv->pConsole) - { - REGISTER_CVAR2_CB("sys_perfhud", &m_sys_perfhud, 0, VF_ALWAYSONCHANGE, "PerfHUD 0:off, 1:In focus, 2:Out of focus", CVarChangeCallback); - - REGISTER_CVAR2("sys_perfhud_pause", &m_sys_perfhud_pause, 0, VF_NULL, "Toggle FPS Buckets exclusive / inclusive"); - - SET_WIDGET_COMMAND("stats_Warnings", Warnings); - SET_WIDGET_COMMAND("stats_RenderSummary", RenderSummary); - SET_WIDGET_COMMAND("stats_RenderBatchStats", RenderBatchStats); - SET_WIDGET_COMMAND("stats_FpsBuckets", FpsBuckets); - SET_WIDGET_COMMAND("stats_Particles", Particles); - SET_WIDGET_COMMAND("stats_PakFile", PakFile); - } - - AzFramework::InputChannelEventListener::Connect(); - - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - InitUI(pGUI.get()); - } -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::LoadBudgets() -{ - XmlNodeRef budgets = gEnv->pSystem->LoadXmlFromFile(PERFHUD_CONFIG_FILE); - - if (budgets) - { - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - m_widgets[i]->LoadBudgets(budgets); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::SaveStats(const char* filename) -{ - XmlNodeRef rootNode = GetISystem()->CreateXmlNode("PerfHudStats"); - - if (rootNode) - { - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - m_widgets[i]->SaveStats(rootNode); - } - - if (!filename) - { - filename = "PerfHudStats.xml"; - } - rootNode->saveToFile(filename); - } -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::ResetWidgets() -{ - TWidgetIterator itWidget; - for (itWidget = m_widgets.begin(); itWidget != m_widgets.end(); ++itWidget) - { - (*itWidget)->Reset(); - } -} - -void CPerfHUD::AddWidget(ICryPerfHUDWidget* pWidget) -{ - assert(pWidget); - static int s_widgetUID = ICryPerfHUDWidget::eWidget_Num; - - if (pWidget->m_id == -1) - { - pWidget->m_id = s_widgetUID++; - } - - m_widgets.push_back(pWidget); -} - -void CPerfHUD::RemoveWidget(ICryPerfHUDWidget* pWidget) -{ - TWidgetIterator widgetIter = m_widgets.begin(); - TWidgetIterator widgetEnd = m_widgets.end(); - - while (widgetIter != widgetEnd) - { - if (pWidget == (*widgetIter).get()) - { - m_widgets.erase(widgetIter); - break; - } - ++widgetIter; - } -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::Done() -{ - AzFramework::InputChannelEventListener::Disconnect(); -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::Draw() -{ - FUNCTION_PROFILER_FAST(GetISystem(), PROFILE_SYSTEM, g_bProfilerEnabled); - - if (m_hudState != m_hudLastState) - { - //restore gui state if the last state was off - bool bRestoreState = (m_hudLastState == eHudOff); - - Show(bRestoreState); - m_hudLastState = m_hudState; - } - - if (m_hudState != eHudOff) - { - //Pause - if (m_sys_perfhud_pause) - { - if ((gEnv->pRenderer->GetFrameID(false) % 40) < 20) - { - float col[4] = {1.f, 1.f, 0.f, 1.f}; - gEnv->pRenderer->Draw2dLabel(500.f, 220.f, 2.f, col, false, "PefHUD Paused"); - } - } - else //Update - { - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - if (m_widgets[i]->ShouldUpdate()) - { - m_widgets[i]->Update(); - } - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::Show(bool bRestoreState) -{ - IMiniGUIPtr pGUI; - if (!CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - return; - } - - switch (m_hudState) - { - case eHudInFocus: - { - pGUI->SetEventListener(this); - - if (!m_hudCreated) - { - InitUI(pGUI.get()); - } - else if (bRestoreState) - { - pGUI->RestoreState(); - } - pGUI->SetEnabled(true); - pGUI->SetInFocus(true); - - int nRootMenus = m_rootMenus.size(); - for (int i = 0; i < nRootMenus; i++) - { - m_rootMenus[i]->SetVisible(1); - } - } - break; - - case eHudOutOfFocus: - { - if (bRestoreState) - { - pGUI->RestoreState(); - } - - int nRootMenus = m_rootMenus.size(); - for (int i = 0; i < nRootMenus; i++) - { - m_rootMenus[i]->SetVisible(0); - } - - pGUI->SetEventListener(0); - pGUI->SetEnabled(true); - pGUI->SetInFocus(false); - } - break; - - case eHudOff: - { - pGUI->SaveState(); - pGUI->Reset(); - pGUI->SetEnabled(false); - } - break; - - default: - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::InitUI(IMiniGUI* pGUI) -{ - assert(m_hudCreated == false); - - IMiniCtrl* pMenu; - XmlNodeRef perfXML = gEnv->pSystem->LoadXmlFromFile(PERFHUD_CONFIG_FILE); - - // - // RENDERING MENU - // - pMenu = CreateMenu("Rendering"); - - IMiniCtrl* pDebugMenu = CreateMenu("Debug", pMenu); - CreateCVarMenuItem(pDebugMenu, "Wireframe", "r_wireframe", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Overdraw", "r_MeasureOverdrawScale", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Freeze Camera", "e_CameraFreeze", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Post Effects", "r_PostProcessEffects", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Deferred decals debug", "r_deferredDecalsDebug", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Shadows", "e_Shadows", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Ocean", "e_WaterOcean", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Characters", "ca_DrawChr", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Coverage Buffer", "e_CoverageBuffer", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Sun", "e_Sun", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Unlit", "r_Unlit", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Disable Normal Maps", "r_texbindmode", 0, 5); - CreateCVarMenuItem(pDebugMenu, "Env Probes", "r_deferredShadingEnvProbes", 0, 1); - CreateCVarMenuItem(pDebugMenu, "Lighting View", "r_texbindmode", 0, 11); - CreateCVarMenuItem(pDebugMenu, "Normal and Lighting View", "r_texbindmode", 0, 6); - CreateCVarMenuItem(pDebugMenu, "Default Material", "e_defaultMaterial", 0, 1); - - //this cvar is not created when perfHUD is initialised - so it doesn't work - //CreateCVarMenuItem(pDebugMenu, "MFX visual debug", "mfx_DebugVisual", 0, 1 ); - - - IMiniCtrl* pStatsMenu = CreateMenu("Stats", pMenu); - //Render Info - CRenderStatsWidget* pRenderStats = new CRenderStatsWidget(pStatsMenu, this); - - if (pRenderStats) - { - if (perfXML) - { - pRenderStats->LoadBudgets(perfXML); - } - m_widgets.push_back(pRenderStats); - } - - CRenderBatchWidget* pRenderBatchStats = new CRenderBatchWidget(pStatsMenu, this); - - if (pRenderBatchStats) - { - m_widgets.push_back(pRenderBatchStats); - } - -#ifndef _RELEASE - CreateCVarMenuItem(pStatsMenu, "Debug Gun", "e_debugDraw", 0, 16); -#endif - CreateCVarMenuItem(pStatsMenu, "Poly / Lod info", "e_debugDraw", 0, 1); - CreateCVarMenuItem(pStatsMenu, "Texture Memory Usage", "e_debugDraw", 0, 4); - CreateCVarMenuItem(pStatsMenu, "Detailed Render Stats", "r_Stats", 0, 1); - CreateCVarMenuItem(pStatsMenu, "Shader Stats", "r_ProfileShaders", 0, 1); - - // - // SYSTEM MENU - // - pMenu = CreateMenu("System"); - - //FPS Buckets - CWarningsWidget* pWarningsWidget = new CWarningsWidget(pMenu, this); - - if (pWarningsWidget) - { - m_widgets.push_back(pWarningsWidget); - } - - CreateCVarMenuItem(pMenu, "Profiler", "profile", 0, 1); - CreateCVarMenuItem(pMenu, "Thread Summary", "r_showmt", 0, 1); - CreateCVarMenuItem(pMenu, "Track File Access", "sys_PakLogInvalidFileAccess", 0, 1); - - //FPS Buckets - CFpsWidget* pFpsBuckets = new CFpsWidget(pMenu, this); - - if (pFpsBuckets) - { - if (perfXML) - { - pFpsBuckets->LoadBudgets(perfXML); - } - m_widgets.push_back(pFpsBuckets); - } - - // - // STREAMING MENU - // - pMenu = CreateMenu("Streaming"); - CreateCVarMenuItem(pMenu, "Streaming Debug", "sys_streaming_debug", 0, 1); - CreateCVarMenuItem(pMenu, "Loaded Geometry Info", "e_streamcgfdebug", 0, 3); - CreateCVarMenuItem(pMenu, "Texture Load/Unload Debug", "r_TexBindMode", 0, 9); - CreateCVarMenuItem(pMenu, "Textures by Size", "r_TexturesStreamingDebug", 0, 4); - CreateCVarMenuItem(pMenu, "Textures by Prio", "r_TexturesStreamingDebug", 0, 5); - - // - // SETUP MENU - // - pMenu = CreateMenu("Setup"); - CreateCallbackMenuItem(pMenu, "Reset HUD", CPerfHUD::ResetCallback, NULL); - CreateCallbackMenuItem(pMenu, "Reload Budgets", CPerfHUD::ReloadBudgetsCallback, NULL); - CreateCallbackMenuItem(pMenu, "Save Stats", CPerfHUD::SaveStatsCallback, NULL); - CreateCVarMenuItem(pMenu, "Pause PerfHUD", "sys_perfhud_pause", 0, 1); - - //save default windows - pGUI->SaveState(); - - m_hudCreated = true; -} -////////////////////////////////////////////////////////////////////////// -// GUI CREATION HELPER FUNCS -////////////////////////////////////////////////////////////////////////// - -IMiniCtrl* CPerfHUD::CreateMenu(const char* name, IMiniCtrl* pParent) -{ - assert(name); - - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - bool subMenu = false; - - if (pParent) - { - assert(pParent->GetType() == eCtrlType_Menu); - subMenu = true; - } - - const float ButtonWidth = 10.f; //arbitrary, button will be scaled based on contained text - - int ctrlFlags = 0; - - if (!subMenu) - { - ctrlFlags = eCtrl_TextAlignCentre | eCtrl_AutoResize; - } - - Rect rcMenuBtn = Rect(m_menuStartX, m_menuStartY, m_menuStartX + ButtonWidth, m_menuStartY + 20); - - IMiniCtrl* pMenu = pGUI->CreateCtrl(pParent, 1, eCtrlType_Menu, ctrlFlags, rcMenuBtn, name); - - if (pMenu && !subMenu) - { - const float MenuBtnSepration = 10.f; - - //Update Menu Positions - rcMenuBtn = pMenu->GetRect(); - m_menuStartX = rcMenuBtn.right + MenuBtnSepration; - m_menuStartY = rcMenuBtn.top; - - m_rootMenus.push_back(pMenu); - } - - return pMenu; - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -bool CPerfHUD::CreateCVarMenuItem(IMiniCtrl* pMenu, const char* name, const char* controlVar, float controlVarOff, float controlVarOn) -{ - assert(pMenu && name && controlVar); - assert(pMenu->GetType() == eCtrlType_Menu); - - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - IMiniCtrl* pCtrl = pGUI->CreateCtrl(pMenu, 100, eCtrlType_Button, eCtrl_CheckButton, Rect(0, 0, 100, 20), name); - - if (pCtrl) - { - if (controlVar) - { - pCtrl->SetControlCVar(controlVar, controlVarOff, controlVarOn); - } - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CPerfHUD::CreateCallbackMenuItem(IMiniCtrl* pMenu, const char* name, ClickCallback clickCallback, void* pCallbackData) -{ - assert(pMenu && name && clickCallback); - assert(pMenu->GetType() == eCtrlType_Menu); - - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - IMiniCtrl* pCtrl = pGUI->CreateCtrl(pMenu, 100, eCtrlType_Button, 0 /*eCtrl_CheckButton*/, Rect(0, 0, 100, 20), name); - - if (pCtrl) - { - pCtrl->SetClickCallback(clickCallback, pCallbackData); - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -IMiniInfoBox* CPerfHUD::CreateInfoMenuItem(IMiniCtrl* pMenu, const char* name, RenderCallback renderCallback, const Rect& rect, bool onAtStart) -{ - assert(pMenu->GetType() == eCtrlType_Menu); - - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - IMiniCtrl* pCtrl = pGUI->CreateCtrl(pMenu, 100, eCtrlType_Button, eCtrl_CheckButton, Rect(0, 0, 100, 20), name); - - int infoFlags = eCtrl_Moveable | eCtrl_CloseButton; - - if (!renderCallback) - { - infoFlags |= eCtrl_AutoResize; - } - - CMiniInfoBox* pInfo = (CMiniInfoBox*)pGUI->CreateCtrl(NULL, 200, eCtrlType_InfoBox, infoFlags, rect, name); - - if (pCtrl) - { - pCtrl->SetConnectedCtrl(pInfo); - - if (onAtStart) - { - pCtrl->SetFlag(eCtrl_Checked); - } - else - { - pInfo->SetVisible(false); - } - - if (renderCallback) - { - pInfo->SetRenderCallback(renderCallback); - } - - return pInfo; - } - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -IMiniTable* CPerfHUD::CreateTableMenuItem(IMiniCtrl* pMenu, const char* name) -{ - assert(pMenu && name); - assert(pMenu->GetType() == eCtrlType_Menu); - - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - CMiniTable* pTable = (CMiniTable*)pGUI->CreateCtrl(NULL, 200, eCtrlType_Table, eCtrl_AutoResize | eCtrl_Moveable | eCtrl_CloseButton, Rect(50, 100, 400, 350), name); - - if (pTable) - { - IMiniCtrl* pCtrl = pGUI->CreateCtrl(pMenu, 100, eCtrlType_Button, eCtrl_CheckButton, Rect(0, 0, 100, 20), name); - - if (pCtrl) - { - pCtrl->SetConnectedCtrl(pTable); - - pTable->SetVisible(false); - - return pTable; - } - } - } - return NULL; -} - -IMiniCtrl* CPerfHUD::GetMenu(const char* name) -{ - int nRootMenus = m_rootMenus.size(); - - for (int i = 0; i < nRootMenus; i++) - { - if (strcmp(m_rootMenus[i]->GetTitle(), name) == 0) - { - return m_rootMenus[i]; - } - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::OnCommand([[maybe_unused]] SCommand& cmd) -{ - //CryLog( "Button Clicked = %d",cmd.nCtrlID ); -} - -////////////////////////////////////////////////////////////////////////// -bool CPerfHUD::OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) -{ - const AzFramework::InputChannelId& channelId = inputChannel.GetInputChannelId(); - const AzFramework::InputDeviceId& deviceId = inputChannel.GetInputDevice().GetInputDeviceId(); - if (AzFramework::InputDeviceKeyboard::IsKeyboardDevice(deviceId) && inputChannel.IsStateBegan()) - { - if (channelId == AzFramework::InputDeviceKeyboard::Key::WindowsSystemPrint) - { - //Cycle modes - const AzFramework::ModifierKeyStates* customData = inputChannel.GetCustomData(); - const AzFramework::ModifierKeyStates modifierKeyStates = customData ? *customData : AzFramework::ModifierKeyStates(); - const bool isAltModifierActive = modifierKeyStates.IsActive(AzFramework::ModifierKeyMask::AltAny); - const bool isCtrlModifierActive = modifierKeyStates.IsActive(AzFramework::ModifierKeyMask::CtrlAny); - if (isAltModifierActive || isCtrlModifierActive) - { - SetNextState(); - } - } - else if (channelId == AzFramework::InputDeviceKeyboard::Key::WindowsSystemScrollLock) - { - //toggle pause - m_sys_perfhud_pause ^= 1; - } - } - - - if (deviceId == AzFramework::InputDeviceGamepad::IdForIndex0) - { - if (inputChannel.IsStateBegan()) - { - bool checkState = false; - - if (channelId == AzFramework::InputDeviceGamepad::Button::L1) - { - m_L1Pressed = true; - checkState = true; - } - else if (channelId == AzFramework::InputDeviceGamepad::Button::R1) - { - m_R1Pressed = true; - checkState = true; - } - else if (channelId == AzFramework::InputDeviceGamepad::Button::X) - { - if (m_changingState) - { - SetNextState(); - } - } - - //if(checkState&&m_L1Pressed&&m_L2Pressed&&m_R1Pressed&&m_R2Pressed) - if (checkState && m_L1Pressed && m_R1Pressed) - { - m_triggersDownStartTime = gEnv->pTimer->GetAsyncCurTime(); - } - } - else if (inputChannel.IsStateUpdated()) - { - float activateTime = (m_hudState == eHudOff) ? ACTIVATE_TIME_FROM_GAME : ACTIVATE_TIME_FROM_HUD; - - if (m_triggersDownStartTime > 0.f && gEnv->pTimer->GetAsyncCurTime() - m_triggersDownStartTime > activateTime) - { - m_changingState = true; - - const char* hudStateStr = NULL; - - switch (m_hudState) - { - case eHudInFocus: - hudStateStr = "CryPerfHUD Edit Mode"; - break; - - case eHudOutOfFocus: - hudStateStr = "CryPerfHUD Game Mode"; - break; - - case eHudOff: - hudStateStr = "CryPerfHUD Off"; - break; - - default: - hudStateStr = "CryPerfHud unknown"; - break; - } - - float col[4] = {1.f, 1.f, 1.f, 1.f}; - gEnv->pRenderer->Draw2dLabel(450.f, 200.f, 2.f, col, false, hudStateStr); - gEnv->pRenderer->Draw2dLabel(450.f, 220.f, 2.f, col, false, "Press X to change Mode"); - } - } - else if (inputChannel.IsStateEnded()) - { - bool triggerReleased = false; - - if (channelId == AzFramework::InputDeviceGamepad::Button::L1) - { - m_L1Pressed = false; - triggerReleased = true; - } - else if (channelId == AzFramework::InputDeviceGamepad::Button::R1) - { - m_R1Pressed = false; - triggerReleased = true; - } - - if (triggerReleased) - { - m_triggersDownStartTime = 0.f; - - if (m_changingState) - { - m_changingState = false; - - //workaround: hardware mouse resets all input states when enabled - //this breaks perfhud selection mode (as triggers are released) - //don't enable mouse until we've finished selection mode - if (m_hudState == eHudInFocus) - { - if (!m_hwMouseEnabled) - { - UiCursorBus::Broadcast(&UiCursorInterface::IncrementVisibleCounter); - m_hwMouseEnabled = true; - } - } - else if (m_hwMouseEnabled) - { - UiCursorBus::Broadcast(&UiCursorInterface::DecrementVisibleCounter); - m_hwMouseEnabled = false; - } - } - } - } - - if (m_hudState == eHudInFocus) - { - //PerfHUD takes control of the input - return true; - } - } - return false; -} - -void CPerfHUD::SetNextState() -{ - if (m_sys_perfhud != eHudOff) - { - m_hudState = (EHudState)((m_hudState + 1) % eHudNumStates); - //CryLogAlways("Setting new HUD state: %d", m_hudState); - - //what to do about cvar? - //ICVar *pPerfCVar = GetISystem()->GetIConsole()->GetCVar("sys_perfhud"); - //pPerfCVar->Set( 1 ); - } -} - -void CPerfHUD::SetState(EHudState state) -{ - if (state != m_hudState) - { - if (m_hwMouseEnabled) - { - if (state != eHudInFocus) - { - UiCursorBus::Broadcast(&UiCursorInterface::DecrementVisibleCounter); - m_hwMouseEnabled = false; - } - } - else if (state == eHudInFocus) - { - UiCursorBus::Broadcast(&UiCursorInterface::IncrementVisibleCounter); - m_hwMouseEnabled = true; - } - - m_hudState = state; - } -} - -void CPerfHUD::Reset() -{ - IMiniGUIPtr pGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pGUI)) - { - pGUI->Reset(); - } -} - -////////////////////////////////////////////////////////////////////////// -// CLICK CALLBACKS -////////////////////////////////////////////////////////////////////////// - -void CPerfHUD::ResetCallback([[maybe_unused]] void* data, [[maybe_unused]] bool status) -{ - ICryPerfHUDPtr pPerfHUD; - if (CryCreateClassInstanceForInterface(cryiidof(), pPerfHUD)) - { - pPerfHUD->Reset(); - } -} - -void CPerfHUD::ReloadBudgetsCallback([[maybe_unused]] void* data, [[maybe_unused]] bool status) -{ - ICryPerfHUDPtr pPerfHUD; - if (CryCreateClassInstanceForInterface(cryiidof(), pPerfHUD)) - { - pPerfHUD->LoadBudgets(); - } -} - -void CPerfHUD::SaveStatsCallback([[maybe_unused]] void* data, [[maybe_unused]] bool status) -{ - ICryPerfHUDPtr pPerfHUD; - if (CryCreateClassInstanceForInterface(cryiidof(), pPerfHUD)) - { - pPerfHUD->SaveStats(); - } -} - -////////////////////////////////////////////////////////////////////////// -// RENDER CALLBACKS -////////////////////////////////////////////////////////////////////////// - -void CPerfHUD::EnableWidget(ICryPerfHUDWidget::EWidgetID id, int mode) -{ - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - if (m_widgets[i]->m_id == id) - { - m_widgets[i]->Enable(mode); - return; - } - } -} - -void CPerfHUD::DisableWidget(ICryPerfHUDWidget::EWidgetID id) -{ - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - if (m_widgets[i]->m_id == id) - { - m_widgets[i]->Disable(); - return; - } - } -} - -////////////////////////////////////////////////////////////////////////// -// Widget Specific Interface -////////////////////////////////////////////////////////////////////////// -void CPerfHUD::AddWarning(float duration, const char* fmt, va_list argList) -{ - if (m_hudState != eHudOff) - { - //could cache warnings window ptr for efficiency - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - if (m_widgets[i]->m_id == ICryPerfHUDWidget::eWidget_Warnings) - { - CWarningsWidget* warnings = (CWarningsWidget*)m_widgets[i].get(); - - if (warnings->ShouldUpdate()) - { - warnings->AddWarningV(duration, fmt, argList); - break; - } - } - } - } -} - -bool CPerfHUD::WarningsWindowEnabled() const -{ - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - if (m_widgets[i]->m_id == ICryPerfHUDWidget::eWidget_Warnings) - { - return m_widgets[i]->ShouldUpdate(); - } - } - - return false; -} - -const std::vector* CPerfHUD::GetFpsBuckets(float& totalTime) const -{ - const int nWidgets = m_widgets.size(); - - for (int i = 0; i < nWidgets; i++) - { - if (m_widgets[i]->m_id == ICryPerfHUDWidget::eWidget_FpsBuckets) - { - return ((CFpsWidget*)m_widgets[i].get())->GetFpsBuckets(totalTime); - } - } - - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -//FPS Buckets Widget -////////////////////////////////////////////////////////////////////////// - -int CFpsWidget::m_cvarPerfHudFpsExclusive = 0; - -CFpsWidget::CFpsWidget(IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud) - : ICryPerfHUDWidget(eWidget_FpsBuckets) -{ - m_fpsBucketSize = 5.f; - m_fpsBudget = 30.f; - m_dpBudget = 2500.f; - m_dpBucketSize = 250.f; - - //FPS Buckets - IMiniCtrl* pFPSMenu = pPerfHud->CreateMenu("FPS", pParentMenu); - m_pInfoBox = pPerfHud->CreateInfoMenuItem(pFPSMenu, "FPS Buckets", NULL, Rect(850, 395, 860, 405)); - pPerfHud->CreateCallbackMenuItem(pFPSMenu, "Reset Buckets", CFpsWidget::ResetCallback, this); - - //Display framerates buckets as inclusive or exclusive - REGISTER_CVAR2("sys_perfhud_fpsBucketsExclusive", &m_cvarPerfHudFpsExclusive, 0, VF_CHEAT, "Toggle FPS Buckets exclusive / inclusive"); - - Init(); -} - -void CFpsWidget::LoadBudgets(XmlNodeRef PerfXML) -{ - if (PerfXML) - { - XmlNodeRef xmlNode; - - //FPS / GPU - explicit bucket values - if ((xmlNode = PerfXML->findChild("fpsBucketValues"))) - { - m_perfBuckets[BUCKET_FPS].buckets.clear(); - m_perfBuckets[BUCKET_GPU].buckets.clear(); - - uint32 nBuckets = xmlNode->getChildCount(); - - for (uint32 i = 0; i < nBuckets; i++) - { - XmlNodeRef bucketVal = xmlNode->getChild(i); - - float target; - bucketVal->getAttr("value", target); - - ICryPerfHUD::PerfBucket bucket(target); - - m_perfBuckets[BUCKET_FPS].buckets.push_back(bucket); - m_perfBuckets[BUCKET_GPU].buckets.push_back(bucket); - } - - m_perfBuckets[BUCKET_FPS].totalTime = 0.f; - m_perfBuckets[BUCKET_GPU].totalTime = 0.f; - } - //Auto generated buckets based on max fps and bucket size - else if ((xmlNode = PerfXML->findChild("fpsBucketMax"))) - { - xmlNode->getAttr("value", m_fpsBudget); - - if ((xmlNode = PerfXML->findChild("fpsBucketSize"))) - { - xmlNode->getAttr("value", m_fpsBucketSize); - } - else - { - m_fpsBucketSize = 5; - } - - m_perfBuckets[BUCKET_FPS].buckets.clear(); - m_perfBuckets[BUCKET_GPU].buckets.clear(); - - float targetFPS = m_fpsBudget; - - for (uint32 i = 0; i < NUM_FPS_BUCKETS_DEFAULT; i++) - { - ICryPerfHUD::PerfBucket bucket(targetFPS); - - m_perfBuckets[BUCKET_FPS].buckets.push_back(bucket); - m_perfBuckets[BUCKET_GPU].buckets.push_back(bucket); - - targetFPS -= m_fpsBucketSize; - } - - m_perfBuckets[BUCKET_FPS].totalTime = 0.f; - m_perfBuckets[BUCKET_GPU].totalTime = 0.f; - } - - //DP buckets - explicit bucket values - if ((xmlNode = PerfXML->findChild("dpBucketValues"))) - { - m_perfBuckets[BUCKET_DP].buckets.clear(); - - uint32 nBuckets = xmlNode->getChildCount(); - - for (uint32 i = 0; i < nBuckets; i++) - { - XmlNodeRef bucketVal = xmlNode->getChild(i); - - float target; - bucketVal->getAttr("value", target); - - ICryPerfHUD::PerfBucket bucket(target); - - m_perfBuckets[BUCKET_DP].buckets.push_back(bucket); - } - m_perfBuckets[BUCKET_DP].totalTime = 0.f; - } - //DPs auto values - else if ((xmlNode = PerfXML->findChild("drawPrimBucketMax"))) - { - xmlNode->getAttr("value", m_dpBudget); - - //Auto generated buckets based on max dp and bucket size - if ((xmlNode = PerfXML->findChild("dpBucketSize"))) - { - xmlNode->getAttr("value", m_dpBucketSize); - } - else - { - m_dpBucketSize = 250.f; - } - - m_perfBuckets[BUCKET_DP].buckets.clear(); - - float nDPs = m_dpBudget - ((NUM_FPS_BUCKETS_DEFAULT - 1) * m_dpBucketSize); - - for (uint32 i = 0; i < NUM_FPS_BUCKETS_DEFAULT; i++) - { - ICryPerfHUD::PerfBucket bucket(nDPs); - - m_perfBuckets[BUCKET_DP].buckets.push_back(bucket); - - nDPs += m_dpBucketSize; - } - m_perfBuckets[BUCKET_DP].totalTime = 0.f; - } - } -} - -template -void CFpsWidget::UpdateBuckets(PerfBucketsStat& bucketStat, float frameTime, const char* name, float stat) -{ - char entryBuffer[CMiniInfoBox::MAX_TEXT_LENGTH] = {0}; - - const uint32 numBuckets = bucketStat.buckets.size(); - - if (frameTime > 0.f) - { - bucketStat.totalTime += frameTime; - - for (uint32 i = 0; i < numBuckets; i++) - { - if (LESS_THAN) - { - if (stat <= bucketStat.buckets[i].target) - { - bucketStat.buckets[i].timeAtTarget += frameTime; - } - } - else - { - if (stat >= bucketStat.buckets[i].target) - { - bucketStat.buckets[i].timeAtTarget += frameTime; - } - } - } - } - - if (bucketStat.totalTime > 0.f) - { - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "%s: %.2f", name, stat); - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - - //render exclusive stats - if (m_cvarPerfHudFpsExclusive) - { - for (uint32 i = 0; i < numBuckets; i++) - { - //inclusive time - float timeAtTarget = bucketStat.buckets[i].timeAtTarget; - - if (i > 0) - { - //exclusive time - timeAtTarget -= bucketStat.buckets[i - 1].timeAtTarget; - - //Add info to gui - float percentAtTarget = 100.f * (timeAtTarget / bucketStat.totalTime); - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "%.2f%%%% of time %.1f -> %.1f FPS", percentAtTarget, bucketStat.buckets[i].target, bucketStat.buckets[i - 1].target); - } - else - { - float percentAtTarget = 100.f * (bucketStat.buckets[i].timeAtTarget / bucketStat.totalTime); - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "%.2f%%%% of time >= %.1f FPS", percentAtTarget, bucketStat.buckets[i].target); - } - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - } - else //render inclusive stats - { - for (uint32 i = 0; i < numBuckets; i++) - { - float percentAtTarget = 100.f * (bucketStat.buckets[i].timeAtTarget / bucketStat.totalTime); - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "%.2f%%%% of time %s %.1f", percentAtTarget, LESS_THAN ? "<=" : ">=", bucketStat.buckets[i].target); - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - } - } -} - -void CFpsWidget::Update() -{ - m_pInfoBox->ClearEntries(); - - // - // FPS - // - { - float frameTime = gEnv->pTimer->GetRealFrameTime(); - UpdateBuckets(m_perfBuckets[BUCKET_FPS], frameTime, "FPS", 1.f / frameTime); - } - - // - // GPU FPS - // - { - float gpuFrameTime = gEnv->pRenderer->GetGPUFrameTime(); - - if (gpuFrameTime > 0.f) - { - m_pInfoBox->AddEntry("", CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - UpdateBuckets(m_perfBuckets[BUCKET_GPU], gpuFrameTime, "GPU FPS", 1.f / gpuFrameTime); - } - } - - // - // Draw Call - // - { - //ugly, but buckets are float only at the moment - float nDPs = (float)gEnv->pRenderer->GetCurrentNumberOfDrawCalls(); - m_pInfoBox->AddEntry("", CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - UpdateBuckets(m_perfBuckets[BUCKET_DP], 1.f, "DPs", nDPs); - } -} - -//Init buckets with default values -void CFpsWidget::Init() -{ - float targetFPS = m_fpsBudget; - float nDPs = m_dpBudget - ((NUM_FPS_BUCKETS_DEFAULT - 1) * m_dpBucketSize); - - for (uint32 i = 0; i < NUM_FPS_BUCKETS_DEFAULT; i++) - { - ICryPerfHUD::PerfBucket bucket(targetFPS); - - m_perfBuckets[BUCKET_FPS].buckets.push_back(bucket); - m_perfBuckets[BUCKET_GPU].buckets.push_back(bucket); - - bucket.target = (float)nDPs; - - m_perfBuckets[BUCKET_DP].buckets.push_back(bucket); - - targetFPS -= m_fpsBucketSize; - nDPs += m_dpBucketSize; - } - - for (uint32 i = 0; i < BUCKET_TYPE_NUM; i++) - { - m_perfBuckets[i].totalTime = 0.f; - } -} - -//Clear bucket totals -void CFpsWidget::Reset() -{ - for (uint32 i = 0; i < BUCKET_TYPE_NUM; i++) - { - PerfBucketsStat& stat = m_perfBuckets[i]; - - const uint32 nBuckets = stat.buckets.size(); - - //Init fps buckets - for (uint32 j = 0; j < nBuckets; j++) - { - stat.buckets[j].timeAtTarget = 0.f; - } - - stat.totalTime = 0.f; - } -} - -void CFpsWidget::ResetCallback(void* data, [[maybe_unused]] bool status) -{ - assert(data); - ((CFpsWidget*)data)->Reset(); -} - -bool CFpsWidget::ShouldUpdate() -{ - return !m_pInfoBox->IsHidden(); -} - -//TODO -void CFpsWidget::SaveStats(XmlNodeRef statsXML) -{ - if (statsXML) - { - const char* perfBucketTypeStr[] = - { - "BUCKET_FPS", - "BUCKET_GPU", - "BUCKET_DP", - }; - - XmlNodeRef fpsNode; - - for (int i = 0; i < BUCKET_TYPE_NUM; i++) - { - PerfBucketsStat& perfBucket = m_perfBuckets[i]; - - if (perfBucket.totalTime > 0.f) - { - if ((fpsNode = statsXML->newChild(perfBucketTypeStr[i]))) - { - XmlNodeRef child; - - const uint32 numBuckets = perfBucket.buckets.size(); - - for (uint32 j = 0; j < numBuckets; j++) - { - float percentAtTarget = 100.f * (perfBucket.buckets[j].timeAtTarget / perfBucket.totalTime); - - if ((child = fpsNode->newChild("bucket"))) - { - child->setAttr("target", perfBucket.buckets[j].target); - } - - if ((child = fpsNode->newChild("percentAtTime"))) - { - child->setAttr("value", percentAtTarget); - } - } - } - } - } - } -} - -const std::vector* CFpsWidget::GetFpsBuckets(float& totalTime) const -{ - totalTime = m_perfBuckets[BUCKET_FPS].totalTime; - return &m_perfBuckets[BUCKET_FPS].buckets; -} - -////////////////////////////////////////////////////////////////////////// -//Render Stats Widget -////////////////////////////////////////////////////////////////////////// - -CRenderStatsWidget::CRenderStatsWidget(IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud) - : ICryPerfHUDWidget(eWidget_RenderStats) -{ - m_pPerfHUD = pPerfHud; - m_fpsBudget = 30.f; - m_dpBudget = 2000; - m_polyBudget = 500000; - m_postEffectBudget = 3; - m_shadowCastBudget = 2; - m_particlesBudget = 1000; - m_pInfoBox = NULL; - m_buildNum = 0; - - ZeroStruct(m_runtimeData); - - m_pInfoBox = pPerfHud->CreateInfoMenuItem(pParentMenu, "Scene Summary", NULL, Rect(45, 350, 100, 400) /*, true*/); - - //Get build number from BuildName.txt - //FILE *buildFile = fxopen("BuildName.txt", "r"); - CCryFile buildFile; - - if (buildFile.Open("./BuildName.txt", "rb", AZ::IO::IArchive::FOPEN_ONDISK | AZ::IO::IArchive::FOPEN_HINT_QUIET)) - { - size_t fileSize = buildFile.GetLength(); - - if (fileSize > 0 && fileSize < 64) - { - char buffer[64] = {0}; - - buildFile.ReadRaw(buffer, fileSize); - - if (buffer[0]) - { - const char* ptr = strchr(buffer, '('); - - if (ptr) - { - ptr++; - m_buildNum = atoi(ptr); - } - } - } - } -} - -void CRenderStatsWidget::Update() -{ - IRenderer* pRenderer = gEnv->pRenderer; - - char entryBuffer[CMiniInfoBox::MAX_TEXT_LENGTH] = {0}; - - //Clear old entries - m_pInfoBox->ClearEntries(); - ZeroStruct(m_runtimeData); - - // - // FPS - // - m_runtimeData.fps = min(9999.f, gEnv->pTimer->GetFrameRate()); - - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "FPS: %.2f (%.2f)", m_runtimeData.fps, m_fpsBudget); - - if (m_runtimeData.fps >= m_fpsBudget) - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - else - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_NORM); - CryPerfHUDWarning(1.f, "FPS Too Low: %.2f", m_runtimeData.fps); - - //PerfHud / AuxRenderer causes us to be RenderThread limited - //Need to investigate vertex buffer locks in AuxRenderer before enabling - - /* - // Fran: please call me before re-enabling this code - - SRenderTimes renderTimes; - pRenderer->GetRenderTimes(renderTimes); - - //wait for main is never 0 - if(renderTimes.fWaitForMain>renderTimes.fWaitForRender && renderTimes.fWaitForMain>renderTimes.fWaitForGPU) - { - m_pInfoBox->AddEntry("Main Thread Limited", CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_ERROR); - m_pPerfHud->AddWarning("Main Thread Limited",1.f); - } - else if(renderTimes.fWaitForRender>renderTimes.fWaitForGPU) - { - m_pInfoBox->AddEntry("Render Thread Limited", CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_ERROR); - m_pPerfHud->AddWarning("Render Thread Limited",1.f); - } - else - { - m_pInfoBox->AddEntry("GPU Limited", CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_ERROR); - m_pPerfHud->AddWarning("GPU Limited",1.f); - }*/ - } - - // - // GPU Time - // - float gpuTime = pRenderer->GetGPUFrameTime(); - - if (gpuTime > 0.f) - { - float gpuFPS = 1.f / gpuTime; - - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "GPU FPS: %.2f (%.2f)", gpuFPS, m_fpsBudget); - if (gpuFPS >= m_fpsBudget) - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - else - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_NORM); - CryPerfHUDWarning(1.f, "GPU FPS Too Low: %.2f", gpuFPS); - } - } - - - // - // HDR - // - bool bHDRModeEnabled = false; - pRenderer->EF_Query(EFQ_HDRModeEnabled, bHDRModeEnabled); - if (bHDRModeEnabled) - { - m_runtimeData.hdrEnabled = true; - if (!m_runtimeData.hdrEnabled) - { - CryPerfHUDWarning(1.f, "HDR Disabled"); - } - } - - if (!gEnv->IsEditor()) - { - // - // Render Thread - // - static ICVar* pMultiThreaded = gEnv->pConsole->GetCVar("r_MultiThreaded"); - if (pMultiThreaded && pMultiThreaded->GetIVal() > 0) - { - //sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "Render Thread Enabled"); - //m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - m_runtimeData.renderThreadEnabled = true; - } - else - { - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "Render Thread Disabled"); - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_NORM); - m_runtimeData.renderThreadEnabled = false; - CryPerfHUDWarning(1.f, "Render Thread Disabled"); - } - } - - - // - // Camera - // - Matrix33 m = Matrix33(pRenderer->GetCamera().GetMatrix()); - m_runtimeData.cameraRot = RAD2DEG(Ang3::GetAnglesXYZ(m)); - m_runtimeData.cameraPos = pRenderer->GetCamera().GetPosition(); - - - // - // Polys / Draw Prims - // - int nShadowVolPolys; - int nPolys; - pRenderer->GetPolyCount(nPolys, nShadowVolPolys); - m_runtimeData.nPolys = nPolys; - m_runtimeData.nDrawPrims = pRenderer->GetCurrentNumberOfDrawCalls(); - - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "Draw Calls: %d (%d)", m_runtimeData.nDrawPrims, m_dpBudget); - - if (m_runtimeData.nDrawPrims <= m_dpBudget) - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - else - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_NORM); - CryPerfHUDWarning(1.f, "Too Many Draw Calls: %d", m_runtimeData.nDrawPrims); - } - - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "Num Tris: %d (%d)", m_runtimeData.nPolys, m_polyBudget); - - if (m_runtimeData.nPolys <= m_polyBudget) - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - else - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_NORM); - CryPerfHUDWarning(1.f, "Too Many Tris: %d", m_runtimeData.nPolys); - } - - // - // Post Effects - // - - gEnv->pRenderer->EF_Query(EFQ_NumActivePostEffects, m_runtimeData.nPostEffects); - sprintf_s(entryBuffer, CMiniInfoBox::MAX_TEXT_LENGTH, "Num Post Effects: %d (%d)", m_runtimeData.nPostEffects, m_postEffectBudget); - - if (m_runtimeData.nPostEffects <= m_postEffectBudget) - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - else - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_NORM); - CryPerfHUDWarning(1.f, "Too Many Post Effects: %d", m_runtimeData.nPostEffects); - } - - m_runtimeData.nFwdLights = 0; - m_runtimeData.nFwdShadowLights = 0; - - ////////////////////////////////////////////////////////////////////////// - if (gEnv->pRenderer) - { - STextureStreamingStats textureStats(true); - gEnv->pRenderer->EF_Query(EFQ_GetTexStreamingInfo, textureStats); - - float fTexRequiredMB = (float)(textureStats.nRequiredStreamedTexturesSize) / (1024 * 1024); - sprintf_s(entryBuffer, "Textures Required: %.2f (%dMB)", fTexRequiredMB, azlossy_cast(textureStats.nMaxPoolSize / (1024 * 1024))); - if (fTexRequiredMB < textureStats.nMaxPoolSize) - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_NORM, CPerfHUD::TEXT_SIZE_NORM); - } - else - { - m_pInfoBox->AddEntry(entryBuffer, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_NORM); - CryPerfHUDWarning(1.f, "Too Many Textures: %.2fMB", fTexRequiredMB); - } - } -} -bool CRenderStatsWidget::ShouldUpdate() -{ - if (!m_pInfoBox->IsHidden() || - m_pPerfHUD->WarningsWindowEnabled()) - { - return true; - } - return false; -} - -void CRenderStatsWidget::LoadBudgets(XmlNodeRef perfXML) -{ - if (perfXML) - { - XmlNodeRef xmlNode; - - if ((xmlNode = perfXML->findChild("fps"))) - { - xmlNode->getAttr("value", m_fpsBudget); - } - - if ((xmlNode = perfXML->findChild("drawPrim"))) - { - xmlNode->getAttr("value", m_dpBudget); - } - - if ((xmlNode = perfXML->findChild("tris"))) - { - xmlNode->getAttr("value", m_polyBudget); - } - - if ((xmlNode = perfXML->findChild("postEffects"))) - { - xmlNode->getAttr("value", m_postEffectBudget); - } - - if ((xmlNode = perfXML->findChild("shadowCastingLights"))) - { - xmlNode->getAttr("value", m_shadowCastBudget); - } - - if ((xmlNode = perfXML->findChild("particles"))) - { - xmlNode->getAttr("value", m_particlesBudget); - } - } -} - -void CRenderStatsWidget::SaveStats(XmlNodeRef statsXML) -{ - if (!ShouldUpdate()) - { - //Force update of stats, widget may not be currently enabled - Update(); - } - - if (statsXML) - { - XmlNodeRef renderNode; - - if ((renderNode = statsXML->newChild("RenderStats"))) - { - XmlNodeRef child; - - if ((child = renderNode->newChild("fps"))) - { - child->setAttr("value", m_runtimeData.fps); - } - - if ((child = renderNode->newChild("hdr"))) - { - child->setAttr("value", m_runtimeData.hdrEnabled); - } - - if ((child = renderNode->newChild("renderThread"))) - { - child->setAttr("value", m_runtimeData.renderThreadEnabled); - } - - if ((child = renderNode->newChild("cameraPos"))) - { - child->setAttr("x", m_runtimeData.cameraPos.x); - child->setAttr("y", m_runtimeData.cameraPos.y); - child->setAttr("z", m_runtimeData.cameraPos.z); - } - - if ((child = renderNode->newChild("cameraRot"))) - { - child->setAttr("x", m_runtimeData.cameraRot.x); - child->setAttr("y", m_runtimeData.cameraRot.y); - child->setAttr("z", m_runtimeData.cameraRot.z); - } - - if ((child = renderNode->newChild("drawPrims"))) - { - child->setAttr("value", m_runtimeData.nDrawPrims); - } - - if ((child = renderNode->newChild("numPolys"))) - { - child->setAttr("value", m_runtimeData.nPolys); - } - - if ((child = renderNode->newChild("numPostEffects"))) - { - child->setAttr("value", m_runtimeData.nPostEffects); - } - - if ((child = renderNode->newChild("numFwdLights"))) - { - child->setAttr("value", m_runtimeData.nFwdLights); - } - - if ((child = renderNode->newChild("numFwdShadowLights"))) - { - child->setAttr("value", m_runtimeData.nFwdShadowLights); - } - - if ((child = renderNode->newChild("numDefLights"))) - { - child->setAttr("value", m_runtimeData.nDefLights); - } - - if ((child = renderNode->newChild("numDefShadowLights"))) - { - child->setAttr("value", m_runtimeData.nDefShadowLights); - } - - if ((child = renderNode->newChild("numDefCubeMaps"))) - { - child->setAttr("value", m_runtimeData.nDefCubeMaps); - } - - if ((child = renderNode->newChild("numParticles"))) - { - child->setAttr("value", m_runtimeData.nParticles); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -//Streaming Stats Widget -////////////////////////////////////////////////////////////////////////// - -CStreamingStatsWidget::CStreamingStatsWidget(IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud) - : ICryPerfHUDWidget(eWidget_StreamingStats) -{ - m_pPerfHUD = pPerfHud; - m_pInfoBox = pPerfHud->CreateInfoMenuItem(pParentMenu, "Streaming", NULL, Rect(45, 200, 100, 300), true); - - //m_maxMeshSizeArroundMB = 0; - //m_maxTextureSizeArroundMB = 0; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingStatsWidget::Update() -{ -} - -////////////////////////////////////////////////////////////////////////// -bool CStreamingStatsWidget::ShouldUpdate() -{ - if (!m_pInfoBox->IsHidden() || - m_pPerfHUD->WarningsWindowEnabled()) - { - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingStatsWidget::LoadBudgets(XmlNodeRef perfXML) -{ - /* -if(perfXML) -{ -XmlNodeRef xmlNode; -if( (xmlNode=perfXML->findChild("MeshSizeArround")) ) -{ - xmlNode->getAttr("value", m_maxMeshSizeArroundMB); -} -if( (xmlNode=perfXML->findChild("TextureSizeArround")) ) -{ - xmlNode->getAttr("value", m_maxTextureSizeArroundMB); -} -} -*/ -} - -////////////////////////////////////////////////////////////////////////// -//Warnings Widget -////////////////////////////////////////////////////////////////////////// - -CWarningsWidget::CWarningsWidget(IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud) - : ICryPerfHUDWidget(eWidget_Warnings) -{ - m_pInfoBox = pPerfHud->CreateInfoMenuItem(pParentMenu, "Warnings", NULL, Rect(890, 150, 900, 200) /*, true*/); - - m_nMainThreadId = CryGetCurrentThreadId(); -} - -void CWarningsWidget::Reset() -{ - m_warnings.clear(); -} - -void CWarningsWidget::Update() -{ - //must be Main thread for MT warnings to work - assert(CryGetCurrentThreadId() == m_nMainThreadId); - - //Update from multithreaded queue - while (!m_threadWarnings.empty()) - { - SWarning warning; - if (m_threadWarnings.try_pop(warning)) - { - AddWarning(warning.remainingDuration, warning.text); - } - } - - float frameTime = gEnv->pTimer->GetRealFrameTime(); - - //delete old warnings - // [K01]: fixing Linux crash - TSWarnings::iterator iter = m_warnings.begin(); - while (iter != m_warnings.end()) - { - SWarning* pW = &(*iter); - pW->remainingDuration -= frameTime; - - if (pW->remainingDuration <= 0.f) - { - iter = m_warnings.erase(iter); - } - else - { - ++iter; - } - } - - int nWarnings = m_warnings.size(); - m_pInfoBox->ClearEntries(); - - //display warnings - for (int i = 0; i < nWarnings; i++) - { - m_pInfoBox->AddEntry(m_warnings[i].text, CPerfHUD::COL_ERROR, CPerfHUD::TEXT_SIZE_WARN); - } -} - -bool CWarningsWidget::ShouldUpdate() -{ - return !m_pInfoBox->IsHidden(); -} - -void CWarningsWidget::SaveStats(XmlNodeRef statsXML) -{ - if (statsXML) - { - const int nWarnings = m_warnings.size(); - - if (nWarnings > 0) - { - XmlNodeRef warningNode; - - if ((warningNode = statsXML->newChild("warnings"))) - { - XmlNodeRef child; - - for (int i = 0; i < nWarnings; i++) - { - if ((child = warningNode->newChild("warning"))) - { - child->setAttr("value", m_warnings[i].text); - } - } - } - } - } -} - -void CWarningsWidget::AddWarningV(float duration, const char* fmt, va_list argList) -{ - char warningText[WARNING_LENGTH]; - - int written = vsnprintf_s(warningText, WARNING_LENGTH, WARNING_LENGTH - 1, fmt, argList); - - if (written == -1) - { - warningText[WARNING_LENGTH - 1] = '\0'; - } - - AddWarning(duration, warningText); -} - -void CWarningsWidget::AddWarning(float duration, const char* warning) -{ - if (CryGetCurrentThreadId() == m_nMainThreadId) - { - const size_t nWarnings = m_warnings.size(); - bool bNewWarning = true; - - ptrdiff_t nCompareLen = strlen(warning); - const char* s = strchr(warning, ':'); - if (s) - { - nCompareLen = s - warning; - } - - for (size_t i = 0; i < nWarnings; i++) - { - if (strncmp(m_warnings[i].text, warning, nCompareLen) == 0) - { - //warning already exists, update duration - m_warnings[i].remainingDuration = duration; - cry_strcpy(m_warnings[i].text, warning); - bNewWarning = false; - break; - } - } - - if (bNewWarning) - { - SWarning newWarning; - newWarning.remainingDuration = duration; - cry_strcpy(newWarning.text, warning); - - m_warnings.push_back(newWarning); - } - } - else - { - //add to thread safe queue, warning will be added next update - SWarning newWarning; - newWarning.remainingDuration = duration; - cry_strcpy(newWarning.text, warning); - m_threadWarnings.push(newWarning); - } -} - -////////////////////////////////////////////////////////////////////////// -//Render Batch Stats Widget -////////////////////////////////////////////////////////////////////////// - -CRenderBatchWidget::CRenderBatchWidget(IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud) - : ICryPerfHUDWidget(eWidget_RenderBatchStats) -{ - m_pTable = pPerfHud->CreateTableMenuItem(pParentMenu, "Render Batch Stats"); - - m_pRStatsCVar = GetISystem()->GetIConsole()->GetCVar("r_stats"); - - m_displayMode = DISPLAY_MODE_BATCH_STATS; - - m_pTable->RemoveColumns(); - m_pTable->AddColumn("Name"); - m_pTable->AddColumn("DPs"); - m_pTable->AddColumn("Instances"); - m_pTable->AddColumn("ZPass"); - m_pTable->AddColumn("Shadows"); - m_pTable->AddColumn("General"); - m_pTable->AddColumn("Transparent"); - m_pTable->AddColumn("Misc"); -} - -void CRenderBatchWidget::Reset() -{ -} - -void CRenderBatchWidget::SaveStats(XmlNodeRef statsXML) -{ -} - -void CRenderBatchWidget::Enable(int mode) -{ - mode = min(mode, DISPLAY_MODE_NUM - 1); - EDisplayMode newMode = (EDisplayMode)mode; - - if (m_displayMode != newMode) - { - //workaround for now, - //since we poke renderer in order to gather stats - switch (m_displayMode) - { - case DISPLAY_MODE_BATCH_STATS: - gEnv->pRenderer->CollectDrawCallsInfo(false); - break; - - case DISPLAY_MODE_GPU_TIMES: - m_pRStatsCVar->Set(0); - break; - } - - switch (newMode) - { - case DISPLAY_MODE_BATCH_STATS: - m_pTable->RemoveColumns(); - m_pTable->AddColumn("Name"); - m_pTable->AddColumn("DPs"); - m_pTable->AddColumn("Instances"); - m_pTable->AddColumn("ZPass"); - m_pTable->AddColumn("Shadows"); - m_pTable->AddColumn("General"); - m_pTable->AddColumn("Transparent"); - m_pTable->AddColumn("Misc"); - m_displayMode = newMode; - break; - - case DISPLAY_MODE_GPU_TIMES: - m_pTable->RemoveColumns(); - m_pTable->AddColumn("Name"); - m_pTable->AddColumn("Num Batches"); - m_pTable->AddColumn("Num Verts"); - m_pTable->AddColumn("Num Tris"); - m_displayMode = newMode; - break; - - default: - CryLogAlways("[Render Batch Stats] Attempting to set incorrect display mode set: %d", mode); - break; - } - } - - m_pTable->Hide(false); -} - -void CRenderBatchWidget::Disable() -{ - //ensure renderer is not doing unnecessary work - m_pRStatsCVar->Set(0); - gEnv->pRenderer->CollectDrawCallsInfo(false); - m_pTable->Hide(true); -} - - -bool CRenderBatchWidget::ShouldUpdate() -{ - return !m_pTable->IsHidden(); -} - -void CRenderBatchWidget::Update() -{ - switch (m_displayMode) - { - case DISPLAY_MODE_BATCH_STATS: - Update_ModeBatchStats(); - break; - case DISPLAY_MODE_GPU_TIMES: - Update_ModeGpuTimes(); - break; - default: - CryLogAlways("[Render Batch Stats]Incorrect Display mode set: %d", m_displayMode); - break; - } -} - -void CRenderBatchWidget::Update_ModeBatchStats() -{ -#if !defined(_RELEASE) - IRenderer* pRenderer = gEnv->pRenderer; - - pRenderer->CollectDrawCallsInfo(true); - - typedef std::map BatchMap; - typedef std::map::iterator BatchMapItor; - - //sorted Map elements - std::vector sortedBatchList; - - BatchMap batchMap; - - //mesh totals - static const char* strMeshTotals = "TOTAL (Mesh)"; - BatchInfoPerPass totalsMesh; - totalsMesh.col.set(255, 255, 255, 255); - totalsMesh.name = strMeshTotals; - - int nDPs = gEnv->pRenderer->GetCurrentNumberOfDrawCalls(); - - //scene totals - static const char* strSceneTotals = "TOTAL (Scene)"; - - BatchInfoPerPass totalsScene; - totalsScene.col.set(0, 255, 255, 255); - totalsScene.name = strSceneTotals; - totalsScene.nBatches = nDPs; - - int unknownDPs = nDPs; - - m_pTable->ClearTable(); - - IRenderer::RNDrawcallsMapMesh& drawCallsInfo = gEnv->pRenderer->GetDrawCallsInfoPerMesh(); - - IRenderer::RNDrawcallsMapMeshItor pEnd = drawCallsInfo.end(); - IRenderer::RNDrawcallsMapMeshItor pItor = drawCallsInfo.begin(); - - //Per RenderNode Stats - for (; pItor != pEnd; ++pItor) - { - IRenderer::SDrawCallCountInfo& drawInfo = pItor->second; - - uint32 nDrawcalls = drawInfo.nShadows + drawInfo.nZpass + drawInfo.nGeneral + drawInfo.nTransparent + drawInfo.nMisc; - - const char* pRenderNodeName = drawInfo.meshName; - const char* pNameShort = strrchr(pRenderNodeName, '/'); - - if (pNameShort) - { - pRenderNodeName = pNameShort + 1; - } - - BatchInfoPerPass batch; - - batch.name = pRenderNodeName; - batch.nBatches = nDrawcalls; - batch.nInstances = 1; - batch.nZpass = drawInfo.nZpass; - batch.nShadows = drawInfo.nShadows; - batch.nGeneral = drawInfo.nGeneral; - batch.nTransparent = drawInfo.nTransparent; - batch.nMisc = drawInfo.nMisc; - - BatchMapItor batchIter = batchMap.find(string(pRenderNodeName)); - - //already an entry for this stat obj - append details - if (batchIter != batchMap.end()) - { - BatchInfoPerPass& currentBatch = batchIter->second; - currentBatch += batch; - } - else - { - //insert new entry into map - std::pair newElem = batchMap.insert(BatchMapItor::value_type(string(pRenderNodeName), batch)); - BatchInfoPerPass& newBatch = newElem.first->second; - sortedBatchList.push_back(&newBatch); - } - - totalsMesh += batch; - } - - unknownDPs -= totalsMesh.nBatches; - - // - // Unknown counts (sceneDP - sum of batches) - // - //could be -ve or +ve (-ve for conditional rendering) - if (unknownDPs != 0) - { - static const char* s_strUnknown = "Unknown"; - static BatchInfoPerPass s_unknownBatch; - s_unknownBatch.Reset(); - s_unknownBatch.name = s_strUnknown; - s_unknownBatch.nBatches = max(0, unknownDPs); - s_unknownBatch.col.set(255, 255, 0, 255); - sortedBatchList.push_back(&s_unknownBatch); - } - - //Scene Totals - m_pTable->AddData(0, totalsScene.col, totalsScene.name); - m_pTable->AddData(1, totalsScene.col, "%d", totalsScene.nBatches); - m_pTable->AddData(2, totalsScene.col, "%d", totalsScene.nInstances); - m_pTable->AddData(3, totalsScene.col, "%d", totalsScene.nZpass); - m_pTable->AddData(4, totalsScene.col, "%d", totalsScene.nShadows); - m_pTable->AddData(5, totalsScene.col, "%d", totalsScene.nGeneral); - m_pTable->AddData(6, totalsScene.col, "%d", totalsScene.nTransparent); - m_pTable->AddData(7, totalsScene.col, "%d", totalsScene.nMisc); - - //Mesh Totals - m_pTable->AddData(0, totalsMesh.col, totalsMesh.name); - m_pTable->AddData(1, totalsMesh.col, "%d", totalsMesh.nBatches); - m_pTable->AddData(2, totalsMesh.col, "%d", totalsMesh.nInstances); - m_pTable->AddData(3, totalsMesh.col, "%d", totalsMesh.nZpass); - m_pTable->AddData(4, totalsMesh.col, "%d", totalsMesh.nShadows); - m_pTable->AddData(5, totalsMesh.col, "%d", totalsMesh.nGeneral); - m_pTable->AddData(6, totalsMesh.col, "%d", totalsMesh.nTransparent); - m_pTable->AddData(7, totalsMesh.col, "%d", totalsMesh.nMisc); - - - if (int nBatches = sortedBatchList.size()) - { - std::sort(sortedBatchList.begin(), sortedBatchList.end(), BatchInfoSortPerPass()); - - for (int i = 0; i < nBatches; i++) - { - BatchInfoPerPass* batch = sortedBatchList[i]; - - int nInstances = max(1, (int)batch->nInstances); - - m_pTable->AddData(0, batch->col, batch->name); - - //Due to different render meshes with the same name, averaged - //stats are a bit confusing, disabling for now - if constexpr (0 && batch->nInstances > 1) - { - m_pTable->AddData(1, batch->col, "%d (%d)", batch->nBatches, batch->nBatches / nInstances); - m_pTable->AddData(2, batch->col, "%d", batch->nInstances); - m_pTable->AddData(3, batch->col, "%d (%d)", batch->nZpass, batch->nZpass / nInstances); - m_pTable->AddData(4, batch->col, "%d (%d)", batch->nShadows, batch->nShadows / nInstances); - m_pTable->AddData(5, batch->col, "%d (%d)", batch->nGeneral, batch->nGeneral / nInstances); - m_pTable->AddData(6, batch->col, "%d (%d)", batch->nTransparent, batch->nTransparent / nInstances); - m_pTable->AddData(7, batch->col, "%d (%d)", batch->nMisc, batch->nMisc / nInstances); - } - else - { - m_pTable->AddData(1, batch->col, "%d", batch->nBatches); - m_pTable->AddData(2, batch->col, "%d", batch->nInstances); - m_pTable->AddData(3, batch->col, "%d", batch->nZpass); - m_pTable->AddData(4, batch->col, "%d", batch->nShadows); - m_pTable->AddData(5, batch->col, "%d", batch->nGeneral); - m_pTable->AddData(6, batch->col, "%d", batch->nTransparent); - m_pTable->AddData(7, batch->col, "%d", batch->nMisc); - } - } - } -#else - m_pTable->ClearTable(); - m_pTable->AddData(0, ColorB(255, 0, 0, 255), "Not supported in Release builds"); -#endif//RELEASE (DO_RENDERSTATS - not available in CrySystem) -} - -void CRenderBatchWidget::Update_ModeGpuTimes() -{ - m_pTable->ClearTable(); - m_pTable->AddData(0, ColorB(255, 0, 0, 255), "Not supported for this platform"); -} - - -#endif //USE_PERFHUD - diff --git a/Code/CryEngine/CrySystem/PerfHUD.h b/Code/CryEngine/CrySystem/PerfHUD.h deleted file mode 100644 index 27078eb3c6..0000000000 --- a/Code/CryEngine/CrySystem/PerfHUD.h +++ /dev/null @@ -1,478 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Button implementation in the MiniGUI - - -#ifndef CRYINCLUDE_CRYSYSTEM_PERFHUD_H -#define CRYINCLUDE_CRYSYSTEM_PERFHUD_H -#pragma once - - -#include - -#ifdef USE_PERFHUD - -#include -#include "MiniGUI/MiniInfoBox.h" -#include "MiniGUI/MiniTable.h" - -//Macros for console based widget control - -#define SET_WIDGET_DECL(WIDGET_NAME) \ - static int s_cvar_##WIDGET_NAME; \ - static void Set_##WIDGET_NAME##_Widget(ICVar * pCvar); - -#define SET_WIDGET_DEF(WIDGET_NAME, WIDGET_ID) \ - int CPerfHUD::s_cvar_##WIDGET_NAME = 0; \ - void CPerfHUD::Set_##WIDGET_NAME##_Widget(ICVar * pCvar) \ - { \ - ICryPerfHUD* pPerfHud = gEnv->pSystem->GetPerfHUD(); \ - if (pPerfHud) \ - { \ - int val = pCvar->GetIVal(); \ - if (val) \ - { \ - pPerfHud->SetState(eHudOutOfFocus); \ - pPerfHud->EnableWidget(ICryPerfHUDWidget::WIDGET_ID, val); \ - } \ - else \ - { \ - pPerfHud->DisableWidget(ICryPerfHUDWidget::WIDGET_ID); \ - } \ - } \ - } - -#define SET_WIDGET_COMMAND(COMMAND_NAME, WIDGET_NAME) \ - REGISTER_CVAR2_CB(COMMAND_NAME, &s_cvar_##WIDGET_NAME, 0, VF_ALWAYSONCHANGE, "", Set_##WIDGET_NAME##_Widget); - -////////////////////////////////////////////////////////////////////////// -// Root window all other controls derive from -class CPerfHUD - : public ICryPerfHUD - , public minigui::IMiniGUIEventListener - , public AzFramework::InputChannelEventListener -{ -public: - CRYINTERFACE_BEGIN() - CRYINTERFACE_ADD(ICryPerfHUD) - CRYINTERFACE_END() - CRYGENERATE_SINGLETONCLASS(CPerfHUD, "PerfHUD", 0x006945f9985e4ce2, 0x872120bfdec09ca5) - -public: - ////////////////////////////////////////////////////////////////////////// - // ICryPerfHUD implementation - ////////////////////////////////////////////////////////////////////////// - virtual void Init(); - virtual void Done(); - virtual void Draw(); - virtual void LoadBudgets(); - virtual void SaveStats(const char* filename); - virtual void ResetWidgets(); - virtual void Reset(); - virtual void Destroy(); - - //Set state through code (rather than using joypad input) - virtual void SetState(EHudState state); - - virtual void Show(bool bRestoreState); - - virtual void AddWidget(ICryPerfHUDWidget* pWidget); - virtual void RemoveWidget(ICryPerfHUDWidget* pWidget); - - ////////////////////////////////////////////////////////////////////////// - // Gui Creation helper funcs - ////////////////////////////////////////////////////////////////////////// - virtual minigui::IMiniCtrl* CreateMenu(const char* name, minigui::IMiniCtrl* pParent = NULL); - virtual bool CreateCVarMenuItem(minigui::IMiniCtrl* pMenu, const char* name, const char* controlVar, float controlVarOn, float controlVarOff); - virtual bool CreateCallbackMenuItem(minigui::IMiniCtrl* pMenu, const char* name, minigui::ClickCallback callback, void* pCallbackData); - virtual minigui::IMiniInfoBox* CreateInfoMenuItem(minigui::IMiniCtrl* pMenu, const char* name, minigui::RenderCallback renderCallback, const minigui::Rect& rect, bool onAtStart = false); - virtual minigui::IMiniTable* CreateTableMenuItem(minigui::IMiniCtrl* pMenu, const char* name); - - virtual minigui::IMiniCtrl* GetMenu(const char* name); - - virtual void EnableWidget(ICryPerfHUDWidget::EWidgetID id, int mode); - virtual void DisableWidget(ICryPerfHUDWidget::EWidgetID id); - - ////////////////////////////////////////////////////////////////////////// - // WARNINGS - Widget Specific Interface - ////////////////////////////////////////////////////////////////////////// - virtual void AddWarning(float duration, const char* fmt, va_list argList); - virtual bool WarningsWindowEnabled() const; - - ////////////////////////////////////////////////////////////////////////// - // FPS - Widget Specific Interface - ////////////////////////////////////////////////////////////////////////// - virtual const std::vector* GetFpsBuckets(float& totalTime) const; - - ////////////////////////////////////////////////////////////////////////// - // IMiniGUIEventListener implementation - ////////////////////////////////////////////////////////////////////////// - virtual void OnCommand(minigui::SCommand& cmd); - ////////////////////////////////////////////////////////////////////////// - - // AzFramework::InputChannelEventListener - bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override; - AZ::s32 GetPriority() const override { return AzFramework::InputChannelEventListener::GetPriorityUI(); } - - ////////////////////////////////////////////////////////////////////////// - // CLICK CALLBACKS - ////////////////////////////////////////////////////////////////////////// - - static void ResetCallback(void* data, bool status); - static void ReloadBudgetsCallback(void* data, bool status); - static void SaveStatsCallback(void* data, bool status); - - ////////////////////////////////////////////////////////////////////////// - // RENDER CALLBACKS - ////////////////////////////////////////////////////////////////////////// - - static void DisplayRenderInfoCallback(const minigui::Rect& rect); - - ////////////////////////////////////////////////////////////////////////// - // CVAR CALLBACK - ////////////////////////////////////////////////////////////////////////// - - static void CVarChangeCallback(ICVar* pCvar); - - SET_WIDGET_DECL(Warnings); - SET_WIDGET_DECL(RenderSummary); - SET_WIDGET_DECL(RenderBatchStats); - SET_WIDGET_DECL(FpsBuckets); - SET_WIDGET_DECL(Particles); - SET_WIDGET_DECL(PakFile); - - ////////////////////////////////////////////////////////////////////////// - // Static Data - ////////////////////////////////////////////////////////////////////////// - - static const float OVERSCAN_X; - static const float OVERSCAN_Y; - - static const ColorB COL_NORM; - static const ColorB COL_WARN; - static const ColorB COL_ERROR; - - static const float TEXT_SIZE_NORM; - static const float TEXT_SIZE_WARN; - static const float TEXT_SIZE_ERROR; - - static const float ACTIVATE_TIME_FROM_GAME; - static const float ACTIVATE_TIME_FROM_HUD; - -protected: - void InitUI(minigui::IMiniGUI* pGUI); - void SetNextState(); - -protected: - - static int m_sys_perfhud; - static int m_sys_perfhud_pause; - - int m_sys_perfhud_prev; - - //record last menu position - float m_menuStartX; - float m_menuStartY; - - bool m_hudCreated; - - bool m_L1Pressed; - bool m_L2Pressed; - bool m_R1Pressed; - bool m_R2Pressed; - bool m_changingState; - bool m_hwMouseEnabled; - - float m_triggersDownStartTime; - - EHudState m_hudState; - EHudState m_hudLastState; - - typedef std::vector< _smart_ptr, stl::STLGlobalAllocator<_smart_ptr > >::iterator TWidgetIterator; - - std::vector< _smart_ptr, stl::STLGlobalAllocator<_smart_ptr > > m_widgets; - std::vector > m_rootMenus; -}; - -class CFpsWidget - : public ICryPerfHUDWidget -{ -public: - - CFpsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud); - - virtual void Reset(); - virtual void Update(); - virtual bool ShouldUpdate(); - virtual void LoadBudgets(XmlNodeRef perfXML); - virtual void SaveStats(XmlNodeRef statsXML); - virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); } - virtual void Disable() { m_pInfoBox->Hide(true); } - - void Init(); - - const std::vector* GetFpsBuckets(float& totalTime) const; - - static void ResetCallback(void* data, bool status); - -protected: - - static const uint32 NUM_FPS_BUCKETS_DEFAULT = 6; - - struct PerfBucketsStat - { - std::vector buckets; - float totalTime; - }; - - template - void UpdateBuckets(PerfBucketsStat& buckets, float frameTime, const char* name, float stat); - - // Data - static int m_cvarPerfHudFpsExclusive; - - enum EPerfBucketType - { - BUCKET_FPS = 0, - BUCKET_GPU, - BUCKET_DP, - BUCKET_TYPE_NUM - }; - - - PerfBucketsStat m_perfBuckets[BUCKET_TYPE_NUM]; - - float m_fpsBucketSize; - float m_fpsBudget; - float m_dpBudget; - float m_dpBucketSize; - - minigui::IMiniInfoBox* m_pInfoBox; -}; - -class CRenderStatsWidget - : public ICryPerfHUDWidget -{ -public: - - CRenderStatsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud); - - virtual void Reset() {} - virtual void Update(); - virtual bool ShouldUpdate(); - virtual void LoadBudgets(XmlNodeRef perfXML); - virtual void SaveStats(XmlNodeRef statsXML); - virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); } - virtual void Disable() { m_pInfoBox->Hide(true); } - -protected: - - //budgets - float m_fpsBudget; - uint32 m_dpBudget; - uint32 m_polyBudget; - uint32 m_postEffectBudget; - uint32 m_shadowCastBudget; - uint32 m_particlesBudget; - - //runtime data - struct SRuntimeData - { - Vec3 cameraPos; - Ang3 cameraRot; - float fps; - uint32 nDrawPrims; - uint32 nPolys; - uint32 nPostEffects; - uint32 nFwdLights; - uint32 nFwdShadowLights; - uint32 nDefLights; - uint32 nDefShadowLights; - uint32 nDefCubeMaps; - int nParticles; - bool hdrEnabled; - bool renderThreadEnabled; - }; - - SRuntimeData m_runtimeData; - minigui::IMiniInfoBox* m_pInfoBox; - ICryPerfHUD* m_pPerfHUD; - uint32 m_buildNum; -}; - -class CStreamingStatsWidget - : public ICryPerfHUDWidget -{ -public: - - CStreamingStatsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud); - - virtual void Reset() {} - virtual void Update(); - virtual bool ShouldUpdate(); - virtual void LoadBudgets(XmlNodeRef perfXML); - virtual void SaveStats(XmlNodeRef statsXML) {}; - virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); } - virtual void Disable() { m_pInfoBox->Hide(true); } - -protected: - //float m_maxMeshSizeArroundMB; - //float m_maxTextureSizeArroundMB; - minigui::IMiniInfoBox* m_pInfoBox; - ICryPerfHUD* m_pPerfHUD; -}; - - -class CWarningsWidget - : public ICryPerfHUDWidget -{ -public: - - CWarningsWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud); - - virtual void Reset(); - virtual void Update(); - virtual bool ShouldUpdate(); - virtual void LoadBudgets(XmlNodeRef perfXML) {}; - virtual void SaveStats(XmlNodeRef statsXML); - virtual void Enable([[maybe_unused]] int mode) { m_pInfoBox->Hide(false); } - virtual void Disable() { m_pInfoBox->Hide(true); } - - void AddWarningV(float duration, const char* fmt, va_list argList); - void AddWarning(float duration, const char* warning); - -protected: - - static const uint32 WARNING_LENGTH = 64; - - struct SWarning - { - char text[WARNING_LENGTH]; - float remainingDuration; - }; - - minigui::IMiniInfoBox* m_pInfoBox; - - typedef std::vector< SWarning > TSWarnings; - - TSWarnings m_warnings; - - CryMT::queue m_threadWarnings; - - threadID m_nMainThreadId; -}; - -class CRenderBatchWidget - : public ICryPerfHUDWidget -{ -public: - - CRenderBatchWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud); - - virtual void Reset(); - virtual void Update(); - virtual bool ShouldUpdate(); - virtual void LoadBudgets(XmlNodeRef perfXML) {}; - virtual void SaveStats(XmlNodeRef statsXML); - virtual void Enable(int mode); - virtual void Disable(); - - void Update_ModeGpuTimes(); - void Update_ModeBatchStats(); - -protected: - - struct BatchInfoGpuTimes - { - const char* name; - uint32 nBatches; - float gpuTime; - int numVerts; - int numIndices; - }; - - struct BatchInfoSortGpuTimes - { - inline bool operator() (const BatchInfoGpuTimes& lhs, const BatchInfoGpuTimes& rhs) const - { - return lhs.gpuTime > rhs.gpuTime; - } - }; - - struct BatchInfoPerPass - { - const char* name; - uint16 nBatches; - uint16 nInstances; - uint16 nZpass; - uint16 nShadows; - uint16 nGeneral; - uint16 nTransparent; - uint16 nMisc; - ColorB col; - - BatchInfoPerPass() - { - Reset(); - } - - void Reset() - { - name = NULL; - nBatches = 0; - nInstances = 0; - nZpass = 0; - nShadows = 0; - nGeneral = 0; - nTransparent = 0; - nMisc = 0; - col.set(255, 255, 255, 255); - } - - void operator += (const BatchInfoPerPass& rhs) - { - nBatches += rhs.nBatches; - nInstances += rhs.nInstances; - nZpass += rhs.nZpass; - nShadows += rhs.nShadows; - nGeneral += rhs.nGeneral; - nTransparent += rhs.nTransparent; - nMisc += rhs.nMisc; - } - }; - - struct BatchInfoSortPerPass - { - inline bool operator() (const BatchInfoPerPass* lhs, const BatchInfoPerPass* rhs) const - { - return lhs->nBatches > rhs->nBatches; - } - }; - - enum EDisplayMode - { - DISPLAY_MODE_NONE = 0, - DISPLAY_MODE_BATCH_STATS, - DISPLAY_MODE_GPU_TIMES, - DISPLAY_MODE_NUM, - }; - - minigui::IMiniTable* m_pTable; - ICVar* m_pRStatsCVar; - EDisplayMode m_displayMode; -}; - -#endif //USE_PERFHUD - -#endif // CRYINCLUDE_CRYSYSTEM_PERFHUD_H diff --git a/Code/CryEngine/CrySystem/PhysRenderer.cpp b/Code/CryEngine/CrySystem/PhysRenderer.cpp deleted file mode 100644 index a17fcb7063..0000000000 --- a/Code/CryEngine/CrySystem/PhysRenderer.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : impelemnation of a simple dedicated renderer for the physics subsystem - - -#include "CrySystem_precompiled.h" - diff --git a/Code/CryEngine/CrySystem/PhysRenderer.h b/Code/CryEngine/CrySystem/PhysRenderer.h deleted file mode 100644 index bbcca4626e..0000000000 --- a/Code/CryEngine/CrySystem/PhysRenderer.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : declaration of a simple dedicated renderer for the physics subsystem - - -#ifndef CRYINCLUDE_CRYSYSTEM_PHYSRENDERER_H -#define CRYINCLUDE_CRYSYSTEM_PHYSRENDERER_H -#pragma once - - -#endif // CRYINCLUDE_CRYSYSTEM_PHYSRENDERER_H diff --git a/Code/CryEngine/CrySystem/Platform/Android/platform_android.cmake b/Code/CryEngine/CrySystem/Platform/Android/platform_android.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Android/platform_android.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# 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. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/CrySystem/Platform/Android/platform_android_files.cmake b/Code/CryEngine/CrySystem/Platform/Android/platform_android_files.cmake deleted file mode 100644 index ce1124fe07..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Android/platform_android_files.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../MobileDetectSpec_Android.cpp - ../../MobileDetectSpec.cpp - ../../MobileDetectSpec.h - ../../ThermalInfoAndroid.h - ../../ThermalInfoAndroid.cpp -) diff --git a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux.cmake b/Code/CryEngine/CrySystem/Platform/Linux/platform_linux.cmake deleted file mode 100644 index 971c8ad67f..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# -# 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. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files - -set(LY_BUILD_DEPENDENCIES - PRIVATE - m -) diff --git a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux_files.cmake b/Code/CryEngine/CrySystem/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# 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. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake b/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index 9c26988e94..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../SystemUtilsApple.h - ../../SystemUtilsApple.mm -) diff --git a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows.cmake b/Code/CryEngine/CrySystem/Platform/Windows/platform_windows.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# 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. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows_files.cmake b/Code/CryEngine/CrySystem/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Code/CryEngine/CrySystem/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios.cmake b/Code/CryEngine/CrySystem/Platform/iOS/platform_ios.cmake deleted file mode 100644 index f607478131..0000000000 --- a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(LY_COMPILE_OPTIONS - PRIVATE - -xobjective-c++ -) - -find_library(UI_KIT_FRAMEWORK UIKit) - -set(LY_BUILD_DEPENDENCIES - PRIVATE - ${UI_KIT_FRAMEWORK} -) diff --git a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake b/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake deleted file mode 100644 index a5d743e6d7..0000000000 --- a/Code/CryEngine/CrySystem/Platform/iOS/platform_ios_files.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../../MobileDetectSpec_Ios.cpp - ../../MobileDetectSpec.cpp - ../../MobileDetectSpec.h - ../../SystemUtilsApple.h - ../../SystemUtilsApple.mm -) - - diff --git a/Code/CryEngine/CrySystem/ProfileLogSystem.cpp b/Code/CryEngine/CrySystem/ProfileLogSystem.cpp deleted file mode 100644 index 2a86dfc2ef..0000000000 --- a/Code/CryEngine/CrySystem/ProfileLogSystem.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ProfileLogSystem.h" - -////////////////////////////////////////////////////////////////////////// -// class CLogElement -////////////////////////////////////////////////////////////////////////// - -CLogElement::CLogElement() - : m_pParent (NULL) - , m_time (0) -{ -} - -CLogElement::CLogElement(CLogElement* pParent) - : m_pParent (pParent) - , m_time (0) -{ -} - -CLogElement::CLogElement(CLogElement* pParent, const char* name, const char* message) - : m_pParent (pParent) - , m_strName (name) - , m_strMessage(message) - , m_time (0) -{ -} - -void CLogElement::Flush(stack_string& indent) -{ - if (m_logElements.empty()) - { - CryLog("%s%s [%.3f ms] %s", indent.c_str(), m_strName.c_str(), m_time, m_strMessage.c_str()); - return; - } - - CryLog("%s+%s [%.3f ms] %s", indent.c_str(), m_strName.c_str(), m_time, m_strMessage.c_str()); - - indent += " "; - for (std::list::iterator it = m_logElements.begin(); it != m_logElements.end(); ++it) - { - (*it).Flush(indent); - } - indent.erase(0, 2); - - CryLog("%s-%s", indent.c_str(), m_strName.c_str()); -} - -ILogElement* CLogElement::Log(const char* name, const char* message) -{ - m_logElements.push_back(CLogElement(this)); - m_logElements.back().m_strName = name; - m_logElements.back().m_strMessage = message; - - return &m_logElements.back(); -} - -ILogElement* CLogElement::SetTime(float time) -{ - m_time = time; - - return m_pParent; -} - -void CLogElement::Clear() -{ - m_logElements.resize(0); -} - -////////////////////////////////////////////////////////////////////////// -// class CProfileLogSystem -////////////////////////////////////////////////////////////////////////// - -CProfileLogSystem::CProfileLogSystem() - : m_rootElelent(NULL) - , m_pLastElelent(NULL) -{ -} - -CProfileLogSystem::~CProfileLogSystem() -{ -} - -ILogElement* CProfileLogSystem::Log(const char* name, const char* message) -{ - if (m_pLastElelent) - { - m_pLastElelent = m_pLastElelent->Log(name, message); - } - else - { - m_rootElelent.Clear(); - m_rootElelent.SetName(name); - m_rootElelent.SetMessage(message); - m_pLastElelent = &m_rootElelent; - } - - return m_pLastElelent; -} - -void CProfileLogSystem::SetTime(ILogElement* pElement, float time) -{ - if (pElement == NULL) - { - return; - } - - m_pLastElelent = pElement->SetTime(time); - if (m_pLastElelent) - { - return; - } - - stack_string indent; - m_rootElelent.Flush(indent); - m_rootElelent.Clear(); -} - -void CProfileLogSystem::Release() -{ - delete this; -} diff --git a/Code/CryEngine/CrySystem/ProfileLogSystem.h b/Code/CryEngine/CrySystem/ProfileLogSystem.h deleted file mode 100644 index b54e3067ec..0000000000 --- a/Code/CryEngine/CrySystem/ProfileLogSystem.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of the IProfileLogSystem interface, which is used to -// save hierarchical log with SHierProfileLogItem - - -#ifndef CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H -#define CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H - -#pragma once - -#include "ProfileLog.h" - -class CLogElement - : public ILogElement -{ -public: - CLogElement(); - CLogElement(CLogElement* pParent); - CLogElement(CLogElement* pParent, const char* name, const char* message); - - virtual ILogElement* Log (const char* name, const char* message); - virtual ILogElement* SetTime (float time); - virtual void Flush (stack_string& indent); - - void Clear (); - - inline void SetName(const char* name) - { - m_strName = name; - } - - inline void SetMessage(const char* message) - { - m_strMessage = message; - } - -private: - string m_strName; - string m_strMessage; - float m_time; // milliSeconds - - CLogElement* m_pParent; - std::list m_logElements; -}; - -class CProfileLogSystem - : public IProfileLogSystem -{ -public: - CProfileLogSystem(); - ~CProfileLogSystem(); - - virtual ILogElement* Log (const char* name, const char* message); - virtual void SetTime (ILogElement* pElement, float time); - virtual void Release (); - -private: - CLogElement m_rootElelent; - ILogElement* m_pLastElelent; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H diff --git a/Code/CryEngine/CrySystem/RemoteCommand.cpp b/Code/CryEngine/CrySystem/RemoteCommand.cpp deleted file mode 100644 index 5f1129be22..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommand.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommand.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -// remote system internal logging -#ifdef RELEASE - #define LOG_VERBOSE(level, txt, ...) -#else - #define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -CRemoteCommandManager::CRemoteCommandManager() -{ - // Create the CVAR - m_pVerboseLevel = gEnv->pConsole->RegisterInt("rc_debugVerboseLevel", 0, VF_DEV_ONLY); -} - -CRemoteCommandManager::~CRemoteCommandManager() -{ - // Release the CVar - if (NULL != m_pVerboseLevel) - { - m_pVerboseLevel->Release(); - m_pVerboseLevel = NULL; - } -} - -IRemoteCommandServer* CRemoteCommandManager::CreateServer(uint16 localPort) -{ - // Create the listener - IServiceNetworkListener* listener = gEnv->pServiceNetwork->CreateListener(localPort); - if (NULL == listener) - { - return NULL; - } - - // Create the wrapper - return new CRemoteCommandServer(this, listener); -} - -IRemoteCommandClient* CRemoteCommandManager::CreateClient() -{ - // Create the wrapper - return new CRemoteCommandClient(this); -} - -void CRemoteCommandManager::RegisterCommandClass(IRemoteCommandClass& commandClass) -{ - // Make sure command class is not already registered - const string& className(commandClass.GetName()); - TClassMap::const_iterator it = m_pClasses.find(className); - if (it != m_pClasses.end()) - { - LOG_VERBOSE(1, "Class '%s' is already registered", - className.c_str()); - - return; - } - - const uint32 classID = m_pClassesByID.size(); - m_pClassesByID.push_back(&commandClass); - m_pClassesMap[ className ] = classID; - m_pClasses[ className ] = &commandClass; - - // Verbose - LOG_VERBOSE(1, "Registered command class '%s' with id %d", - className.c_str(), - classID); -} - -#ifndef RELEASE -bool CRemoteCommandManager::CheckVerbose(const uint32 level) const -{ - const int verboseLevel = m_pVerboseLevel->GetIVal(); - return (int)level < verboseLevel; -} - -void CRemoteCommandManager::Log(const char* txt, ...) const -{ - // format the print buffer - char buffer[512]; - va_list ap; - va_start(ap, txt); - vsprintf_s(buffer, sizeof(buffer), txt, ap); - va_end(ap); - - // pass to log - gEnv->pLog->LogAlways(buffer); -} -#endif - -void CRemoteCommandManager::BuildClassMapping(const std::vector& classNames, std::vector< IRemoteCommandClass* >& outClasses) -{ - LOG_VERBOSE(3, "Building class mapping for %d classes", - classNames.size()); - - // Output list size has the same size as class names array - const uint32 numClasses = classNames.size(); - outClasses.resize(numClasses); - - // Match the classes - for (size_t i = 0; i < numClasses; ++i) - { - // Find the matching class - const string& className = classNames[i]; - TClassMap::const_iterator it = m_pClasses.find(className); - if (it != m_pClasses.end()) - { - CRY_ASSERT(className == it->second->GetName()); - CRY_ASSERT(it->second != NULL); - outClasses[i] = it->second; - - // Report class mapping in heavy verbose mode - LOG_VERBOSE(3, "Class[%d] = %s", - i, - className.c_str()); - } - else - { - outClasses[i] = NULL; - - // Class not mapped (this can cause errors) - LOG_VERBOSE(0, "Remote command class '%s' not found on this machine", - className.c_str()); - } - } -} - -void CRemoteCommandManager::SetVerbosityLevel(const uint32 level) -{ - // propagate the value to CVar (so it is consistent across the engine) - if (NULL != m_pVerboseLevel) - { - m_pVerboseLevel->Set((int)level); - } -} - -void CRemoteCommandManager::GetClassList(std::vector& outClassNames) const -{ - const uint32 numClasses = m_pClassesByID.size(); - outClassNames.resize(numClasses); - for (size_t id = 0; id < numClasses; ++id) - { - IRemoteCommandClass* theClass = m_pClassesByID[id]; - if (NULL != theClass) - { - outClassNames[id] = theClass->GetName(); - } - } -} - -bool CRemoteCommandManager::FindClassId(IRemoteCommandClass* commandClass, uint32& outClassId) const -{ - // Local search (linear, slower) - TClassIDMap::const_iterator it = m_pClassesMap.find(commandClass->GetName()); - if (it != m_pClassesMap.end()) - { - outClassId = it->second; - return true; - } - - // Not found - return false; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/RemoteCommand.h b/Code/CryEngine/CrySystem/RemoteCommand.h deleted file mode 100644 index 6ce5e3fd11..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommand.h +++ /dev/null @@ -1,459 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation - - -#pragma once - - -//----------------------------------------------------------------------------- - -#include "IServiceNetwork.h" -#include "IRemoteCommand.h" -#include "CryThread.h" - -class CRemoteCommandManager; - -// Remote command client implementation -class CRemoteCommandClient - : public IRemoteCommandClient - , public CryRunnable -{ -protected: - //------------------------------------------------------------- - - class Command - { - public: - ILINE IServiceNetworkMessage* GetMessage() const - { - return m_pMessage; - } - - ILINE uint32 GetCommandId() const - { - return m_id; - } - - public: - // Create command data from serializing a remote command object - static Command* Compile(const IRemoteCommand& cmd, const uint32 commandId, const uint32 classId); - - void AddRef(); - void Release(); - - private: - Command(); - ~Command(); - - volatile int m_refCount; - uint32 m_id; - const char* m_szClassName; // debug only - IServiceNetworkMessage* m_pMessage; - }; - - //------------------------------------------------------------- - - // Local connection reference to command - // NOTE: pCommand is reference counted from the calling code - struct CommandRef - { - Command* m_pCommand; - uint64 m_lastSentTime; - - ILINE CommandRef() - : m_pCommand(NULL) - , m_lastSentTime(0) - {} - - ILINE CommandRef(Command* pCommand) - : m_pCommand(pCommand) - , m_lastSentTime(0) - {} - - // Order function for set container (we want to keep the commands sorted by ID) - static ILINE bool CompareCommandRefs(CommandRef* const& a, CommandRef* const& b) - { - return a->m_pCommand->GetCommandId() < b->m_pCommand->GetCommandId(); - } - }; - - //------------------------------------------------------------- - - // Remote server connection wrapper - class Connection - : public IRemoteCommandConnection - { - // How many commands we can send upfront before waiting for an ACK - static const uint32 kCommandSendLead = 50; - - // How much command data can be merged into a single packet (KB) - static const uint32 kCommandMaxMergePacketSize = 1024; - - // Time after which we start resending commands (ms) - static const uint32 kCommandResendTime = 2000; - - protected: - CRemoteCommandManager* m_pManager; - volatile int m_refCount; - - // Connection (from service network layer) - IServiceNetworkConnection* m_pConnection; - - // Cached address of the remote endpoint - ServiceNetworkAddress m_remoteAddress; - - // Pending commands, they are kept ed here until they are ACKed as executed by server - typedef std::vector TCommands; - TCommands m_pCommands; - CryMutex m_commandAccessMutex; - - // A queue of raw messages - typedef CryMT::CLocklessPointerQueue TRawMessageQueue; - TRawMessageQueue m_pRawMessages; - CryMutex m_rawMessagesMutex; - - // Last command that was ACKed as received by server - // This is used to synchronize the both ends of the pipeline - uint32 m_lastReceivedCommand; - - // Last command that was ACKed as executed by server - // This is used to synchronize the both ends of the pipeline - uint32 m_lastExecutedCommand; - - public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - - public: - Connection(CRemoteCommandManager* pManager, IServiceNetworkConnection* pConnection, uint32 currentCommandId); - - // Add command to sending queue in this connection - void AddToSendQueue(Command* pCommand); - - // Process the communication, returns false if connection should be deleted - bool Update(); - - // Send the "disconnect" message to the remote side therefore gracefully closing the connection. - void SendDisconnectMessage(); - - public: - // IRemoteCommandConnection interface implementation - virtual bool IsAlive() const; - virtual const ServiceNetworkAddress& GetRemoteAddress() const; - virtual bool SendRawMessage(IServiceNetworkMessage* pMessage); - virtual IServiceNetworkMessage* ReceiveRawMessage(); - virtual void Close(bool bFlushQueueBeforeClosing = false); - virtual void AddRef(); - virtual void Release(); - - private: - ~Connection(); - }; - -protected: - CRemoteCommandManager* m_pManager; - - typedef std::vector TConnections; - TConnections m_pConnections; - TConnections m_pConnectionsToDelete; - CryMutex m_accessMutex; - - // Local command ID counter, incremented atomically using CryInterlockedIncrement - volatile uint32 m_commandId; - - typedef CryThread TRemoteClientThread; - TRemoteClientThread* m_pThread; - CryEvent m_threadEvent; - bool m_bCloseThread; - -public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - -public: - CRemoteCommandClient(CRemoteCommandManager* pManager); - virtual ~CRemoteCommandClient(); - - // IRemoteCommandClient interface - virtual void Delete(); - virtual bool Schedule(const IRemoteCommand& command); - virtual IRemoteCommandConnection* ConnectToServer(const class ServiceNetworkAddress& serverAddress); - - // CryRunnable interface implementation - virtual void Run(); - virtual void Cancel(); -}; - -//----------------------------------------------------------------------------- - -// Remote command server implementation -class CRemoteCommandServer - : public IRemoteCommandServer - , public CryRunnable -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(RemoteCommand_h) -#endif - -protected: - // Wrapped commands - class WrappedCommand - { - private: - IRemoteCommand* m_pCommand; - volatile int m_refCount; - uint32 m_commandID; - - public: - ILINE const uint32 GetId() const - { - return m_commandID; - } - - ILINE IRemoteCommand* GetCommand() const - { - return m_pCommand; - } - - public: - WrappedCommand(IRemoteCommand* pCommand, const uint32 commandId); - void AddRef(); - void Release(); - - private: - ~WrappedCommand(); - }; - - // Local endpoint - class Endpoint - { - private: - IServiceNetworkConnection* m_pConnection; - class CRemoteCommandServer* m_pServer; - CRemoteCommandManager* m_pManager; - - // ACK counters for synchronization - uint32 m_lastReceivedCommand; - uint32 m_lastExecutedCommand; - uint32 m_lastReceivedCommandACKed; - uint32 m_lastExecutedCommandACKed; - CryMutex m_accessLock; - - // We have received class list (it's a valid RC connection) - bool m_bHasReceivedClassList; - - // Locally mapped class id (because IDs on remote side can be different than here) - typedef std::vector< IRemoteCommandClass* > TLocalClassFactoryList; - TLocalClassFactoryList m_pLocalClassFactories; - - // Commands that were received and should be executed - typedef CryMT::CLocklessPointerQueue< WrappedCommand > TCommandQueue; - TCommandQueue m_pCommandsToExecute; - CryMutex m_commandListLock; - - public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - - // Get the endpoint connection - ILINE IServiceNetworkConnection* GetConnection() const - { - return m_pConnection; - } - - // Have we received a class list from the client - ILINE bool HasReceivedClassList() const - { - return m_bHasReceivedClassList; - } - - public: - Endpoint(CRemoteCommandManager* pManager, class CRemoteCommandServer* pServer, IServiceNetworkConnection* pConnection); - ~Endpoint(); - - // Execute pending commands (called from main thread) - void Execute(); - - // Update (send/receive, etc) Returns false if endpoint died. - bool Update(); - - // Get the class name as translated by this endpoint (by ID) - const char* GetClassName(const uint32 classId) const; - - // Create command object by class ID - IRemoteCommand* CreateObject(const uint32 classId) const; - }; - - // Received raw message - // Beware to use always via pointer to this type since propper reference counting is not implemented for copy and assigment - struct RawMessage - { - // We keep a reference to connection so we know where to send the response - IServiceNetworkConnection* m_pConnection; - IServiceNetworkMessage* m_pMessage; - - ILINE RawMessage(IServiceNetworkConnection* pConnection, IServiceNetworkMessage* pMessage) - : m_pConnection(pConnection) - , m_pMessage(pMessage) - { - m_pMessage->AddRef(); - m_pConnection->AddRef(); - } - - ILINE ~RawMessage() - { - m_pMessage->Release(); - m_pConnection->Release(); - } - - private: - ILINE RawMessage([[maybe_unused]] const RawMessage& other) {}; - ILINE RawMessage& operator==([[maybe_unused]] const RawMessage& other) { return *this; } - }; - -protected: - CRemoteCommandManager* m_pManager; - - // Network listening socket - IServiceNetworkListener* m_pListener; - - // Live endpoints - typedef std::vector TEndpoints; - TEndpoints m_pEndpoints; - TEndpoints m_pUpdateEndpoints; - CryMutex m_accessLock; - - // Endpoints that were discarded and should be deleted - // We can delete endpoints only from the update thread - TEndpoints m_pEndpointToDelete; - - // Received raw messages - typedef CryMT::CLocklessPointerQueue TRawMessagesQueue; - TRawMessagesQueue m_pRawMessages; - CryMutex m_rawMessagesLock; - - // Listeners for raw messages that require synchronous processing - typedef std::vector TRawMessageListenersSync; - TRawMessageListenersSync m_pRawListenersSync; - - // Listeners for raw messages that can be processed asynchronously (faster path) - typedef std::vector TRawMessageListenersAsync; - TRawMessageListenersAsync m_pRawListenersAsync; - - // Command communication and deserialization is done on thread - typedef CryThread TRemoteServerThread; - TRemoteServerThread* m_pThread; - - // Suppression counter (execution of commands is suppressed when>0) - // This is updated using CryInterlocked* functions - volatile int m_suppressionCounter; - bool m_bIsSuppressed; - - // Request to close the network thread - bool m_bCloseThread; - -public: - ILINE CRemoteCommandManager* GetManager() const - { - return m_pManager; - } - -public: - CRemoteCommandServer(CRemoteCommandManager* pManager, IServiceNetworkListener* pListener); - virtual ~CRemoteCommandServer(); - - // IRemoteCommandServer interface implementation - virtual void Delete(); - virtual void FlushCommandQueue(); - virtual void SuppressCommands(); - virtual void ResumeCommands(); - virtual void RegisterSyncMessageListener(IRemoteCommandListenerSync* pListener); - virtual void UnregisterSyncMessageListener(IRemoteCommandListenerSync* pListener); - virtual void RegisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener); - virtual void UnregisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener); - virtual void Broadcast(IServiceNetworkMessage* pMessage); - virtual bool HasConnectedClients() const; - - // CryRunnable - virtual void Run(); - virtual void Cancel(); - -protected: - void ProcessRawMessageAsync(IServiceNetworkMessage* pMessage, IServiceNetworkConnection* pConnection); - void ProcessRawMessagesSync(); -}; - -//----------------------------------------------------------------------------- - -// Remote command manager implementation -class CRemoteCommandManager - : public IRemoteCommandManager -{ -public: - CRemoteCommandManager(); - virtual ~CRemoteCommandManager(); - - // IRemoteCommandManager interface implementation - virtual void SetVerbosityLevel(const uint32 level); - virtual IRemoteCommandServer* CreateServer(uint16 localPort); - virtual IRemoteCommandClient* CreateClient(); - virtual void RegisterCommandClass(IRemoteCommandClass& commandClass); - - // Debug print -#ifdef RELEASE - void Log([[maybe_unused]] const char* txt, ...) const {}; - bool CheckVerbose([[maybe_unused]] const uint32 level) const { return false; } -#else - void Log(const char* txt, ...) const; - bool CheckVerbose(const uint32 level) const; -#endif - - // Build ID->Class Factory mapping given the class name list, will report errors to the log. - void BuildClassMapping(const std::vector& classNames, std::vector< IRemoteCommandClass* >& outClasses); - - // Get list of class names (in order of their IDs) - void GetClassList(std::vector& outClassNames) const; - - // Find class ID for given class, returns false if not found - bool FindClassId(IRemoteCommandClass* commandClass, uint32& outClassId) const; - -public: - ILINE CRemoteCommandManager* GetManager() - { - return this; - } - -private: - // Class name mapping - typedef std::map< string, IRemoteCommandClass* > TClassMap; - TClassMap m_pClasses; - - // Class ID lookup - typedef std::vector< IRemoteCommandClass* > TClassIDList; - TClassIDList m_pClassesByID; - - // Class ID mapping - typedef std::map< string, int > TClassIDMap; - TClassIDMap m_pClassesMap; - - // Verbose level - ICVar* m_pVerboseLevel; -}; diff --git a/Code/CryEngine/CrySystem/RemoteCommandClient.cpp b/Code/CryEngine/CrySystem/RemoteCommandClient.cpp deleted file mode 100644 index 1855aae4a9..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandClient.cpp +++ /dev/null @@ -1,756 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommand.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -// remote system internal logging -#ifdef RELEASE - #define LOG_VERBOSE(level, txt, ...) -#else - #define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -CRemoteCommandClient::Command::Command() - : m_refCount(1) - , m_szClassName(NULL) - , m_id(0) -{ -} - -CRemoteCommandClient::Command::~Command() -{ - // Release message buffer with compiled command data - if (m_pMessage != NULL) - { - m_pMessage->Release(); - m_pMessage = NULL; - } -} - -CRemoteCommandClient::Command* CRemoteCommandClient::Command::Compile(const IRemoteCommand& cmd, const uint32 commandId, const uint32 classId) -{ - // Build command header - CommandHeader header; - header.classId = classId; - header.commandId = commandId; - header.size = 0; // not known yet - - // Output stream builder - CDataWriteStreamBuffer writer; - - // Start the packet with a command header (it will be later overwritten) - writer << header; - - // Serialize command header and data - const uint32 commandDataStart = writer.GetSize(); - cmd.SaveToStream(writer); - const uint32 commandDataEnd = writer.GetSize(); - - // Extract a message from the stream - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL == pMessage) - { - // No message was generated (for some reason) - // Do not allow this command to compile - return NULL; - } - - // Rewrite header with the proper command size - // This is a little bit over-the-top because it uses another serializer created - // on top of the message buffer. The advantage is that we have the endianess problem abstracted away. - // TODO: consider writing the size directly - { - // update header with popper data size - const uint32 dataSize = commandDataEnd - commandDataStart; - header.size = dataSize; - - // rewrite the header in existing message - CDataWriteStreamToMessage inPlaceWriter(pMessage); - inPlaceWriter << header; - } - - // Create command wrapper - Command* pCommand = new Command(); - pCommand->m_id = commandId; - pCommand->m_szClassName = cmd.GetClass()->GetName(); - pCommand->m_pMessage = pMessage; - return pCommand; -} - -void CRemoteCommandClient::Command::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CRemoteCommandClient::Command::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -//----------------------------------------------------------------------------- - -CRemoteCommandClient::Connection::Connection(CRemoteCommandManager* pManager, IServiceNetworkConnection* pConnection, uint32 currentCommandId) - : m_pConnection(pConnection) - , m_pManager(pManager) - , m_lastReceivedCommand(currentCommandId) - , m_lastExecutedCommand(currentCommandId) - , m_remoteAddress(pConnection->GetRemoteAddress()) - , m_refCount(1) -{ - // The first thing to do after the connection is initialized is to - // send the message with list of classes supported by this side. - { - // Write the header - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_ClassList; - header.count = currentCommandId; // send the intial command ID so we can be in sync - - // Get the class list for our local remote command manager - std::vector< string > classList; - GetManager()->GetClassList(classList); - - // Write the message - CDataWriteStreamBuffer writer; - writer << header; - writer << classList; - - // Send the message to the remote side - IServiceNetworkMessage* pMsg = writer.BuildMessage(); - if (NULL != pMsg) - { - LOG_VERBOSE(1, "Sent class list message (%d classes, size=%d) to '%s'", - classList.size(), - pMsg->GetSize(), - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // TODO: well, there is no reason this can fail since the connection is brand new, but... - // We still relay on the service network to deliver this message unharmed. - m_pConnection->SendMsg(pMsg); - - // cleanup - pMsg->Release(); - } - } -} - -CRemoteCommandClient::Connection::~Connection() -{ - // Close the connection - const bool bFlushBeforeClosing = false; - Close(bFlushBeforeClosing); - - // Release any commands left over on the list - for (TCommands::const_iterator it = m_pCommands.begin(); - it != m_pCommands.end(); ++it) - { - (*it)->m_pCommand->Release(); - delete (*it); - } - m_pCommands.clear(); - - // Release all of the raw messages that were not picked up - while (!m_pRawMessages.empty()) - { - IServiceNetworkMessage* pMessage = m_pRawMessages.pop(); - pMessage->Release(); - } - - // Release the connection object - SAFE_RELEASE(m_pConnection); -} - -void CRemoteCommandClient::Connection::SendDisconnectMessage() -{ - if (NULL != m_pConnection && m_pConnection->IsAlive()) - { - IDataWriteStream* pWriter = gEnv->pServiceNetwork->CreateMessageWriter(); - if (NULL != pWriter) - { - // write header to message - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.count = 0; - header.msgType = PackedHeader::eCommand_Disconnect; - *pWriter << header; - - // Send the disconnect signal - IServiceNetworkMessage* pMessage = pWriter->BuildMessage(); - if (NULL != pMessage) - { - m_pConnection->SendMsg(pMessage); - pMessage->Release(); - } - - pWriter->Delete(); - } - } -} - -void CRemoteCommandClient::Connection::AddToSendQueue(Command* pCommand) -{ - // Do not add commands if the connection is closed - if (m_pConnection == NULL) - { - return; - } - - // Add command to local list - // NOTE: this list always needs to be sorted in increasing command ID for various optimization reason. - // This is achieved by resorting after pushing each element. Usually the cost of this is close to nothing - // because incoming commands tend to be added with increasing command IDs. - // The only case when something else can happen is when commands are added from different threads - // and the one that was lower CommandID took longer to serialize and therefore is added later. - // Anyway, this case is handled here. - { - CryAutoLock lock(m_commandAccessMutex); - - // Always add to the end (don't try to guess position) - // TODO: consider binary search - m_pCommands.push_back(new CommandRef(pCommand)); - - // Resort, NODE: This usually does not sort anything because the vector is already sorted - std::sort(m_pCommands.begin(), m_pCommands.end(), CommandRef::CompareCommandRefs); - } - - // Keep local reference to command (since we added it to our array) - pCommand->AddRef(); -} - -bool CRemoteCommandClient::Connection::Update() -{ - // If the network connection got dead we should close this one to - if ((NULL == m_pConnection) || !m_pConnection->IsAlive()) - { - return false; - } - - // Receive ACKs first so we have better view of what to send - uint32 newLastExecutedCommand = m_lastExecutedCommand; - uint32 newLastReceivedCommand = m_lastReceivedCommand; - IServiceNetworkMessage* pMsg = m_pConnection->ReceiveMsg(); - while (pMsg != NULL) - { - // Deserialize the message - { - CDataReadStreamFormMessage reader(pMsg); - ResponseHeader response; - reader << response; - - // is this proper command system message ? - if (response.magic == PackedHeader::kMagic) - { - if (response.msgType == PackedHeader::eCommand_ACK) - { - // Update internal ACK values - // This code supports getting the ACK messages out of order. - newLastExecutedCommand = max(newLastExecutedCommand, response.lastCommandExecuted); - newLastReceivedCommand = max(newLastReceivedCommand, response.lastCommandReceived); - - LOG_VERBOSE(3, "ACK (rcv=%d, exe=%d) received from '%s'", - response.lastCommandReceived, - response.lastCommandExecuted, - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - else if (response.msgType == PackedHeader::eCommand_Disconnect) - { - // Disconnect request was received - LOG_VERBOSE(3, "DISCONNECT (rcv=%d, exe=%d) received from '%s'", - response.lastCommandReceived, - response.lastCommandExecuted, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Close connection - m_pConnection->Close(); - m_pConnection->Release(); - m_pConnection = NULL; - - // release the message - pMsg->Release(); - - // Signal manager to delete this object - return false; - } - } - else - { - // Keep an extra reference for the message in the raw message list - pMsg->AddRef(); - - // Assume it's a raw message, add it to the raw list - m_pRawMessages.push(pMsg); - } - } - - // Release message data - pMsg->Release(); - - // Get next message from the network - pMsg = m_pConnection->ReceiveMsg(); - } - - // ACK was updated - if ((newLastExecutedCommand != m_lastExecutedCommand) || - (newLastReceivedCommand != m_lastReceivedCommand)) - { - m_lastExecutedCommand = newLastExecutedCommand; - m_lastReceivedCommand = newLastReceivedCommand; - - // Drop commands that were ACKed as received (server has them and they will be executed soon) - { - CryAutoLock lock(m_commandAccessMutex); - - // we use this to count how many elements we need to remove later from the command vector - uint32 numCommandsToDelete = 0; - - for (TCommands::const_iterator it = m_pCommands.begin(); - it != m_pCommands.end(); ++it) - { - CommandRef* cmdRef = *it; - - // Command is still needed because it was not yet received by the remote part - if (cmdRef->m_pCommand->GetCommandId() > newLastReceivedCommand) - { - break; - } - - // Drop the command data - cmdRef->m_pCommand->Release(); - delete cmdRef; - - ++numCommandsToDelete; - } - - // Erase the command slots in the vector (in one batch) - if (numCommandsToDelete > 0) - { - m_pCommands.erase(m_pCommands.begin(), m_pCommands.begin() + numCommandsToDelete); - } - } - } - - // (Re)Send the commands - { - // Calculate the maximum command ID we can send, this depends on - // the last command that was ACKed as executed on the remote side. - // This effectively throttles the communication and prevents the - // situation when remote side is flooded with unprocessed commands. - // NOTE: the time when command is executed is different to the - // time that command is received. Sometimes if the server is suppressed (level loading) - // it can take a long time before commands begin to execute. - const uint32 maxCommandIdToSend = m_lastExecutedCommand + kCommandSendLead; - - // Calculate the cutoff time for sending (all commands that were not send before this time will be sent again) - // This assumes that the last sent time for new commands is 0 (so they will always got sent the first time) - // This situation can only happen due to the network failure since RemoteCommand layer does not require the commands to be resent. - const uint64 currentTime = gEnv->pTimer->GetAsyncTime().GetMilliSecondsAsInt64(); - const uint64 cutoffTime = currentTime - kCommandResendTime; - - std::vector< CommandRef* > commandsInPacket; // temp array - - // Process until we send all that there is to send - for (;; ) - { - // When sending connections try to merge them in larger packets. - // NOTE: this should not impact delivery time since we are not waiting - // for pending commands to accumulate before sending them, it's just an optimization - // to prevent may small messages from being sent. - uint32 packetDataSizeSoFar = 0; - { - CryAutoLock lock(m_commandAccessMutex); - - // fast local clear - // TODO: do we have a good template alternative to temporary array on stack? - packetDataSizeSoFar = 0; - commandsInPacket.resize(0); - - for (TCommands::iterator it = m_pCommands.begin(); - it != m_pCommands.end(); ++it) - { - CommandRef* commandRef = *it; - - // this command is to new, don't send it - if (commandRef->m_pCommand->GetCommandId() >= maxCommandIdToSend) - { - break; - } - - // should we send this command ? - if (commandRef->m_lastSentTime < cutoffTime) - { - // will it fit into current packet ? - const uint32 commandDataSize = commandRef->m_pCommand->GetMessage()->GetSize(); - if (packetDataSizeSoFar == 0 || // always add at least one command to the packet (no splitting) - (packetDataSizeSoFar + commandDataSize < kCommandMaxMergePacketSize)) - { - if (commandRef->m_lastSentTime == 0) - { - LOG_VERBOSE(3, "Command ID=%d is sent FIRST TIME to '%s'", - commandRef->m_pCommand->GetCommandId(), - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - else - { - LOG_VERBOSE(3, "Command ID=%d is resent to '%s'", - commandRef->m_pCommand->GetCommandId(), - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - - // will be sent - commandsInPacket.push_back(commandRef); - packetDataSizeSoFar += commandDataSize; - } - else - { - LOG_VERBOSE(3, "Command ID=%d is to big (%d) to fit packet size limit (%d)", - commandRef->m_pCommand->GetCommandId(), - commandDataSize, - kCommandMaxMergePacketSize); - - // no more commands will fit current packet - break; - } - } - } - } - - // No new commands to be send - if (commandsInPacket.empty()) - { - break; - } - - // Stats - LOG_VERBOSE(3, "Sending %d commands in packet, total size=%d, maxID=%d, dest: %s", - commandsInPacket.size(), - packetDataSizeSoFar, - maxCommandIdToSend, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Estimate the size of the network packet - const uint32 messageDataSize = packetDataSizeSoFar + PackedHeader::kSerializationSize; - - // Allocate and fill the message buffer - IServiceNetworkMessage* pSendMsg = gEnv->pServiceNetwork->AllocMessageBuffer(messageDataSize); - if (NULL != pSendMsg) - { - CDataWriteStreamToMessage writer(pSendMsg); - - // Packet header - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_Command; - header.count = commandsInPacket.size(); // number commands to send in this packet - writer << header; - - // Merge data of single commands - for (size_t i = 0; i < commandsInPacket.size(); ++i) - { - const IServiceNetworkMessage* pCommandMsg = commandsInPacket[i]->m_pCommand->GetMessage(); - writer.Write(pCommandMsg->GetPointer(), pCommandMsg->GetSize()); - } - - // Schedule the packet for sending via our network connection - if (m_pConnection->SendMsg(pSendMsg)) - { - // Only after the network layer has accepted our message we can assume that the commands were sent - for (size_t i = 0; i < commandsInPacket.size(); ++i) - { - CommandRef* cmdRef = commandsInPacket[i]; - cmdRef->m_lastSentTime = currentTime; - } - - // Release temporary message memory - pSendMsg->Release(); - } - else - { - // We failed to send the message (possibly the send queue is full) - pSendMsg->Release(); - break; - } - } - else - { - // No message was created, stop sending - break; - } - } - } - - // Keep the connection alive - return true; -} - -bool CRemoteCommandClient::Connection::IsAlive() const -{ - return (NULL != m_pConnection) && (m_pConnection->IsAlive()); -} - -const ServiceNetworkAddress& CRemoteCommandClient::Connection::GetRemoteAddress() const -{ - return m_remoteAddress; -} - -void CRemoteCommandClient::Connection::Close(bool bFlushQueueBeforeClosing /*= false*/) -{ - // Close the connection - if (NULL != m_pConnection) - { - if (m_pConnection->IsAlive() && bFlushQueueBeforeClosing) - { - // We have a chance to send a graceful disconnect message, so send it - SendDisconnectMessage(); - - // Send all the messages from the send queue before closing this connection. - // This does not block current thread. - m_pConnection->FlushAndClose(IServiceNetworkConnection::kDefaultFlushTime); - } - else - { - // Just close the connection (hasher way) - m_pConnection->Close(); - } - } -} - -bool CRemoteCommandClient::Connection::SendRawMessage(IServiceNetworkMessage* pMessage) -{ - // We can send the raw messages right away - if (NULL != m_pConnection && m_pConnection->IsAlive()) - { - return m_pConnection->SendMsg(pMessage); - } - else - { - return false; - } -} - -IServiceNetworkMessage* CRemoteCommandClient::Connection::ReceiveRawMessage() -{ - return m_pRawMessages.pop(); -} - -void CRemoteCommandClient::Connection::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CRemoteCommandClient::Connection::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -//----------------------------------------------------------------------------- - -CRemoteCommandClient::CRemoteCommandClient(CRemoteCommandManager* pManager) - : m_pManager(pManager) - , m_commandId(0) - , m_bCloseThread(false) -{ - // Start processing thread (sending, etc) - m_pThread = new TRemoteClientThread(); - m_pThread->Start(*this); -} - -CRemoteCommandClient::~CRemoteCommandClient() -{ - // Stop the thread - if (NULL != m_pThread) - { - m_pThread->Cancel(); - m_pThread->Stop(); - m_pThread->WaitForThread(); - delete m_pThread; - } - - // Delete connections - for (size_t i = 0; i < m_pConnections.size(); ++i) - { - m_pConnections[i]->Release(); - } - m_pConnections.clear(); -} - -void CRemoteCommandClient::Delete() -{ - delete this; -} - -IRemoteCommandConnection* CRemoteCommandClient::ConnectToServer(const class ServiceNetworkAddress& serverAddress) -{ - CryAutoLock< CryMutex > lock(m_accessMutex); - - // Do not connect twice to the same server - for (TConnections::const_iterator it = m_pConnections.begin(); - it != m_pConnections.end(); ++it) - { - if (ServiceNetworkAddress::CompareBaseAddress((*it)->GetRemoteAddress(), serverAddress)) - { - LOG_VERBOSE(0, "Failed to connect to server '%s': already connected", - serverAddress.ToString().c_str()); - - return NULL; - } - } - - // Open a network connection - IServiceNetworkConnection* pNetConnection = gEnv->pServiceNetwork->Connect(serverAddress); - if (NULL == pNetConnection) - { - LOG_VERBOSE(0, "Failed to connect to server '%s': server is not responding", - serverAddress.ToString().c_str()); - - return NULL; - } - - // Get current command ID (only commands after this one will be sent) - const uint32 firstCommandId = m_commandId; - - // Create a wrapping class and add it to the connection list - Connection* pConnection = new Connection(GetManager(), pNetConnection, firstCommandId); - m_pConnections.push_back(pConnection); - - // Keep internal reference - pConnection->AddRef(); - - LOG_VERBOSE(0, "Connected to remote command server '%s', first command ID=%d", - serverAddress.ToString().c_str(), - firstCommandId); - - return pConnection; -} - -bool CRemoteCommandClient::Schedule(const IRemoteCommand& command) -{ - // No connections - if (m_pConnections.empty()) - { - return false; - } - - // Find ClassID for command - uint32 classId = 0; - if (!GetManager()->FindClassId(command.GetClass(), classId)) - { - LOG_VERBOSE(0, "Class '%s' not recognized. Did you call RegisterClass() ?", - command.GetClass()->GetName()); - - return false; - } - - // Alloc new command ID and compile command data - // TODO: consider moving the compilation to thread (this may be unsafe). - const uint32 commandId = CryInterlockedIncrement((volatile int*) &m_commandId); - Command* pCommand = Command::Compile(command, commandId, classId); - - // Register new command in all of the existing server connections - if (NULL != pCommand) - { - CryAutoLock lock(m_accessMutex); - - for (TConnections::const_iterator it = m_pConnections.begin(); - it != m_pConnections.end(); ++it) - { - (*it)->AddToSendQueue(pCommand); - } - - // We are done with our reference - pCommand->Release(); - } - - // Signal the thread to process data - m_threadEvent.Set(); - return true; -} - -void CRemoteCommandClient::Run() -{ - TConnections pUpdateList; - - CryThreadSetName(-1, "RemoteCommandThread"); - - while (!m_bCloseThread) - { - // copy to local list for updating - { - CryAutoLock lock(m_accessMutex); - pUpdateList = m_pConnections; - } - - // update current connection list - for (TConnections::const_iterator it = pUpdateList.begin(); - it != pUpdateList.end(); ++it) - { - if (!(*it)->Update()) - { - CryAutoLock lock(m_accessMutex); - m_pConnectionsToDelete.push_back(*it); - } - } - - // delete pending connections - { - CryAutoLock lock(m_accessMutex); - for (TConnections::iterator it = m_pConnectionsToDelete.begin(); - it != m_pConnectionsToDelete.end(); ++it) - { - // delete the object - (*it)->Release(); - (*it)->Close(true); - - // remove from connection list - TConnections::iterator jt = std::find(m_pConnections.begin(), m_pConnections.end(), *it); - if (jt != m_pConnections.end()) - { - m_pConnections.erase(jt); - } - } - - // reset the array - m_pConnectionsToDelete.clear(); - } - - // Limit the CPU usage - const uint32 maxWaitTime = 100; - m_threadEvent.Wait(maxWaitTime); - } -} - -void CRemoteCommandClient::Cancel() -{ - m_bCloseThread = true; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp b/Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp deleted file mode 100644 index 6857a9a31c..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandHelpers.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Helper classes for remote command system - - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -CDataReadStreamFormMessage::CDataReadStreamFormMessage(const IServiceNetworkMessage* message) - : m_pMessage(message) - , m_size(message->GetSize()) - , m_pData(static_cast(message->GetPointer())) - , m_offset(0) -{ - // AddRef() is not const unfortunatelly - const_cast(m_pMessage)->AddRef(); -} - -CDataReadStreamFormMessage::~CDataReadStreamFormMessage() -{ - // Release() is not const unfortunatelly - const_cast(m_pMessage)->Release(); -} - -void CDataReadStreamFormMessage::Delete() -{ - delete this; -} - -void CDataReadStreamFormMessage::Skip(const uint32 size) -{ - CRY_ASSERT(m_offset + size < m_size); - m_offset += size; -} - -void CDataReadStreamFormMessage::Read(void* pData, const uint32 size) -{ - CRY_ASSERT(m_offset + size < m_size); - const char* pReadPtr = m_pData + m_offset; - memcpy(pData, pReadPtr, size); - m_offset += size; -} - -void CDataReadStreamFormMessage::Read8(void* pData) -{ - // it does not actually matter if its uint64, int64 or double so use any - ReadType(pData); -} - -void CDataReadStreamFormMessage::Read4(void* pData) -{ - // it does not actually matter if its uint32, int32 or float so use any - ReadType(pData); -} - -void CDataReadStreamFormMessage::Read2(void* pData) -{ - // it does not actually matter if its uint16, int16 so use any - ReadType(pData); -} - -void CDataReadStreamFormMessage::Read1(void* pData) -{ - // it does not actually matter if its uint8, int8 so use any - ReadType(pData); -} - -const void* CDataReadStreamFormMessage::GetPointer() -{ - const char* pReadPtr = m_pData + m_offset; - return pReadPtr; -} - -//----------------------------------------------------------------------------- - -CDataWriteStreamToMessage::CDataWriteStreamToMessage(IServiceNetworkMessage* pMessage) - : m_pMessage(pMessage) - , m_size(pMessage->GetSize()) - , m_pData(static_cast(pMessage->GetPointer())) - , m_offset(0) -{ - m_pMessage->AddRef(); -} - -CDataWriteStreamToMessage::~CDataWriteStreamToMessage() -{ - m_pMessage->Release(); -} - -void CDataWriteStreamToMessage::Delete() -{ - delete this; -} - -const uint32 CDataWriteStreamToMessage::GetSize() const -{ - return m_size; -} - -void CDataWriteStreamToMessage::CopyToBuffer(void* pData) const -{ - memcpy(pData, m_pData, m_size); -} - -IServiceNetworkMessage* CDataWriteStreamToMessage::BuildMessage() const -{ - m_pMessage->AddRef(); - return m_pMessage; -} - -void CDataWriteStreamToMessage::Write(const void* pData, const uint32 size) -{ - CRY_ASSERT(m_offset + size < m_size); - memcpy((char*)m_pData + m_offset, pData, size); - m_offset += size; -} - -void CDataWriteStreamToMessage::Write8(const void* pData) -{ - // it does not actually matter if its uint64, int64 or double so use any - WriteType(pData); -} - -void CDataWriteStreamToMessage::Write4(const void* pData) -{ - // it does not actually matter if its uint32, int32 or float so use any - WriteType(pData); -} - -void CDataWriteStreamToMessage::Write2(const void* pData) -{ - // it does not actually matter if its uint16, int16 so use any - WriteType(pData); -} - -void CDataWriteStreamToMessage::Write1(const void* pData) -{ - // it does not actually matter if its uint8, int8 so use any - WriteType(pData); -} - -//----------------------------------------------------------------------------- - -CDataReadStreamMemoryBuffer::CDataReadStreamMemoryBuffer(const void* pData, const uint32 size) - : m_size(size) - , m_offset(0) -{ - m_pData = new uint8 [size]; - memcpy(m_pData, pData, size); -} - -CDataReadStreamMemoryBuffer::~CDataReadStreamMemoryBuffer() -{ - delete [] m_pData; - m_pData = NULL; -} - -void CDataReadStreamMemoryBuffer::Delete() -{ - delete this; -} - -void CDataReadStreamMemoryBuffer::Skip(const uint32 size) -{ - CRY_ASSERT(m_offset + size <= m_size); - m_offset += size; -} - -void CDataReadStreamMemoryBuffer::Read8(void* pData) -{ - Read(pData, 8); - SwapEndian(*reinterpret_cast(pData)); -} - -void CDataReadStreamMemoryBuffer::Read4(void* pData) -{ - Read(pData, 4); - SwapEndian(*reinterpret_cast(pData)); -} - -void CDataReadStreamMemoryBuffer::Read2(void* pData) -{ - Read(pData, 2); - SwapEndian(*reinterpret_cast(pData)); -} - -void CDataReadStreamMemoryBuffer::Read1(void* pData) -{ - return Read(pData, 1); -} - -const void* CDataReadStreamMemoryBuffer::GetPointer() -{ - return m_pData + m_offset; -}; - -void CDataReadStreamMemoryBuffer::Read(void* pData, const uint32 size) -{ - CRY_ASSERT(m_offset + size <= m_size); - memcpy(pData, m_pData + m_offset, size); - m_offset += size; -} - -//----------------------------------------------------------------------------- - -CDataWriteStreamBuffer::CDataWriteStreamBuffer() - : m_size(0) -{ - // Start with the initial (preallocated) partition - // This optimization assumes that initial size of most of the messages will be small. - // NOTE: default partition is not added to the partition table (that would require push_backs to vector) - char* partitionMemory = &m_defaultPartition[0]; - m_pCurrentPointer = partitionMemory; - m_leftInPartition = sizeof(m_defaultPartition); -} - -CDataWriteStreamBuffer::~CDataWriteStreamBuffer() -{ - // Free all memory partitions that were allocated dynamically - for (size_t i = 0; i < m_pPartitions.size(); ++i) - { - CryModuleFree(m_pPartitions[i]); - } -} - -void CDataWriteStreamBuffer::Delete() -{ - delete this; -} - -const uint32 CDataWriteStreamBuffer::GetSize() const -{ - return m_size; -} - -void CDataWriteStreamBuffer::CopyToBuffer(void* pData) const -{ - uint32 dataLeft = m_size; - char* pWritePtr = (char*)pData; - - // Copy data from default (preallocated) partition - { - const uint32 partitionSize = sizeof(m_defaultPartition); - const uint32 dataToCopy = min(partitionSize, dataLeft); - memcpy(pWritePtr, &m_defaultPartition[0], dataToCopy); - - // advance - pWritePtr += dataToCopy; - dataLeft -= dataToCopy; - } - - // Copy data from dynamic partitions - for (uint32 i = 0; i < m_pPartitions.size(); ++i) - { - // get size of data to copy - const uint32 partitionSize = m_partitionSizes[i]; - const uint32 dataToCopy = min(partitionSize, dataLeft); - memcpy(pWritePtr, m_pPartitions[i], dataToCopy); - - // advance - pWritePtr += dataToCopy; - dataLeft -= dataToCopy; - } - - // Make sure all data was written - CRY_ASSERT(dataLeft == 0); -} - -IServiceNetworkMessage* CDataWriteStreamBuffer::BuildMessage() const -{ - // No data written, no message created - if (0 == m_size) - { - return NULL; - } - - // Create message to hold all the data - IServiceNetworkMessage* pMessage = gEnv->pServiceNetwork->AllocMessageBuffer(m_size); - if (NULL == pMessage) - { - return NULL; - } - - // Copy data to messages - CopyToBuffer(pMessage->GetPointer()); - return pMessage; -} - -void CDataWriteStreamBuffer::Write(const void* pData, const uint32 size) -{ - static const uint32 kAdditionalPartitionSize = 65536; - - uint32 dataLeft = size; - while (dataLeft > 0) - { - // new partition needed - if (m_leftInPartition == 0) - { - // Allocate new partition data - char* partitionMemory = (char*)CryModuleMalloc(kAdditionalPartitionSize); - CRY_ASSERT(partitionMemory != NULL); - - // add new partition to list - m_partitionSizes.push_back(kAdditionalPartitionSize); - m_pPartitions.push_back(partitionMemory); - m_pCurrentPointer = partitionMemory; - m_leftInPartition = kAdditionalPartitionSize; - } - - // how many bytes can we write to current partition ? - const uint32 maxToWrite = min(m_leftInPartition, dataLeft); - memcpy(m_pCurrentPointer, pData, maxToWrite); - - // advance - m_size += maxToWrite; - dataLeft -= maxToWrite; - pData = (const char*)pData + maxToWrite; - m_pCurrentPointer += maxToWrite; - m_leftInPartition -= maxToWrite; - } -} - -void CDataWriteStreamBuffer::Write8(const void* pData) -{ - // it does not actually matter if its uint64, int64 or double so use any - WriteType(pData); -} - -void CDataWriteStreamBuffer::Write4(const void* pData) -{ - // it does not actually matter if its uint32, int32 or float so use any - WriteType(pData); -} - -void CDataWriteStreamBuffer::Write2(const void* pData) -{ - // it does not actually matter if its uint16, int16 so use any - WriteType(pData); -} - -void CDataWriteStreamBuffer::Write1(const void* pData) -{ - // it does not actually matter if its uint8, int8 so use any - WriteType(pData); -} - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/RemoteCommandHelpers.h b/Code/CryEngine/CrySystem/RemoteCommandHelpers.h deleted file mode 100644 index 948097db22..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandHelpers.h +++ /dev/null @@ -1,307 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system helper classes - - -#ifndef CRYINCLUDE_CRYSYSTEM_REMOTECOMMANDHELPERS_H -#define CRYINCLUDE_CRYSYSTEM_REMOTECOMMANDHELPERS_H -#pragma once - - -//------------------------------------------------------------------------ - -#include "IRemoteCommand.h" - -struct IServiceNetworkMessage; - -//------------------------------------------------------------------------ - -// Stream reader for service network message -// Implements automatic byte swapping -class CDataReadStreamFormMessage - : public IDataReadStream -{ -private: - const IServiceNetworkMessage* m_pMessage; - const char* m_pData; - uint32 m_offset; - uint32 m_size; - -private: - template - ILINE void ReadType(void* pData) - { - CRY_ASSERT(m_offset + sizeof(T) < m_size); - const T& readPos = *reinterpret_cast(m_pData + m_offset); - *reinterpret_cast(pData) = readPos; - SwapEndian(*reinterpret_cast(pData)); - m_offset += sizeof(T); - } - -public: - CDataReadStreamFormMessage(const IServiceNetworkMessage* message); - virtual ~CDataReadStreamFormMessage(); - - const uint32 GetOffset() const - { - return m_offset; - } - - void SetPosition(uint32 offset) - { - m_offset = offset; - } - -public: - // IDataReadStream interface - virtual void Delete(); - virtual void Skip(const uint32 size); - virtual void Read(void* pData, const uint32 size); - virtual void Read8(void* pData); - virtual void Read4(void* pData); - virtual void Read2(void* pData); - virtual void Read1(void* pData); - virtual const void* GetPointer(); -}; - -//------------------------------------------------------------------------ - -// Stream writer that writes into the service network message -class CDataWriteStreamToMessage - : public IDataWriteStream -{ -private: - IServiceNetworkMessage* m_pMessage; - char* m_pData; - uint32 m_offset; - uint32 m_size; - -private: - template - ILINE void WriteType(const void* pData) - { - CRY_ASSERT(m_offset + sizeof(T) < m_size); - T& writePos = *reinterpret_cast(m_pData + m_offset); - writePos = *reinterpret_cast(pData); - SwapEndian(writePos); - m_offset += sizeof(T); - } - -public: - CDataWriteStreamToMessage(IServiceNetworkMessage* pMessage); - virtual ~CDataWriteStreamToMessage(); - - // IDataWriteStream interface implementation - virtual void Delete(); - virtual const uint32 GetSize() const; - virtual struct IServiceNetworkMessage* BuildMessage() const; - virtual void CopyToBuffer(void* pData) const; - virtual void Write(const void* pData, const uint32 size); - virtual void Write8(const void* pData); - virtual void Write4(const void* pData); - virtual void Write2(const void* pData); - virtual void Write1(const void* pData); -}; - -//------------------------------------------------------------------------ - -/// Stream reader reading from owner memory buffer -class CDataReadStreamMemoryBuffer - : public IDataReadStream -{ -private: - const uint32 m_size; - uint8* m_pData; - uint32 m_offset; - -public: - // memory is copied! - CDataReadStreamMemoryBuffer(const void* pData, const uint32 size); - virtual ~CDataReadStreamMemoryBuffer(); - - virtual void Delete(); - virtual void Skip(const uint32 size); - virtual void Read8(void* pData); - virtual void Read4(void* pData); - virtual void Read2(void* pData); - virtual void Read1(void* pData); - virtual const void* GetPointer(); - virtual void Read(void* pData, const uint32 size); -}; - -//------------------------------------------------------------------------ - -// Stream writer that writes into the internal memory buffer -class CDataWriteStreamBuffer - : public IDataWriteStream -{ - static const uint32 kStaticPartitionSize = 4096; - -private: - // Default (preallocated) partition - char m_defaultPartition[ kStaticPartitionSize ]; - - // Allocated dynamic partitions - std::vector m_pPartitions; - - // Size of the dynamic message partitions - std::vector m_partitionSizes; - - // Pointer to current writing position in the current partition - char* m_pCurrentPointer; - - // Space left in current partition - uint32 m_leftInPartition; - - // Total message size so far - uint32 m_size; - -private: - // Directly write typed data into the stream - template - ILINE void WriteType(const void* pData) - { - // try to use the faster path if we are not crossing the partition boundary - if (m_leftInPartition >= sizeof(T)) - { - // faster case - T& writePos = *reinterpret_cast(m_pCurrentPointer); - writePos = *reinterpret_cast(pData); - SwapEndian(writePos); - m_pCurrentPointer += sizeof(T); - m_leftInPartition -= sizeof(T); - m_size += sizeof(T); - } - else - { - // slower case (more generic) - T tempVal(*reinterpret_cast(pData)); - SwapEndian(tempVal); - Write(&tempVal, sizeof(tempVal)); - } - } - -public: - CDataWriteStreamBuffer(); - virtual ~CDataWriteStreamBuffer(); - - // IDataWriteStream interface implementation - virtual void Delete(); - virtual const uint32 GetSize() const; - virtual IServiceNetworkMessage* BuildMessage() const; - virtual void CopyToBuffer(void* pData) const; - virtual void Write(const void* pData, const uint32 size); - virtual void Write8(const void* pData); - virtual void Write4(const void* pData); - virtual void Write2(const void* pData); - virtual void Write1(const void* pData); -}; - -//----------------------------------------------------------------------------- - -// Packet header -struct PackedHeader -{ - // Estimation (or better yet, exact value) of how much data this header will take when written. - // Please make sure that actual size after serialization is not bigger than this value. - static const uint32 kSerializationSize = sizeof(uint8) + sizeof(uint32) + sizeof(uint32); - - // Magic value that identifies command messages vs raw messages - static const uint32 kMagic = 0xABBAF00D; - - // Command type - // Keep the values unchanged as this may break the protocol - enum ECommand - { - // Server class list mapping - eCommand_ClassList = 0, - - // Command data - eCommand_Command = 1, - - // Disconnect signal - eCommand_Disconnect = 2, - - // ACK packet - eCommand_ACK = 3, - }; - - uint32 magic; - uint8 msgType; - uint32 count; - - // serialization operator - template< class T > - friend T& operator<<(T& stream, PackedHeader& header) - { - stream << header.magic; - stream << header.msgType; - stream << header.count; - return stream; - } -}; - -// Header sent with every command -struct CommandHeader -{ - uint32 commandId; - uint32 classId; - uint32 size; - - CommandHeader() - : commandId(0) - , classId(0) - , size(0) - {} - - // serialization operator - template< class T > - friend T& operator<<(T& stream, CommandHeader& header) - { - stream << header.commandId; - stream << header.classId; - stream << header.size; - return stream; - } -}; - -// General Response/ACK header -struct ResponseHeader -{ - uint32 magic; - uint8 msgType; - uint32 lastCommandReceived; - uint32 lastCommandExecuted; - - ResponseHeader() - : lastCommandReceived(0) - , lastCommandExecuted(0) - , msgType(PackedHeader::eCommand_ACK) - {} - - // serialization operator - template< class T > - friend T& operator<<(T& stream, ResponseHeader& header) - { - stream << header.magic; - stream << header.msgType; - stream << header.lastCommandReceived; - stream << header.lastCommandExecuted; - return stream; - } -}; - -//----------------------------------------------------------------------------- - -#endif // CRYINCLUDE_CRYSYSTEM_REMOTECOMMANDHELPERS_H diff --git a/Code/CryEngine/CrySystem/RemoteCommandServer.cpp b/Code/CryEngine/CrySystem/RemoteCommandServer.cpp deleted file mode 100644 index 362a9faf1a..0000000000 --- a/Code/CryEngine/CrySystem/RemoteCommandServer.cpp +++ /dev/null @@ -1,832 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Remote command system implementation (server) - -#include "CrySystem_precompiled.h" -#include "IServiceNetwork.h" -#include "RemoteCommand.h" -#include "RemoteCommandHelpers.h" - -//----------------------------------------------------------------------------- - -// remote system internal logging -#ifdef RELEASE -#define LOG_VERBOSE(level, txt, ...) -#else -#define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -CRemoteCommandServer::WrappedCommand::WrappedCommand(IRemoteCommand* pCommand, const uint32 commandId) - : m_pCommand(pCommand) - , m_refCount(1) - , m_commandID(commandId) -{ -} - -CRemoteCommandServer::WrappedCommand::~WrappedCommand() -{ - CRY_ASSERT(m_refCount == 0); - m_pCommand->Delete(); -} - -void CRemoteCommandServer::WrappedCommand::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CRemoteCommandServer::WrappedCommand::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -//----------------------------------------------------------------------------- - -CRemoteCommandServer::Endpoint::Endpoint(CRemoteCommandManager* pManager, class CRemoteCommandServer* pServer, IServiceNetworkConnection* pConnection) - : m_pConnection(pConnection) - , m_pManager(pManager) - , m_pServer(pServer) - , m_lastReceivedCommand(0) - , m_lastExecutedCommand(0) - , m_lastReceivedCommandACKed(0) - , m_lastExecutedCommandACKed(0) - , m_bHasReceivedClassList(false) -{ -} - -CRemoteCommandServer::Endpoint::~Endpoint() -{ - // release commands that were not yet executed - // this will release the command memory buffers (if they are not referenced elsewhere) - while (!m_pCommandsToExecute.empty()) - { - WrappedCommand* pCommand = m_pCommandsToExecute.pop(); - pCommand->Release(); - } - - // make sure the network connection is closed - if (NULL != m_pConnection) - { - // send the disconnect message - { - CDataWriteStreamBuffer writer; - - // format messages - PackedHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_Disconnect; - header.count = 0; - writer << header; - - // Send the message - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL != pMessage) - { - m_pConnection->SendMsg(pMessage); - pMessage->Release(); - } - } - - // close the connection (but try to send messages out) - m_pConnection->FlushAndClose(IServiceNetworkConnection::kDefaultFlushTime); - m_pConnection->Release(); - m_pConnection = NULL; - } -} - -const char* CRemoteCommandServer::Endpoint::GetClassName(const uint32 classId) const -{ - // class index is out of bounds - if (classId >= m_pLocalClassFactories.size()) - { - return "InvalidClassID"; - } - - // get class factory for the class ID - IRemoteCommandClass* theClass = m_pLocalClassFactories[ classId ]; - if (NULL == theClass) - { - // ID is valid but we do not support this class - // Can happen, usually due to version mismatch between client and server binaries - return "UnsupportedClassID"; - } - - return theClass->GetName(); -} - -IRemoteCommand* CRemoteCommandServer::Endpoint::CreateObject(const uint32 classId) const -{ - // class index is out of bounds - if (classId >= m_pLocalClassFactories.size()) - { - return NULL; - } - - // get class factory for given class index - IRemoteCommandClass* theClass = m_pLocalClassFactories[ classId ]; - if (NULL == theClass) - { - // ID is valid but we do not support this class - // Can happen, usually due to version mismatch between client and server binaries - return NULL; - } - - // use the class definition to create the instance of the remote command object - return theClass->CreateObject(); -} - -void CRemoteCommandServer::Endpoint::Execute() -{ - uint32 idOfLastExecutedCommand = 0; - - // Process the commands on the execution list - while (!m_pCommandsToExecute.empty()) - { - // Pop the command from the stack - WrappedCommand* pCommand = m_pCommandsToExecute.pop(); - - LOG_VERBOSE(3, "Executing command '%s', ID %d", - pCommand->GetCommand()->GetClass()->GetName(), - pCommand->GetId()); - - // Here is where the magic happens - { - pCommand->GetCommand()->Execute(); - } - - // Keep track of the command ID executed so far (so we can update the ACK later) - CRY_ASSERT(pCommand->GetId() > idOfLastExecutedCommand); - idOfLastExecutedCommand = pCommand->GetId(); - - // Command was executed, we can release it - pCommand->Release(); - } - - // Update the ACK data (if it's needed) - if (idOfLastExecutedCommand != 0) - { - CryAutoLock lock(m_accessLock); - - LOG_VERBOSE(3, "Updating LastExecutedCommandID %d->%d", - m_lastExecutedCommand, - idOfLastExecutedCommand); - - // Well, it only makes sens if the current command ID is greater that the last one executed - CRY_ASSERT(idOfLastExecutedCommand > m_lastExecutedCommand); - if (idOfLastExecutedCommand > m_lastExecutedCommand) - { - m_lastExecutedCommand = idOfLastExecutedCommand; - } - } -} - -bool CRemoteCommandServer::Endpoint::Update() -{ - // Check connection status - if (!m_pConnection->IsAlive()) - { - // Signal the owner that this endpoint should be deleted - return false; - } - - // Receive and deserialize the commands - // Note that this is done asynchronously so commands can be decoded even if the main thread is busy - // Note that execution is DEFERRED to the main thread (I wouldn't risk doing it from this thread ;-)) - bool bDisconnectReceived = false; - IServiceNetworkMessage* pMsg = m_pConnection->ReceiveMsg(); - while (NULL != pMsg && !bDisconnectReceived) - { - CDataReadStreamFormMessage reader(pMsg); - - // read back the packet header - PackedHeader packetHeader; - reader << packetHeader; - - // Is this a command system messages ? - if (packetHeader.magic == PackedHeader::kMagic) - { - switch (packetHeader.msgType) - { - // Class list, usually sent as first thing after connection - case PackedHeader::eCommand_ClassList: - { - // deserialize class names - std::vector< string > classNames; - reader << classNames; - - // sync the command ID to the current value on the client - const uint32 firstCommandID = packetHeader.count; - m_lastExecutedCommand = firstCommandID; - m_lastExecutedCommandACKed = firstCommandID; - m_lastReceivedCommand = firstCommandID; - m_lastReceivedCommandACKed = firstCommandID; - m_bHasReceivedClassList = true; - - LOG_VERBOSE(3, "Received class list packet, count=%d, first message=%d from '%s'", - classNames.size(), - packetHeader.count, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // create class mapping between remote client and this server - GetManager()->BuildClassMapping(classNames, m_pLocalClassFactories); - break; - } - - // Actual command packets - case PackedHeader::eCommand_Command: - { - LOG_VERBOSE(3, "Received packet, count=%d from '%s'", - packetHeader.count, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // load the serialized commands - const uint32 numCommands = packetHeader.count; - for (uint32 i = 0; i < numCommands; ++i) - { - // Each command is prefixed with header - CommandHeader header; - reader << header; - - // We must be able to skip to the end of the command data because sometimes - // some data can be omitted - either by dropping the command altogether or - // by faulty deserialization. Don't trust the user. - const uint32 offset = reader.GetOffset(); - const uint32 endOffset = offset + header.size; // here is where we can skip - - LOG_VERBOSE(3, "Received command ID=%d (class id=%d, size=%d) from '%s'", - header.commandId, - header.classId, - header.size, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Do not process commands out of order. - // This should not happen if network is in good health, but we cannot assume that, never-ever. - // This code will cause our side to stop executing new commands until the remote side to resend the missing ones. - // Typically it is better than executing commands out of order. - const uint32 expectedNextCommand = m_lastReceivedCommand + 1; - if (header.commandId > expectedNextCommand) - { - LOG_VERBOSE(0, "Out of order command ID (%d > %d) received from '%s'", - header.commandId, - expectedNextCommand, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // next commands will be even older, no need to check them - break; - } - - // Do not process the old commands - // This may happen pretty often when command is resent while the ACK is "in-flight" - // Just drop the data and go on. - if (header.commandId <= m_lastReceivedCommand) - { - // getting old command is not an error, it just means that we have large enough lag - // that the client started resending old commands. - LOG_VERBOSE(1, "Old command (%d <= %d) received from '%s'", - header.commandId, - m_lastReceivedCommand, - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - else - { - // next command received, we are very strict about matchig the command IDs here - CRY_ASSERT(header.commandId == expectedNextCommand); - m_lastReceivedCommand = expectedNextCommand; - - // create the command - IRemoteCommand* pCommand = CreateObject(header.classId); - if (NULL != pCommand) - { - // Fine-grain logging - LOG_VERBOSE(3, "Received command '%s', classId=%d, commandId=%d from '%s'", - pCommand->GetClass()->GetName(), - header.classId, - header.commandId, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - // Deserialize the command data from network message - pCommand->LoadFromStream(reader); - - // Add to list of commands to execute - { - m_pCommandsToExecute.push(new WrappedCommand(pCommand, header.commandId)); - } - } - else - { - LOG_VERBOSE(0, "ClassId %d not recognized. Skipping command ID%d from '%s'", - header.classId, - header.commandId, - m_pConnection->GetRemoteAddress().ToString().c_str()); - } - - // Update the last command ID - m_lastReceivedCommand = header.commandId; - } - - // Sync the message stream to popper position - CRY_ASSERT(reader.GetOffset() <= endOffset); - reader.SetPosition(endOffset); - } - - break; - } - - // request to disconnect (graceful) - case PackedHeader::eCommand_Disconnect: - { - LOG_VERBOSE(3, "Received disconnect request from '%s'", - m_pConnection->GetRemoteAddress().ToString().c_str()); - - m_pConnection->Close(); - bDisconnectReceived = true; - - break; - } - - // should not happen - default: - { - LOG_VERBOSE(0, "Invalid message type '%s' received from '%s'", - packetHeader.msgType, - m_pConnection->GetRemoteAddress().ToString().c_str()); - - break; - } - } - } - else - { - // This is a raw message, try to process immediately using async listeners. - // If it fails, add to the queue for processing on the main thread by sync listeners. - m_pServer->ProcessRawMessageAsync(pMsg, m_pConnection); - } - - // Release the message data - pMsg->Release(); - - // Get the next message from network - if (!bDisconnectReceived) - { - pMsg = m_pConnection->ReceiveMsg(); - } - } - - // The value of lastExecutedCommand can change outside this thread, - // so capture it one and keep it constant for the duration of the logic in this function. - const uint32 snapshotLastExecutedCommand = m_lastExecutedCommand; - - // Determine if we should send generate the ACK signal - if ((snapshotLastExecutedCommand != m_lastExecutedCommandACKed) || - (m_lastReceivedCommand != m_lastReceivedCommandACKed)) // this can - { - ResponseHeader header; - header.magic = PackedHeader::kMagic; - header.msgType = PackedHeader::eCommand_ACK; - header.lastCommandReceived = m_lastReceivedCommand; - header.lastCommandExecuted = snapshotLastExecutedCommand; // note that we use the captured values - - LOG_VERBOSE(3, "Sending ACK to '%s' with LastReceived=%d, LastExecuted=%d", - m_pConnection->GetRemoteAddress().ToString().c_str(), - header.lastCommandReceived, - header.lastCommandExecuted); - - // Write header into the message - CDataWriteStreamBuffer writer; - writer << header; - - // Extract the message - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL != pMessage) - { - // Send it back over the connection (works as ACK) - if (m_pConnection->SendMsg(pMessage)) - { - // Only after the message is accepted by the network we can assume that we have ACKed it properly - // This can still leave a possibility that this message gets eaten in the network but we will resend newer ACK - // soon enough that we don't need to bother with this. - m_lastExecutedCommandACKed = header.lastCommandExecuted; - m_lastReceivedCommandACKed = header.lastCommandReceived; - } - - pMessage->Release(); - } - } - - // Continue - return true; -} - -//----------------------------------------------------------------------------- - -CRemoteCommandServer::CRemoteCommandServer(CRemoteCommandManager* pManager, IServiceNetworkListener* pListener) - : m_pManager(pManager) - , m_pListener(pListener) - , m_bCloseThread(false) - , m_suppressionCounter(0) - , m_bIsSuppressed(false) -{ - // Start processing thread (receiving from network, deserialization, etc) - m_pThread = new TRemoteServerThread(); - m_pThread->Start(*this); -} - -CRemoteCommandServer::~CRemoteCommandServer() -{ - // Stop the thread, assumes that thread is responsive - if (NULL != m_pThread) - { - m_pThread->Cancel(); - m_pThread->Stop(); - m_pThread->WaitForThread(); - delete m_pThread; - } - - // Cleanup the clients endpoints - for (TEndpoints::const_iterator it = m_pEndpoints.begin(); - it != m_pEndpoints.end(); ++it) - { - delete (*it); - } - m_pEndpoints.clear(); - - // Cleanup the clients that were not yet deleted but are dead - for (TEndpoints::const_iterator it = m_pEndpointToDelete.begin(); - it != m_pEndpointToDelete.end(); ++it) - { - delete (*it); - } - m_pEndpointToDelete.clear(); - - // Cleanup the raw messages - while (!m_pRawMessages.empty()) - { - delete m_pRawMessages.pop(); - } - - // Properly close the listening socket - if (m_pListener != NULL) - { - m_pListener->Close(); - m_pListener->Release(); - m_pListener = NULL; - } -} - -void CRemoteCommandServer::ProcessRawMessageAsync(IServiceNetworkMessage* pMessage, IServiceNetworkConnection* pConnection) -{ - // we lock for the whole duration of the function - I think that's the safest. - // this function is being called from remote command server thread and even if it locks for a moment that's not a tragic situation. - CryAutoLock lock(m_rawMessagesLock); - - // Process the message using async listeners - bool bWasProcessed = false; - for (TRawMessageListenersAsync::const_iterator it = m_pRawListenersAsync.begin(); - it != m_pRawListenersAsync.end(); ++it) - { - CDataReadStreamFormMessage reader(pMessage); - CDataWriteStreamBuffer writer; - - // Request the listener to process this message - if ((*it)->OnRawMessageAsync(pConnection->GetRemoteAddress(), reader, writer)) - { - // Send response back using the source connection - if (writer.GetSize() > 0) - { - IServiceNetworkMessage* pNewMessage = writer.BuildMessage(); - if (NULL != pNewMessage) - { - pConnection->SendMsg(pNewMessage); - pNewMessage->Release(); - } - } - - // mark as processed - bWasProcessed = true; - break; - } - } - - // Stats - if (bWasProcessed) - { - LOG_VERBOSE(3, "Raw message from '%s', size %d ASYNC, PROCESSED", - pConnection->GetRemoteAddress().ToString().c_str(), - pMessage->GetSize()); - } - else - { - LOG_VERBOSE(3, "Raw message from '%s', size %d ASYNC, NOT PROCESSED", - pConnection->GetRemoteAddress().ToString().c_str(), - pMessage->GetSize()); - } - - // If we have sync listeners add the raw message for processing on the main thread - if (!bWasProcessed && !m_pRawListenersSync.empty()) - { - m_pRawMessages.push(new RawMessage(pConnection, pMessage)); - } -} - -void CRemoteCommandServer::ProcessRawMessagesSync() -{ - // get messages - TRawMessageListenersSync listeners; - { - CryAutoLock lock(m_rawMessagesLock); - listeners = m_pRawListenersSync; - } - - // process each message - while (!m_pRawMessages.empty()) - { - RawMessage* pMsg = m_pRawMessages.pop(); - - // Process messages only from alive connection (they could die before we got a chance to process the message) - if (pMsg && pMsg->m_pConnection->IsAlive()) - { - // Try to process by on of the listeners - bool bWasProcessed = false; - for (TRawMessageListenersSync::const_iterator jt = listeners.begin(); - jt != listeners.end(); ++jt) - { - CDataReadStreamFormMessage reader(pMsg->m_pMessage); - CDataWriteStreamBuffer writer; - - // Request the listener to process this message - if ((*jt)->OnRawMessageSync(pMsg->m_pConnection->GetRemoteAddress(), reader, writer)) - { - // Send response back using the source connection - if (writer.GetSize() > 0) - { - IServiceNetworkMessage* pMessage = writer.BuildMessage(); - if (NULL != pMessage) - { - pMsg->m_pConnection->SendMsg(pMessage); - pMessage->Release(); - } - } - - // mark as processed - bWasProcessed = true; - break; - } - } - - // Stats - if (bWasProcessed) - { - LOG_VERBOSE(3, "Raw message from '%s', size %d SYNC PROCESSED", - pMsg->m_pConnection->GetRemoteAddress().ToString().c_str(), - pMsg->m_pMessage->GetSize()); - } - else - { - LOG_VERBOSE(3, "Raw message from '%s', size %d SYNC NOT PROCESSED", - pMsg->m_pConnection->GetRemoteAddress().ToString().c_str(), - pMsg->m_pMessage->GetSize()); - } - } - - /// Cleanup - delete pMsg; - } -} - -void CRemoteCommandServer::Delete() -{ - delete this; -} - -void CRemoteCommandServer::FlushCommandQueue() -{ - // Always process raw messages, even if commands are suspended - ProcessRawMessagesSync(); - - // When the command server is suppressed externally, well, then don't execute any commands - // This is usually used when the main thread is doing some heavy stuff. - // TODO: Consider signaling the clients about this condition. - if (m_bIsSuppressed) - { - LOG_VERBOSE(4, "FlushCommandQueue: suppressed (counter=%d)", - m_suppressionCounter); - - return; - } - - // Update the endpoints from a copy of the list - { - CryAutoLock lock(m_accessLock); - m_pUpdateEndpoints = m_pEndpoints; - } - - // Execute the commands for each endpoint - for (TEndpoints::const_iterator it = m_pUpdateEndpoints.begin(); - it != m_pUpdateEndpoints.end(); ++it) - { - (*it)->Execute(); - } - - // Delete endpoints that were discarded within the thread (due to network errors) - // We couldn't do that there because we would need to lock to much inside the mutex (bad idea) - if (!m_pEndpointToDelete.empty()) - { - // TODO: consider using different CS for pDeletedEnpoints array - CryAutoLock lock(m_accessLock); - - // delete the endpoint structured (deferred) - for (size_t i = 0; i < m_pEndpointToDelete.size(); ++i) - { - delete m_pEndpointToDelete[i]; - } - - m_pEndpointToDelete.clear(); - } -} - -void CRemoteCommandServer::SuppressCommands() -{ - if (CryInterlockedIncrement(&m_suppressionCounter) > 0) - { - m_bIsSuppressed = true; - } -} - -void CRemoteCommandServer::ResumeCommands() -{ - if (CryInterlockedDecrement(&m_suppressionCounter) == 0) - { - m_bIsSuppressed = false; - } -} - -void CRemoteCommandServer::Run() -{ - TEndpoints updateList; - - CryThreadSetName(-1, "RemoteCommandThread"); - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(RemoteCommandServer_cpp) -#endif - - while (!m_bCloseThread) - { - // Accept new connections - { - IServiceNetworkConnection* pNewConnection = m_pListener->Accept(); - if (NULL != pNewConnection) - { - LOG_VERBOSE(2, "New endpoint created with connection '%s'", - pNewConnection->GetRemoteAddress().ToString().c_str()); - - // Create endpoint wrapper - Endpoint* pEndPoint = new Endpoint(GetManager(), this, pNewConnection); - - // Add to endpoint list - { - CryAutoLock lock(m_accessLock); - m_pEndpoints.push_back(pEndPoint); - } - } - } - - // Get the current endpoint table (for update) - { - CryAutoLock lock(m_accessLock); - updateList = m_pEndpoints; - } - - // Update endpoints - for (TEndpoints::iterator it = updateList.begin(); - it != updateList.end(); ++it) - { - Endpoint* ep = (*it); - if (!ep->Update()) - { - LOG_VERBOSE(2, "RemoteCommand endpoint '%s' closed", - ep->GetConnection()->GetRemoteAddress().ToString().c_str()); - - // remove the endpoint from the original list - { - CryAutoLock lock(m_accessLock); - - // it's safe to remove from the endpoints list - we are iterating over a copy - m_pEndpoints.erase(std::find(m_pEndpoints.begin(), m_pEndpoints.end(), ep)); - - // don't delete the endpoint structure now (it may still be executed on main thread) - // instead add it to a list that will be processed at the end of execution so this endpoint can get deleted - m_pEndpointToDelete.push_back(ep); - } - } - } - - // Limit the CPU usage - // TODO: consider using some event based mechanism since the only source of - // work for this thread is the network we can esily be triggered by that. - Sleep(5); - } -} - -void CRemoteCommandServer::Cancel() -{ - m_bCloseThread = true; -} - -void CRemoteCommandServer::RegisterSyncMessageListener(IRemoteCommandListenerSync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - m_pRawListenersSync.push_back(pListener); -} - -void CRemoteCommandServer::UnregisterSyncMessageListener(IRemoteCommandListenerSync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - - TRawMessageListenersSync::iterator it = std::find(m_pRawListenersSync.begin(), m_pRawListenersSync.end(), pListener); - if (it != m_pRawListenersSync.end()) - { - m_pRawListenersSync.erase(it); - } -} - -void CRemoteCommandServer::RegisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - m_pRawListenersAsync.push_back(pListener); -} - -void CRemoteCommandServer::UnregisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) -{ - CryAutoLock lock(m_rawMessagesLock); - - TRawMessageListenersAsync::iterator it = std::find(m_pRawListenersAsync.begin(), m_pRawListenersAsync.end(), pListener); - if (it != m_pRawListenersAsync.end()) - { - m_pRawListenersAsync.erase(it); - } -} - -void CRemoteCommandServer::Broadcast(IServiceNetworkMessage* pMessage) -{ - if (NULL != pMessage && pMessage->GetSize() > 0) - { - CryAutoLock lock(m_rawMessagesLock); - for (TEndpoints::const_iterator jt = m_pEndpoints.begin(); - jt != m_pEndpoints.end(); ++jt) - { - Endpoint* pEndpoint = (*jt); - if (pEndpoint->HasReceivedClassList()) - { - IServiceNetworkConnection* pConnection = pEndpoint->GetConnection(); - if (NULL != pConnection) - { - pConnection->SendMsg(pMessage); - } - } - } - } -} - -bool CRemoteCommandServer::HasConnectedClients() const -{ - CryAutoLock lock(m_rawMessagesLock); - - for (TEndpoints::const_iterator jt = m_pEndpoints.begin(); - jt != m_pEndpoints.end(); ++jt) - { - Endpoint* pEndpoint = (*jt); - if (pEndpoint->HasReceivedClassList()) - { - IServiceNetworkConnection* pConnection = pEndpoint->GetConnection(); - if (pConnection->IsAlive()) - { - return true; - } - } - } - - return false; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/ResourceManager.cpp b/Code/CryEngine/CrySystem/ResourceManager.cpp deleted file mode 100644 index 08a674136d..0000000000 --- a/Code/CryEngine/CrySystem/ResourceManager.cpp +++ /dev/null @@ -1,894 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Resource Manager - - -#include "CrySystem_precompiled.h" -#include "ResourceManager.h" -#include "System.h" -#include "MaterialUtils.h" -#include -#include -#include -#include -#include -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define RESOURCEMANAGER_CPP_SECTION_1 1 -#define RESOURCEMANAGER_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION RESOURCEMANAGER_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(ResourceManager_cpp) -#endif - -#define LEVEL_PAK_FILENAME "level.pak" -#define LEVEL_PAK_INMEMORY_MAXSIZE 10 * 1024 * 1024 - -#define ENGINE_PAK_FILENAME "engine.pak" -#define LEVEL_CACHE_PAK_FILENAME "xml.pak" - -#define GAME_DATA_PAK_FILENAME "gamedata.pak" -#define FAST_LOADING_PAKS_SRC_FOLDER "_fastload/" -#define FRONTEND_COMMON_PAK_FILENAME_SP "modes/menucommon_sp.pak" -#define FRONTEND_COMMON_PAK_FILENAME_MP "modes/menucommon_mp.pak" -#define FRONTEND_COMMON_LIST_FILENAME "menucommon" -#define LEVEL_CACHE_SRC_FOLDER "_levelcache/" -#define LEVEL_CACHE_BIND_ROOT "LevelCache" -#define LEVEL_RESOURCE_LIST "resourcelist.txt" -#define AUTO_LEVEL_RESOURCE_LIST "auto_resourcelist.txt" -#define AUTO_LEVEL_SEQUENCE_RESOURCE_LIST "auto_resources_sequence.txt" -#define AUTO_LEVEL_TOTAL_RESOURCE_LIST "auto_resourcelist_total.txt" -#define AUTO_LEVEL_TOTAL_SEQUENCE_RESOURCE_LIST "auto_resources_total_sequence.txt" - -////////////////////////////////////////////////////////////////////////// -// IResourceList implementation class. -////////////////////////////////////////////////////////////////////////// -class CLevelResourceList - : public AZ::IO::IResourceList -{ -public: - CLevelResourceList() - { - m_pFileBuffer = 0; - m_nBufferSize = 0; - m_nCurrentLine = 0; - }; - ~CLevelResourceList() - { - Clear(); - }; - - uint32 GetFilenameHash(const char* sResourceFile) - { - char filename[512]; - azstrcpy(filename, AZ_ARRAY_SIZE(filename), sResourceFile); - MaterialUtils::UnifyMaterialName(filename); - - uint32 code = CCrc32::ComputeLowercase(filename); - return code; - } - - virtual void Add([[maybe_unused]] AZStd::string_view sResourceFile) - { - assert(0); // Not implemented. - } - virtual void Clear() - { - delete [] m_pFileBuffer; - m_pFileBuffer = 0; - m_nBufferSize = 0; - stl::free_container(m_lines); - stl::free_container(m_resources_crc32); - m_nCurrentLine = 0; - } - - struct ComparePredicate - { - bool operator()(const char* s1, const char* s2) - { - return strcmp(s1, s2) < 0; - } - }; - - virtual bool IsExist(AZStd::string_view sResourceFile) - { - uint32 nHash = GetFilenameHash(sResourceFile.data()); - if (stl::binary_find(m_resources_crc32.begin(), m_resources_crc32.end(), nHash) != m_resources_crc32.end()) - { - return true; - } - return false; - } - virtual bool Load(AZStd::string_view sResourceListFilename) - { - Clear(); - CCryFile file; - if (file.Open(sResourceListFilename.data(), "rb", AZ::IO::IArchive::FOPEN_ONDISK)) // File access can happen from disk as well. - { - m_nBufferSize = file.GetLength(); - if (m_nBufferSize > 0) - { - m_pFileBuffer = new char[m_nBufferSize]; - size_t numBytesRead = file.ReadRaw(m_pFileBuffer, file.GetLength()); - - if (numBytesRead <= 0 || numBytesRead != file.GetLength()) - { - AZ_Error("ResourceManager", false, "Unable to read data for: %.*s", aznumeric_cast(sResourceListFilename.size()), sResourceListFilename.data()); - return false; - } - m_pFileBuffer[m_nBufferSize - 1] = 0; - - char seps[] = "\r\n"; - - m_lines.reserve(5000); - - // Parse file, every line in a file represents a resource filename. - char* nextToken = nullptr; - char* token = azstrtok(m_pFileBuffer, 0, seps, &nextToken); - while (token != NULL) - { - m_lines.push_back(token); - token = azstrtok(NULL, 0, seps, &nextToken); - } - - m_resources_crc32.resize(m_lines.size()); - for (int i = 0, numlines = m_lines.size(); i < numlines; i++) - { - MaterialUtils::UnifyMaterialName(const_cast(m_lines[i])); - m_resources_crc32[i] = CCrc32::ComputeLowercase(m_lines[i]); - } - std::sort(m_resources_crc32.begin(), m_resources_crc32.end()); - } - return true; - } - return false; - } - virtual const char* GetFirst() - { - m_nCurrentLine = 0; - if (!m_lines.empty()) - { - return m_lines[0]; - } - return NULL; - } - virtual const char* GetNext() - { - m_nCurrentLine++; - if (m_nCurrentLine < (int)m_lines.size()) - { - return m_lines[m_nCurrentLine]; - } - return NULL; - } - - void GetMemoryStatistics(ICrySizer* pSizer) - { - pSizer->Add(this, sizeof(*this)); - pSizer->Add(m_pFileBuffer, m_nBufferSize); - pSizer->AddContainer(m_lines); - pSizer->AddContainer(m_resources_crc32); - } - -public: - char* m_pFileBuffer; - int m_nBufferSize; - typedef std::vector Lines; - Lines m_lines; - int m_nCurrentLine; - std::vector m_resources_crc32; -}; - - -////////////////////////////////////////////////////////////////////////// -CResourceManager::CResourceManager() -{ - m_bRegisteredFileOpenSink = false; - m_bOwnResourceList = false; - m_bLevelTransitioning = false; - - m_fastLoadPakPaths.reserve(8); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::PrepareLevel(const char* sLevelFolder, const char* sLevelName) -{ - LOADING_TIME_PROFILE_SECTION; - - m_sLevelFolder = sLevelFolder; - m_sLevelName = sLevelName; - m_bLevelTransitioning = false; - m_currentLevelCacheFolder = CryPathString(LEVEL_CACHE_SRC_FOLDER) + sLevelName; - - if (g_cvars.archiveVars.nLoadCache) - { - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - // The prefab system doesn't use level.pak - if (!usePrefabSystemForLevels) - { - CryPathString levelpak = PathUtil::Make(sLevelFolder, LEVEL_PAK_FILENAME); - size_t nPakFileSize = gEnv->pCryPak->FGetSize(levelpak.c_str()); - if (nPakFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs. - { - // Force level.pak from this level in memory. - gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - } - } - - gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - - // - // Load _levelCache paks in the order they are stored on the disk - reduce seek time - // - - if (gEnv->pConsole->GetCVar("e_StreamCgf") && gEnv->pConsole->GetCVar("e_StreamCgf")->GetIVal() != 0) - { - LoadLevelCachePak("cga.pak", "", true); - LoadLevelCachePak("cgf.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("cgf_cache.pak", "", false); - } - } - - LoadLevelCachePak("chr.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("chr_cache.pak", "", false); - } - - LoadLevelCachePak("dds0.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("dds_cache.pak", "", false); - } - - LoadLevelCachePak("skin.pak", "", true); - - if (g_cvars.archiveVars.nStreamCache) - { - LoadLevelCachePak("skin_cache.pak", "", false); - } - - LoadLevelCachePak(LEVEL_CACHE_PAK_FILENAME, "", true); - } - - AZStd::intrusive_ptr pResList = new CLevelResourceList; - gEnv->pCryPak->SetResourceList(AZ::IO::IArchive::RFOM_Level, pResList.get()); - m_bOwnResourceList = true; - - // Load resourcelist.txt, TODO: make sure there are no duplicates - if (g_cvars.archiveVars.nSaveLevelResourceList == 0) - { - string filename = PathUtil::Make(sLevelFolder, AUTO_LEVEL_RESOURCE_LIST); - if (!pResList->Load(filename.c_str())) // If we saving resource list do not use auto_resourcelist.txt - { - // Try resource list created by the editor. - filename = PathUtil::Make(sLevelFolder, LEVEL_RESOURCE_LIST); - pResList->Load(filename.c_str()); - } - } - //LoadFastLoadPaks(); - - if (g_cvars.archiveVars.nStreamCache) - { - m_AsyncPakManager.ParseLayerPaks(GetCurrentLevelCacheFolder()); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadFastLoadPaks(bool bToMemory) -{ - if (g_cvars.archiveVars.nSaveFastloadResourceList != 0) - { - // Record a file list for _FastLoad/startup.pak - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return false; - } - else - { - LOADING_TIME_PROFILE_SECTION; - - // Load a special _fastload paks - int nPakPreloadFlags = AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32 | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK; - if (bToMemory && g_cvars.archiveVars.nLoadCache) - { - nPakPreloadFlags |= AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY; - } - - const char* const assetsDir = "@assets@"; - const char* shaderPakPath = "ShaderCacheStartup.pak"; - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION RESOURCEMANAGER_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(ResourceManager_cpp) -#endif - - gEnv->pCryPak->OpenPacks(assetsDir, AZ::IO::PathString(FAST_LOADING_PAKS_SRC_FOLDER) + "*.pak", nPakPreloadFlags, &m_fastLoadPakPaths); - gEnv->pCryPak->OpenPack(assetsDir, shaderPakPath, AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK); - gEnv->pCryPak->OpenPack(assetsDir, "Engine.pak", AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY); - return !m_fastLoadPakPaths.empty(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadFastLoadPaks() -{ - for (uint32 i = 0; i < m_fastLoadPakPaths.size(); i++) - { - // Unload a special _fastload paks - gEnv->pCryPak->ClosePack(m_fastLoadPakPaths[i].c_str(), AZ::IO::IArchive::FLAGS_PATH_REAL); - } - m_fastLoadPakPaths.clear(); - - if (gEnv && gEnv->pRenderer) - { - gEnv->pRenderer->UnloadShaderStartupCache(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadLevel() -{ - gEnv->pCryPak->SetResourceList(AZ::IO::IArchive::RFOM_Level, NULL); - - if (m_bRegisteredFileOpenSink) - { - if (g_cvars.archiveVars.nSaveTotalResourceList) - { - SaveRecordedResources(true); - m_recordedFiles.clear(); - } - } - - stl::free_container(m_sLevelFolder); - stl::free_container(m_sLevelName); - stl::free_container(m_currentLevelCacheFolder); - - // should always be empty, since it is freed at the end of - // the level loading process, if it is not - // something went wrong and we have a levelheap leak - assert(m_openedPaks.capacity() == 0); - - m_pSequenceResourceList = NULL; -} - -////////////////////////////////////////////////////////////////////////// -AZ::IO::IResourceList* CResourceManager::GetLevelResourceList() -{ - auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level); - return pResList; -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading) -{ - LOADING_TIME_PROFILE_SECTION; - CryPathString pakPath = GetCurrentLevelCacheFolder() + "/" + sPakName; - - pakPath.MakeLower(); - pakPath.replace(AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR); - - // Check if pak is already loaded - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if (strstr(m_openedPaks[i].filename.c_str(), pakPath.c_str())) - { - return true; - } - } - - // check pak file size. - size_t nFileSize = gEnv->pCryPak->FGetSize(pakPath.c_str(), true); - - if (nFileSize <= 0) - { - // Cached file does not exist - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Level cache pak file %s does not exist", pakPath.c_str()); - return false; - } - - //set these flags as DLC LevelCache Paks are found via the mod paths, - //and the paks can never be inside other paks so we optimise the search - uint32 nOpenPakFlags = AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32 | AZ::IO::IArchive::FLAGS_CHECK_MOD_PATHS | AZ::IO::IArchive::FLAGS_NEVER_IN_PAK; - - if (nFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs. - { - if (!(nOpenPakFlags & AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY_CPU)) - { - nOpenPakFlags |= AZ::IO::IArchive::FLAGS_PAK_IN_MEMORY; - } - } - - SOpenedPak op; - - if (gEnv->pCryPak->OpenPack(sBindRoot, { pakPath.c_str(), pakPath.size() }, nOpenPakFlags | AZ::IO::IArchive::FOPEN_HINT_QUIET, NULL, &op.filename)) - { - op.bOnlyDuringLevelLoading = bOnlyDuringLevelLoading; - m_openedPaks.push_back(op); - return true; - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadModeSwitchPak(const char* sPakName, const bool multiplayer) -{ - if (g_cvars.archiveVars.nSaveLevelResourceList) - { - //Don't load the pak if we're trying to save a resourcelist in order to build it. - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return true; - } - else - { - if (g_cvars.archiveVars.nLoadModePaks) - { - // Unload SP common pak if switching to multiplayer - if (multiplayer) - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); - } - else - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP, FRONTEND_COMMON_LIST_FILENAME "_mp"); - } - //Load the mode switching pak. If this is available and up to date it speeds up this process considerably - bool bOpened = gEnv->pCryPak->OpenPack("@assets@", sPakName, 0); - bool bLoaded = gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - return (bOpened && bLoaded); - } - else - { - return true; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer) -{ - if (g_cvars.archiveVars.nSaveLevelResourceList && m_bRegisteredFileOpenSink) - { - m_sLevelFolder = sResourceListName; - SaveRecordedResources(); - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - else - { - if (g_cvars.archiveVars.nLoadModePaks) - { - //Unload the mode switching pak. - gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - gEnv->pCryPak->ClosePack(sPakName, 0); - //Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc, currently SP only - if (!multiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP); - } - else if (multiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_MP); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::LoadMenuCommonPak(const char* sPakName) -{ - if (g_cvars.archiveVars.nSaveMenuCommonResourceList) - { - //Don't load the pak if we're trying to save a resourcelist in order to build it. - m_recordedFiles.clear(); - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - return true; - } - else - { - //Load the mode switching pak. If this is available and up to date it speeds up this process considerably - bool bOpened = gEnv->pCryPak->OpenPack("@assets@", sPakName, 0); - bool bLoaded = gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_GPU); - return (bOpened && bLoaded); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadMenuCommonPak(const char* sPakName, const char* sResourceListName) -{ - if (g_cvars.archiveVars.nSaveMenuCommonResourceList) - { - m_sLevelFolder = sResourceListName; - SaveRecordedResources(); - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - else - { - //Unload the mode switching pak. - gEnv->pCryPak->LoadPakToMemory(sPakName, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - gEnv->pCryPak->ClosePack(sPakName, 0); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadLevelCachePak(const char* sPakName) -{ - LOADING_TIME_PROFILE_SECTION; - CryPathString pakPath = GetCurrentLevelCacheFolder() + "/" + sPakName; - pakPath.MakeLower(); - pakPath.replace(AZ_WRONG_FILESYSTEM_SEPARATOR, AZ_CORRECT_FILESYSTEM_SEPARATOR); - - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if (strstr(m_openedPaks[i].filename.c_str(), pakPath.c_str())) - { - gEnv->pCryPak->ClosePack(m_openedPaks[i].filename.c_str(), AZ::IO::IArchive::FLAGS_PATH_REAL); - m_openedPaks.erase(m_openedPaks.begin() + i); - break; - } - } - - if (m_openedPaks.empty()) - { - stl::free_container(m_openedPaks); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::UnloadAllLevelCachePaks(bool bLevelLoadEnd) -{ - LOADING_TIME_PROFILE_SECTION; - - if (!bLevelLoadEnd) - { - m_AsyncPakManager.Clear(); - UnloadFastLoadPaks(); - } - else - { - m_AsyncPakManager.UnloadLevelLoadPaks(); - } - - uint32 nClosePakFlags = AZ::IO::IArchive::FLAGS_PATH_REAL; //AZ::IO::IArchive::FLAGS_CHECK_MOD_PATHS | AZ::IO::IArchive::FLAGS_NEVER_IN_PAK | AZ::IO::IArchive::FLAGS_PATH_REAL; - - for (int i = 0; i < (int)m_openedPaks.size(); i++) - { - if ((m_openedPaks[i].bOnlyDuringLevelLoading && bLevelLoadEnd) || - !bLevelLoadEnd) - { - gEnv->pCryPak->ClosePack(m_openedPaks[i].filename.c_str(), nClosePakFlags); - } - } - - if (g_cvars.archiveVars.nLoadCache) - { - gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - - bool usePrefabSystemForLevels = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult( - usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); - - if (!usePrefabSystemForLevels) - { - // Force level.pak out of memory. - gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload); - } - } - if (!bLevelLoadEnd) - { - stl::free_container(m_openedPaks); - } -} - -////////////////////////////////////////////////////////////////////////// - -bool CResourceManager::LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) -{ - return m_AsyncPakManager.LoadPakToMemAsync(pPath, bLevelLoadOnly); -} - -bool CResourceManager::LoadLayerPak(const char* sLayerName) -{ - return m_AsyncPakManager.LoadLayerPak(sLayerName); -} - -void CResourceManager::UnloadLayerPak(const char* sLayerName) -{ - m_AsyncPakManager.UnloadLayerPak(sLayerName); -} - -void CResourceManager::GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const -{ - m_AsyncPakManager.GetLayerPakStats(stats, bCollectAllStats); -} - -void CResourceManager::UnloadAllAsyncPaks() -{ - m_AsyncPakManager.Clear(); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Update() -{ - m_AsyncPakManager.Update(); -} -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Init() -{ - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::Shutdown() -{ - UnloadAllLevelCachePaks(false); - if (GetISystem() && GetISystem()->GetISystemEventDispatcher()) - { - GetISystem()->GetISystemEventDispatcher()->RemoveListener(this); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CResourceManager::IsStreamingCachePak(const char* filename) const -{ - const char* cachePaks[] = { - "dds_cache.pak", - "cgf_cache.pak", - "skin_cache.pak", - "chr_cache.pak" - }; - - for (int i = 0; i < sizeof(cachePaks) / sizeof(cachePaks[0]); ++i) - { - if (strstr(filename, cachePaks[i])) - { - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_FRONTEND_INITIALISED: - { - GetISystem()->GetStreamEngine()->PauseStreaming(false, -1); - } - break; - - case ESYSTEM_EVENT_GAME_POST_INIT_DONE: - { - if (g_cvars.archiveVars.nSaveFastloadResourceList != 0) - { - SaveRecordedResources(); - - if (g_cvars.archiveVars.nSaveLevelResourceList == 0 && g_cvars.archiveVars.nSaveTotalResourceList == 0) - { - m_recordedFiles.clear(); - } - } - // Unload all paks from memory, after game init. - UnloadAllLevelCachePaks(false); - gEnv->pCryPak->LoadPaksToMemory(0, false); - - if (g_cvars.archiveVars.nLoadCache) - { - //Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc - if (!gEnv->bMultiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP); - } - } - - //Load and precache frontend shader cache - if (g_cvars.archiveVars.nLoadFrontendShaderCache) - { - gEnv->pRenderer->LoadShaderLevelCache(); - gEnv->pRenderer->EF_Query(EFQ_SetShaderCombinations); - } - - break; - } - - case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE: - { - if (g_cvars.archiveVars.nLoadFrontendShaderCache) - { - gEnv->pRenderer->UnloadShaderLevelCache(); - } - - if (!gEnv->bMultiplayer) - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp"); - } - else - { - UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP, FRONTEND_COMMON_LIST_FILENAME "_mp"); - } - - m_bLevelTransitioning = !m_sLevelName.empty(); - - m_lastLevelLoadTime.SetValue(0); - m_beginLevelLoadTime = gEnv->pTimer->GetAsyncTime(); - if (g_cvars.archiveVars.nSaveLevelResourceList || g_cvars.archiveVars.nSaveTotalResourceList) - { - if (!g_cvars.archiveVars.nSaveTotalResourceList) - { - m_recordedFiles.clear(); - } - - if (!m_bRegisteredFileOpenSink) - { - gEnv->pCryPak->RegisterFileAccessSink(this); - m_bRegisteredFileOpenSink = true; - } - } - - // Cancel any async pak loading, it will fight with the impending sync IO - m_AsyncPakManager.CancelPendingJobs(); - - // Pause streaming engine for anything but sound, music, video and flash. - uint32 nMask = (1 << eStreamTaskTypeFlash) | (1 << eStreamTaskTypeVideo) | STREAM_TASK_TYPE_AUDIO_ALL; // Unblock specified streams - nMask = ~nMask; // Invert mask, bit set means blocking type. - GetISystem()->GetStreamEngine()->PauseStreaming(true, nMask); - } - break; - - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - if (m_bOwnResourceList) - { - m_bOwnResourceList = false; - // Clear resource list, after level loading. - auto pResList = gEnv->pCryPak->GetResourceList(AZ::IO::IArchive::RFOM_Level); - if (pResList) - { - pResList->Clear(); - } - } - } - - break; - - case ESYSTEM_EVENT_LEVEL_UNLOAD: - UnloadAllLevelCachePaks(false); - - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_START: - { - // Unpause all streams in streaming engine. - GetISystem()->GetStreamEngine()->PauseStreaming(false, -1); - } - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_FIRST_FRAME: - { - UnloadAllLevelCachePaks(true); - } - break; - - case ESYSTEM_EVENT_LEVEL_PRECACHE_END: - { - CTimeValue t = gEnv->pTimer->GetAsyncTime(); - m_lastLevelLoadTime = t - m_beginLevelLoadTime; - - if (g_cvars.archiveVars.nSaveLevelResourceList && m_bRegisteredFileOpenSink) - { - SaveRecordedResources(); - - if (!g_cvars.archiveVars.nSaveTotalResourceList) - { - gEnv->pCryPak->UnregisterFileAccessSink(this); - m_bRegisteredFileOpenSink = false; - } - } - - UnloadAllLevelCachePaks(true); - } - break; - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::GetMemoryStatistics(ICrySizer* pSizer) -{ - pSizer->AddContainer(m_openedPaks); -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::ReportFileOpen([[maybe_unused]] AZ::IO::HandleType inFileHandle, AZStd::string_view szFullPath) -{ - if (!g_cvars.archiveVars.nSaveLevelResourceList && !g_cvars.archiveVars.nSaveFastloadResourceList && !g_cvars.archiveVars.nSaveMenuCommonResourceList && !g_cvars.archiveVars.nSaveTotalResourceList) - { - return; - } - - string file = PathUtil::MakeGamePath(string(szFullPath.data(), szFullPath.size())); - file.replace('\\', '/'); - file.MakeLower(); - { - CryAutoCriticalSection lock(recordedFilesLock); - m_recordedFiles.push_back(file); - } -} - -////////////////////////////////////////////////////////////////////////// -void CResourceManager::SaveRecordedResources(bool bTotalList) -{ - CryAutoCriticalSection lock(recordedFilesLock); - - std::set fileset; - - // eliminate duplicate values - std::vector::iterator endLocation = std::unique(m_recordedFiles.begin(), m_recordedFiles.end()); - m_recordedFiles.erase(endLocation, m_recordedFiles.end()); - - fileset.insert(m_recordedFiles.begin(), m_recordedFiles.end()); - - string sSequenceFilename = PathUtil::AddSlash(m_sLevelFolder) + (bTotalList ? AUTO_LEVEL_TOTAL_SEQUENCE_RESOURCE_LIST : AUTO_LEVEL_SEQUENCE_RESOURCE_LIST); - { - AZ::IO::HandleType fileHandle = fxopen(sSequenceFilename, "wb", true); - if (fileHandle != AZ::IO::InvalidHandle) - { - for (std::vector::iterator it = m_recordedFiles.begin(); it != m_recordedFiles.end(); ++it) - { - const char* str = it->c_str(); - AZ::IO::Print(fileHandle, "%s\n", str); - } - gEnv->pFileIO->Close(fileHandle); - } - } - - string sResourceSetFilename = PathUtil::AddSlash(m_sLevelFolder) + (bTotalList ? AUTO_LEVEL_TOTAL_RESOURCE_LIST : AUTO_LEVEL_RESOURCE_LIST); - { - AZ::IO::HandleType fileHandle = fxopen(sResourceSetFilename, "wb", true); - if (fileHandle != AZ::IO::InvalidHandle) - { - for (std::set::iterator it = fileset.begin(); it != fileset.end(); ++it) - { - const char* str = it->c_str(); - AZ::IO::Print(fileHandle, "%s\n", str); - } - gEnv->pFileIO->Close(fileHandle); - } - } -} - -////////////////////////////////////////////////////////////////////////// -CTimeValue CResourceManager::GetLastLevelLoadTime() const -{ - return m_lastLevelLoadTime; -} diff --git a/Code/CryEngine/CrySystem/ResourceManager.h b/Code/CryEngine/CrySystem/ResourceManager.h deleted file mode 100644 index aa697b3927..0000000000 --- a/Code/CryEngine/CrySystem/ResourceManager.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Interface to the Resource Manager - - -#ifndef CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H -#define CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H -#pragma once - - -#include -#include "AsyncPakManager.h" - -////////////////////////////////////////////////////////////////////////// -// IResource manager interface -////////////////////////////////////////////////////////////////////////// -class CResourceManager - : public IResourceManager - , public ISystemEventListener - , public AZ::IO::IArchiveFileAccessSink -{ -public: - CResourceManager(); - - void Init(); - void Shutdown(); - - bool IsStreamingCachePak(const char* filename) const; - - ////////////////////////////////////////////////////////////////////////// - // IResourceManager interface implementation. - ////////////////////////////////////////////////////////////////////////// - void PrepareLevel(const char* sLevelFolder, const char* sLevelName); - void UnloadLevel(); - AZ::IO::IResourceList* GetLevelResourceList(); - bool LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading); - void UnloadLevelCachePak(const char* sPakName); - bool LoadModeSwitchPak(const char* sPakName, const bool multiplayer); - void UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer); - bool LoadMenuCommonPak(const char* sPakName); - void UnloadMenuCommonPak(const char* sPakName, const char* sResourceListName); - bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly); - void UnloadAllAsyncPaks(); - bool LoadLayerPak(const char* sLayerName); - void UnloadLayerPak(const char* sLayerName); - void UnloadAllLevelCachePaks(bool bLevelLoadEnd); - void GetMemoryStatistics(ICrySizer* pSizer); - bool LoadFastLoadPaks(bool bToMemory); - void UnloadFastLoadPaks(); - CTimeValue GetLastLevelLoadTime() const; - void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // IArchiveFileAccessSink interface implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void ReportFileOpen(AZ::IO::HandleType inFileHandle, AZStd::string_view szFullPath); - ////////////////////////////////////////////////////////////////////////// - - // Per frame update of the resource manager. - void Update(); - - CryPathString GetCurrentLevelCacheFolder() const { return m_currentLevelCacheFolder; }; - void SaveRecordedResources(bool bTotalList = false); - -private: - - ////////////////////////////////////////////////////////////////////////// - - CryPathString m_currentLevelCacheFolder; - - struct SOpenedPak - { - AZStd::fixed_string filename; - bool bOnlyDuringLevelLoading; - }; - std::vector m_openedPaks; - - CAsyncPakManager m_AsyncPakManager; - - string m_sLevelFolder; - string m_sLevelName; - bool m_bLevelTransitioning; - - bool m_bRegisteredFileOpenSink; - bool m_bOwnResourceList; - - CTimeValue m_beginLevelLoadTime; - CTimeValue m_lastLevelLoadTime; - - AZStd::intrusive_ptr m_pSequenceResourceList; - - CryCriticalSection recordedFilesLock; - std::vector m_recordedFiles; - - AZStd::vector< AZStd::fixed_string > m_fastLoadPakPaths; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_RESOURCEMANAGER_H diff --git a/Code/CryEngine/CrySystem/SSAPI.DLL b/Code/CryEngine/CrySystem/SSAPI.DLL deleted file mode 100644 index b1f3d6cfce..0000000000 --- a/Code/CryEngine/CrySystem/SSAPI.DLL +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:45dfbb9836e8a8ac4ed5b427528dadf9134618e6977a1eb67af067e0eaadc185 -size 561936 diff --git a/Code/CryEngine/CrySystem/Sampler.cpp b/Code/CryEngine/CrySystem/Sampler.cpp deleted file mode 100644 index b6866ba6cd..0000000000 --- a/Code/CryEngine/CrySystem/Sampler.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "Sampler.h" - -#if defined(WIN32) - -#include -#include -#include - -#define MAX_SYMBOL_LENGTH 512 - -////////////////////////////////////////////////////////////////////////// -// Makes thread. -////////////////////////////////////////////////////////////////////////// -class CSamplingThread -{ -public: - CSamplingThread(CSampler* pSampler) - { - m_hThread = NULL; - m_pSampler = pSampler; - m_bStop = false; - m_samplePeriodMs = pSampler->GetSamplePeriod(); - - m_hProcess = GetCurrentProcess(); - m_hSampledThread = GetCurrentThread(); - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &m_hSampledThread, 0, FALSE, DUPLICATE_SAME_ACCESS); - } - - // Start thread. - void Start(); - void Stop(); - -protected: - virtual ~CSamplingThread() {}; - static DWORD WINAPI ThreadFunc(void* pThreadParam); - void Run(); // Derived classes must override this. - - HANDLE m_hProcess; - HANDLE m_hThread; - HANDLE m_hSampledThread; - DWORD m_ThreadId; - - CSampler* m_pSampler; - bool m_bStop; - int m_samplePeriodMs; -}; - -////////////////////////////////////////////////////////////////////////// -void CSamplingThread::Start() -{ - m_hThread = CreateThread(NULL, 0, ThreadFunc, this, 0, &m_ThreadId); -} - -////////////////////////////////////////////////////////////////////////// -void CSamplingThread::Stop() -{ - m_bStop = true; -} - -////////////////////////////////////////////////////////////////////////// -DWORD CSamplingThread::ThreadFunc(void* pThreadParam) -{ - CSamplingThread* thread = (CSamplingThread*)pThreadParam; - thread->Run(); - // Auto destruct thread class. - delete thread; - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSamplingThread::Run() -{ - //SetThreadPriority( m_hThread,THREAD_PRIORITY_HIGHEST ); - SetThreadPriority(m_hThread, THREAD_PRIORITY_TIME_CRITICAL); - while (!m_bStop) - { - SuspendThread(m_hSampledThread); - - CONTEXT context; - context.ContextFlags = CONTEXT_CONTROL; - - uint64 ip = 0; - if (GetThreadContext(m_hSampledThread, &context)) - { -#ifdef CONTEXT_i386 - ip = context.Eip; -#else - ip = context.Rip; -#endif - } - ResumeThread(m_hSampledThread); - - if (!m_pSampler->AddSample(ip)) - { - break; - } - - Sleep(m_samplePeriodMs); - } -} - -////////////////////////////////////////////////////////////////////////// -CSampler::CSampler() -{ - m_pSamplingThread = NULL; - SetMaxSamples(2000); - m_bSamplingFinished = false; - m_bSampling = false; - m_samplePeriodMs = 1; //1ms -} - -////////////////////////////////////////////////////////////////////////// -CSampler::~CSampler() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::SetMaxSamples(int nMaxSamples) -{ - m_rawSamples.reserve(nMaxSamples); - m_nMaxSamples = nMaxSamples; -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::Start() -{ - if (m_bSampling) - { - return; - } - - CryLogAlways("Staring Sampling with interval %dms, max samples: %d ...", m_samplePeriodMs, m_nMaxSamples); - - m_bSampling = true; - m_bSamplingFinished = false; - m_pSamplingThread = new CSamplingThread(this); - m_rawSamples.clear(); - m_functionSamples.clear(); - - m_pSamplingThread->Start(); -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::Stop() -{ - if (m_bSamplingFinished) - { - } - if (m_bSampling) - { - m_pSamplingThread->Stop(); - } - m_bSampling = false; - m_pSamplingThread = 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::Update() -{ - if (m_bSamplingFinished) - { - ProcessSampledData(); - m_bSamplingFinished = false; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CSampler::AddSample(uint64 ip) -{ - if ((int)m_rawSamples.size() >= m_nMaxSamples) - { - m_bSamplingFinished = true; - m_bSampling = false; - m_pSamplingThread = 0; - return false; - } - m_rawSamples.push_back(ip); - return true; -} - -inline bool CompareFunctionSamples(const CSampler::SFunctionSample& s1, const CSampler::SFunctionSample& s2) -{ - return s1.nSamples < s2.nSamples; -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::ProcessSampledData() -{ - CryLogAlways("Processing collected samples..."); - - uint32 i; - // Count duplicates. - std::map counts; - std::map::iterator cit; - for (i = 0; i < m_rawSamples.size(); i++) - { - uint32 ip = (uint32)m_rawSamples[i]; - cit = counts.find(ip); - if (cit != counts.end()) - { - cit->second++; - } - else - { - counts[ip] = 0; - } - } - - std::map funcCounts; - - AZ::Debug::SymbolStorage::StackLine func, file, module; - int line; - void* baseAddr; - string funcName; - for (i = 0; i < m_rawSamples.size(); i++) - { - // lookup module name here, and aggregate the results - AZ::Debug::SymbolStorage::FindFunctionFromIP((void*)m_rawSamples[i], &func, &file, &module, line, baseAddr); - - // Developer note: this file was using the module name instead of the function name. There was stub code - // to use the function name instead that. This function was updated to use FindFunctionFromIP(), but - // continues to use the module instead of the function. - funcName = module; - funcCounts[funcName] += 1; - } - - { - // Combine function samples. - std::map::iterator it; - for (it = funcCounts.begin(); it != funcCounts.end(); ++it) - { - SFunctionSample fs; - fs.function = it->first; - fs.nSamples = it->second; - m_functionSamples.push_back(fs); - } - } - - // Sort vector by number of samples. - std::sort(m_functionSamples.begin(), m_functionSamples.end(), CompareFunctionSamples); - - LogSampledData(); -} - -////////////////////////////////////////////////////////////////////////// -void CSampler::LogSampledData() -{ - int nTotalSamples = m_rawSamples.size(); - - // Log sample info. - CryLogAlways("========================================================================="); - CryLogAlways("= Profiler Output"); - CryLogAlways("========================================================================="); - - float fOnePercent = (float)nTotalSamples / 100; - - float fPercentTotal = 0; - int nSampleSum = 0; - for (uint32 i = 0; i < m_functionSamples.size(); i++) - { - // Calculate percentage. - float fPercent = m_functionSamples[i].nSamples / fOnePercent; - const char* func = m_functionSamples[i].function; - CryLogAlways("%6.2f%% (%4d samples) : %s", fPercent, m_functionSamples[i].nSamples, func); - fPercentTotal += fPercent; - nSampleSum += m_functionSamples[i].nSamples; - } - CryLogAlways("Samples: %d / %d (%.2f%%)", nSampleSum, nTotalSamples, fPercentTotal); - CryLogAlways("========================================================================="); -} - - -#endif // defined(WIN32) diff --git a/Code/CryEngine/CrySystem/Sampler.h b/Code/CryEngine/CrySystem/Sampler.h deleted file mode 100644 index b2c61013a2..0000000000 --- a/Code/CryEngine/CrySystem/Sampler.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SAMPLER_H -#define CRYINCLUDE_CRYSYSTEM_SAMPLER_H -#pragma once - -#ifdef WIN32 - -class CSamplingThread; - -////////////////////////////////////////////////////////////////////////// -// Sampler class is running a second thread which is at regular intervals -// eg 1ms samples main thread and stores current IP in the samples buffers. -// After sampling finishes it can resolve collected IP buffer info to -// the function names and calculated where most of the execution time spent. -////////////////////////////////////////////////////////////////////////// -class CSampler -{ -public: - struct SFunctionSample - { - string function; - uint32 nSamples; // Number of samples per function. - }; - - CSampler(); - ~CSampler(); - - void Start(); - void Stop(); - void Update(); - - // Adds a new sample to the ip buffer, return false if no more samples can be added. - bool AddSample(uint64 ip); - void SetMaxSamples(int nMaxSamples); - - int GetSamplePeriod() const { return m_samplePeriodMs; } - void SetSamplePeriod(int millis) { m_samplePeriodMs = millis; } - -private: - void ProcessSampledData(); - void LogSampledData(); - - // Buffer for IP samples. - std::vector m_rawSamples; - std::vector m_functionSamples; - int m_nMaxSamples; - bool m_bSampling; - bool m_bSamplingFinished; - - int m_samplePeriodMs; - - CSamplingThread* m_pSamplingThread; -}; - -#else //WIN32 - -// Dummy sampler. -class CSampler -{ -public: - void Start() {} - void Stop() {} - void Update() {} - void SetMaxSamples(int) {} - void SetSamplePeriod(int) {} -}; - -#endif // WIN32 - -#endif // CRYINCLUDE_CRYSYSTEM_SAMPLER_H diff --git a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.cpp b/Code/CryEngine/CrySystem/Serialization/ArchiveHost.cpp deleted file mode 100644 index f7ed4ae46c..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include "JSONIArchive.h" -#include "JSONOArchive.h" -#include "BinArchive.h" -#include "XmlIArchive.h" -#include "XmlOArchive.h" -#include - -namespace Serialization -{ - bool LoadFile(std::vector& content, const char* filename) - { - AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(filename, "rb"); - if (!fileHandle) - { - return false; - } - - gEnv->pCryPak->FSeek(fileHandle, 0, SEEK_END); - size_t size = gEnv->pCryPak->FTell(fileHandle); - gEnv->pCryPak->FSeek(fileHandle, 0, SEEK_SET); - - content.resize(size); - bool result = true; - if (size != 0) - { - result = gEnv->pCryPak->FRead(&content[0], size, fileHandle) == size; - } - gEnv->pCryPak->FClose(fileHandle); - return result; - } - - class CArchiveHost - : public IArchiveHost - { - public: - bool LoadJsonFile(const SStruct& obj, const char* filename) override - { - std::vector content; - if (!LoadFile(content, filename)) - { - return false; - } - JSONIArchive ia; - if (!ia.open(content.data(), content.size())) - { - return false; - } - return ia(obj); - } - - bool SaveJsonFile(const char* gameFilename, const SStruct& obj) override - { - char buffer[AZ::IO::IArchive::MaxPath]; - const char* filename = gEnv->pCryPak->AdjustFileName(gameFilename, buffer, AZ_ARRAY_SIZE(buffer), AZ::IO::IArchive::FLAGS_FOR_WRITING); - JSONOArchive oa; - if (!oa(obj)) - { - return false; - } - return oa.save(filename); - } - - bool LoadJsonBuffer(const SStruct& obj, const char* buffer, size_t bufferLength) override - { - if (bufferLength == 0) - { - return false; - } - JSONIArchive ia; - if (!ia.open(buffer, bufferLength)) - { - return false; - } - return ia(obj); - } - - bool SaveJsonBuffer(DynArray& buffer, const SStruct& obj) override - { - JSONOArchive oa; - if (!oa(obj)) - { - return false; - } - buffer.assign(oa.buffer(), oa.buffer() + oa.length()); - return true; - } - - - bool LoadBinaryFile(const SStruct& obj, const char* filename) override - { - std::vector content; - if (!LoadFile(content, filename)) - { - return false; - } - BinIArchive ia; - if (!ia.open(content.data(), content.size())) - { - return false; - } - return ia(obj); - } - - bool SaveBinaryFile(const char* gameFilename, const SStruct& obj) override - { - char buffer[AZ::IO::IArchive::MaxPath]; - const char* filename = gEnv->pCryPak->AdjustFileName(gameFilename, buffer, AZ_ARRAY_SIZE(buffer), AZ::IO::IArchive::FLAGS_FOR_WRITING); - BinOArchive oa; - obj(oa); - return oa.save(filename); - } - - bool LoadBinaryBuffer(const SStruct& obj, const char* buffer, size_t bufferLength) override - { - if (bufferLength == 0) - { - return false; - } - BinIArchive ia; - if (!ia.open(buffer, bufferLength)) - { - return false; - } - return ia(obj); - } - - bool SaveBinaryBuffer(DynArray& buffer, const SStruct& obj) override - { - BinOArchive oa; - obj(oa); - buffer.assign(oa.buffer(), oa.buffer() + oa.length()); - return true; - } - - bool CloneBinary(const SStruct& dest, const SStruct& src) override - { - BinOArchive oa; - src(oa); - BinIArchive ia; - if (!ia.open(oa.buffer(), oa.length())) - { - return false; - } - dest(ia); - return true; - } - - bool CompareBinary(const SStruct& lhs, const SStruct& rhs) override - { - BinOArchive oa1; - lhs(oa1); - BinOArchive oa2; - rhs(oa2); - if (oa1.length() != oa2.length()) - { - return false; - } - return memcmp(oa1.buffer(), oa2.buffer(), oa1.length()) == 0; - } - - bool SaveXmlFile(const char* filename, const SStruct& obj, const char* rootNodeName) override - { - XmlNodeRef node = SaveXmlNode(obj, rootNodeName); - if (!node) - { - return false; - } - return node->saveToFile(filename); - } - - bool LoadXmlFile(const SStruct& obj, const char* filename) override - { - XmlNodeRef node = gEnv->pSystem->LoadXmlFromFile(filename); - if (!node) - { - return false; - } - return LoadXmlNode(obj, node); - } - - XmlNodeRef SaveXmlNode(const SStruct& obj, const char* nodeName) override - { - CXmlOArchive oa; - XmlNodeRef node = gEnv->pSystem->CreateXmlNode(nodeName); - if (!node) - { - return XmlNodeRef(); - } - oa.SetXmlNode(node); - if (!obj(oa)) - { - return XmlNodeRef(); - } - return oa.GetXmlNode(); - } - - bool SaveXmlNode(XmlNodeRef& node, const SStruct& obj) override - { - if (!node) - { - return false; - } - CXmlOArchive oa; - oa.SetXmlNode(node); - return obj(oa); - } - - bool LoadXmlNode(const SStruct& obj, const XmlNodeRef& node) override - { - CXmlIArchive ia; - ia.SetXmlNode(node); - if (!obj(ia)) - { - return false; - } - return true; - } - }; - - IArchiveHost* CreateArchiveHost() - { - return new CArchiveHost; - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.h b/Code/CryEngine/CrySystem/Serialization/ArchiveHost.h deleted file mode 100644 index 360dded0c7..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/ArchiveHost.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -namespace Serialization -{ - IArchiveHost* CreateArchiveHost(); -} diff --git a/Code/CryEngine/CrySystem/Serialization/BinArchive.cpp b/Code/CryEngine/CrySystem/Serialization/BinArchive.cpp deleted file mode 100644 index f16c15cc96..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/BinArchive.cpp +++ /dev/null @@ -1,839 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "BinArchive.h" -#include -#include "Serialization/ClassFactory.h" - -namespace Serialization { - static const unsigned char SIZE16 = 254; - static const unsigned char SIZE32 = 255; - - static const unsigned int BIN_MAGIC = 0xb1a4c17f; - - //#ifdef _DEBUG - //typedef std::map HashMap; - //static HashMap hashMap; - //#endif - - BinOArchive::BinOArchive() - : IArchive(OUTPUT | BINARY) - { - clear(); - } - - void BinOArchive::clear() - { - stream_.clear(); - stream_.write((const char*)&BIN_MAGIC, sizeof(BIN_MAGIC)); - } - - size_t BinOArchive::length() const - { - return stream_.position(); - } - - bool BinOArchive::save(const char* filename) - { - FILE* f = nullptr; - azfopen(&f, filename, "wb"); - if (!f) - { - return false; - } - - if (fwrite(buffer(), 1, length(), f) != length()) - { - fclose(f); - return false; - } - - fclose(f); - return true; - } - - inline void BinOArchive::openNode(const char* name, bool size8) - { - if (!strlen(name)) - { - return; - } - - unsigned short hash = calcHash(name); - stream_.write(hash); - - blockSizeOffsets_.push_back(int(stream_.position())); - stream_.write((unsigned char)0); - if (!size8) - { - stream_.write((unsigned short)0); - } - -#ifdef _DEBUG - // HashMap::iterator i = hashMap.find(hash); - // if(i != hashMap.end() && i->second != name) - // ASSERT_STR(0, name); - // hashMap[hash] = name; -#endif - } - - inline void BinOArchive::closeNode(const char* name, bool size8) - { - if (!strlen(name)) - { - return; - } - - unsigned int offset = blockSizeOffsets_.back(); - unsigned int size = (unsigned int)(stream_.position() - offset - sizeof(unsigned char) - (size8 ? 0 : sizeof(unsigned short))); - blockSizeOffsets_.pop_back(); - unsigned char* sizePtr = (unsigned char*)(stream_.buffer() + offset); - - if (size < SIZE16) - { - *sizePtr = size; - if (!size8) - { - unsigned char* buffer = sizePtr + 3; - memmove(buffer - 2, buffer, size); - stream_.setPosition(stream_.position() - 2); - } - } - else - { - YASLI_ASSERT(!size8); - if (size < 0x10000) - { - *sizePtr = SIZE16; - *((unsigned short*)(sizePtr + 1)) = size; - } - else - { - unsigned char* buffer = sizePtr + 3; - stream_.write((unsigned short)0); - *sizePtr = SIZE32; - memmove(buffer + 2, buffer, size); - *((unsigned int*)(sizePtr + 1)) = size; - } - } - } - - bool BinOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - bool size8 = strlen(value.get()) + 1 < SIZE16; - openNode(name, size8); - stream_ << value.get(); - stream_.write(char(0)); - closeNode(name, size8); - return true; - } - - bool BinOArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - bool size8 = (wcslen(value.get()) + 1) * 2 < SIZE16; - openNode(name, size8); - stream_ << value.get(); - stream_.write(short(0)); - closeNode(name, size8); - return true; - } - - bool BinOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - openNode(name); - stream_.write(value); - closeNode(name); - return true; - } - - bool BinOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - ser(*this); - closeNode(name, false); - return true; - } - - bool BinOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - - unsigned int size = (unsigned int)ser.size(); - if (size < SIZE16) - { - stream_.write((unsigned char)size); - } - else if (size < 0x10000) - { - stream_.write(SIZE16); - stream_.write((unsigned short)size); - } - else - { - stream_.write(SIZE32); - stream_.write(size); - } - - if (strlen(name)) - { - if (size > 0) - { - int i = 0; - do - { - char elementName[16]; - azitoa(i++, elementName, AZ_ARRAY_SIZE(elementName), 10); - ser(*this, elementName, ""); - } while (ser.next()); - } - - closeNode(name, false); - } - else - { - if (size > 0) - { - do - { - ser(*this, "", ""); - } - while (ser.next()); - } - } - - return true; - } - - bool BinOArchive::operator()(IPointer& ptr, const char* name, [[maybe_unused]] const char* label) - { - openNode(name, false); - - const char* typeName = ptr.registeredTypeName(); - if (!typeName) - { - typeName = ""; - } - if (typeName[0] == '\0' && ptr.get()) - { - CRY_ASSERT_MESSAGE(0, "Writing unregistered class. Use SERIALIZATION_CLASS_NAME macro for registration."); - } - - TypeID baseType = ptr.baseType(); - - if (ptr.get()) - { - stream_ << typeName; - stream_.write(char(0)); - ptr.serializer()(*this); - } - else - { - stream_.write(char(0)); - } - - closeNode(name, false); - return true; - } - - ////////////////////////////////////////////////////////////////////////// - - BinIArchive::BinIArchive() - : IArchive(INPUT | BINARY) - , loadedData_(0) - { - } - - BinIArchive::~BinIArchive() - { - close(); - } - - bool BinIArchive::load(const char* filename) - { - close(); - - FILE* f = nullptr; - azfopen(&f, filename, "rb"); - - if (!f) - { - return false; - } - fseek(f, 0, SEEK_END); - size_t length = ftell(f); - fseek(f, 0, SEEK_SET); - if (length == 0) - { - fclose(f); - return false; - } - loadedData_ = new char[length]; - if (fread((void*)loadedData_, 1, length, f) != length || !open(loadedData_, length)) - { - close(); - fclose(f); - return false; - } - fclose(f); - return true; - } - - bool BinIArchive::open(const char* buffer, size_t size) - { - if (size < sizeof(int)) - { - return false; - } - if (*(unsigned*)(buffer) != BIN_MAGIC) - { - return false; - } - buffer += sizeof(unsigned int); - size -= sizeof(unsigned int); - - blocks_.push_back(Block(buffer, (unsigned int)size)); - return true; - } - - void BinIArchive::close() - { - if (loadedData_) - { - delete[] loadedData_; - } - loadedData_ = 0; - } - - bool BinIArchive::openNode(const char* name) - { - Block block(0, 0); - if (currentBlock().get(name, block)) - { - blocks_.push_back(block); - return true; - } - return false; - } - - void BinIArchive::closeNode([[maybe_unused]] const char* name, [[maybe_unused]] bool check) - { - YASLI_ASSERT(!check || currentBlock().validToClose()); - blocks_.pop_back(); - } - - bool BinIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - string str; - read(str); - value.set(str.c_str()); - return true; - } - - if (!openNode(name)) - { - return false; - } - - string str; - read(str); - value.set(str.c_str()); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - wstring str; - read(str); - value.set(str.c_str()); - return true; - } - - if (!openNode(name)) - { - return false; - } - - wstring str; - read(str); - value.set(str.c_str()); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - - bool BinIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - read(value); - return true; - } - - if (!openNode(name)) - { - return false; - } - - read(value); - closeNode(name); - return true; - } - - bool BinIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - if (!strlen(name)) - { - ser(*this); - return true; - } - - if (!openNode(name)) - { - return false; - } - - ser(*this); - closeNode(name, false); - return true; - } - - bool BinIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (strlen(name)) - { - if (!openNode(name)) - { - return false; - } - - size_t size = currentBlock().readPackedSize(); - ser.resize(size); - - if (size > 0) - { - int i = 0; - do - { - char elementName[16]; - azitoa(i++, elementName, AZ_ARRAY_SIZE(elementName), 10); - ser(*this, elementName, ""); - } - while (ser.next()); - } - closeNode(name); - return true; - } - else - { - size_t size = currentBlock().readPackedSize(); - ser.resize(size); - if (size > 0) - { - do - { - ser(*this, "", ""); - } - while (ser.next()); - } - return true; - } - } - - bool BinIArchive::operator()(IPointer& ptr, const char* name, [[maybe_unused]] const char* label) - { - if (strlen(name) && !openNode(name)) - { - return false; - } - - string typeName; - read(typeName); - if (ptr.get() && (typeName.empty() || strcmp(typeName.c_str(), ptr.registeredTypeName()) != 0)) - { - ptr.create(""); // 0 - } - if (!typeName.empty() && !ptr.get()) - { - ptr.create(typeName.c_str()); - } - - if (SStruct ser = ptr.serializer()) - { - ser(*this); - } - - if (strlen(name)) - { - closeNode(name); - } - return true; - } - - unsigned int BinIArchive::Block::readPackedSize() - { - unsigned char size8; - read(size8); - if (size8 < SIZE16) - { - return size8; - } - if (size8 == SIZE16) - { - unsigned short size16; - read(size16); - return size16; - } - unsigned int size32; - read(size32); - return size32; - } - - bool BinIArchive::Block::get(const char* name, Block& block) - { - if (begin_ == end_) - { - return false; - } - complex_ = true; - unsigned short hashName = calcHash(name); - const char* currInitial = curr_; - bool restarted = false; - for (;; ) - { - if (curr_ >= end_) - { - return false; - } - - unsigned short hash; - read(hash); - unsigned int size = readPackedSize(); - - const char* currPrev = curr_; - if ((curr_ += size) == end_) - { - if (restarted) - { - return false; - } - curr_ = begin_; - restarted = true; - } - - //ASSERT(curr_ < end_); - - if (hash == hashName) - { - block = Block(currPrev, size); - return true; - } - - if (curr_ == currInitial) - { - return false; - } - } - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/BinArchive.h b/Code/CryEngine/CrySystem/Serialization/BinArchive.h deleted file mode 100644 index 2d7daba899..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/BinArchive.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -// For tags 16-bit xor-hash is used, with check for uniquness in debug -// Block size is automatic: 8, 16 or 32 bits - -#include "Serialization/IArchive.h" -#include "MemoryWriter.h" - -namespace Serialization { - inline unsigned short calcHash(const char* str) - { - unsigned short hash = 0; - const unsigned short* p = (const unsigned short*)(str); - for (;; ) - { - unsigned short w = *p++; - if (!(w & 0xff)) - { - break; - } - hash ^= w; - if (!(w & 0xff00)) - { - break; - } - } - return hash; - } - - class BinOArchive - : public IArchive - { - public: - - BinOArchive(); - ~BinOArchive() {} - - void clear(); - size_t length() const; - const char* buffer() const { return stream_.buffer(); } - bool save(const char* fileName); - - bool operator()(bool& value, const char* name, const char* label); - bool operator()(IString& value, const char* name, const char* label); - bool operator()(IWString& value, const char* name, const char* label); - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(int8& value, const char* name, const char* label); - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - bool operator()(const SStruct& ser, const char* name, const char* label); - bool operator()(IContainer& ser, const char* name, const char* label); - bool operator()(IPointer& ptr, const char* name, const char* label); - - using IArchive::operator(); - - private: - void openContainer(const char* name, int size, const char* typeName); - void openNode(const char* name, bool size8 = true); - void closeNode(const char* name, bool size8 = true); - - std::vector blockSizeOffsets_; - MemoryWriter stream_; - }; - - ////////////////////////////////////////////////////////////////////////// - - class BinIArchive - : public IArchive - { - public: - - BinIArchive(); - ~BinIArchive(); - - bool load(const char* fileName); - bool open(const char* buffer, size_t length); // doesn't copy the buffer - bool open(const BinOArchive& ar) { return open(ar.buffer(), ar.length()); } - void close(); - - bool operator()(bool& value, const char* name, const char* label); - bool operator()(IString& value, const char* name, const char* label); - bool operator()(IWString& value, const char* name, const char* label); - bool operator()(float& value, const char* name, const char* label); - bool operator()(double& value, const char* name, const char* label); - bool operator()(int16& value, const char* name, const char* label); - bool operator()(uint16& value, const char* name, const char* label); - bool operator()(int32& value, const char* name, const char* label); - bool operator()(uint32& value, const char* name, const char* label); - bool operator()(int64& value, const char* name, const char* label); - bool operator()(uint64& value, const char* name, const char* label); - - bool operator()(int8& value, const char* name, const char* label); - bool operator()(uint8& value, const char* name, const char* label); - bool operator()(char& value, const char* name, const char* label); - - bool operator()(const SStruct& ser, const char* name, const char* label); - bool operator()(IContainer& ser, const char* name, const char* label); - bool operator()(IPointer& ptr, const char* name, const char* label); - - using IArchive::operator(); - - private: - class Block - { - public: - Block(const char* data, int size) - : begin_(data) - , end_(data + size) - , curr_(data) - , complex_(false) {} - - bool get(const char* name, Block& block); - - void read(void* data, int size) - { - YASLI_ASSERT(curr_ + size <= end_); - memcpy(data, curr_, size); - curr_ += size; - } - - template - void read(T& x){ read(&x, sizeof(x)); } - - void read(string& s) - { - YASLI_ASSERT(curr_ + strlen(curr_) < end_); - s = curr_; - curr_ += strlen(curr_) + 1; - } - void read(wstring& s) - { - YASLI_ASSERT(curr_ + sizeof(wchar_t) * wcslen((wchar_t*)curr_) < end_); - s = (wchar_t*)curr_; - curr_ += (wcslen((wchar_t*)curr_) + 1) * sizeof(wchar_t); - } - - unsigned int readPackedSize(); - - bool validToClose() const { return complex_ || curr_ == end_; } - - private: - const char* begin_; - const char* end_; - const char* curr_; - bool complex_; - }; - - typedef std::vector Blocks; - Blocks blocks_; - const char* loadedData_; - - bool openNode(const char* name); - void closeNode(const char* name, bool check = true); - Block& currentBlock() { return blocks_.back(); } - template - void read(T& t) { currentBlock().read(t); } - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.cpp b/Code/CryEngine/CrySystem/Serialization/JSONIArchive.cpp deleted file mode 100644 index 8e323cc44c..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.cpp +++ /dev/null @@ -1,1525 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include -#include -#include "Serialization/ClassFactory.h" -#include "Serialization/STL.h" -#include "JSONIArchive.h" -#include "Serialization/BlackBox.h" -#include "MemoryReader.h" -#include "MemoryWriter.h" - -#if 0 -# define DEBUG_TRACE(fmt, ...) printf(fmt "\n", __VA_ARGS__) -# define DEBUG_TRACE_TOKENIZER(fmt, ...) printf(fmt "\n", __VA_ARGS__) -#else -# define DEBUG_TRACE(...) -# define DEBUG_TRACE_TOKENIZER(...) -#endif - -namespace Serialization { - static char hexValueTable[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, - - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - static void unescapeString(std::vector& buf, string& out, const char* begin, const char* end) - { - if (begin >= end) - { - out.clear(); - return; - } - // TODO: use stack string - buf.resize(end - begin); - char* ptr = &buf[0]; - while (begin != end) - { - if (*begin != '\\') - { - *ptr = *begin; - ++ptr; - } - else - { - ++begin; - if (begin == end) - { - break; - } - - switch (*begin) - { - case '0': - *ptr = '\0'; - ++ptr; - break; - case 't': - *ptr = '\t'; - ++ptr; - break; - case 'n': - *ptr = '\n'; - ++ptr; - break; - case 'r': - *ptr = '\r'; - ++ptr; - break; - case '\\': - *ptr = '\\'; - ++ptr; - break; - case '\"': - *ptr = '\"'; - ++ptr; - break; - case '\'': - *ptr = '\''; - ++ptr; - break; - case 'x': - if (begin + 2 < end) - { - *ptr = (hexValueTable[int(begin[1])] << 4) + hexValueTable[int(begin[2])]; - ++ptr; - begin += 2; - break; - } - default: - *ptr = *begin; - ++ptr; - break; - } - } - ++begin; - } - buf.resize(ptr - &buf[0]); - if (!buf.empty()) - { - out.assign(&buf[0], &buf[0] + buf.size()); - } - else - { - out.clear(); - } - } - - // --------------------------------------------------------------------------- - - class JSONTokenizer - { - public: - JSONTokenizer(); - - Token operator()(const char* text) const; - private: - inline bool isSpace(char c) const; - inline bool isWordPart(unsigned char c) const; - inline bool isComment(char c) const; - inline bool isQuoteOpen(int& quoteIndex, char c) const; - inline bool isQuoteClose(int quoteIndex, char c) const; - inline bool isQuote(char c) const; - }; - - JSONTokenizer::JSONTokenizer() - { - } - - inline bool JSONTokenizer::isSpace(char c) const - { - return c == ' ' || c == '\t' || c == '\n' || c == '\r'; - } - - inline bool JSONTokenizer::isComment(char c) const - { - return c == '#'; - } - - - inline bool JSONTokenizer::isQuote(char c) const - { - return c == '\"'; - } - - static const char charTypes[256] = { - 0 /* 0x00: */, - 0 /* 0x01: */, - 0 /* 0x02: */, - 0 /* 0x03: */, - 0 /* 0x04: */, - 0 /* 0x05: */, - 0 /* 0x06: */, - 0 /* 0x07: */, - 0 /* 0x08: */, - 0 /* 0x09: \t */, - 0 /* 0x0A: \n */, - 0 /* 0x0B: */, - 0 /* 0x0C: */, - 0 /* 0x0D: */, - 0 /* 0x0E: */, - 0 /* 0x0F: */, - - - 0 /* 0x10: */, - 0 /* 0x11: */, - 0 /* 0x12: */, - 0 /* 0x13: */, - 0 /* 0x14: */, - 0 /* 0x15: */, - 0 /* 0x16: */, - 0 /* 0x17: */, - 0 /* 0x18: */, - 0 /* 0x19: */, - 0 /* 0x1A: */, - 0 /* 0x1B: */, - 0 /* 0x1C: */, - 0 /* 0x1D: */, - 0 /* 0x1E: */, - 0 /* 0x1F: */, - - - 0 /* 0x20: */, - 0 /* 0x21: ! */, - 0 /* 0x22: " */, - 0 /* 0x23: # */, - 0 /* 0x24: $ */, - 0 /* 0x25: % */, - 0 /* 0x26: & */, - 0 /* 0x27: ' */, - 0 /* 0x28: ( */, - 0 /* 0x29: ) */, - 0 /* 0x2A: * */, - 0 /* 0x2B: + */, - 0 /* 0x2C: , */, - 1 /* 0x2D: - */, - 1 /* 0x2E: . */, - 0 /* 0x2F: / */, - - - 1 /* 0x30: 0 */, - 1 /* 0x31: 1 */, - 1 /* 0x32: 2 */, - 1 /* 0x33: 3 */, - 1 /* 0x34: 4 */, - 1 /* 0x35: 5 */, - 1 /* 0x36: 6 */, - 1 /* 0x37: 7 */, - 1 /* 0x38: 8 */, - 1 /* 0x39: 9 */, - 0 /* 0x3A: : */, - 0 /* 0x3B: ; */, - 0 /* 0x3C: < */, - 0 /* 0x3D: = */, - 0 /* 0x3E: > */, - 0 /* 0x3F: ? */, - - - 0 /* 0x40: @ */, - 1 /* 0x41: A */, - 1 /* 0x42: B */, - 1 /* 0x43: C */, - 1 /* 0x44: D */, - 1 /* 0x45: E */, - 1 /* 0x46: F */, - 1 /* 0x47: G */, - 1 /* 0x48: H */, - 1 /* 0x49: I */, - 1 /* 0x4A: J */, - 1 /* 0x4B: K */, - 1 /* 0x4C: L */, - 1 /* 0x4D: M */, - 1 /* 0x4E: N */, - 1 /* 0x4F: O */, - - - 1 /* 0x50: P */, - 1 /* 0x51: Q */, - 1 /* 0x52: R */, - 1 /* 0x53: S */, - 1 /* 0x54: T */, - 1 /* 0x55: U */, - 1 /* 0x56: V */, - 1 /* 0x57: W */, - 1 /* 0x58: X */, - 1 /* 0x59: Y */, - 1 /* 0x5A: Z */, - 0 /* 0x5B: [ */, - 0 /* 0x5C: \ */, - 0 /* 0x5D: ] */, - 0 /* 0x5E: ^ */, - 1 /* 0x5F: _ */, - - - 0 /* 0x60: ` */, - 1 /* 0x61: a */, - 1 /* 0x62: b */, - 1 /* 0x63: c */, - 1 /* 0x64: d */, - 1 /* 0x65: e */, - 1 /* 0x66: f */, - 1 /* 0x67: g */, - 1 /* 0x68: h */, - 1 /* 0x69: i */, - 1 /* 0x6A: j */, - 1 /* 0x6B: k */, - 1 /* 0x6C: l */, - 1 /* 0x6D: m */, - 1 /* 0x6E: n */, - 1 /* 0x6F: o */, - - - 1 /* 0x70: p */, - 1 /* 0x71: q */, - 1 /* 0x72: r */, - 1 /* 0x73: s */, - 1 /* 0x74: t */, - 1 /* 0x75: u */, - 1 /* 0x76: v */, - 1 /* 0x77: w */, - 1 /* 0x78: x */, - 1 /* 0x79: y */, - 1 /* 0x7A: z */, - 0 /* 0x7B: { */, - 0 /* 0x7C: | */, - 0 /* 0x7D: } */, - 0 /* 0x7E: ~ */, - 0 /* 0x7F: */, - - - 0 /* 0x80: */, - 0 /* 0x81: */, - 0 /* 0x82: */, - 0 /* 0x83: */, - 0 /* 0x84: */, - 0 /* 0x85: */, - 0 /* 0x86: */, - 0 /* 0x87: */, - 0 /* 0x88: */, - 0 /* 0x89: */, - 0 /* 0x8A: */, - 0 /* 0x8B: */, - 0 /* 0x8C: */, - 0 /* 0x8D: */, - 0 /* 0x8E: */, - 0 /* 0x8F: */, - - - 0 /* 0x90: */, - 0 /* 0x91: */, - 0 /* 0x92: */, - 0 /* 0x93: */, - 0 /* 0x94: */, - 0 /* 0x95: */, - 0 /* 0x96: */, - 0 /* 0x97: */, - 0 /* 0x98: */, - 0 /* 0x99: */, - 0 /* 0x9A: */, - 0 /* 0x9B: */, - 0 /* 0x9C: */, - 0 /* 0x9D: */, - 0 /* 0x9E: */, - 0 /* 0x9F: */, - - - 0 /* 0xA0: */, - 0 /* 0xA1: */, - 0 /* 0xA2: */, - 0 /* 0xA3: */, - 0 /* 0xA4: */, - 0 /* 0xA5: */, - 0 /* 0xA6: */, - 0 /* 0xA7: */, - 0 /* 0xA8: */, - 0 /* 0xA9: */, - 0 /* 0xAA: */, - 0 /* 0xAB: */, - 0 /* 0xAC: */, - 0 /* 0xAD: */, - 0 /* 0xAE: */, - 0 /* 0xAF: */, - - - 0 /* 0xB0: */, - 0 /* 0xB1: */, - 0 /* 0xB2: */, - 0 /* 0xB3: */, - 0 /* 0xB4: */, - 0 /* 0xB5: */, - 0 /* 0xB6: */, - 0 /* 0xB7: */, - 0 /* 0xB8: */, - 0 /* 0xB9: */, - 0 /* 0xBA: */, - 0 /* 0xBB: */, - 0 /* 0xBC: */, - 0 /* 0xBD: */, - 0 /* 0xBE: */, - 0 /* 0xBF: */, - - - 0 /* 0xC0: */, - 0 /* 0xC1: */, - 0 /* 0xC2: */, - 0 /* 0xC3: */, - 0 /* 0xC4: */, - 0 /* 0xC5: */, - 0 /* 0xC6: */, - 0 /* 0xC7: */, - 0 /* 0xC8: */, - 0 /* 0xC9: */, - 0 /* 0xCA: */, - 0 /* 0xCB: */, - 0 /* 0xCC: */, - 0 /* 0xCD: */, - 0 /* 0xCE: */, - 0 /* 0xCF: */, - - - 0 /* 0xD0: */, - 0 /* 0xD1: */, - 0 /* 0xD2: */, - 0 /* 0xD3: */, - 0 /* 0xD4: */, - 0 /* 0xD5: */, - 0 /* 0xD6: */, - 0 /* 0xD7: */, - 0 /* 0xD8: */, - 0 /* 0xD9: */, - 0 /* 0xDA: */, - 0 /* 0xDB: */, - 0 /* 0xDC: */, - 0 /* 0xDD: */, - 0 /* 0xDE: */, - 0 /* 0xDF: */, - - - 0 /* 0xE0: */, - 0 /* 0xE1: */, - 0 /* 0xE2: */, - 0 /* 0xE3: */, - 0 /* 0xE4: */, - 0 /* 0xE5: */, - 0 /* 0xE6: */, - 0 /* 0xE7: */, - 0 /* 0xE8: */, - 0 /* 0xE9: */, - 0 /* 0xEA: */, - 0 /* 0xEB: */, - 0 /* 0xEC: */, - 0 /* 0xED: */, - 0 /* 0xEE: */, - 0 /* 0xEF: */, - - - 0 /* 0xF0: */, - 0 /* 0xF1: */, - 0 /* 0xF2: */, - 0 /* 0xF3: */, - 0 /* 0xF4: */, - 0 /* 0xF5: */, - 0 /* 0xF6: */, - 0 /* 0xF7: */, - 0 /* 0xF8: */, - 0 /* 0xF9: */, - 0 /* 0xFA: */, - 0 /* 0xFB: */, - 0 /* 0xFC: */, - 0 /* 0xFD: */, - 0 /* 0xFE: */, - 0 /* 0xFF: */ - }; - - inline bool JSONTokenizer::isWordPart(unsigned char c) const - { - return charTypes[c] != 0; - } - - Token JSONTokenizer::operator()(const char* ptr) const - { - while (isSpace(*ptr)) - { - ++ptr; - } - Token cur(ptr, ptr); - while (!cur && *ptr != '\0') - { - while (isComment(*cur.end)) - { -#if 0 - const char* commentStart = ptr; -#endif - while (*cur.end && *cur.end != '\n') - { - ++cur.end; - } - while (isSpace(*cur.end)) - { - ++cur.end; - } - DEBUG_TRACE_TOKENIZER("Got comment: '%s'", string(commentStart, cur.end).c_str()); - cur.start = cur.end; - } - CRY_ASSERT(!isSpace(*cur.end)); - if (isQuote(*cur.end)) - { - ++cur.end; - while (*cur.end) - { - if (*cur.end == '\\') - { - ++cur.end; - if (*cur.end) - { - if (*cur.end != 'x' && *cur.end != 'X') - { - ++cur.end; - } - else - { - ++cur.end; - if (*cur.end) - { - ++cur.end; - } - } - } - } - if (isQuote(*cur.end)) - { - ++cur.end; - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - else - { - ++cur.end; - } - } - } - else - { - if (!*cur.end) - { - return cur; - } - - DEBUG_TRACE_TOKENIZER("%c", *cur.end); - if (isWordPart(*cur.end)) - { - do - { - ++cur.end; - } while (isWordPart(*cur.end) != 0); - } - else - { - ++cur.end; - return cur; - } - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - } - DEBUG_TRACE_TOKENIZER("Tokenizer result: '%s'", cur.str().c_str()); - return cur; - } - - - // --------------------------------------------------------------------------- - - JSONIArchive::JSONIArchive() - : IArchive(INPUT | TEXT) - , buffer_(0) - { - } - - JSONIArchive::~JSONIArchive() - { - if (buffer_) - { - free(buffer_); - buffer_ = 0; - } - stack_.clear(); - reader_.reset(); - } - - bool JSONIArchive::open(const char* buffer, size_t length, bool free) - { - if (!length) - { - return false; - } - - if (buffer) - { - reader_.reset(new MemoryReader(buffer, length, free)); - } - buffer_ = 0; - - token_ = Token(reader_->begin(), reader_->begin()); - stack_.clear(); - - stack_.push_back(Level()); - readToken(); - putToken(); - stack_.back().start = token_.end; - return true; - } - - - bool JSONIArchive::load(const char* filename) - { - FILE* file = nullptr; - azfopen(&file, filename, "rb"); - if (file) - { - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - fseek(file, 0, SEEK_SET); - - void* buffer = 0; - if (fileSize > 0) - { - buffer = CryModuleMalloc(fileSize + 1); - CRY_ASSERT(buffer != 0); - memset(buffer, 0, fileSize + 1); - size_t elementsRead = fread(buffer, fileSize, 1, file); - CRY_ASSERT(((char*)(buffer))[fileSize] == '\0'); - if (elementsRead != 1) - { - CryModuleFree(buffer); - return false; - } - } - fclose(file); - - filename_ = filename; - buffer_ = buffer; - if (fileSize > 0) - { - return open((char*)buffer, fileSize, false); - } - else - { - return false; - } - } - else - { - return false; - } - } - - void JSONIArchive::readToken() - { - JSONTokenizer tokenizer; - token_ = tokenizer(token_.end); - DEBUG_TRACE(" ~ read token '%s' at %i", token_.str().c_str(), token_.start - reader_->begin()); - } - - void JSONIArchive::putToken() - { - DEBUG_TRACE(" putToken: '%s'", token_.str().c_str()); - token_ = Token(token_.start, token_.start); - } - - int JSONIArchive::line(const char* position) const - { - return int(std::count(reader_->begin(), position, '\n') + 1); - } - - bool JSONIArchive::isName(Token token) const - { - if (!token) - { - return false; - } - char firstChar = token.start[0]; - if (firstChar == '"') - { - return true; - } - return false; - } - - - bool JSONIArchive::expect(char token) - { - if (token_ != token) - { - const char* lineEnd = token_.start; - while (lineEnd && *lineEnd != '\0' && *lineEnd != '\r' && *lineEnd != '\n') - { - ++lineEnd; - } - - MemoryWriter msg; - msg << "Error parsing file, expected ':' at line " << line(token_.start) << ":\n" - << string(token_.start, lineEnd).c_str(); - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - return true; - } - - void JSONIArchive::skipBlock() - { - DEBUG_TRACE("Skipping block from %i ...", token_.end - reader_->begin()); - if (openBracket() || openContainerBracket()) - { - closeBracket(); // Skipping entire block - } - else - { - readToken(); // Skipping value - } - readToken(); - if (token_ != ',') - { - putToken(); - } - DEBUG_TRACE(" ...till %i", token_.end - reader_->begin()); - } - - bool JSONIArchive::findName(const char* name, Token* outName) - { - DEBUG_TRACE(" * finding name '%s'", name); - DEBUG_TRACE(" started at byte %i", int(token_.start - reader_->begin())); - if (stack_.empty()) - { - // TODO: diagnose - return false; - } - if (stack_.back().isKeyValue) - { - return true; - } - const char* start = 0; - const char* blockBegin = stack_.back().start; - if (*blockBegin == '\0') - { - return false; - } - - readToken(); - if (token_ == ',') - { - readToken(); - } - if (!token_) - { - start = blockBegin; - token_.set(blockBegin, blockBegin); - readToken(); - } - - if (stack_.size() == 1 || stack_.back().isContainer || outName != 0) - { - if (token_ == ']' || token_ == '}') - { - DEBUG_TRACE("Got close bracket..."); - putToken(); - return false; - } - else - { - DEBUG_TRACE("Got unnamed value: '%s'", token_.str().c_str()); - putToken(); - return true; - } - } - else - { - if (isName(token_)) - { - DEBUG_TRACE("Seems to be a name '%s'", token_.str().c_str()); - Token nameContent(token_.start + 1, token_.end - 1); - if (nameContent == name) - { - readToken(); - expect(':'); - DEBUG_TRACE("Got one"); - return true; - } - else - { - start = token_.start; - - readToken(); - expect(':'); - skipBlock(); - } - } - else - { - start = token_.start; - if (token_ == ']' || token_ == '}') - { - token_ = Token(blockBegin, blockBegin); - } - else - { - putToken(); - skipBlock(); - } - } - } - - while (true) - { - readToken(); - if (!token_) - { - token_.set(blockBegin, blockBegin); - continue; - } - //return false; // Reached end of file while searching for name - DEBUG_TRACE("'%s'", token_.str().c_str()); - DEBUG_TRACE("Checking for loop: %i and %i", token_.start - reader_->begin(), start - reader_->begin()); - CRY_ASSERT(start != 0); - if (token_.start == start) - { - putToken(); - DEBUG_TRACE("unable to find..."); - return false; // Reached a full circle: unable to find name - } - - if (token_ == '}' || token_ == ']') // CONVERSION - { - DEBUG_TRACE("Going to begin of block, from %i", token_.start - reader_->begin()); - token_ = Token(blockBegin, blockBegin); - DEBUG_TRACE(" to %i", token_.start - reader_->begin()); - continue; // Reached '}' or ']' while searching for name, continue from begin of block - } - - if (name[0] == '\0') - { - if (isName(token_)) - { - readToken(); - if (!token_) - { - return false; // Reached end of file while searching for name - } - expect(':'); - skipBlock(); - } - else - { - putToken(); // Not a name - put it back - return true; - } - } - else - { - if (isName(token_)) - { - Token nameContent(token_.start + 1, token_.end - 1); - readToken(); - expect(':'); - if (nameContent == name) - { - return true; - } - else - { - skipBlock(); - } - } - else - { - putToken(); - skipBlock(); - } - } - } - - return false; - } - - bool JSONIArchive::openBracket() - { - readToken(); - if (token_ == '{') - { - return true; - } - putToken(); - return false; - } - - bool JSONIArchive::closeBracket() - { - int relativeLevel = 0; - while (true) - { - readToken(); - if (token_ == ',') - { - readToken(); - } - if (!token_) - { - MemoryWriter msg; - CRY_ASSERT(!stack_.empty()); - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while no matching bracket found"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - else if (token_ == '}' || token_ == ']') // CONVERSION - { - if (relativeLevel == 0) - { - return true; - } - else - { - --relativeLevel; - } - } - else if (token_ == '{' || token_ == '[') // CONVERSION - { - ++relativeLevel; - } - } - return false; - } - - bool JSONIArchive::openContainerBracket() - { - readToken(); - if (token_ == '[') - { - return true; - } - putToken(); - return false; - } - - bool JSONIArchive::closeContainerBracket() - { - readToken(); - if (token_ == ']') - { - DEBUG_TRACE("closeContainerBracket(): ok"); - return true; - } - else - { - DEBUG_TRACE("closeContainerBracket(): failed ('%s')", token_.str().c_str()); - putToken(); - return false; - } - } - - bool JSONIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - } - else if (openContainerBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - stack_.back().isContainer = true; - } - else - { - return false; - } - - ser(*this); - CRY_ASSERT(!stack_.empty()); - stack_.pop_back(); -#if !defined(NDEBUG) - bool closed = -#endif - closeBracket(); - CRY_ASSERT(closed); - return true; - } - return false; - } - - bool JSONIArchive::operator()(const SBlackBox& box, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket() || openContainerBracket()) - { - const char* start = token_.start; - putToken(); - skipBlock(); - const char* end = token_.start; - if (end < start) - { - CRY_ASSERT(0); - return false; - } - while (end > start && - (*(end - 1) == ' ' - || *(end - 1) == '\r' - || *(end - 1) == '\n' - || *(end - 1) == '\t')) - { - --end; - } - // box has to be const in the interface so we can serialize - // temporary variables (i.e. function call result or structures - // constructed on the stack) - const_cast(box).set("json", (void*)start, end - start); - return true; - } - } - return false; - } - - bool JSONIArchive::operator()(IKeyValue& keyValue, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) - { - Token nextName; - if (!stack_.empty() && stack_.back().isContainer) - { - readToken(); - if (isName(token_) && checkStringValueToken()) - { - string key; - unescapeString(unescapeBuffer_, key, token_.start + 1, token_.end - 1); - keyValue.set(key.c_str()); - readToken(); - if (!expect(':')) - { - return false; - } - if (!keyValue.serializeValue(*this, "", 0)) - { - return false; - } - return true; - } - else - { - putToken(); - return false; - } - } - else if (findName("", &nextName)) - { - string key; - unescapeString(unescapeBuffer_, key, nextName.start + 1, nextName.end - 1); - keyValue.set(key.c_str()); - stack_.push_back(Level()); - stack_.back().isKeyValue = true; - - bool result = keyValue.serializeValue(*this, "", 0); - if (stack_.empty()) - { - // TODO: diagnose - return false; - } - stack_.pop_back(); - return result; - } - return false; - } - - - bool JSONIArchive::operator()(IPointer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - if (openBracket()) - { - stack_.push_back(Level()); - stack_.back().start = token_.end; - stack_.back().isKeyValue = true; - - readToken(); - if (isName(token_)) - { - if (checkStringValueToken()) - { - string typeName; - unescapeString(unescapeBuffer_, typeName, token_.start + 1, token_.end - 1); - - if (typeName != ser.registeredTypeName()) - { - ser.create(typeName.c_str()); - } - readToken(); - expect(':'); - operator()(ser.serializer(), "", 0); - } - } - else - { - putToken(); - - ser.create(""); - } - closeBracket(); - stack_.pop_back(); - return true; - } - } - return false; - } - - - bool JSONIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - bool containerBracket = openContainerBracket(); - bool dictionaryBracket = false; - if (!containerBracket) - { - dictionaryBracket = openBracket(); - } - if (containerBracket || dictionaryBracket) - { - stack_.push_back(Level()); - stack_.back().isContainer = true; - stack_.back().start = token_.end; - - std::size_t size = ser.size(); - std::size_t index = 0; - - while (true) - { - readToken(); - if (token_ == ',') - { - readToken(); - } - if (token_ == '}' || token_ == ']') - { - break; - } - else if (!token_) - { - CRY_ASSERT(0 && "Reached end of file while reading container!"); - return false; - } - putToken(); - if (index == size) - { - size = index + 1; - } - if (index < size) - { - if (!ser(*this, "", "")) - { - // We've got a named item within a container, - // i.e. looks like a dictionary but not a container. - // Bail out, it is nothing we can do here. - closeBracket(); - break; - } - } - else - { - skipBlock(); - } - ser.next(); - ++index; - } - if (size > index) - { - ser.resize(index); - } - - CRY_ASSERT(!stack_.empty()); - stack_.pop_back(); - return true; - } - } - return false; - } - - void JSONIArchive::checkValueToken() - { - if (!token_) - { - CRY_ASSERT(!stack_.empty()); - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while reading element's value"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - } - } - - bool JSONIArchive::checkStringValueToken() - { - if (!token_) - { - return false; - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": End of file while reading element's value"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - if (token_.start[0] != '"' || token_.end[-1] != '"') - { - return false; - MemoryWriter msg; - const char* start = stack_.back().start; - msg << filename_.c_str() << ": " << line(start) << " line"; - msg << ": Expected string"; - CRY_ASSERT_MESSAGE(0, msg.c_str()); - return false; - } - return true; - } - - bool JSONIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = strtoul(token_.start, 0, 10); - return true; - } - return false; - } - - - bool JSONIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (int16)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (uint16)strtoul(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = _strtoi64(token_.start, 0, 10); -#else - value = strtoll(token_.start, 0, 10); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = _strtoui64(token_.start, 0, 10); -#else - value = strtoull(token_.start, 0, 10); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = float(std::atof(token_.str().c_str())); -#else - value = strtof(token_.start, 0); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); -#ifdef _MSC_VER - value = std::atof(token_.str().c_str()); -#else - value = strtod(token_.start, 0); -#endif - return true; - } - return false; - } - - bool JSONIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - if (checkStringValueToken()) - { - string buf; - unescapeString(unescapeBuffer_, buf, token_.start + 1, token_.end - 1); - value.set(buf.c_str()); - } - else - { - return false; - } - return true; - } - return false; - } - - - inline size_t utf8InUtf16Len(const char* p) - { - size_t result = 0; - - for (; *p; ++p) - { - unsigned char ch = (unsigned char)(*p); - - if (ch < 0x80 || (ch >= 0xC0 && ch < 0xFC)) - { - ++result; - } - } - - return result; - } - - inline const char* readUtf16FromUtf8(unsigned int* ch, const char* s) - { - const unsigned char byteMark = 0x80; - const unsigned char byteMaskRead = 0x3F; - - const unsigned char* str = (const unsigned char*)s; - - size_t len; - if (*str < byteMark) - { - *ch = *str; - return s + 1; - } - else if (*str < 0xC0) - { - *ch = ' '; - return s + 1; - } - else if (*str < 0xE0) - { - len = 2; - } - else if (*str < 0xF0) - { - len = 3; - } - else if (*str < 0xF8) - { - len = 4; - } - else if (*str < 0xFC) - { - len = 5; - } - else - { - *ch = ' '; - return s + 1; - } - - const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - *ch = (*str++ & ~firstByteMark[len]); - - switch (len) - { - case 5: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 4: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 3: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - case 2: - (*ch) <<= 6; - (*ch) += (*str++ & byteMaskRead); - } - - return (const char*)str; - } - - - inline void utf8ToUtf16(wstring* out, const char* in) - { - out->clear(); - out->reserve(utf8InUtf16Len(in)); - - for (; *in; ) - { - unsigned int character; - in = readUtf16FromUtf8(&character, in); - (*out) += (wchar_t)character; - } - } - - - bool JSONIArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - if (checkStringValueToken()) - { - string buf; - unescapeString(unescapeBuffer_, buf, token_.start + 1, token_.end - 1); - wstring wbuf; - utf8ToUtf16(&wbuf, buf.c_str()); - value.set(wbuf.c_str()); - } - else - { - return false; - } - return true; - } - return false; - } - - bool JSONIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - if (token_ == "true") - { - value = true; - } - else if (token_ == "false") - { - value = false; - } - else - { - CRY_ASSERT(0 && "Invalid boolean value"); - } - return true; - } - return false; - } - - bool JSONIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (int8)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (uint8)strtol(token_.start, 0, 10); - return true; - } - return false; - } - - bool JSONIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - if (findName(name)) - { - readToken(); - checkValueToken(); - value = (char)strtol(token_.start, 0, 10); - return true; - } - return false; - } -} -// vim:ts=4 sw=4: diff --git a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.h b/Code/CryEngine/CrySystem/Serialization/JSONIArchive.h deleted file mode 100644 index b38476a597..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONIArchive.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "Serialization/IArchive.h" -#include "MemoryReader.h" -#include "Token.h" -#include - -namespace Serialization { - class MemoryReader; - - class JSONIArchive - : public IArchive - { - public: - JSONIArchive(); - ~JSONIArchive(); - - bool load(const char* filename); - bool open(const char* buffer, size_t length, bool free = false); - - // virtuals: - bool operator()(bool& value, const char* name = "", const char* label = 0); - bool operator()(IString& value, const char* name = "", const char* label = 0); - bool operator()(IWString& value, const char* name = "", const char* label = 0); - bool operator()(float& value, const char* name = "", const char* label = 0); - bool operator()(double& value, const char* name = "", const char* label = 0); - bool operator()(int16& value, const char* name = "", const char* label = 0); - bool operator()(uint16& value, const char* name = "", const char* label = 0); - bool operator()(int32& value, const char* name = "", const char* label = 0); - bool operator()(uint32& value, const char* name = "", const char* label = 0); - bool operator()(int64& value, const char* name = "", const char* label = 0); - bool operator()(uint64& value, const char* name = "", const char* label = 0); - - bool operator()(int8& value, const char* name = "", const char* label = 0); - bool operator()(uint8& value, const char* name = "", const char* label = 0); - bool operator()(char& value, const char* name = "", const char* label = 0); - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0); - bool operator()(const SBlackBox& ser, const char* name = "", const char* label = 0); - bool operator()(IContainer& ser, const char* name = "", const char* label = 0); - bool operator()(IKeyValue& ser, const char* name = "", const char* label = 0); - bool operator()(IPointer& ser, const char* name = "", const char* label = 0); - - using IArchive::operator(); - private: - bool findName(const char* name, Token* outName = 0); - bool openBracket(); - bool closeBracket(); - - bool openContainerBracket(); - bool closeContainerBracket(); - - void checkValueToken(); - bool checkStringValueToken(); - void readToken(); - void putToken(); - int line(const char* position) const; - bool isName(Token token) const; - - bool expect(char token); - void skipBlock(); - - struct Level - { - const char* start; - const char* firstToken; - bool isContainer; - bool isKeyValue; - Level() - : isContainer(false) - , isKeyValue(false) {} - }; - typedef std::vector Stack; - Stack stack_; - - std::unique_ptr reader_; - Token token_; - std::vector unescapeBuffer_; - string filename_; - void* buffer_; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.cpp b/Code/CryEngine/CrySystem/Serialization/JSONOArchive.cpp deleted file mode 100644 index d1aef5601e..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.cpp +++ /dev/null @@ -1,828 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "JSONOArchive.h" -#include "MemoryWriter.h" -#include "Serialization/KeyValue.h" -#include "Serialization/ClassFactory.h" -#include "Serialization/BlackBox.h" -#include - -namespace Serialization { - // Some of non-latin1 characters here are not escaped to - // keep compatibility with 8-bit local encoding (e.g. windows-1251) - static const char* escapeTable[256] = { - "\\0" /* 0x00: */, - "\\x01" /* 0x01: */, - "\\x02" /* 0x02: */, - "\\x03" /* 0x03: */, - "\\x04" /* 0x04: */, - "\\x05" /* 0x05: */, - "\\x06" /* 0x06: */, - "\\x07" /* 0x07: */, - "\\x08" /* 0x08: */, - "\\t" /* 0x09: \t */, - "\\n" /* 0x0A: \n */, - "\\x0B" /* 0x0B: */, - "\\x0C" /* 0x0C: */, - "\\r" /* 0x0D: */, - "\\x0E" /* 0x0E: */, - "\\x0F" /* 0x0F: */, - - - "\\x10" /* 0x10: */, - "\\x11" /* 0x11: */, - "\\x12" /* 0x12: */, - "\\x13" /* 0x13: */, - "\\x14" /* 0x14: */, - "\\x15" /* 0x15: */, - "\\x16" /* 0x16: */, - "\\x17" /* 0x17: */, - "\\x18" /* 0x18: */, - "\\x19" /* 0x19: */, - "\\x1A" /* 0x1A: */, - "\\x1B" /* 0x1B: */, - "\\x1C" /* 0x1C: */, - "\\x1D" /* 0x1D: */, - "\\x1E" /* 0x1E: */, - "\\x1F" /* 0x1F: */, - - - " " /* 0x20: */, - "!" /* 0x21: ! */, - "\\\"" /* 0x22: " */, - "#" /* 0x23: # */, - "$" /* 0x24: $ */, - "%" /* 0x25: % */, - "&" /* 0x26: & */, - "'" /* 0x27: ' */, - "(" /* 0x28: ( */, - ")" /* 0x29: ) */, - "*" /* 0x2A: * */, - "+" /* 0x2B: + */, - "," /* 0x2C: , */, - "-" /* 0x2D: - */, - "." /* 0x2E: . */, - "/" /* 0x2F: / */, - - - "0" /* 0x30: 0 */, - "1" /* 0x31: 1 */, - "2" /* 0x32: 2 */, - "3" /* 0x33: 3 */, - "4" /* 0x34: 4 */, - "5" /* 0x35: 5 */, - "6" /* 0x36: 6 */, - "7" /* 0x37: 7 */, - "8" /* 0x38: 8 */, - "9" /* 0x39: 9 */, - ":" /* 0x3A: : */, - ";" /* 0x3B: ; */, - "<" /* 0x3C: < */, - "=" /* 0x3D: = */, - ">" /* 0x3E: > */, - "?" /* 0x3F: ? */, - - - "@" /* 0x40: @ */, - "A" /* 0x41: A */, - "B" /* 0x42: B */, - "C" /* 0x43: C */, - "D" /* 0x44: D */, - "E" /* 0x45: E */, - "F" /* 0x46: F */, - "G" /* 0x47: G */, - "H" /* 0x48: H */, - "I" /* 0x49: I */, - "J" /* 0x4A: J */, - "K" /* 0x4B: K */, - "L" /* 0x4C: L */, - "M" /* 0x4D: M */, - "N" /* 0x4E: N */, - "O" /* 0x4F: O */, - - - "P" /* 0x50: P */, - "Q" /* 0x51: Q */, - "R" /* 0x52: R */, - "S" /* 0x53: S */, - "T" /* 0x54: T */, - "U" /* 0x55: U */, - "V" /* 0x56: V */, - "W" /* 0x57: W */, - "X" /* 0x58: X */, - "Y" /* 0x59: Y */, - "Z" /* 0x5A: Z */, - "[" /* 0x5B: [ */, - "\\\\" /* 0x5C: \ */, - "]" /* 0x5D: ] */, - "^" /* 0x5E: ^ */, - "_" /* 0x5F: _ */, - - - "`" /* 0x60: ` */, - "a" /* 0x61: a */, - "b" /* 0x62: b */, - "c" /* 0x63: c */, - "d" /* 0x64: d */, - "e" /* 0x65: e */, - "f" /* 0x66: f */, - "g" /* 0x67: g */, - "h" /* 0x68: h */, - "i" /* 0x69: i */, - "j" /* 0x6A: j */, - "k" /* 0x6B: k */, - "l" /* 0x6C: l */, - "m" /* 0x6D: m */, - "n" /* 0x6E: n */, - "o" /* 0x6F: o */, - - - "p" /* 0x70: p */, - "q" /* 0x71: q */, - "r" /* 0x72: r */, - "s" /* 0x73: s */, - "t" /* 0x74: t */, - "u" /* 0x75: u */, - "v" /* 0x76: v */, - "w" /* 0x77: w */, - "x" /* 0x78: x */, - "y" /* 0x79: y */, - "z" /* 0x7A: z */, - "{" /* 0x7B: { */, - "|" /* 0x7C: | */, - "}" /* 0x7D: } */, - "~" /* 0x7E: ~ */, - "\x7F" /* 0x7F: */, // for utf-8 - - - "\x80" /* 0x80: */, - "\x81" /* 0x81: */, - "\x82" /* 0x82: */, - "\x83" /* 0x83: */, - "\x84" /* 0x84: */, - "\x85" /* 0x85: */, - "\x86" /* 0x86: */, - "\x87" /* 0x87: */, - "\x88" /* 0x88: */, - "\x89" /* 0x89: */, - "\x8A" /* 0x8A: */, - "\x8B" /* 0x8B: */, - "\x8C" /* 0x8C: */, - "\x8D" /* 0x8D: */, - "\x8E" /* 0x8E: */, - "\x8F" /* 0x8F: */, - - - "\x90" /* 0x90: */, - "\x91" /* 0x91: */, - "\x92" /* 0x92: */, - "\x93" /* 0x93: */, - "\x94" /* 0x94: */, - "\x95" /* 0x95: */, - "\x96" /* 0x96: */, - "\x97" /* 0x97: */, - "\x98" /* 0x98: */, - "\x99" /* 0x99: */, - "\x9A" /* 0x9A: */, - "\x9B" /* 0x9B: */, - "\x9C" /* 0x9C: */, - "\x9D" /* 0x9D: */, - "\x9E" /* 0x9E: */, - "\x9F" /* 0x9F: */, - - - "\xA0" /* 0xA0: */, - "\xA1" /* 0xA1: */, - "\xA2" /* 0xA2: */, - "\xA3" /* 0xA3: */, - "\xA4" /* 0xA4: */, - "\xA5" /* 0xA5: */, - "\xA6" /* 0xA6: */, - "\xA7" /* 0xA7: */, - "\xA8" /* 0xA8: */, - "\xA9" /* 0xA9: */, - "\xAA" /* 0xAA: */, - "\xAB" /* 0xAB: */, - "\xAC" /* 0xAC: */, - "\xAD" /* 0xAD: */, - "\xAE" /* 0xAE: */, - "\xAF" /* 0xAF: */, - - - "\xB0" /* 0xB0: */, - "\xB1" /* 0xB1: */, - "\xB2" /* 0xB2: */, - "\xB3" /* 0xB3: */, - "\xB4" /* 0xB4: */, - "\xB5" /* 0xB5: */, - "\xB6" /* 0xB6: */, - "\xB7" /* 0xB7: */, - "\xB8" /* 0xB8: */, - "\xB9" /* 0xB9: */, - "\xBA" /* 0xBA: */, - "\xBB" /* 0xBB: */, - "\xBC" /* 0xBC: */, - "\xBD" /* 0xBD: */, - "\xBE" /* 0xBE: */, - "\xBF" /* 0xBF: */, - - - "\xC0" /* 0xC0: */, - "\xC1" /* 0xC1: */, - "\xC2" /* 0xC2: */, - "\xC3" /* 0xC3: */, - "\xC4" /* 0xC4: */, - "\xC5" /* 0xC5: */, - "\xC6" /* 0xC6: */, - "\xC7" /* 0xC7: */, - "\xC8" /* 0xC8: */, - "\xC9" /* 0xC9: */, - "\xCA" /* 0xCA: */, - "\xCB" /* 0xCB: */, - "\xCC" /* 0xCC: */, - "\xCD" /* 0xCD: */, - "\xCE" /* 0xCE: */, - "\xCF" /* 0xCF: */, - - - "\xD0" /* 0xD0: */, - "\xD1" /* 0xD1: */, - "\xD2" /* 0xD2: */, - "\xD3" /* 0xD3: */, - "\xD4" /* 0xD4: */, - "\xD5" /* 0xD5: */, - "\xD6" /* 0xD6: */, - "\xD7" /* 0xD7: */, - "\xD8" /* 0xD8: */, - "\xD9" /* 0xD9: */, - "\xDA" /* 0xDA: */, - "\xDB" /* 0xDB: */, - "\xDC" /* 0xDC: */, - "\xDD" /* 0xDD: */, - "\xDE" /* 0xDE: */, - "\xDF" /* 0xDF: */, - - - "\xE0" /* 0xE0: */, - "\xE1" /* 0xE1: */, - "\xE2" /* 0xE2: */, - "\xE3" /* 0xE3: */, - "\xE4" /* 0xE4: */, - "\xE5" /* 0xE5: */, - "\xE6" /* 0xE6: */, - "\xE7" /* 0xE7: */, - "\xE8" /* 0xE8: */, - "\xE9" /* 0xE9: */, - "\xEA" /* 0xEA: */, - "\xEB" /* 0xEB: */, - "\xEC" /* 0xEC: */, - "\xED" /* 0xED: */, - "\xEE" /* 0xEE: */, - "\xEF" /* 0xEF: */, - - - "\xF0" /* 0xF0: */, - "\xF1" /* 0xF1: */, - "\xF2" /* 0xF2: */, - "\xF3" /* 0xF3: */, - "\xF4" /* 0xF4: */, - "\xF5" /* 0xF5: */, - "\xF6" /* 0xF6: */, - "\xF7" /* 0xF7: */, - "\xF8" /* 0xF8: */, - "\xF9" /* 0xF9: */, - "\xFA" /* 0xFA: */, - "\xFB" /* 0xFB: */, - "\xFC" /* 0xFC: */, - "\xFD" /* 0xFD: */, - "\xFE" /* 0xFE: */, - "\xFF" /* 0xFF: */ - }; - - static void escapeString(MemoryWriter& dest, const char* begin, const char* end) - { - while (begin != end) - { - const char* str = escapeTable[(unsigned char)(*begin)]; - dest.write(str); - ++begin; - } - } - - // --------------------------------------------------------------------------- - - static const int TAB_WIDTH = 2; - - JSONOArchive::JSONOArchive(int textWidth, const char* header) - : IArchive(OUTPUT | TEXT) - , header_(header) - , textWidth_(textWidth) - , compactOffset_(0) - { - buffer_.reset(new MemoryWriter(1024, true)); - if (header_) - { - (*buffer_) << header_; - } - - YASLI_ASSERT(stack_.empty()); - stack_.push_back(Level(false, 0, 0)); - } - - JSONOArchive::~JSONOArchive() - { - } - - bool JSONOArchive::save(const char* fileName) - { - YASLI_ESCAPE(fileName && strlen(fileName) > 0, return false); - YASLI_ESCAPE(stack_.size() == 1, return false); - YASLI_ESCAPE(buffer_.get() != 0, return false); - YASLI_ESCAPE(buffer_->position() <= buffer_->size(), return false); - stack_.pop_back(); - FILE* file = nullptr; - azfopen(&file, fileName, "wb"); - if (file) - { - if (fwrite(buffer_->c_str(), 1, buffer_->position(), file) != buffer_->position()) - { - fclose(file); - return false; - } - fclose(file); - return true; - } - else - { - return false; - } - } - - const char* JSONOArchive::c_str() const - { - return buffer_->c_str(); - } - - size_t JSONOArchive::length() const - { - return buffer_->position(); - } - - void JSONOArchive::openBracket() - { - *buffer_ << "{"; - } - - void JSONOArchive::closeBracket() - { - *buffer_ << "}"; - } - - void JSONOArchive::openContainerBracket() - { - *buffer_ << "["; - } - - void JSONOArchive::closeContainerBracket() - { - *buffer_ << "]"; - } - - void JSONOArchive::placeName(const char* name) - { - if (stack_.back().isKeyValue) - { - return; - } - if ((name[0] != '\0' || !stack_.back().isContainer) && stack_.size() > 1) - { - *buffer_ << "\""; - *buffer_ << name; - *buffer_ << "\": "; - stack_.back().nameIndex += 1; - } - } - - void JSONOArchive::placeIndent(bool putComma) - { - if (stack_.back().isKeyValue) - { - return; - } - if (putComma && stack_.back().elementIndex > 0) - { - *buffer_ << ","; - } - if (buffer_->position() > 0) - { - *buffer_ << "\n"; - } - int count = int(stack_.size() - 1); - stack_.back().indentCount += count; - stack_.back().elementIndex += 1; - for (int i = 0; i < count; ++i) - { - *buffer_ << "\t"; - } - compactOffset_ = 0; - } - - void JSONOArchive::placeIndentCompact(bool putComma) - { - if (stack_.back().isKeyValue) - { - return; - } - if (putComma && stack_.back().elementIndex > 0) - { - *buffer_ << ","; - } - if ((compactOffset_ % 32) != 0 && stack_.back().isContainer) - { - *buffer_ << " "; - compactOffset_ += 1; - stack_.back().elementIndex += 1; - } - else if (buffer_->size()) - { - *buffer_ << "\n"; - int count = int(stack_.size() - 1); - stack_.back().indentCount += count /* * TAB_WIDTH*/; - stack_.back().elementIndex += 1; - for (int i = 0; i < count; ++i) - { - *buffer_ << "\t"; - } - compactOffset_ = 1; - } - } - - bool JSONOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - *buffer_ << (value ? "true" : "false"); - return true; - } - - - bool JSONOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - (*buffer_) << "\""; - const char* str = value.get(); - escapeString(*buffer_, str, str + strlen(value.get())); - (*buffer_) << "\""; - return true; - } - - inline char* writeUtf16ToUtf8(char* s, unsigned int ch) - { - const unsigned char byteMark = 0x80; - const unsigned char byteMask = 0xBF; - - size_t len; - - if (ch < 0x80) - { - len = 1; - } - else if (ch < 0x800) - { - len = 2; - } - else if (ch < 0x10000) - { - len = 3; - } - else if (ch < 0x200000) - { - len = 4; - } - else - { - return s; - } - - s += len; - - const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - switch (len) - { - case 4: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 3: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 2: - *--s = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 1: - *--s = (char)(ch | firstByteMark[len]); - } - - return s + len; - } - - bool JSONOArchive::operator()(IWString& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - (*buffer_) << "\""; - - const wchar_t* in = value.get(); - for (; *in; ++in) - { - char buf[6]; - escapeString(*buffer_, buf, writeUtf16ToUtf8(buf, *in)); - } - - (*buffer_) << "\""; - return true; - } - - bool JSONOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) - { - placeIndentCompact(); - placeName(name); - (*buffer_) << value; - return true; - } - - bool JSONOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - std::size_t position = buffer_->position(); - openBracket(); - stack_.push_back(Level(false, position, int(strlen(name) + 2 * (name[0] & 1) + (stack_.size() - 1) * TAB_WIDTH + 2))); - - YASLI_ASSERT(ser); - ser(*this); - - bool joined = joinLinesIfPossible(); - bool noNames = stack_.back().nameIndex == 0; - if (noNames) - { - if (stack_.size() != 2) - { - buffer_->buffer()[stack_.back().startPosition] = '['; - } - } - stack_.pop_back(); - if (!joined) - { - placeIndent(false); - } - else - { - *buffer_ << " "; - } - if (noNames) - { - closeContainerBracket(); - } - else - { - closeBracket(); - } - return true; - } - - bool JSONOArchive::operator()(const SBlackBox& box, const char* name, [[maybe_unused]] const char* label) - { - if (strcmp(box.format, "json") != 0) - { - return false; - } - if (box.size == 0) - { - return false; - } - - placeIndent(); - placeName(name); - return buffer_->write(box.data, box.size); - } - - bool JSONOArchive::operator()(IKeyValue& keyValue, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - - *buffer_ << "\""; - *buffer_ << keyValue.get(); - *buffer_ << "\": "; - stack_.back().nameIndex += 1; - - stack_.back().isKeyValue = true; - keyValue.serializeValue(*this, "", 0); - stack_.back().isKeyValue = false; - if (stack_.back().isContainer) - { - stack_.back().isDictionary = true; - } - return true; - } - - bool JSONOArchive::operator()(IPointer& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - openBracket(); - const char* registeredTypeName = ser.registeredTypeName(); - if (registeredTypeName && registeredTypeName[0] != '\0') - { - *buffer_ << " "; - placeName(registeredTypeName); - stack_.back().isKeyValue = true; - operator()(ser.serializer(), ""); - stack_.back().isKeyValue = false; - *buffer_ << " "; - } - closeBracket(); - return true; - } - - bool JSONOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) - { - placeIndent(); - placeName(name); - std::size_t position = buffer_->position(); - openContainerBracket(); - stack_.push_back(Level(true, position, int(strlen(name) + 2 * (name[0] & 1) + stack_.size() - 1 * TAB_WIDTH + 2))); - - std::size_t size = ser.size(); - if (size > 0) - { - do - { - ser(*this, "", ""); - } while (ser.next()); - } - - bool joined = joinLinesIfPossible(); - bool isDictionary = stack_.back().isDictionary; - if (isDictionary) - { - buffer_->buffer()[stack_.back().startPosition] = '{'; - } - stack_.pop_back(); - if (!joined) - { - placeIndent(false); - } - else - { - *buffer_ << " "; - } - - if (isDictionary) - { - closeBracket(); - } - else - { - closeContainerBracket(); - } - return true; - } - - static char* joinLines(char* start, char* end) - { - YASLI_ASSERT(start <= end); - char* next = start; - while (next != end) - { - if (*next != '\t' && *next != '\r') - { - if (*next != '\n') - { - *start = *next; - } - else - { - *start = ' '; - } - ++start; - } - ++next; - } - return start; - } - - bool JSONOArchive::joinLinesIfPossible() - { - YASLI_ASSERT(!stack_.empty()); - std::size_t startPosition = stack_.back().startPosition; - YASLI_ASSERT(startPosition < buffer_->size()); - int indentCount = stack_.back().indentCount; - //YASLI_ASSERT(startPosition >= indentCount); - if (buffer_->position() - startPosition - indentCount < std::size_t(textWidth_)) - { - char* buffer = buffer_->buffer(); - char* start = buffer + startPosition; - char* end = buffer + buffer_->position(); - end = joinLines(start, end); - std::size_t newPosition = end - buffer; - YASLI_ASSERT(newPosition <= buffer_->position()); - buffer_->setPosition(newPosition); - return true; - } - return false; - } -} -// vim:ts=4 sw=4: diff --git a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.h b/Code/CryEngine/CrySystem/Serialization/JSONOArchive.h deleted file mode 100644 index 5701c992ac..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/JSONOArchive.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "Serialization/IArchive.h" -#include "Serialization/MemoryWriter.h" - -namespace Serialization { - class MemoryWriter; - - class JSONOArchive - : public IArchive - { - public: - // header = 0 - default header, use "" to omit - JSONOArchive(int textWidth = 80, const char* header = 0); - ~JSONOArchive(); - - bool save(const char* fileName); - - const char* c_str() const; - const char* buffer() const { return c_str(); } - size_t length() const; - - // from Archive: - bool operator()(bool& value, const char* name = "", const char* label = 0); - bool operator()(IString& value, const char* name = "", const char* label = 0); - bool operator()(IWString& value, const char* name = "", const char* label = 0); - bool operator()(float& value, const char* name = "", const char* label = 0); - bool operator()(double& value, const char* name = "", const char* label = 0); - bool operator()(int16& value, const char* name = "", const char* label = 0); - bool operator()(uint16& value, const char* name = "", const char* label = 0); - bool operator()(int32& value, const char* name = "", const char* label = 0); - bool operator()(uint32& value, const char* name = "", const char* label = 0); - bool operator()(int64& value, const char* name = "", const char* label = 0); - bool operator()(uint64& value, const char* name = "", const char* label = 0); - - bool operator()(char& value, const char* name = "", const char* label = 0); - bool operator()(int8& value, const char* name = "", const char* label = 0); - bool operator()(uint8& value, const char* name = "", const char* label = 0); - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0); - bool operator()(const SBlackBox& box, const char* name = "", const char* label = 0); - bool operator()(IContainer& ser, const char* name = "", const char* label = 0); - bool operator()(IKeyValue& keyValue, const char* name = "", const char* label = 0); - bool operator()(IPointer& ser, const char* name = "", const char* label = 0); - // ^^^ - - using IArchive::operator(); - private: - void openBracket(); - void closeBracket(); - void openContainerBracket(); - void closeContainerBracket(); - void placeName(const char* name); - void placeIndent(bool putComma = true); - void placeIndentCompact(bool putComma = true); - - bool joinLinesIfPossible(); - - struct Level - { - Level(bool _isContainer, std::size_t position, int column) - : isKeyValue(false) - , isContainer(_isContainer) - , isDictionary(false) - , startPosition(position) - , nameIndex(0) - , elementIndex(0) - , indentCount(-column) - {} - bool isKeyValue; - bool isContainer; - bool isDictionary; - std::size_t startPosition; - int nameIndex; - int elementIndex; - int indentCount; - }; - - typedef std::vector Stack; - Stack stack_; - std::unique_ptr buffer_; - const char* header_; - int textWidth_; - string fileName_; - int compactOffset_; - bool isKeyValue_; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryReader.cpp b/Code/CryEngine/CrySystem/Serialization/MemoryReader.cpp deleted file mode 100644 index ee424d065f..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryReader.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include "Serialization/Assert.h" -#include "MemoryReader.h" -#include -#include - -namespace Serialization { - MemoryReader::MemoryReader() - : size_(0) - , position_(0) - , memory_(0) - , ownedMemory_(false) - { - } - - - MemoryReader::MemoryReader(const void* memory, std::size_t size, bool ownAndFree) - : size_(size) - , position_((const char*)(memory)) - , memory_((const char*)(memory)) - , ownedMemory_(ownAndFree) - { - } - - MemoryReader::~MemoryReader() - { - if (ownedMemory_) - { - free(const_cast(memory_)); - memory_ = 0; - size_ = 0; - } - } - - void MemoryReader::setPosition(const char* position) - { - position_ = position; - } - - void MemoryReader::read(void* data, std::size_t size) - { - YASLI_ASSERT(memory_ && position_); - YASLI_ASSERT(position_ - memory_ + size <= size_); - memcpy(data, position_, size); - position_ += size; - } - - bool MemoryReader::checkedRead(void* data, std::size_t size) - { - if (!memory_ || !position_) - { - return false; - } - if (position_ - memory_ + size > size_) - { - return false; - } - - memcpy(data, position_, size); - position_ += size; - return true; - } - - bool MemoryReader::checkedSkip(std::size_t size) - { - if (!memory_ || !position_) - { - return false; - } - if (position_ - memory_ + size > size_) - { - return false; - } - - position_ += size; - return true; - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryReader.h b/Code/CryEngine/CrySystem/Serialization/MemoryReader.h deleted file mode 100644 index 88ae1d0060..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryReader.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -namespace Serialization { - class MemoryReader - { - public: - - MemoryReader(); - MemoryReader(const void* memory, size_t size, bool ownAndFree = false); - ~MemoryReader(); - - void setPosition(const char* position); - const char* position(){ return position_; } - - template - void read(T& value) - { - read(reinterpret_cast(&value), sizoef(value)); - } - void read(void* data, size_t size); - bool checkedSkip(size_t size); - bool checkedRead(void* data, size_t size); - template - bool checkedRead(T& t) - { - return checkedRead((void*)&t, sizeof(t)); - } - - const char* buffer() const{ return memory_; } - size_t size() const{ return size_; } - - const char* begin() const{ return memory_; } - const char* end() const{ return memory_ + size_; } - private: - size_t size_; - const char* position_; - const char* memory_; - bool ownedMemory_; - }; -} -// vim:ts=4 sw=4: diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.cpp b/Code/CryEngine/CrySystem/Serialization/MemoryWriter.cpp deleted file mode 100644 index c426119812..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include -#include "Serialization/Assert.h" -#include -#include -#include -#include -#ifdef _MSC_VER -# include -# define isnan _isnan -#endif - -#include "MemoryWriter.h" - -#undef YASLI_ASSERT -#define YASLI_ASSERT(x) - -namespace Serialization { - MemoryWriter::MemoryWriter(std::size_t size, bool reallocate) - : size_(size) - , reallocate_(reallocate) - , digits_(5) - { - allocate(size); - } - - MemoryWriter::~MemoryWriter() - { - position_ = 0; - CryModuleFree(memory_); - } - - void MemoryWriter::allocate(std::size_t initialSize) - { - memory_ = (char*)CryModuleMalloc(initialSize + 1); - position_ = memory_; - } - - void MemoryWriter::reallocate(std::size_t newSize) - { - YASLI_ASSERT(newSize > size_); - std::size_t pos = position(); - // Supressing the warning as we generally don't handle malloc errors. - // cppcheck-suppress memleakOnRealloc - memory_ = (char*)CryModuleRealloc(memory_, newSize + 1); - YASLI_ASSERT(memory_ != 0); - position_ = memory_ + pos; - size_ = newSize; - } - - MemoryWriter& MemoryWriter::operator<<(int value) - { - // TODO: optimize - char buffer[12]; - sprintf_s(buffer, "%i", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(long value) - { - // TODO: optimize - char buffer[12]; -#ifdef _MSC_VER - sprintf_s(buffer, "%i", value); -#else - sprintf_s(buffer, "%li", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned long value) - { - // TODO: optimize - char buffer[12]; -#ifdef _MSC_VER - sprintf_s(buffer, "%u", value); -#else - sprintf_s(buffer, "%lu", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(long long value) - { - // TODO: optimize - char buffer[24]; -#ifdef _MSC_VER - sprintf_s(buffer, "%I64i", value); -#else - sprintf_s(buffer, "%lli", value); -#endif - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned long long value) - { - // TODO: optimize - char buffer[24]; - sprintf_s(buffer, "%llu", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned int value) - { - // TODO: optimize - char buffer[12]; - sprintf_s(buffer, "%u", value); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(unsigned char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - MemoryWriter& MemoryWriter::operator<<(signed char value) - { - char buffer[12]; - sprintf_s(buffer, "%i", int(value)); - return operator<<((const char*)buffer); - } - - inline void cutRightZeros(const char* str) - { - for (char* p = (char*)str + strlen(str) - 1; p >= str; --p) - { - if (*p == '0') - { - *p = 0; - } - else - { - return; - } - } - } - - MemoryWriter& MemoryWriter::operator<<(double value) - { - YASLI_ASSERT(!isnan(value)); - - char buf[64] = { 0 }; - sprintf_s(buf, "%f", value); - operator<<(buf); - return *this; - } - - MemoryWriter& MemoryWriter::operator<<(const char* value) - { - write((void*)value, strlen(value)); - YASLI_ASSERT(position() < size()); - *position_ = '\0'; - return *this; - } - - MemoryWriter& MemoryWriter::operator<<(const wchar_t* value) - { - write((void*)value, wcslen(value) * sizeof(wchar_t)); - YASLI_ASSERT(position() < size()); - *position_ = '\0'; - return *this; - } - - void MemoryWriter::setPosition(std::size_t pos) - { - YASLI_ASSERT(pos < size_); - YASLI_ASSERT(memory_ + pos <= position_); - position_ = memory_ + pos; - } - - void MemoryWriter::write(const char* value) - { - write((void*)value, strlen(value)); - } - - bool MemoryWriter::write(const void* data, std::size_t size) - { - YASLI_ASSERT(memory_ <= position_); - YASLI_ASSERT(position() < this->size()); - if (size_ - position() > size) - { - memcpy(position_, data, size); - position_ += size; - } - else - { - if (!reallocate_) - { - return false; - } - - reallocate(size_ * 2); - write(data, size); - } - YASLI_ASSERT(position() < this->size()); - return true; - } - - void MemoryWriter::write(char c) - { - if (size_ - position() > 1) - { - *(char*)(position_) = c; - ++position_; - } - else - { - YASLI_ESCAPE(reallocate_, return ); - reallocate(size_ * 2); - write(c); - } - YASLI_ASSERT(position() < this->size()); - } -} diff --git a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.h b/Code/CryEngine/CrySystem/Serialization/MemoryWriter.h deleted file mode 100644 index 314a39c2d8..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/MemoryWriter.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -namespace Serialization { - class MemoryWriter - { - public: - MemoryWriter(std::size_t size = 128, bool reallocate = true); - ~MemoryWriter(); - - const char* c_str() { return memory_; }; - const wchar_t* w_str() { return (wchar_t*)memory_; }; - char* buffer() { return memory_; } - const char* buffer() const { return memory_; } - std::size_t size() const{ return size_; } - void clear() { position_ = memory_; } - - // String interface (after this calls '\0' is always written) - MemoryWriter& operator<<(int value); - MemoryWriter& operator<<(long value); - MemoryWriter& operator<<(unsigned long value); - MemoryWriter& operator<<(unsigned int value); - MemoryWriter& operator<<(long long value); - MemoryWriter& operator<<(unsigned long long value); - MemoryWriter& operator<<(float value) { return (*this) << double(value); } - MemoryWriter& operator<<(double value); - MemoryWriter& operator<<(signed char value); - MemoryWriter& operator<<(unsigned char value); - MemoryWriter& operator<<(char value); - MemoryWriter& operator<<(const char* value); - MemoryWriter& operator<<(const wchar_t* value); - - // Binary interface (does not writes trailing '\0') - template - void write(const T& value) - { - write(reinterpret_cast(&value), sizeof(value)); - } - void write(char c); - void write(const char* str); - bool write(const void* data, std::size_t size); - - std::size_t position() const{ return position_ - memory_; } - void setPosition(std::size_t pos); - - MemoryWriter& setDigits(int digits) { digits_ = (unsigned char)digits; return *this; } - - private: - void allocate(std::size_t initialSize); - void reallocate(std::size_t newSize); - - std::size_t size_; - char* position_; - char* memory_; - bool reallocate_; - unsigned char digits_; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/Test_ArchiveHost.cpp b/Code/CryEngine/CrySystem/Serialization/Test_ArchiveHost.cpp deleted file mode 100644 index 9608da72c6..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/Test_ArchiveHost.cpp +++ /dev/null @@ -1,492 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include - -#include - -#include "ArchiveHost.h" -#include -#include -#include -#include -#include - -namespace Serialization -{ - struct SMember - { - string name; - float weight; - - SMember() - : weight(0.0f) - {} - - void CheckEquality(const SMember& copy) const - { - EXPECT_TRUE(name == copy.name); - EXPECT_TRUE(weight == copy.weight); - } - - void Change(int index) - { - name = "Changed name "; - name += (index % 10) + '0'; - weight = float(index); - } - - void Serialize(IArchive& ar) - { - ar(name, "name"); - ar(weight, "weight"); - } - }; - - class CPolyBase - : public _i_reference_target_t - { - public: - CPolyBase() - { - baseMember = "Regular base member"; - } - - virtual void Change() - { - baseMember = "Changed base member"; - } - - virtual void Serialize(IArchive& ar) - { - ar(baseMember, "baseMember"); - } - - virtual void CheckEquality(const CPolyBase* copy) const - { - EXPECT_TRUE(baseMember == copy->baseMember); - } - - virtual bool IsDerivedA() const - { - return false; - } - virtual bool IsDerivedB() const - { - return false; - } - protected: - string baseMember; - }; - - class CPolyDerivedA - : public CPolyBase - { - public: - void Serialize(IArchive& ar) - { - CPolyBase::Serialize(ar); - ar(derivedMember, "derivedMember"); - } - - bool IsDerivedA() const override - { - return true; - } - - void CheckEquality(const CPolyBase* copyBase) const - { - EXPECT_TRUE(copyBase->IsDerivedA()); - const CPolyDerivedA* copy = (CPolyDerivedA*)copyBase; - EXPECT_TRUE(derivedMember == copy->derivedMember); - - CPolyBase::CheckEquality(copyBase); - } - protected: - string derivedMember; - }; - - class CPolyDerivedB - : public CPolyBase - { - public: - CPolyDerivedB() - : derivedMember("B Derived") - {} - - bool IsDerivedB() const override - { - return true; - } - - void Serialize(IArchive& ar) - { - CPolyBase::Serialize(ar); - ar(derivedMember, "derivedMember"); - } - - void CheckEquality(const CPolyBase* copyBase) const - { - EXPECT_TRUE(copyBase->IsDerivedB()); - const CPolyDerivedB* copy = (const CPolyDerivedB*)copyBase; - EXPECT_TRUE(derivedMember == copy->derivedMember); - - CPolyBase::CheckEquality(copyBase); - } - protected: - string derivedMember; - }; - - struct SNumericTypes - { - SNumericTypes() - : m_bool(false) - , m_char(0) - , m_int8(0) - , m_uint8(0) - , m_int16(0) - , m_uint16(0) - , m_int32(0) - , m_uint32(0) - , m_int64(0) - , m_uint64(0) - , m_float(0.0f) - , m_double(0.0) - {} - - void Change() - { - m_bool = true; - m_char = -1; - m_int8 = -2; - m_uint8 = 0xff - 3; - m_int16 = -6; - m_uint16 = 0xff - 7; - m_int32 = -4; - m_uint32 = -5; - m_int64 = -8ll; - m_uint64 = 9ull; - m_float = -10.0f; - m_double = -11.0; - } - - void Serialize(IArchive& ar) - { - ar(m_bool, "bool"); - ar(m_char, "char"); - ar(m_int8, "int8"); - ar(m_uint8, "uint8"); - ar(m_int16, "int16"); - ar(m_uint16, "uint16"); - ar(m_int32, "int32"); - ar(m_uint32, "uint32"); - ar(m_int64, "int64"); - ar(m_uint64, "uint64"); - ar(m_float, "float"); - ar(m_double, "double"); - } - - void CheckEquality(const SNumericTypes& rhs) const - { - EXPECT_TRUE(m_bool == rhs.m_bool); - EXPECT_TRUE(m_char == rhs.m_char); - EXPECT_TRUE(m_int8 == rhs.m_int8); - EXPECT_TRUE(m_uint8 == rhs.m_uint8); - EXPECT_TRUE(m_int16 == rhs.m_int16); - EXPECT_TRUE(m_uint16 == rhs.m_uint16); - EXPECT_TRUE(m_int32 == rhs.m_int32); - EXPECT_TRUE(m_uint32 == rhs.m_uint32); - EXPECT_TRUE(m_int64 == rhs.m_int64); - EXPECT_TRUE(m_uint64 == rhs.m_uint64); - EXPECT_TRUE(m_float == rhs.m_float); - EXPECT_TRUE(m_double == rhs.m_double); - } - - bool m_bool; - - char m_char; - int8 m_int8; - uint8 m_uint8; - - int16 m_int16; - uint16 m_uint16; - - int32 m_int32; - uint32 m_uint32; - - int64 m_int64; - uint64 m_uint64; - - float m_float; - double m_double; - }; - - class CComplexClass - { - public: - CComplexClass() - : index(0) - { - name = "Foo"; - stringList.push_back("Choice 1"); - stringList.push_back("Choice 2"); - stringList.push_back("Choice 3"); - - polyPtr.reset(new CPolyDerivedA()); - - polyVector.push_back(new CPolyDerivedB); - polyVector.push_back(new CPolyBase); - - SMember& a = stringToStructMap["a"]; - a.name = "A"; - SMember& b = stringToStructMap["b"]; - b.name = "B"; - - members.resize(13); - - intToString.push_back(std::make_pair(1, "one")); - intToString.push_back(std::make_pair(2, "two")); - intToString.push_back(std::make_pair(3, "three")); - stringToInt.push_back(std::make_pair("one", 1)); - stringToInt.push_back(std::make_pair("two", 2)); - stringToInt.push_back(std::make_pair("three", 3)); - } - - void Change() - { - name = "Slightly changed name"; - index = 2; - polyPtr.reset(new CPolyDerivedB()); - polyPtr->Change(); - - for (size_t i = 0; i < members.size(); ++i) - { - members[i].Change(int(i)); - } - - members.erase(members.begin()); - - for (size_t i = 0; i < polyVector.size(); ++i) - { - polyVector[i]->Change(); - } - - polyVector.resize(4); - polyVector.push_back(new CPolyBase()); - polyVector[4]->Change(); - - const size_t arrayLen = sizeof(array) / sizeof(array[0]); - for (size_t i = 0; i < arrayLen; ++i) - { - array[i].Change(int(arrayLen - i)); - } - - numericTypes.Change(); - - vectorOfStrings.push_back("str1"); - vectorOfStrings.push_back("2str"); - vectorOfStrings.push_back("thirdstr"); - - stringToStructMap.erase("a"); - SMember& c = stringToStructMap["c"]; - c.name = "C"; - - intToString.push_back(std::make_pair(4, "four")); - stringToInt.push_back(std::make_pair("four", 4)); - } - - void Serialize(IArchive& ar) - { - ar(name, "name"); - ar(polyPtr, "polyPtr"); - ar(polyVector, "polyVector"); - ar(members, "members"); - { - StringListValue value(stringList, stringList[index]); - ar(value, "stringList"); - index = value.index(); - if (index == -1) - { - index = 0; - } - } - ar(array, "array"); - ar(numericTypes, "numericTypes"); - ar(vectorOfStrings, "vectorOfStrings"); - ar(stringToInt, "stringToInt"); - } - - void CheckEquality(const CComplexClass& copy) const - { - EXPECT_TRUE(name == copy.name); - EXPECT_TRUE(index == copy.index); - - EXPECT_TRUE(polyPtr != 0); - EXPECT_TRUE(copy.polyPtr != 0); - polyPtr->CheckEquality(copy.polyPtr); - - EXPECT_TRUE(members.size() == copy.members.size()); - for (size_t i = 0; i < members.size(); ++i) - { - members[i].CheckEquality(copy.members[i]); - } - - EXPECT_TRUE(polyVector.size() == copy.polyVector.size()); - for (size_t i = 0; i < polyVector.size(); ++i) - { - if (polyVector[i] == 0) - { - EXPECT_TRUE(copy.polyVector[i] == 0); - continue; - } - EXPECT_TRUE(copy.polyVector[i] != 0); - polyVector[i]->CheckEquality(copy.polyVector[i]); - } - - const size_t arrayLen = sizeof(array) / sizeof(array[0]); - for (size_t i = 0; i < arrayLen; ++i) - { - array[i].CheckEquality(copy.array[i]); - } - - numericTypes.CheckEquality(copy.numericTypes); - - EXPECT_TRUE(stringToInt.size() == copy.stringToInt.size()); - for (size_t i = 0; i < stringToInt.size(); ++i) - { - EXPECT_TRUE(stringToInt[i] == copy.stringToInt[i]); - } - } - protected: - string name; - typedef std::vector Members; - std::vector vectorOfStrings; - std::vector > intToString; - std::vector > stringToInt; - Members members; - int32 index; - SNumericTypes numericTypes; - - StringListStatic stringList; - std::vector< _smart_ptr > polyVector; - _smart_ptr polyPtr; - - std::map stringToStructMap; - - SMember array[5]; - }; - - struct ArchiveHostTests - : ::testing::Test - { - public: - void SetUp() override - { - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - m_classFactoryRTTI = AZStd::make_unique(); - } - - void TearDown() - { - m_classFactoryRTTI.reset(); - - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } - - struct ClassFactoryRTTI - { - ClassFactoryRTTI() - : CPolyBaseCPolyBase_DerivedDescription("base", "Base") - , CPolyBaseCPolyBase_Creator(&CPolyBaseCPolyBase_DerivedDescription) - , TypeCPolyBase_DerivedDescription("derived_a", "Derived A") - , TypeCPolyBase_Creator(&TypeCPolyBase_DerivedDescription) - , CPolyDerivedBCPolyBase_DerivedDescription("derived_b", "Derived B") - , CPolyDerivedBCPolyBase_Creator(&CPolyDerivedBCPolyBase_DerivedDescription) - {} - - ~ClassFactoryRTTI() - { - Serialization::ClassFactory::destroy(); - } - - const Serialization::TypeDescription CPolyBaseCPolyBase_DerivedDescription; - Serialization::ClassFactory::Creator CPolyBaseCPolyBase_Creator; - - const Serialization::TypeDescription TypeCPolyBase_DerivedDescription; - Serialization::ClassFactory::Creator TypeCPolyBase_Creator; - - const Serialization::TypeDescription CPolyDerivedBCPolyBase_DerivedDescription; - Serialization::ClassFactory::Creator CPolyDerivedBCPolyBase_Creator; - }; - AZStd::unique_ptr m_classFactoryRTTI; - }; - - TEST_F(ArchiveHostTests, JsonBasicTypes) - { - std::unique_ptr host(CreateArchiveHost()); - - DynArray bufChanged; - CComplexClass objChanged; - objChanged.Change(); - host->SaveJsonBuffer(bufChanged, SStruct(objChanged)); - EXPECT_TRUE(!bufChanged.empty()); - - DynArray bufResaved; - { - CComplexClass obj; - - EXPECT_TRUE(host->LoadJsonBuffer(SStruct(obj), bufChanged.data(), bufChanged.size())); - EXPECT_TRUE(host->SaveJsonBuffer(bufResaved, SStruct(obj))); - EXPECT_TRUE(!bufResaved.empty()); - - obj.CheckEquality(objChanged); - } - EXPECT_TRUE(bufChanged.size() == bufResaved.size()); - for (size_t i = 0; i < bufChanged.size(); ++i) - { - EXPECT_TRUE(bufChanged[i] == bufResaved[i]); - } - } - - TEST_F(ArchiveHostTests, BinBasicTypes) - { - std::unique_ptr host(CreateArchiveHost()); - - DynArray bufChanged; - CComplexClass objChanged; - objChanged.Change(); - host->SaveBinaryBuffer(bufChanged, SStruct(objChanged)); - EXPECT_TRUE(!bufChanged.empty()); - - DynArray bufResaved; - { - CComplexClass obj; - - EXPECT_TRUE(host->LoadBinaryBuffer(SStruct(obj), bufChanged.data(), bufChanged.size())); - EXPECT_TRUE(host->SaveBinaryBuffer(bufResaved, SStruct(obj))); - EXPECT_TRUE(!bufResaved.empty()); - - obj.CheckEquality(objChanged); - } - EXPECT_TRUE(bufChanged.size() == bufResaved.size()); - for (size_t i = 0; i < bufChanged.size(); ++i) - { - EXPECT_TRUE(bufChanged[i] == bufResaved[i]); - } - } -} - diff --git a/Code/CryEngine/CrySystem/Serialization/Token.h b/Code/CryEngine/CrySystem/Serialization/Token.h deleted file mode 100644 index 4f730054e4..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/Token.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include - -#include "Serialization/Strings.h" - -namespace Serialization { - struct Token - { - Token(const char* _str = 0) - : start(_str) - , end(_str ? _str + strlen(_str) : 0) - { - } - - Token(const char* _str, size_t _len) - : start(_str) - , end(_str + _len) {} - Token(const char* _start, const char* _end) - : start(_start) - , end(_end) {} - - void set(const char* _start, const char* _end) { start = _start; end = _end; } - std::size_t length() const{ return end - start; } - - bool operator==(const Token& rhs) const - { - if (length() != rhs.length()) - { - return false; - } - return memcmp(start, rhs.start, length()) == 0; - } - bool operator==(const string& rhs) const - { - if (length() != rhs.size()) - { - return false; - } - return memcmp(start, rhs.c_str(), length()) == 0; - } - - bool operator==(const char* text) const - { - if (strncmp(text, start, length()) == 0) - { - return text[length()] == '\0'; - } - return false; - } - bool operator!=(const char* text) const - { - if (strncmp(text, start, length()) == 0) - { - return text[length()] != '\0'; - } - return true; - } - bool operator==(char c) const - { - return length() == 1 && *start == c; - } - bool operator!=(char c) const - { - return length() != 1 || *start != c; - } - - operator bool() const{ - return start != end; - } - string str() const{ return string(start, end); } - - const char* start; - const char* end; - }; -} diff --git a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.cpp b/Code/CryEngine/CrySystem/Serialization/XmlIArchive.cpp deleted file mode 100644 index 914b7857e0..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CryExtension/Impl/ClassWeaver.h" - -#include -#include - -#include "XmlIArchive.h" - -#include -#include - -namespace XmlUtil -{ - int g_hintSuccess = 0; - int g_hintFail = 0; - - - XmlNodeRef FindChildNode(XmlNodeRef pParent, const int childIndexOverride, int& childIndexHint, const char* const name) - { - CRY_ASSERT(pParent); - - if (0 <= childIndexOverride) - { - CRY_ASSERT(childIndexOverride < pParent->getChildCount()); - return pParent->getChild(childIndexOverride); - } - else - { - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - CRY_ASSERT(0 <= childIndexHint); - - const int childCount = pParent->getChildCount(); - const bool hasValidChildHint = (childIndexHint < childCount); - if (hasValidChildHint) - { - XmlNodeRef pChildNode = pParent->getChild(childIndexHint); - if (pChildNode->isTag(name)) - { - g_hintSuccess++; - const int nextChildIndexHint = childIndexHint + 1; - childIndexHint = (nextChildIndexHint < childCount) ? nextChildIndexHint : 0; - return pChildNode; - } - else - { - g_hintFail++; - } - } - - for (int i = 0; i < childCount; ++i) - { - XmlNodeRef pChildNode = pParent->getChild(i); - if (pChildNode->isTag(name)) - { - const int nextChildIndexHint = i + 1; - childIndexHint = (nextChildIndexHint < childCount) ? nextChildIndexHint : 0; - return pChildNode; - } - } - } - return XmlNodeRef(); - } - - - template< typename T, typename TOut > - bool ReadChildNodeAs(XmlNodeRef pParent, const int childIndexOverride, int& childIndexHint, const char* const name, TOut& valueOut) - { - XmlNodeRef pChild = FindChildNode(pParent, childIndexOverride, childIndexHint, name); - if (pChild) - { - T tmp; - const bool readValueSuccess = pChild->getAttr("value", tmp); - if (readValueSuccess) - { - valueOut = tmp; - } - return readValueSuccess; - } - return false; - } - - - template< typename T > - bool ReadChildNode(XmlNodeRef pParent, const int childIndexOverride, int& childIndexHint, const char* const name, T& valueOut) - { - return ReadChildNodeAs< T >(pParent, childIndexOverride, childIndexHint, name, valueOut); - } -} - - -Serialization::CXmlIArchive::CXmlIArchive() - : IArchive(INPUT | NO_EMPTY_NAMES) - , m_childIndexOverride(-1) - , m_childIndexHint(0) -{ -} - - -Serialization::CXmlIArchive::CXmlIArchive(XmlNodeRef pRootNode) - : IArchive(INPUT | NO_EMPTY_NAMES) - , m_pRootNode(pRootNode) - , m_childIndexOverride(-1) - , m_childIndexHint(0) -{ - CRY_ASSERT(m_pRootNode); -} - - -Serialization::CXmlIArchive::~CXmlIArchive() -{ -} - - -void Serialization::CXmlIArchive::SetXmlNode(XmlNodeRef pNode) -{ - m_pRootNode = pNode; -} - - -XmlNodeRef Serialization::CXmlIArchive::GetXmlNode() const -{ - return m_pRootNode; -} - - -bool Serialization::CXmlIArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) -{ - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - const char* const stringValue = pChild->getAttr("value"); - if (stringValue) - { - value = (strcmp("true", stringValue) == 0); - value = value || (strcmp("1", stringValue) == 0); - return true; - } - return false; - } - return false; -} - - -bool Serialization::CXmlIArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) -{ - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - const char* const stringValue = pChild->getAttr("value"); - if (stringValue) - { - value.set(stringValue); - return true; - } - return false; - } - return false; -} - - -bool Serialization::CXmlIArchive::operator()([[maybe_unused]] IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) -{ - CryFatalError("CXmlIArchive::operator() with IWString is not implemented"); - return false; -} - - -bool Serialization::CXmlIArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< int >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< uint >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< int >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< uint >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::ReadChildNodeAs< int >(m_pRootNode, m_childIndexOverride, m_childIndexHint, name, value); -} - - -bool Serialization::CXmlIArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - CXmlIArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - const bool serializeSuccess = ser(childArchive); - return serializeSuccess; - } - return false; -} - - -bool Serialization::CXmlIArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - bool serializeSuccess = true; - - XmlNodeRef pChild = XmlUtil::FindChildNode(m_pRootNode, m_childIndexOverride, m_childIndexHint, name); - if (pChild) - { - const int elementCount = pChild->getChildCount(); - ser.resize(elementCount); - - if (0 < elementCount) - { - CXmlIArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - for (int i = 0; i < elementCount; ++i) - { - childArchive.m_childIndexOverride = i; - - serializeSuccess &= ser(childArchive, "Element", "Element"); - ser.next(); - } - } - } - - return serializeSuccess; -} diff --git a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.h b/Code/CryEngine/CrySystem/Serialization/XmlIArchive.h deleted file mode 100644 index dd23febef6..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlIArchive.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __XML_I_ARCHIVE__H__ -#define __XML_I_ARCHIVE__H__ - -#include - -namespace Serialization -{ - class CXmlIArchive - : public IArchive - { - public: - CXmlIArchive(); - CXmlIArchive(XmlNodeRef pRootNode); - ~CXmlIArchive(); - - void SetXmlNode(XmlNodeRef pNode); - XmlNodeRef GetXmlNode() const; - - // IArchive - bool operator()(bool& value, const char* name = "", const char* label = 0) override; - bool operator()(IString& value, const char* name = "", const char* label = 0) override; - bool operator()(IWString& value, const char* name = "", const char* label = 0) override; - bool operator()(float& value, const char* name = "", const char* label = 0) override; - bool operator()(double& value, const char* name = "", const char* label = 0) override; - bool operator()(int16& value, const char* name = "", const char* label = 0) override; - bool operator()(uint16& value, const char* name = "", const char* label = 0) override; - bool operator()(int32& value, const char* name = "", const char* label = 0) override; - bool operator()(uint32& value, const char* name = "", const char* label = 0) override; - bool operator()(int64& value, const char* name = "", const char* label = 0) override; - bool operator()(uint64& value, const char* name = "", const char* label = 0) override; - - bool operator()(int8& value, const char* name = "", const char* label = 0) override; - bool operator()(uint8& value, const char* name = "", const char* label = 0) override; - bool operator()(char& value, const char* name = "", const char* label = 0) override; - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override; - bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override; - // ~IArchive - - using IArchive::operator(); - - private: - XmlNodeRef m_pRootNode; - int m_childIndexOverride; - int m_childIndexHint; - }; -} - -#endif diff --git a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.cpp b/Code/CryEngine/CrySystem/Serialization/XmlOArchive.cpp deleted file mode 100644 index 1133a7e51e..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CryExtension/Impl/ClassWeaver.h" - -#include -#include - -#include "XmlOArchive.h" - -#include -#include - -namespace XmlUtil -{ - XmlNodeRef CreateChildNode(XmlNodeRef pParent, const char* const name) - { - CRY_ASSERT(pParent); - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - XmlNodeRef pChild = pParent->createNode(name); - CRY_ASSERT(pChild); - - pParent->addChild(pChild); - return pChild; - } - - template < typename T, typename TIn > - bool WriteChildNodeAs(XmlNodeRef pParent, const char* const name, const TIn& value) - { - XmlNodeRef pChild = XmlUtil::CreateChildNode(pParent, name); - CRY_ASSERT(pChild); - - pChild->setAttr("value", static_cast< T >(value)); - return true; - } - - template < typename T > - bool WriteChildNode(XmlNodeRef pParent, const char* const name, const T& value) - { - return WriteChildNodeAs< T >(pParent, name, value); - } -} - -Serialization::CXmlOArchive::CXmlOArchive() - : IArchive(OUTPUT | NO_EMPTY_NAMES) -{ -} - - -Serialization::CXmlOArchive::CXmlOArchive(XmlNodeRef pRootNode) - : IArchive(OUTPUT | NO_EMPTY_NAMES) - , m_pRootNode(pRootNode) -{ - CRY_ASSERT(m_pRootNode); -} - - -Serialization::CXmlOArchive::~CXmlOArchive() -{ -} - - -void Serialization::CXmlOArchive::SetXmlNode(XmlNodeRef pNode) -{ - m_pRootNode = pNode; -} - - -XmlNodeRef Serialization::CXmlOArchive::GetXmlNode() const -{ - return m_pRootNode; -} - - -bool Serialization::CXmlOArchive::operator()(bool& value, const char* name, [[maybe_unused]] const char* label) -{ - const char* const stringValue = value ? "true" : "false"; - return XmlUtil::WriteChildNode(m_pRootNode, name, stringValue); -} - - -bool Serialization::CXmlOArchive::operator()(IString& value, const char* name, [[maybe_unused]] const char* label) -{ - const char* const stringValue = value.get(); - return XmlUtil::WriteChildNode(m_pRootNode, name, stringValue); -} - - -bool Serialization::CXmlOArchive::operator()([[maybe_unused]] IWString& value, [[maybe_unused]] const char* name, [[maybe_unused]] const char* label) -{ - CryFatalError("CXmlOArchive::operator() with IWString is not implemented"); - return false; -} - - -bool Serialization::CXmlOArchive::operator()(float& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(double& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< int >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint16& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< uint >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint32& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint64& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNode(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(int8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< int >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(uint8& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< uint >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(char& value, const char* name, [[maybe_unused]] const char* label) -{ - return XmlUtil::WriteChildNodeAs< int >(m_pRootNode, name, value); -} - - -bool Serialization::CXmlOArchive::operator()(const SStruct& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - XmlNodeRef pChild = XmlUtil::CreateChildNode(m_pRootNode, name); - CXmlOArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - const bool serializeSuccess = ser(childArchive); - - return serializeSuccess; -} - - -bool Serialization::CXmlOArchive::operator()(IContainer& ser, const char* name, [[maybe_unused]] const char* label) -{ - CRY_ASSERT(name); - CRY_ASSERT(name[ 0 ]); - - bool serializeSuccess = true; - - XmlNodeRef pChild = XmlUtil::CreateChildNode(m_pRootNode, name); - CXmlOArchive childArchive(pChild); - childArchive.SetFilter(GetFilter()); - childArchive.SetInnerContext(GetInnerContext()); - - const size_t containerSize = ser.size(); - if (0 < containerSize) - { - do - { - serializeSuccess &= ser(childArchive, "Element", "Element"); - } while (ser.next()); - } - - return serializeSuccess; -} diff --git a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.h b/Code/CryEngine/CrySystem/Serialization/XmlOArchive.h deleted file mode 100644 index 4451d2ba75..0000000000 --- a/Code/CryEngine/CrySystem/Serialization/XmlOArchive.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef __XML_O_ARCHIVE__H__ -#define __XML_O_ARCHIVE__H__ - -#include - -namespace Serialization -{ - class CXmlOArchive - : public IArchive - { - public: - CXmlOArchive(); - CXmlOArchive(XmlNodeRef pRootNode); - ~CXmlOArchive(); - - void SetXmlNode(XmlNodeRef pNode); - XmlNodeRef GetXmlNode() const; - - // IArchive - bool operator()(bool& value, const char* name = "", const char* label = 0) override; - bool operator()(IString& value, const char* name = "", const char* label = 0) override; - bool operator()(IWString& value, const char* name = "", const char* label = 0) override; - bool operator()(float& value, const char* name = "", const char* label = 0) override; - bool operator()(double& value, const char* name = "", const char* label = 0) override; - bool operator()(int16& value, const char* name = "", const char* label = 0) override; - bool operator()(uint16& value, const char* name = "", const char* label = 0) override; - bool operator()(int32& value, const char* name = "", const char* label = 0) override; - bool operator()(uint32& value, const char* name = "", const char* label = 0) override; - bool operator()(int64& value, const char* name = "", const char* label = 0) override; - bool operator()(uint64& value, const char* name = "", const char* label = 0) override; - - bool operator()(int8& value, const char* name = "", const char* label = 0) override; - bool operator()(uint8& value, const char* name = "", const char* label = 0) override; - bool operator()(char& value, const char* name = "", const char* label = 0) override; - - bool operator()(const SStruct& ser, const char* name = "", const char* label = 0) override; - bool operator()(IContainer& ser, const char* name = "", const char* label = 0) override; - // ~IArchive - - using IArchive::operator(); - - private: - XmlNodeRef m_pRootNode; - }; -} - -#endif diff --git a/Code/CryEngine/CrySystem/ServerHandler.cpp b/Code/CryEngine/CrySystem/ServerHandler.cpp deleted file mode 100644 index 85b3192650..0000000000 --- a/Code/CryEngine/CrySystem/ServerHandler.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "ServerHandler.h" - -ServerHandler::ServerHandler(const char* bucket, int affinity, int serverTimeout) - : HandlerBase(bucket, affinity) -{ - m_serverTimeout = serverTimeout; - DoScan(); -} - -void ServerHandler::DoScan() -{ - std::set gotIndices; - for (int i = 0; i < m_srvLocks.size(); ++i) - { - gotIndices.insert(m_srvLocks[i]->number); - } - for (int i = 0; i < MAX_CLIENTS_NUM; ++i) - { - if (gotIndices.find(i) == gotIndices.end()) - { - std::unique_ptr lock(new SSyncLock(m_clientLockName, i, false)); - if (lock->IsValid()) - { - std::unique_ptr srv(new SSyncLock(m_serverLockName, i, true)); - if (srv->IsValid()) - { - m_srvLocks.push_back(std::move(srv)); - m_clientLocks.push_back(std::move(lock)); - CryLogAlways("Client %d bound", i); - } - else - { - CryLogAlways("Failed to bind client %d", i); - } - } - } - } - if (!m_clientLocks.empty()) - { - SetAffinity(); - } - m_lastScan = gEnv->pTimer->GetAsyncTime(); -} - -bool ServerHandler::Sync() -{ - if ((gEnv->pTimer->GetAsyncTime() - m_lastScan).GetSeconds() > 1.0f) - { - DoScan(); - } - for (int i = 0; i < m_srvLocks.size(); ) - { - m_srvLocks[i]->Signal(); - if (!m_clientLocks[i]->Wait(m_serverTimeout))//actually if not waited, let's kill it! - { - CryLogAlways("Dropped client %d", m_clientLocks[i]->number); - m_clientLocks[i]->Own(m_clientLockName); - m_clientLocks.erase(m_clientLocks.begin() + i); - m_srvLocks.erase(m_srvLocks.begin() + i); - continue; - } - ++i; - } - return false;//!m_clientLocks.empty(); -} - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/ServerHandler.h b/Code/CryEngine/CrySystem/ServerHandler.h deleted file mode 100644 index 37a870efee..0000000000 --- a/Code/CryEngine/CrySystem/ServerHandler.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SERVERHANDLER_H -#define CRYINCLUDE_CRYSYSTEM_SERVERHANDLER_H -#pragma once - -#include "HandlerBase.h" -#include "SyncLock.h" - -struct ServerHandler - : public HandlerBase -{ - ServerHandler(const char* bucket, int affinity, int serverTimeout); - - void DoScan(); - bool Sync(); - -private: - int m_serverTimeout; - std::vector > m_clientLocks; - std::vector > m_srvLocks; - CTimeValue m_lastScan; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_SERVERHANDLER_H diff --git a/Code/CryEngine/CrySystem/ServerThrottle.cpp b/Code/CryEngine/CrySystem/ServerThrottle.cpp deleted file mode 100644 index c183f1a4fc..0000000000 --- a/Code/CryEngine/CrySystem/ServerThrottle.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ServerThrottle.h" -#include "TimeValue.h" -#include "ISystem.h" -#include "ITimer.h" -#include "IConsole.h" - -#if defined(WIN32) -static float ftdiff(const FILETIME& b, const FILETIME& a) -{ - uint64 aa = *reinterpret_cast(&a); - uint64 bb = *reinterpret_cast(&b); - return (bb - aa) * 1e-7f; -} - -class CCPUMonitor -{ -public: - CCPUMonitor(ISystem* pSystem, int nCPUs) - : m_lastUpdate(0.0f) - , m_pTimer(pSystem->GetITimer()) - , m_nCPUs(nCPUs) - { - FILETIME notNeeded; - GetProcessTimes(GetCurrentProcess(), ¬Needed, ¬Needed, &m_lastKernel, &m_lastUser); - } - - float* Update() - { - CTimeValue frameTime = gEnv->pTimer->GetFrameStartTime(); - if (frameTime - m_lastUpdate > 5.0f) - { - m_lastUpdate = frameTime; - - static float result = 0.0f; - - FILETIME kernel, user, cur; - FILETIME notNeeded; - GetSystemTimeAsFileTime(&cur); - GetProcessTimes(GetCurrentProcess(), ¬Needed, ¬Needed, &kernel, &user); - - float sKernel = ftdiff(kernel, m_lastKernel); - float sUser = ftdiff(user, m_lastUser); - float sCur = ftdiff(cur, m_lastTime); - - result = 100 * (sKernel + sUser) / sCur / m_nCPUs; - - m_lastTime = cur; - m_lastKernel = kernel; - m_lastUser = user; - - return &result; - } - return 0; - } - -private: - ITimer* m_pTimer; - CTimeValue m_lastUpdate; - FILETIME m_lastKernel, m_lastUser, m_lastTime; - int m_nCPUs; -}; -#else -class CCPUMonitor -{ -public: - CCPUMonitor(ISystem*, int) {} - - float* Update() { return 0; } -}; -#endif - -CServerThrottle::CServerThrottle(ISystem* pSys, int nCPUs) -{ - m_pCPUMonitor.reset(new CCPUMonitor(pSys, nCPUs)); - m_pDedicatedMaxRate = pSys->GetIConsole()->GetCVar("sv_DedicatedMaxRate"); - m_pDedicatedCPU = pSys->GetIConsole()->GetCVar("sv_DedicatedCPUPercent"); - m_pDedicatedCPUVariance = pSys->GetIConsole()->GetCVar("sv_DedicatedCPUVariance"); - - m_minFPS = 20; - m_maxFPS = 60; - m_nSteps = 8; - m_nCurStep = 0; - - if (m_pDedicatedCPU->GetFVal() >= 1.0f) - { - SetStep(m_nSteps / 2, 0); - } -} - -CServerThrottle::~CServerThrottle() -{ -} - -void CServerThrottle::Update() -{ - float tgtCPU = m_pDedicatedCPU->GetFVal(); - if (tgtCPU < 1) - { - return; - } - if (float* pCPU = m_pCPUMonitor->Update()) - { - float varCPU = m_pDedicatedCPUVariance->GetFVal(); - if (tgtCPU < 5) - { - tgtCPU = 5; - } - else if (tgtCPU > 95) - { - tgtCPU = 95; - } - float minCPU = std::max(tgtCPU - varCPU, tgtCPU / 2.0f); - float maxCPU = std::min(tgtCPU + varCPU, (100.0f + tgtCPU) / 2.0f); - - if (*pCPU > maxCPU) - { - SetStep(m_nCurStep - 1, pCPU); - } - else if (*pCPU < minCPU) - { - SetStep(m_nCurStep + 1, pCPU); - } - } -} - -void CServerThrottle::SetStep(int step, float* pDueToCPU) -{ - if (step < 0) - { - step = 0; - } - else if (step > m_nSteps) - { - step = m_nSteps; - } - if (step != m_nCurStep) - { - float fps = step * (m_maxFPS - m_minFPS) / m_nSteps + m_minFPS; - m_pDedicatedMaxRate->Set(fps); - if (pDueToCPU) - { - CryLog("ServerThrottle: Set framerate to %.1f fps [due to cpu being %d%%]", fps, int(*pDueToCPU + 0.5f)); - } - else - { - CryLog("ServerThrottle: Set framerate to %.1f fps", fps); - } - m_nCurStep = step; - } -} diff --git a/Code/CryEngine/CrySystem/ServerThrottle.h b/Code/CryEngine/CrySystem/ServerThrottle.h deleted file mode 100644 index ce658f4d2e..0000000000 --- a/Code/CryEngine/CrySystem/ServerThrottle.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Handle raising/lowering the frame rate on server -// based upon CPU usage - - -#ifndef CRYINCLUDE_CRYSYSTEM_SERVERTHROTTLE_H -#define CRYINCLUDE_CRYSYSTEM_SERVERTHROTTLE_H -#pragma once - - -struct ISystem; - -class CCPUMonitor; - -class CServerThrottle -{ -public: - CServerThrottle(ISystem* pSys, int nCPUs); - ~CServerThrottle(); - void Update(); - -private: - std::unique_ptr m_pCPUMonitor; - - void SetStep(int step, float* dueToCPU); - - float m_minFPS; - float m_maxFPS; - int m_nSteps; - int m_nCurStep; - ICVar* m_pDedicatedMaxRate; - ICVar* m_pDedicatedCPU; - ICVar* m_pDedicatedCPUVariance; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_SERVERTHROTTLE_H diff --git a/Code/CryEngine/CrySystem/ServiceNetwork.cpp b/Code/CryEngine/CrySystem/ServiceNetwork.cpp deleted file mode 100644 index 4ead14bcba..0000000000 --- a/Code/CryEngine/CrySystem/ServiceNetwork.cpp +++ /dev/null @@ -1,2035 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network implementation - - -#include "CrySystem_precompiled.h" -#include "ServiceNetwork.h" -#include "RemoteCommandHelpers.h" - -#include - -//----------------------------------------------------------------------------- - -// network system internal logging -#ifdef RELEASE - #define LOG_VERBOSE(level, txt, ...) -#else - #define LOG_VERBOSE(level, txt, ...) if (GetManager()->CheckVerbose(level)) { GetManager()->Log(txt, __VA_ARGS__); } -#endif - -//----------------------------------------------------------------------------- - -namespace -{ - union AddValueConv - { - struct - { - uint8 ip0, ip1, ip2, ip3; - } bytes; - - uint32 u32; - }; - - inline void TranslateAddress(const ServiceNetworkAddress& addr, AZ::AzSock::AzSocketAddress& outAddr) - { - AddValueConv addr_value; - addr_value.bytes.ip0 = addr.GetAddress().m_ip0; - addr_value.bytes.ip1 = addr.GetAddress().m_ip1; - addr_value.bytes.ip2 = addr.GetAddress().m_ip2; - addr_value.bytes.ip3 = addr.GetAddress().m_ip3; - - outAddr.SetAddress(addr_value.u32, addr.GetAddress().m_port); - } - - inline void TranslateAddress(const AZ::AzSock::AzSocketAddress& addr, ServiceNetworkAddress& outAddr) - { - AddValueConv addr_value; - - const AZSOCKADDR_IN* addrIn = reinterpret_cast(addr.GetTargetAddress()); - addr_value.u32 = AZ::AzSock::NetToHostLong((*addrIn).sin_addr.s_addr); - - outAddr = ServiceNetworkAddress( - addr_value.bytes.ip0, - addr_value.bytes.ip1, - addr_value.bytes.ip2, - addr_value.bytes.ip3, - addr.GetAddrPort()); - } - - inline bool SocketConnectionsFull(AZ::AzSock::AzSockError error) - { - return (error == AZ::AzSock::AzSockError::eASE_NO_ERROR || error == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK || error == AZ::AzSock::AzSockError::eASE_EWOULDBLOCK_CONN); - } -} - -//----------------------------------------------------------------------------- - -CServiceNetworkMessage::CServiceNetworkMessage(const uint32 id, const uint32 size) - : m_refCount(1) - , m_size(size) - , m_id(id) -{ - // Allocate buffer memory - m_pData = CryModuleMalloc(size); -} - -CServiceNetworkMessage::~CServiceNetworkMessage() -{ - // Release the memory buffer - CryModuleFree(m_pData); - m_pData = NULL; -} - -uint32 CServiceNetworkMessage::GetSize() const -{ - return m_size; -} - -uint32 CServiceNetworkMessage::GetId() const -{ - return m_id; -} - -void* CServiceNetworkMessage::GetPointer() -{ - return m_pData; -} - -const void* CServiceNetworkMessage::GetPointer() const -{ - return m_pData; -} - -void CServiceNetworkMessage::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CServiceNetworkMessage::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -IDataReadStream* CServiceNetworkMessage::CreateReader() const -{ - return new CDataReadStreamFormMessage(this); -} - -//----------------------------------------------------------------------------- - -void CServiceNetworkConnection::Header::Swap() -{ - // if we are on big endian system swap data to LE - // NOTE: this is a little bit confusing so see how the eLittleEndian and eBigEndian is defined - SwapEndian(m_size, eLittleEndian); -} - -void CServiceNetworkConnection::InitHeader::Swap() -{ - // if we are on big endian system swap data to LE - // NOTE: this is a little bit confusing so see how the eLittleEndian and eBigEndian is defined - SwapEndian(m_tryCount, eLittleEndian); - SwapEndian(m_guid0, eLittleEndian); - SwapEndian(m_guid1, eLittleEndian); -} - -//----------------------------------------------------------------------------- - -CServiceNetworkConnection::CServiceNetworkConnection( - class CServiceNetwork* manager, - EEndpoint endpointType, - AZSOCKET socket, - const CryGUID& connectionID, - const ServiceNetworkAddress& localAddress, - const ServiceNetworkAddress& remoteAddress) - - : m_pManager(manager) - , m_connectionID(connectionID) - , m_socket(socket) - , m_localAddress(localAddress) - , m_remoteAddress(remoteAddress) - , m_endpointType(endpointType) - , m_state(eState_Initializing) - , m_sendQueueDataSize(0) - , m_receiveQueueDataSize(0) - , m_messageDataSentSoFar(0) - , m_messageDataReceivedSoFar(0) - , m_bCloseRequested(false) - , m_pCurrentReceiveMessage(NULL) - , m_messageReceiveLength(0) - , m_messageDummyReadLength(0) - , m_reconnectTryCount(0) - , m_bDisableCommunication(false) - , m_pSendedMessages(NULL) - , m_refCount(1) -{ - // put the socket back in non blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, false); - - // reset stats - m_statsNumDataSend = 0; - m_statsNumDataReceived = 0; - m_statsNumPacketsSend = 0; - m_statsNumPacketsReceived = 0; - - // reset timers to values at the creation time - const uint64 currentNetworkTime = m_pManager->GetNetworkTime(); - m_lastReconnectTime = currentNetworkTime; - m_lastMessageReceivedTime = currentNetworkTime; - m_lastInitializationSendTime = currentNetworkTime; - - // make sure keep alive messages are sent as soon as possible - m_lastKeepAliveSendTime = currentNetworkTime - kKeepAlivePeriod; - - LOG_VERBOSE(3, "Connection(): local='%s', remote='%s', this=%p", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); -} - -CServiceNetworkConnection::~CServiceNetworkConnection() -{ - // in here we must be already closed! - CRY_ASSERT(m_state == eState_Closed); - - LOG_VERBOSE(3, "~Connection(): local='%s', remote='%s', this=%p", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // can happen - if (m_pCurrentReceiveMessage != NULL) - { - m_pCurrentReceiveMessage->Release(); - m_pCurrentReceiveMessage = NULL; - } -} - -void CServiceNetworkConnection::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CServiceNetworkConnection::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -void CServiceNetworkConnection::Close() -{ - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: close requested", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - m_bCloseRequested = true; - m_bDisableCommunication = true; -} - -void CServiceNetworkConnection::FlushAndClose(const uint32 timeout) -{ - if (!m_bDisableCommunication) - { - // We don't have any messages on the waiting list, we can close immediately - if (m_pSendQueue.empty()) - { - // Normal close - Close(); - } - else - { - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: flush and close requested", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Disable communication layer so no more new messages can be transmitted - m_bDisableCommunication = true; - - // Register in the manager list of connections to close after sending queue is empty - m_pManager->RegisterForDeferredClose(*this, timeout); - } - } -} - -void CServiceNetworkConnection::FlushAndWait() -{ - // Disable communication layer so no more new messages can be transmitted - m_bDisableCommunication = true; - - // Wait for the connection to be empty - while (IsAlive() && !m_pSendQueue.empty()) - { - Sleep(1); - } - - // Resume communication layer - m_bDisableCommunication = false; -} - -const CryGUID& CServiceNetworkConnection::GetGUID() const -{ - return m_connectionID; -} - -const ServiceNetworkAddress& CServiceNetworkConnection::GetRemoteAddress() const -{ - return m_remoteAddress; -} - -const ServiceNetworkAddress& CServiceNetworkConnection::GetLocalAddress() const -{ - return m_localAddress; -} - -void CServiceNetworkConnection::Reset() -{ - if (m_state == eState_Initializing || m_state == eState_Valid) - { - // Close the socket (we wont be able to use it anyway) - if (AZ::AzSock::IsAzSocketValid(m_socket)) - { - AZ::AzSock::Shutdown(m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - // Reset messages buffers pointers - m_messageDataSentSoFar = 0; - m_messageDataReceivedSoFar = 0; - - // release current in-flight message - if (m_pCurrentReceiveMessage != NULL) - { - m_pCurrentReceiveMessage->Release(); - m_pCurrentReceiveMessage = NULL; - } - - // reset reconnection timer - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - m_lastReconnectTime = m_pManager->GetNetworkTime(); - - // we are in the lost state now, we can try to reconnect - m_state = eState_Lost; - - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: LOST!", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } -} - -void CServiceNetworkConnection::Shutdown() -{ - // Close the socket - if (AZ::AzSock::IsAzSocketValid(m_socket)) - { - AZ::AzSock::Shutdown(m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - // Release all pending messages (they wont be sent anyway) - while (!m_pSendQueue.empty()) - { - CServiceNetworkMessage* message = m_pSendQueue.pop(); - message->Release(); - } - - // release current in-flight message - if (m_pCurrentReceiveMessage != NULL) - { - m_pCurrentReceiveMessage->Release(); - m_pCurrentReceiveMessage = NULL; - } - - // Reset internal send/recv state - m_messageDataSentSoFar = 0; - m_messageDataReceivedSoFar = 0; - - // Force the state - m_state = eState_Closed; - - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: CLOSED!", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); -} - -void CServiceNetworkConnection::Update() -{ - const uint64 currentNetworkTime = m_pManager->GetNetworkTime(); - - // We requested to close the socket - if (m_bCloseRequested) - { - m_bCloseRequested = false; - Shutdown(); - return; - } - - // State machine - switch (m_state) - { - // Connection is closed, nothing to do - case eState_Closed: - { - break; - } - - // We are still not initialized fully - case eState_Initializing: - { - // receive messages when waiting for connection - ProcessReceivingQueue(); - - // if we are a client send the connection initialization messages - if (m_endpointType == eEndpoint_Client) - { - // General timeout handling - if (HandleTimeout(currentNetworkTime)) - { - // do not send to often - if ((currentNetworkTime - m_lastInitializationSendTime) > kInitializationPerior) - { - // send the initialization message - if (TryInitialize()) - { - // message was sent, wait a moment before sending next one - m_lastInitializationSendTime = currentNetworkTime; - } - } - } - } - else if (m_endpointType == eEndpoint_Server) - { - // Server side when waiting for full initialization is sending the "keep alive" messages - // Note that we cannot time out on this end - ProcessKeepAlive(); - } - - break; - } - - // Connection is lost - case eState_Lost: - { - // if we are the client endpoint we can try to reconnect to the server - if (m_endpointType == eEndpoint_Client) - { - // do not try to reconnect to often (floods the network) - if ((currentNetworkTime - m_lastReconnectTime) > kReconnectTryPerior) - { - // reset timer - m_lastReconnectTime = currentNetworkTime; - - // try to reconnect - if (TryReconnect()) - { - // put the socket back in non blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, false); - - // give us some slack with timeout after reconnection - m_lastMessageReceivedTime = currentNetworkTime; - - // yeah, we got reconnected, try to reinitialize the connection - m_messageDataReceivedSoFar = 0; - m_state = eState_Initializing; - } - } - } - else if (m_endpointType == eEndpoint_Server) - { - // wait for the reconnection timeout - if ((currentNetworkTime - m_lastMessageReceivedTime) > hReconnectTimeOut) - { - // reconnection time out has occurred - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: reconnection timeout", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Close - Shutdown(); - } - } - - break; - } - - // Valid connection - case eState_Valid: - { - // Is it time to send a keep alive message? - ProcessKeepAlive(); - - // Process the queue of messages - ProcessSendingQueue(); - ProcessReceivingQueue(); - - // General timeout handling - if (m_endpointType == eEndpoint_Client) - { - HandleTimeout(currentNetworkTime); - } - - break; - } - - default: - { - // should not happen - break; - } - } -} - -bool CServiceNetworkConnection::HandleTimeout(const uint64 currentNetworkTime) -{ - // Connections never time out when there is a debugger attached -#if defined(WIN32) || defined(WIN64) - if (IsDebuggerPresent()) - { - // connection is still alive - return true; - } -#endif - - // Connection time out when there is a long time without any activity from server side (no keep alive or other messages) - const uint64 timeSinceLastMessage = currentNetworkTime - m_lastMessageReceivedTime; - if (timeSinceLastMessage > kTimeout) - { - // Connection has timed out - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: timed out", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Put in lost state, wait a while before reconnecting - m_lastReconnectTime = currentNetworkTime; - m_state = eState_Lost; - - // Close the socket now - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - - // Connection was lost - return false; - } - - // Connection still alive - return true; -} - -bool CServiceNetworkConnection::TryInitialize() -{ - // This is sent only be clients trying to establish connection with server - // Connection ID is sent over to the server so he can easily identify re connections (even when port changes) - - // Initialization data header - InitHeader header; - header.m_cmd = eCommand_Initialize; - header.m_pad0 = 0; - header.m_pad1 = 0; - header.m_pad2 = 0; - header.m_tryCount = m_reconnectTryCount; - header.m_guid0 = m_connectionID.lopart; - header.m_guid1 = m_connectionID.hipart; - - // Swap the endianess in header (for sending) - header.Swap(); - - // Try send - const bool autoHandleErrors = false; // we do not need errors here - const uint32 dataLeft = sizeof(header) - m_messageDataSentSoFar; - const uint32 ret = TrySend(&header, dataLeft, autoHandleErrors); - m_messageDataSentSoFar += ret; - - // Full packet was sent - if (m_messageDataSentSoFar == sizeof(header)) - { - // We sent the initialization message - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: init message sent, try counter=%d", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_reconnectTryCount); - - // we sent the initialization packet, reset - m_messageDataSentSoFar = 0; - return true; - } - - // Still not valid - return false; -} - -bool CServiceNetworkConnection::TryReconnect() -{ - // We can't reconnect with disabled communication - if (m_bDisableCommunication) - { - return false; - } - - // Create new socket if needed - if (!AZ::AzSock::IsAzSocketValid(m_socket)) - { - m_socket = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(m_socket)) - { - // We sent the initialization message - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: failed to recreate socket", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - return false; - } - } - - // Translate remote address - AZ::AzSock::AzSocketAddress addr; - TranslateAddress(m_remoteAddress, addr); - - // When reconnecting always use the blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, true); - - // every time we reconnect increment the internal counter so the receiving end (server) - // will be able to identity the up-to-date connection (and discard the older one) - CRY_ASSERT(m_endpointType == eEndpoint_Client); - m_reconnectTryCount += 1; - - // Connect (blocking) - const int result = AZ::AzSock::Connect(m_socket, addr); - if (result == 0) - { - // Spew to log (important info) - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: SUCCESSFULLY RECONNECTED", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // When connected put socket in the non blocking mode - AZ::AzSock::SetSocketBlockingMode(m_socket, false); - - // connected! - return true; - } - - // not connection, should not happen often - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: failed to reconnect", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // still not connected - return false; -} - -void CServiceNetworkConnection::SendKeepAlive(const uint64 currentNetworkTime) -{ - // Keep alive message is just ONE byte (makes it easier) - uint8 message = eCommand_KeepAlive; - if (1 == TrySend(&message, 1, false)) - { - // Throttle the sending - m_lastKeepAliveSendTime = currentNetworkTime; - - // At high verbose level we need even this :) - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: keep alive SENT", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } -} - -void CServiceNetworkConnection::ProcessSendingQueue() -{ - // Get the top message from the send queue - if (NULL == m_pSendedMessages) - { - m_pSendedMessages = m_pSendQueue.pop(); - if (NULL == m_pSendedMessages) - { - return; - } - } - - // Get the size of the data to transmit - const uint32 messageSize = m_pSendedMessages->GetSize(); - const uint32 headerSize = sizeof(Header); - - // Nothing sent yet, send header - if (m_messageDataSentSoFar < headerSize) - { - // prepare header - endian safe - Header header; - header.m_cmd = eCommand_Data; - header.m_size = messageSize; - - // Swap the header for reading - header.Swap(); - - // send the header - const uint32 dataLeft = headerSize - m_messageDataSentSoFar; - const uint32 sent = TrySend((const char*)&header + m_messageDataSentSoFar, dataLeft, true); - m_messageDataSentSoFar += sent; - } - - // Send message data - const uint32 endOfDataOffset = messageSize + headerSize; - if (m_messageDataSentSoFar >= headerSize && m_messageDataSentSoFar < endOfDataOffset) - { - // send and advance - const uint32 dataLeft = endOfDataOffset - m_messageDataSentSoFar; - const uint32 dataOffset = m_messageDataSentSoFar - headerSize; - const uint32 sent = TrySend((const char*)m_pSendedMessages->GetPointer() + dataOffset, dataLeft, true); - m_messageDataSentSoFar += sent; - } - - // All the data from the message was sent, release the message from this queue - // Note: this message may still be in some other sent queues for connections - if (m_messageDataSentSoFar >= endOfDataOffset) - { - // At high verbose level we need even this :) - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: message ID %d (size=%d) removed from queue", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_pSendedMessages->GetId(), - m_pSendedMessages->GetSize()); - - CryInterlockedAdd(&m_sendQueueDataSize, -(int)m_pSendedMessages->GetSize()); - - // stats (not collected in release builds) -#ifndef RELEASE - CryInterlockedIncrement((volatile int*) &m_statsNumPacketsSend); -#endif - - // release local message reference - m_pSendedMessages->Release(); - m_pSendedMessages = NULL; - - // rewind to zero to indicate fresh message - m_messageDataSentSoFar = 0; - } -} - -void CServiceNetworkConnection::ProcessKeepAlive() -{ - const uint64 currentNetworkTime = m_pManager->GetNetworkTime(); - if ((currentNetworkTime - m_lastKeepAliveSendTime) > kKeepAlivePeriod) - { - // Well, if we are in the middle of something make sure we do not interrupt it with KeepAlive - if (m_messageDataSentSoFar == 0) - { - SendKeepAlive(currentNetworkTime); - } - } -} - -void CServiceNetworkConnection::ProcessReceivingQueue() -{ - // To much data already, do not process - const uint32 kReceivedDataLimit = m_pManager->GetReceivedDataQueueLimit(); - if (m_receiveQueueDataSize > kReceivedDataLimit) - { - return; - } - - // Internal offset - const uint32 kOffsetHeader = 1; - const uint32 kOffsetData = 5; - - // Dummy receive - while (m_messageDummyReadLength > 0) - { - // batch size - const uint32 kTempBufferSize = 256; - - // read dummy data - uint8 tempBuffer[ kTempBufferSize ]; - const uint32 maxRead = min(kTempBufferSize, m_messageDummyReadLength); - const uint32 readCount = TryReceive(tempBuffer, maxRead, false); - m_messageDummyReadLength -= readCount; - - // got less - if (readCount < maxRead) - { - break; - } - } - - // Do not process normal messages until we receive all of the bogus data - if (m_messageDummyReadLength > 0) - { - return; - } - - // First byte - header - if (m_messageDataReceivedSoFar == 0) - { - // message header, read type - uint8 messageType = 0; - const int result = TryReceive(&messageType, 1, true); - if (result == 1) - { - // keep alive received, if we are not yet fully initialized it's the signal that we are :) - if (messageType == eCommand_KeepAlive) - { - // we got confirmed by server - if (m_state == eState_Initializing) - { - // change state - CRY_ASSERT(m_endpointType == eEndpoint_Client); - m_state = eState_Valid; - - // At high verbose level we need even this :) - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: connection confirmed by server", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - else - { - // At low-level verbose log even this - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: keep alive RECEIVED", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - - // update the keep alive data timer - m_lastKeepAliveSendTime = m_pManager->GetNetworkTime(); - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - } - else if (messageType == eCommand_Data) - { - // wait for the message length - m_messageReceiveLength = 0; - m_messageDataReceivedSoFar = kOffsetHeader; - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - - // At low-level verbose log even this - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: got data message header", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - else if (messageType == eCommand_Initialize) - { - // let the system process the message - m_messageDummyReadLength = sizeof(InitHeader) - 1; - - // At low-level verbose log even this - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: outdated initheader received", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - } - else - { - // Serious error - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: received invalid command (%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - messageType); - - // reset the connection - Reset(); - } - } - } - - // Message length - if (m_messageDataReceivedSoFar >= kOffsetHeader && m_messageDataReceivedSoFar < kOffsetData) - { - // receive the message length - const uint32 dataOffset = m_messageDataReceivedSoFar - kOffsetHeader; - const uint32 dataLeft = sizeof(uint32) - dataOffset; - const uint32 len = TryReceive((char*)&m_messageReceiveLength + dataOffset, dataLeft, true); - m_messageDataReceivedSoFar += len; - - // Update last message time - if (len > 0) - { - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - } - - // full length received - if (m_messageDataReceivedSoFar == 5) - { - // Swap endianess (for BE platforms) - // NOTE: if this is a little bit confusing, see how the eLittleEndian and eBigEndian are defined - SwapEndian(m_messageReceiveLength, eLittleEndian); - - // Sanity check on the message size - if (m_messageReceiveLength > kMaximumMessageSize) - { - // Serious error - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: unsupported message size (%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_messageReceiveLength); - - Reset(); - } - else if (m_messageReceiveLength > 0) - { - // Create new message that we will add the data into - CRY_ASSERT(m_pCurrentReceiveMessage == NULL); - m_pCurrentReceiveMessage = static_cast< CServiceNetworkMessage* >(m_pManager->AllocMessageBuffer(m_messageReceiveLength)); - CRY_ASSERT(m_pCurrentReceiveMessage != NULL); - - // Serious error - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: created receive buffer ID %d, (size=%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_pCurrentReceiveMessage ? m_pCurrentReceiveMessage->GetId() : 0, - m_messageReceiveLength); - } - } - } - - // Message data - if (m_messageDataReceivedSoFar >= kOffsetData) - { - CRY_ASSERT(m_pCurrentReceiveMessage != NULL); - PREFAST_ASSUME(m_pCurrentReceiveMessage); - - // Message fully received, put in the receive queue (at the end!) - const uint32 dataOffset = m_messageDataReceivedSoFar - kOffsetData; - const uint32 dataLeft = m_pCurrentReceiveMessage->GetSize() - dataOffset; - const uint32 len = TryReceive((char*)m_pCurrentReceiveMessage->GetPointer() + dataOffset, dataLeft, true); - m_messageDataReceivedSoFar += len; - - // connection got lost - if (m_state == eState_Lost) - { - return; - } - - // Update last message time - if (len > 0) - { - m_lastMessageReceivedTime = m_pManager->GetNetworkTime(); - } - - // Full message received! - if (m_messageDataReceivedSoFar == (kOffsetData + m_pCurrentReceiveMessage->GetSize())) - { - // Serious error - LOG_VERBOSE(2, "Connection local='%s', remote='%s', this=%p: full message received(%d), adding to queue", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_pCurrentReceiveMessage->GetSize()); - - // Put in the receive queue, only if no communication is disabled - if (m_bDisableCommunication) - { - m_pCurrentReceiveMessage->Release(); - } - else - { - m_pReceiveQueue.push(m_pCurrentReceiveMessage); - } - - // Stats (not collected in release builds) -#ifndef RELEASE - CryInterlockedIncrement((volatile int*) &m_statsNumPacketsReceived); -#endif - - // Reset - m_pCurrentReceiveMessage = NULL; - m_messageDataReceivedSoFar = 0; - } - } -} - -uint32 CServiceNetworkConnection::TrySend(const void* dataBuffer, uint32 dataSize, bool autoHandleErrors /*=true*/) -{ - // Send the data - const int ret = AZ::AzSock::Send(m_socket, (const char*) dataBuffer, dataSize, 0); - if (AZ::AzSock::SocketErrorOccured(ret)) - { - // We would block, that's not an error - if (ret == static_cast(AZ::AzSock::AzSockError::eASE_EWOULDBLOCK)) - { - return 0; - } - - // Report connection problems - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: send() error: %d", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - ret); - - // Put connection in the lost state - if (autoHandleErrors) - { - Reset(); - } - - // Nothing was sent (according to our logic) - return 0; - } - - // Update stats -#ifndef RELEASE - CryInterlockedAdd((volatile int*) &m_statsNumDataSend, ret); -#endif - - // Return the true amount of data sent - return ret; -} - -uint32 CServiceNetworkConnection::TryReceive(void* dataBuffer, uint32 dataSize, bool autoHandleErrors) -{ - // Send the data - const int ret = AZ::AzSock::Recv(m_socket, (char*) dataBuffer, dataSize, 0); - if (AZ::AzSock::SocketErrorOccured(ret)) - { - // We would block, that's not an error - if (ret == static_cast(AZ::AzSock::AzSockError::eASE_EWOULDBLOCK)) - { - return 0; - } - - // Connection was closed - if (ret == static_cast(AZ::AzSock::AzSockError::eASE_ECONNRESET)) - { - // Report connection problems - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: CLOSED BY PEER", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // Shutdown socket - Shutdown(); - return 0; - } - - // Report connection problems - LOG_VERBOSE(1, "Connection local='%s', remote='%s', this=%p: recv() error: %d", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - ret); - - // Put connection in the lost state - if (autoHandleErrors) - { - Reset(); - } - - // Nothing was sent (according to our logic) - return 0; - } - - // Update stats -#ifndef RELEASE - CryInterlockedAdd((volatile int*) &m_statsNumDataReceived, ret); -#endif - - // Return the true amount of data sent - return ret; -} - -bool CServiceNetworkConnection::SendMsg(IServiceNetworkMessage* message) -{ - // Invalid message - if (NULL == message || message->GetSize() == 0) - { - return false; - } - - // Communication layer is disabled, not possible to send any more messages - if (m_bDisableCommunication) - { - return false; - } - - // Process data size limits - { - const uint32 sizeAfterThisMessage = m_sendQueueDataSize + message->GetSize(); - const uint32 sendQueueLimit = m_pManager->GetSendDataQueueLimit(); - if (sizeAfterThisMessage > sendQueueLimit) - { - // Report connection problems - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: to much data on send queue", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this); - - // To much data on the queue already, we will not be sending this message - return false; - } - - // Keep the local reference so the source data does not get deleted - message->AddRef(); - - // Update the queue data size - CryInterlockedAdd(&m_sendQueueDataSize, message->GetSize()); - - // Append the message to the sending queue - m_pSendQueue.push(static_cast< CServiceNetworkMessage* >(message)); - } - - // Well, we can't tell any more than that - return true; -} - -IServiceNetworkMessage* CServiceNetworkConnection::ReceiveMsg() -{ - // Anything on the queue ? - IServiceNetworkMessage* message = NULL; - if (!m_pReceiveQueue.empty()) - { - message = m_pReceiveQueue.pop(); - - // Report connection problems - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: message ID %d (size=%d) popped by receive end", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - message->GetId(), - message->GetSize()); - } - - return message; -} - -bool CServiceNetworkConnection::IsAlive() const -{ - return m_state != eState_Closed; -} - -uint32 CServiceNetworkConnection::GetMessageSendCount() const -{ - return m_statsNumPacketsSend; -} - -uint32 CServiceNetworkConnection::GetMessageReceivedCount() const -{ - return m_statsNumPacketsReceived; -} - -uint64 CServiceNetworkConnection::GetMessageSendDataSize() const -{ - return m_statsNumDataSend; -} - -uint64 CServiceNetworkConnection::GetMessageReceivedDataSize() const -{ - return m_statsNumDataReceived; -} - -bool CServiceNetworkConnection::HandleReconnect(AZSOCKET socket, const uint32 tryCount) -{ - CRY_ASSERT(m_endpointType == eEndpoint_Server); - - // connection is older - if (tryCount < m_reconnectTryCount) - { - LOG_VERBOSE(3, "Connection local='%s', remote='%s', this=%p: reconnection request OLDER (%d<%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - tryCount, - m_reconnectTryCount); - - return false; - } - - // should not happen - if (tryCount == m_reconnectTryCount) - { - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: reconnection request COLLISION (%d==%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - tryCount, - m_reconnectTryCount); - - return false; - } - - // newer connection, close current socket - AZ::AzSock::Shutdown(m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(m_socket); - - // reset send/receive counters (will resend last message from the queue) - m_messageDataReceivedSoFar = 0; - m_messageDataSentSoFar = 0; - - // Set new socket and update reconnection counter - m_socket = socket; - m_reconnectTryCount = tryCount; - - // revive the connection - m_state = eState_Valid; - - LOG_VERBOSE(0, "Connection local='%s', remote='%s', this=%p: successfull reconnection with counter (%d)", - m_localAddress.ToString().c_str(), - m_remoteAddress.ToString().c_str(), - (UINT_PTR) this, - m_reconnectTryCount); - - // processed - return true; -} - -//----------------------------------------------------------------------------- - -CServiceNetworkListener::CServiceNetworkListener(CServiceNetwork* pManager, AZSOCKET socket, const ServiceNetworkAddress& address) - : m_pManager(pManager) - , m_socket(socket) - , m_localAddress(address) - , m_closeRequestReceived(false) - , m_refCount(1) -{ - LOG_VERBOSE(3, "Listener() local='%s', this=%p", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); -} - -CServiceNetworkListener::~CServiceNetworkListener() -{ - AZ_Assert(!AZ::AzSock::IsAzSocketValid(m_socket), "AZSocket still valid on ServiceNetworkListener destructor"); - - LOG_VERBOSE(3, "~Listener() local='%s', this=%p", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); -} - -void CServiceNetworkListener::Update() -{ - // We requested to close this listener - if (m_closeRequestReceived) - { - LOG_VERBOSE(3, "Listener local='%s', this=%p: closing due to request", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); - - // Close the socket - if (AZ::AzSock::IsAzSocketValid(m_socket)) - { - AZ::AzSock::CloseSocket(m_socket); - m_socket = AZ_SOCKET_INVALID; - } - - // Close all connections - for (TConnectionList::iterator it = m_pLocalConnections.begin(); - it != m_pLocalConnections.end(); ++it) - { - (*it)->Close(); - (*it)->Release(); - } - - m_pLocalConnections.clear(); - m_closeRequestReceived = false; - - return; - } - - // Process connection requests - ProcessIncomingConnections(); - - // Service the pending connection - ProcessPendingConnections(); - - // Remove any local connection that got dead - for (TConnectionList::iterator it = m_pLocalConnections.begin(); - it != m_pLocalConnections.end(); /*++it*/) - { - if (!(*it)->IsAlive()) - { - LOG_VERBOSE(2, "Listener local='%s', this=%p: removing dead connection '%s' (%p)", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - (*it)->GetRemoteAddress().ToString().c_str(), - (UINT_PTR) (*it)); - - (*it)->Release(); - it = m_pLocalConnections.erase(it); - } - else - { - ++it; - } - } -} - -const ServiceNetworkAddress& CServiceNetworkListener::GetLocalAddress() const -{ - return m_localAddress; -} - -uint32 CServiceNetworkListener::GetConnectionCount() const -{ - // not safe ? - return m_pLocalConnections.size(); -} - -IServiceNetworkConnection* CServiceNetworkListener::Accept() -{ - // Look for any connection on the list that is in the "initialized" state - { - CryAutoLock lock(m_accessLock); - for (TConnectionList::iterator it = m_pLocalConnections.begin(); - it != m_pLocalConnections.end(); ++it) - { - // we are looking for connections in the "eState_Initializing" which mean that they are valid but not yet recognized by the outside world - CServiceNetworkConnection* con = (*it); - if (con->m_state == CServiceNetworkConnection::eState_Initializing) - { - LOG_VERBOSE(1, "Listener local='%s', this=%p: accepting connection from '%s' (%p)", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con->GetRemoteAddress().ToString().c_str(), - (UINT_PTR) con); - - // switch state to "valid" - con->m_state = CServiceNetworkConnection::eState_Valid; - - // when returning outside increment the ref count (we still want to keep our internal reference) - con->AddRef(); - return con; - } - } - } - - // No pending connections - return NULL; -} - -bool CServiceNetworkListener::IsAlive() const -{ - return AZ::AzSock::IsAzSocketValid(m_socket); -} - -void CServiceNetworkListener::AddRef() -{ - CryInterlockedIncrement(&m_refCount); -} - -void CServiceNetworkListener::Release() -{ - if (0 == CryInterlockedDecrement(&m_refCount)) - { - delete this; - } -} - -void CServiceNetworkListener::Close() -{ - LOG_VERBOSE(2, "Listener local='%s', this=%p: close requested", - m_localAddress.ToString().c_str(), - (UINT_PTR) this); - - m_closeRequestReceived = true; -} - -void CServiceNetworkListener::ProcessIncomingConnections() -{ - // Accept all possible connections as soon as possible (the connect side is blocking) - for (;; ) - { - // Get the pending connection from TCP/IP layers - AZ::AzSock::AzSocketAddress remoteAddrInet; - AZSOCKET sock = AZ::AzSock::Accept(m_socket, remoteAddrInet); - - // No more connections - if (SocketConnectionsFull(AZ::AzSock::AzSockError(sock))) - { - break; - } - - // Different error - if (!AZ::AzSock::IsAzSocketValid(sock)) - { - // Connection has other problems - LOG_VERBOSE(1, "Listener local='%s', this=%p: accept() error: %d", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - (int)sock); - - break; - } - - // Get the remote address - ServiceNetworkAddress remoteAddress; - TranslateAddress(remoteAddrInet, remoteAddress); - - // Any way create a new pending connection information - PendingConnection* pendingConnection = new PendingConnection; - pendingConnection->m_remoteAddress = remoteAddress; - pendingConnection->m_dataReceivedSoFar = 0; - pendingConnection->m_socket = sock; - - // Connection has other problems - LOG_VERBOSE(2, "Listener local='%s', this=%p: new pending connection from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - remoteAddress.ToString().c_str()); - - // Add to list (not locked because its used only from net thread) - m_pPendingConnections.push_back(pendingConnection); - } -} - -void CServiceNetworkListener::ProcessPendingConnections() -{ - // Process only pending connections, not locked because its used only from net thread - for (TPendingConnectionList::iterator it = m_pPendingConnections.begin(); - it != m_pPendingConnections.end(); /*++it*/) - { - PendingConnection& con = *(*it); - - // Read the incoming data - CRY_ASSERT(con.m_dataReceivedSoFar < sizeof(con.m_initHeader)); - const uint32 dataLeft = sizeof(con.m_initHeader) - con.m_dataReceivedSoFar; - const int size = AZ::AzSock::Recv(con.m_socket, (char*)&con.m_initHeader + con.m_dataReceivedSoFar, dataLeft, 0); - - // The only no-action case: no data yet - if (size == static_cast(AZ::AzSock::AzSockError::eASE_EWOULDBLOCK)) - { - ++it; - continue; - } - - // Something more important - if (AZ::AzSock::SocketErrorOccured(size)) - { - // well, some problem on the way, remove the pending connection from the list (client will resend) - LOG_VERBOSE(1, "Listener local='%s', this=%p: pending connection from '%s' lost: %d", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str(), - (int)size); - } - else - { - // data was received - CRY_ASSERT(size < (int)dataLeft); - con.m_dataReceivedSoFar += size; - - // still not enough data - if (con.m_dataReceivedSoFar < sizeof(con.m_initHeader)) - { - ++it; - continue; - } - - // validate header - if (con.m_initHeader.m_cmd == CServiceNetworkConnection::eCommand_Initialize) - { - // Swap the header after reading - con.m_initHeader.Swap(); - - // Extract the connection ID - const CryGUID connectionId = CryGUID::Construct(con.m_initHeader.m_guid0, con.m_initHeader.m_guid1); - - // try find existing connection with the same connection GUID (reconnection) - CServiceNetworkConnection* existingConnection = NULL; - for (TConnectionList::const_iterator jt = m_pLocalConnections.begin(); - jt != m_pLocalConnections.end(); ++jt) - { - if ((*jt)->GetGUID() == connectionId) - { - existingConnection = *jt; - break; - } - } - - // if existing connection was found that we probably were trying to reconnect - if (existingConnection != NULL) - { - // we already have this connection on our list and we got reconnected with the some GUID - // this usually means that the client has lost communication with server for some time - LOG_VERBOSE(1, "Listener local='%s', this=%p: reconnection from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str()); - - // substitute the connection with newer one (if it is really newer) - if (!existingConnection->HandleReconnect(con.m_socket, con.m_initHeader.m_tryCount)) - { - // well, we didn't use this connect (it was older than the current one, close it) - AZ::AzSock::Shutdown(con.m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(con.m_socket); - } - else - { - // add to global list of active debug connections (so we can start receiving data) - m_pManager->RegisterConnection(*existingConnection); - } - } - else - { - // no previous connection registered, create one now - CServiceNetworkConnection* newConnection = new CServiceNetworkConnection( - m_pManager, - CServiceNetworkConnection::eEndpoint_Server, // this connection is created from listener side which is considered the "server" - con.m_socket, - connectionId, - m_localAddress, - con.m_remoteAddress); - - // this is the first time we see this connection on set the proper connection counter - newConnection->m_reconnectTryCount = con.m_initHeader.m_tryCount; - - // happy moment, log it - LOG_VERBOSE(0, "Listener local='%s', this=%p: confirmed connection from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str()); - - // make sure connection is in valid state - CRY_ASSERT(newConnection->m_state == CServiceNetworkConnection::eState_Initializing); - - // add to local list - CRY_ASSERT(newConnection->IsInitialized() == false); - { - CryAutoLock lock(m_accessLock); - m_pLocalConnections.push_back(newConnection); - newConnection->AddRef(); - } - - // add to global list of active debug connections (so we can start receiving data) - m_pManager->RegisterConnection(*newConnection); - } - } - else - { - // well, some problem on the way, remove the pending connection from the list (client will resend) - LOG_VERBOSE(0, "Listener local='%s', this=%p: invalid connection data received from '%s'", - m_localAddress.ToString().c_str(), - (UINT_PTR) this, - con.m_remoteAddress.ToString().c_str()); - - // close the socket - AZ::AzSock::Shutdown(con.m_socket, SD_BOTH); - AZ::AzSock::CloseSocket(con.m_socket); - } - } - - // any way, delete the connection from the pending list - delete (*it); - it = m_pPendingConnections.erase(it); - } -} - -//----------------------------------------------------------------------------- - -CServiceNetwork::CServiceNetwork() - : m_networkTime(0) - , m_bExitRequested(false) - , m_bufferID(1) -{ - // Create the CVAR - m_pVerboseLevel = gEnv->pConsole->RegisterInt("net_debugVerboseLevel", 0, VF_DEV_ONLY); - - // Send/receive Queue size limits - m_pReceiveDataQueueLimit = gEnv->pConsole->RegisterInt("net_receiveQueueSize", 20 << 20, VF_DEV_ONLY); - m_pSendDataQueueLimit = gEnv->pConsole->RegisterInt("net_sendQueueSize", 5 << 20, VF_DEV_ONLY); - - // Reinitialize the random number generator with independent seed value - m_guidGenerator.Seed((uint32)GetNetworkTime()); - - // Start thread - m_pThread = new TServiceNetworkThread(); - m_pThread->Start(*this); -} - -CServiceNetwork::~CServiceNetwork() -{ - // Signal the network thread to stop - if (NULL != m_pThread) - { - m_pThread->Cancel(); - m_pThread->WaitForThread(); - delete m_pThread; - } - - // Release all closeing connections - for (TConnectionsToCloseArray::const_iterator it = m_connectionsToClose.begin(); - it != m_connectionsToClose.end(); ++it) - { - (*it).pConnection->Release(); - } - - // Release and close all connections - for (TConnectionArray::const_iterator it = m_pConnections.begin(); - it != m_pConnections.end(); ++it) - { - (*it)->Close(); - (*it)->Release(); - } - - // Release all listeners - for (TListenerArray::const_iterator it = m_pListeners.begin(); - it != m_pListeners.end(); ++it) - { - (*it)->Release(); - } - - // Release the CVars - SAFE_RELEASE(m_pVerboseLevel); - SAFE_RELEASE(m_pReceiveDataQueueLimit); - SAFE_RELEASE(m_pSendDataQueueLimit); -} - -#ifndef RELEASE -bool CServiceNetwork::CheckVerbose(const uint32 level) const -{ - const int verboseLevel = m_pVerboseLevel->GetIVal(); - return (int)level < verboseLevel; -} - -void CServiceNetwork::Log(const char* txt, ...) const -{ - // format the print buffer - char buffer[512]; - va_list ap; - va_start(ap, txt); - vsprintf_s(buffer, sizeof(buffer), txt, ap); - va_end(ap); - - // pass to log - gEnv->pLog->LogAlways(buffer); -} -#endif - -void CServiceNetwork::Cancel() -{ - m_bExitRequested = true; - - if (m_pThread) - { - m_pThread->Stop(); - } -} - -void CServiceNetwork::Run() -{ - CryThreadSetName(THREADID_NULL, "ServiceNetworkThread"); - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ServiceNetwork_cpp) -#endif - - TListenerArray updatingListeners; - TConnectionArray updatingConnections; - TConnectionsToCloseArray updatingConnectionsToClose; - - // Process messages - while (!m_bExitRequested) - { - // Well, copy the lists for the duration of update - { - CryAutoLock lock(m_accessMutex); - updatingListeners = m_pListeners; - updatingConnections = m_pConnections; - updatingConnectionsToClose = m_connectionsToClose; - } - - if ((!gEnv) || (!gEnv->pTimer)) - { - Sleep(5); - continue; - } - - // Update network time - m_networkTime = gEnv->pTimer->GetAsyncTime().GetMilliSecondsAsInt64(); - - // Process the listeners (accepts and pending connections) - for (TListenerArray::const_iterator it = updatingListeners.begin(); - it != updatingListeners.end(); ++it) - { - (*it)->Update(); - - // Remove dead listeners from the main list - if (!(*it)->IsAlive()) - { - CryAutoLock lock(m_accessMutex); - - // remove from array - TListenerArray::iterator jt = std::find(m_pListeners.begin(), m_pListeners.end(), *it); - CRY_ASSERT(jt != m_pListeners.end()); - m_pListeners.erase(jt); - - // release internal reference (may delete object if no longer used on main thread) - (*it)->Release(); - } - } - - - // Process the closing connections - for (TConnectionsToCloseArray::const_iterator it = updatingConnectionsToClose.begin(); - it != updatingConnectionsToClose.end(); ++it) - { - const ConnectionToClose& info = *it; - - bool bTimeout = false; - if (info.maxWaitTime && m_networkTime > info.maxWaitTime) - { - bTimeout = true; - } - - // should we close it now ? - if (bTimeout || !it->pConnection->IsAlive() || it->pConnection->IsSendingQueueEmpty()) - { - info.pConnection->Close(); - info.pConnection->Release(); - - // erase from list - { - CryAutoLock lock(m_accessMutex); - for (TConnectionsToCloseArray::iterator jt = m_connectionsToClose.begin(); - jt != m_connectionsToClose.end(); ++jt) - { - if ((*jt).pConnection == info.pConnection) - { - m_connectionsToClose.erase(jt); - break; - } - } - } - } - } - - // Process the connections - for (TConnectionArray::const_iterator it = updatingConnections.begin(); - it != updatingConnections.end(); ++it) - { - (*it)->Update(); - - // Remove dead connections from the main list - if (!(*it)->IsAlive()) - { - CryAutoLock lock(m_accessMutex); - - // remove from array - TConnectionArray::iterator jt = std::find(m_pConnections.begin(), m_pConnections.end(), *it); - CRY_ASSERT(jt != m_pConnections.end()); - m_pConnections.erase(jt); - - // release internal reference (may delete object if no longer used on main thread) - (*it)->Release(); - } - } - - // Internal delay - // TODO: this is guess work right now - Sleep(5); - } -} - -void CServiceNetwork::SetVerbosityLevel(const uint32 level) -{ - // propagate the value to CVar (so it is consistent across the engine) - if (NULL != m_pVerboseLevel) - { - m_pVerboseLevel->Set((int)level); - } -} - -IServiceNetworkMessage* CServiceNetwork::AllocMessageBuffer(const uint32 size) -{ - // Allocate message with new ID - const uint32 bufferID = CryInterlockedIncrement(&m_bufferID); - return new CServiceNetworkMessage(bufferID, size); -} - -IDataWriteStream* CServiceNetwork::CreateMessageWriter() -{ - return new CDataWriteStreamBuffer(); -} - -IDataReadStream* CServiceNetwork::CreateMessageReader(const void* pData, const uint32 dataSize) -{ - if (pData != NULL && dataSize > 0) - { - return new CDataReadStreamMemoryBuffer(pData, dataSize); - } - - return NULL; -} - -ServiceNetworkAddress CServiceNetwork::GetHostAddress(const string& addressString, uint16 optionalPort /*=0*/) const -{ - // cut the address into base and port part - string hostname = addressString.c_str(); - - const int pos = addressString.rfind(':'); - if (pos != -1) - { - // substitute the port number from the part in string - if (optionalPort == 0) - { - const char* portNumberStr = addressString.c_str() + pos + 1; - optionalPort = (uint16)atoi(portNumberStr); - } - - // remove the port part from base address - hostname = addressString.Left(pos); - } - - AZ::AzSock::AzSocketAddress socketAddress; - socketAddress.SetAddress(hostname.c_str(), optionalPort); - - // log on hi verbose mode - LOG_VERBOSE(3, "GetHostAddress(%s) -> %s", addressString.c_str(), socketAddress.GetAddress().c_str()); - - // format the network address - ServiceNetworkAddress out; - TranslateAddress(socketAddress, out); - return out; -} - -IServiceNetworkListener* CServiceNetwork::CreateListener(uint16 localPort) -{ - // Create socket - AZSOCKET createdSocket = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(createdSocket)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): socket() failed: %s", localPort, AZ::AzSock::GetStringForError(createdSocket)); - return NULL; - } - - // Disable merging of small blocks to fight high latency connection - // NOTE: consoles support this mode by default - const int ret3 = AZ::AzSock::EnableTCPNoDelay(createdSocket, true); - if (AZ::AzSock::SocketErrorOccured(ret3)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): setsockopt() failed: %s", localPort, AZ::AzSock::GetStringForError(ret3)); - - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Reuse address - { - const int optRet = AZ::AzSock::SetSocketOption(createdSocket, AZ::AzSock::AzSocketOption::REUSEADDR, true); - if (AZ::AzSock::SocketErrorOccured(optRet)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): setsockopt() (reuse) failed", localPort); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - } - - // Put the listener socket in the non blocking mode - if (!AZ::AzSock::SetSocketBlockingMode(createdSocket, false)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): setsockopt() failed", localPort); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Setup local bind address - AZ::AzSock::AzSocketAddress service; - service.SetAddrPort(localPort); - - // Bind socket - const int ret = AZ::AzSock::Bind(createdSocket, service); - if (AZ::AzSock::SocketErrorOccured(ret)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): bind() failed: %s", localPort, AZ::AzSock::GetStringForError(createdSocket)); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Listen for incoming connection requests on the created socket - const int ret2 = AZ::AzSock::Listen(createdSocket, 64 /*backLogSize*/); - if (AZ::AzSock::SocketErrorOccured(ret2)) - { - // Connection has other problems - LOG_VERBOSE(0, "CreateListener(%d): listen() failed: %s", localPort, AZ::AzSock::GetStringForError(createdSocket)); - - // cleanup - AZ::AzSock::CloseSocket(createdSocket); - return NULL; - } - - // Get our local address - AZ::AzSock::AzSocketAddress localAddressInet; - AZ::AzSock::GetSockName(createdSocket, localAddressInet); - - // Translate to debug network address data - ServiceNetworkAddress localAddress; - TranslateAddress(localAddressInet, localAddress); - - // Spew to log (important info) - LOG_VERBOSE(0, "bind() to '%s'", localAddress.ToString().c_str()); - - // Create the listener wrapper - CServiceNetworkListener* listener = new CServiceNetworkListener(this, createdSocket, localAddress); - - // Listener was created - LOG_VERBOSE(0, "CreateListener(%d): listener created, local address=%s", localPort, listener->GetLocalAddress().ToString().c_str()); - - // Add to list of local listeners - { - CryAutoLock lock(m_accessMutex); - m_pListeners.push_back(listener); - listener->AddRef(); - } - - // Return wrapping interface - return listener; -} - -void CServiceNetwork::RegisterConnection(CServiceNetworkConnection& con) -{ - CryAutoLock lock(m_accessMutex); - - // Make sure to register each connection only once - TConnectionArray::const_iterator it = std::find(m_pConnections.begin(), m_pConnections.end(), &con); - if (it == m_pConnections.end()) - { - // Low-level info - LOG_VERBOSE(3, "RegisterConnection(): registered connection from '%s' to '%s', %p", - con.GetLocalAddress().ToString().c_str(), - con.GetRemoteAddress().ToString().c_str(), - (UINT_PTR) &con); - - // add to connections list, that means we need to also increment the refcount - m_pConnections.push_back(&con); - con.AddRef(); - } -} - -void CServiceNetwork::RegisterForDeferredClose(CServiceNetworkConnection& con, const uint32 timeout) -{ - CryAutoLock lock(m_accessMutex); - - // Low-level info - LOG_VERBOSE(3, "RegisterConnection(): registered connection from '%s' to '%s', %p for defered close, timeout=%d", - con.GetLocalAddress().ToString().c_str(), - con.GetRemoteAddress().ToString().c_str(), - (UINT_PTR) &con, - timeout); - - // Add to connections list, that means we need to also increment the refcount - ConnectionToClose info; - info.pConnection = &con; - info.maxWaitTime = (timeout > 0) ? (GetNetworkTime() + timeout) : 0; - m_connectionsToClose.push_back(info); - - // Keep internal reference - con.AddRef(); -} - -IServiceNetworkConnection* CServiceNetwork::Connect(const ServiceNetworkAddress& remoteAddress) -{ - // Create new socket if needed - AZSOCKET socket = AZ::AzSock::Socket(); - if (!AZ::AzSock::IsAzSocketValid(socket)) - { - // Connection has problems - LOG_VERBOSE(0, "Connect(%s): socket() failed: %s", remoteAddress.ToString().c_str(), AZ::AzSock::GetStringForError(socket)); - return NULL; - } - - // Translate remote address - AZ::AzSock::AzSocketAddress addr; - TranslateAddress(remoteAddress, addr); - - // Spew to log (important info) - LOG_VERBOSE(1, "Connecting to '%s'...", remoteAddress.ToString().c_str()); - - // Connect (blocking) - const int result = AZ::AzSock::Connect(socket, addr); - if (AZ::AzSock::SocketErrorOccured(result)) - { - // Spew to log (important info) - LOG_VERBOSE(0, "connect() to '%s' failed: %s", remoteAddress.ToString().c_str(), AZ::AzSock::GetStringForError(result)); - return NULL; - } - - // Get the address of local socket endpoint - // Get our local address - AZ::AzSock::AzSocketAddress localAddressInet; - AZ::AzSock::GetSockName(socket, localAddressInet); - - // Translate to debug network address data - ServiceNetworkAddress localAddress; - TranslateAddress(localAddressInet, localAddress); - - // Spew to log (important info) - LOG_VERBOSE(1, "connected() from '%s' to '%s'", localAddress.ToString().c_str(), remoteAddress.ToString().c_str()); - - // Allocate some connection ID - const uint64 loPart = m_guidGenerator.GenerateUint64(); - const uint64 hiPart = m_guidGenerator.GenerateUint64(); - const CryGUID connectionID = CryGUID::Construct(loPart, hiPart); - - // Spew to log (important info) - LOG_VERBOSE(3, "New connection GUID: %08x-%08x-%08x-%08x", (uint64)(hiPart >> 32), (uint64)(hiPart & 0xFFFFFFFF), (uint64)(loPart >> 32), (uint64)(loPart & 0xFFFFFFFF)); - - // Create connection wrapper - CServiceNetworkConnection* newConnection = new CServiceNetworkConnection( - this, - CServiceNetworkConnection::eEndpoint_Client, // we are the client, we are connecting to remove destination - socket, - connectionID, - localAddress, - remoteAddress); - - // Add to list of connections - { - CryAutoLock lock(m_accessMutex); - m_pConnections.push_back(newConnection); - - // since we add the object to our internal list keep an extra reference to it - newConnection->AddRef(); - } - - // Well, good luck and have fun :) - return newConnection; -} - -//----------------------------------------------------------------------------- - -// Do not remove (can mess up the uber file builds) -#undef LOG_VERBOSE - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/ServiceNetwork.h b/Code/CryEngine/CrySystem/ServiceNetwork.h deleted file mode 100644 index 23c3500082..0000000000 --- a/Code/CryEngine/CrySystem/ServiceNetwork.h +++ /dev/null @@ -1,475 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Service network implementation - - -#pragma once - - -//----------------------------------------------------------------------------- - -#include "IServiceNetwork.h" -#include - -class CServiceNetwork; - -//----------------------------------------------------------------------------- - -// General message buffer -class CServiceNetworkMessage - : public IServiceNetworkMessage -{ -private: - void* m_pData; - uint32 m_id; - uint32 m_size; - int volatile m_refCount; - -public: - CServiceNetworkMessage(const uint32 id, const uint32 size); - virtual ~CServiceNetworkMessage(); - - // IServiceNetworMessage interface - virtual uint32 GetId() const; - virtual uint32 GetSize() const; - virtual void* GetPointer(); - virtual const void* GetPointer() const; - virtual struct IDataReadStream* CreateReader() const; - virtual void AddRef(); - virtual void Release(); -}; - -//----------------------------------------------------------------------------- - -// General network TCP/IP connection -class CServiceNetworkConnection - : public IServiceNetworkConnection -{ -public: - friend class CServiceNetworkListener; - - // maximum size of a single message (0.5MB by default) - static const uint32 kMaximumMessageSize = 5 << 19; - - // initialization message send period (ms) - static const uint64 kInitializationPerior = 1000; - - // keep alive period (ms), by default every 2s - static const uint64 kKeepAlivePeriod = 2000; - - // reconnection retries period (ms) - static const uint64 kReconnectTryPerior = 1000; - - // timeout for assuming server side connection dead (reconnection timeout) - static const uint64 hReconnectTimeOut = 30 * 1000; - - // communication time out (ms) - static const uint64 kTimeout = 5000; - - // Type of endpoint - enum EEndpoint - { - // This is the server side of the connection (on the side of the listening socket) - eEndpoint_Server, - - // This is the client side of the connection (we connected to the listening socket) - eEndpoint_Client, - }; - - // Internal state machine - enum EState - { - // Connection is initializing - eState_Initializing, - - // Connection is valid - eState_Valid, - - // Operation on the socket failed (we may need to reconnect) - eState_Lost, - - // Connection is closed - eState_Closed, - }; - - // Command IDs, do not change the numerical values - enum ECommand - { - // Data block command - eCommand_Data = 1, - - // Keep alive command - eCommand_KeepAlive = 2, - - // Initialize communication channel (sent only once) - eCommand_Initialize = 3, - }; - - #pragma pack(push) - #pragma pack(1) - - struct Header - { - uint8 m_cmd; - uint32 m_size; - - void Swap(); - }; - - struct InitHeader - { - uint8 m_cmd; - uint8 m_pad0; - uint8 m_pad1; - uint8 m_pad2; - uint32 m_tryCount; - uint64 m_guid0; - uint64 m_guid1; - - void Swap(); - }; - - #pragma pack(pop) - -private: - CServiceNetwork* m_pManager; - - // Type of endpoint (client/server) - EEndpoint m_endpointType; - - // Connection state (internal) - EState m_state; - - // Reference count (updated using CryInterlocked* functions) - int volatile m_refCount; - - // Internal socket data - AZSOCKET m_socket; - - // Local address - ServiceNetworkAddress m_localAddress; - - // Remote connection address - ServiceNetworkAddress m_remoteAddress; - - // Internal connection ID (unique) - CryGUID m_connectionID; - - // Internal time counters - uint64 m_lastReconnectTime; - uint64 m_lastKeepAliveSendTime; - uint64 m_lastMessageReceivedTime; - uint64 m_lastInitializationSendTime; - uint32 m_reconnectTryCount; - - // Statistics (updated from threads using CryIntelocked* functions) - volatile uint32 m_statsNumPacketsSend; - volatile uint32 m_statsNumPacketsReceived; - volatile uint32 m_statsNumDataSend; - volatile uint32 m_statsNumDataReceived; - - // Queue of messages to send (thread access possible) - typedef CryMT::CLocklessPointerQueue< CServiceNetworkMessage > TSendQueue; - CServiceNetworkMessage* m_pSendedMessages; - TSendQueue m_pSendQueue; - uint32 m_messageDataSentSoFar; - volatile int m_sendQueueDataSize; - - // Queue of received message - typedef CryMT::CLocklessPointerQueue< CServiceNetworkMessage > TReceiveQueue; - TReceiveQueue m_pReceiveQueue; - uint32 m_receiveQueueDataSize; - uint32 m_messageDataReceivedSoFar; - uint32 m_messageReceiveLength; - - // Message being received "right now" - CServiceNetworkMessage* m_pCurrentReceiveMessage; - uint32 m_messageDummyReadLength; - - // External request to close this connection was issued - bool m_bCloseRequested; - - // Do not accept any new data for sending or receiving - bool m_bDisableCommunication; - -public: - ILINE bool IsInitialized() const - { - return m_state != eState_Initializing; - } - - ILINE bool IsSendingQueueEmpty() const - { - return m_pSendQueue.empty(); - } - - ILINE CServiceNetwork* GetManager() const - { - return m_pManager; - } - -public: - CServiceNetworkConnection( - class CServiceNetwork* manager, - EEndpoint endpointType, - AZSOCKET socket, - const CryGUID& connectionID, - const ServiceNetworkAddress& localAddress, - const ServiceNetworkAddress& remoteAddress); - - virtual ~CServiceNetworkConnection(); - - // IServiceNetworkConnection interface implementation - virtual const ServiceNetworkAddress& GetRemoteAddress() const; - virtual const ServiceNetworkAddress& GetLocalAddress() const; - virtual const CryGUID& GetGUID() const; - virtual bool IsAlive() const; - virtual uint32 GetMessageSendCount() const; - virtual uint32 GetMessageReceivedCount() const; - virtual uint64 GetMessageSendDataSize() const; - virtual uint64 GetMessageReceivedDataSize() const; - virtual bool SendMsg(IServiceNetworkMessage* message); - virtual IServiceNetworkMessage* ReceiveMsg(); - virtual void FlushAndClose(const uint32 timeout); - virtual void FlushAndWait(); - virtual void Close(); - virtual void AddRef(); - virtual void Release(); - - // All remote connections are updated on the client side - // This is called from service network update thread, try not to call by hand :) - void Update(); - -private: - void ProcessSendingQueue(); - void ProcessReceivingQueue(); - - // Keep alive message handling - void ProcessKeepAlive(); - void SendKeepAlive(const uint64 currentNetworkTime); - bool HandleTimeout(const uint64 currentNetworkTime); - - // Handle the reconnection request - bool HandleReconnect(AZSOCKET socket, const uint32 tryCount); - - // General send/receive functions with error handling. - // If socket error occurs the connection will be put in the lost state. - uint32 TrySend(const void* dataBuffer, uint32 dataSize, bool autoHandleErrors); - - // Internal receive function with error handling - uint32 TryReceive(void* dataBuffer, uint32 dataSize, bool autoHandleErrors); - - // Try to reconnect to the remote address - bool TryReconnect(); - - // Try to send the initialization header - bool TryInitialize(); - - // Low-level socket shutdown (hash way) - void Shutdown(); - - // Reset the connection (put in the lost state and reconnect) - void Reset(); -}; - -//----------------------------------------------------------------------------- - -// TCP/IP listener -class CServiceNetworkListener - : public IServiceNetworkListener -{ - typedef CServiceNetworkConnection::InitHeader TInitHeader; - - struct PendingConnection - { - // Connection socket - AZSOCKET m_socket; - - // Initialization of initialization header received so far - uint32 m_dataReceivedSoFar; - - // Initialization header - TInitHeader m_initHeader; - - // Remote address (as returned from accept) - ServiceNetworkAddress m_remoteAddress; - }; - -protected: - // Owner (the manager) - CServiceNetwork* m_pManager; - - // Reference count, updated using CryInterlocked* functions - int volatile m_refCount; - - // Listening socket - AZSOCKET m_socket; - - // Local address (usually has the IP in 127.0.0.1:port form) - ServiceNetworkAddress m_localAddress; - - // Request to close this listener was received - bool m_closeRequestReceived; - - // Pending connections (but not yet initialized) - typedef std::vector< PendingConnection* > TPendingConnectionList; - TPendingConnectionList m_pPendingConnections; - - // All active connections spawned from this listener - typedef std::vector< CServiceNetworkConnection* > TConnectionList; - TConnectionList m_pLocalConnections; - - // Access lock for the class members (thread safe) - CryMutex m_accessLock; - -public: - ILINE CServiceNetwork* GetManager() const - { - return m_pManager; - } - -public: - CServiceNetworkListener(CServiceNetwork* pManager, AZSOCKET socket, const ServiceNetworkAddress& address); - virtual ~CServiceNetworkListener(); - - void Update(); - - // IServiceNetworkListener interface implementation - virtual const ServiceNetworkAddress& GetLocalAddress() const; - virtual uint32 GetConnectionCount() const; - virtual IServiceNetworkConnection* Accept(); - virtual bool IsAlive() const; - virtual void AddRef(); - virtual void Release(); - virtual void Close(); - -private: - void ProcessIncomingConnections(); - void ProcessPendingConnections(); -}; - -//----------------------------------------------------------------------------- - -// TCP/IP manager for service connection channels -class CServiceNetwork - : public IServiceNetwork - , public CryRunnable -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ServiceNetwork_h) -#endif - -protected: - struct ConnectionToClose - { - CServiceNetworkConnection* pConnection; - - // timeout for forded close - uint64 maxWaitTime; - }; - -protected: - // Local listeners - typedef std::vector< CServiceNetworkListener* > TListenerArray; - TListenerArray m_pListeners; - - // Local connections - typedef std::vector< CServiceNetworkConnection* > TConnectionArray; - TConnectionArray m_pConnections; - - // Connections that are waiting for all of their data to be sent before closing - typedef std::vector< ConnectionToClose > TConnectionsToCloseArray; - TConnectionsToCloseArray m_connectionsToClose; - - // We are running on threads, needed to sync the access to arrays - CryMutex m_accessMutex; - - // Current network time (ms) - uint64 m_networkTime; - - // Exit was requested - bool m_bExitRequested; - - // Message verbose level - ICVar* m_pVerboseLevel; - - // Thread - typedef CryThread< CServiceNetwork > TServiceNetworkThread; - TServiceNetworkThread* m_pThread; - - // Buffer ID allocator (unique, incremented atomically using CryInterlockedIncrement) - volatile int m_bufferID; - - // Random number generator for GUID creation - CRndGen m_guidGenerator; - - // Send/Receive queue size limit - ICVar* m_pReceiveDataQueueLimit; - ICVar* m_pSendDataQueueLimit; - -public: - ILINE const uint64 GetNetworkTime() const - { - return m_networkTime; - } - - ILINE const CServiceNetwork* GetManager() const - { - return this; - } - - ILINE const uint32 GetReceivedDataQueueLimit() const - { - return m_pReceiveDataQueueLimit->GetIVal(); - } - - ILINE const uint32 GetSendDataQueueLimit() const - { - return m_pSendDataQueueLimit->GetIVal(); - } - -public: - CServiceNetwork(); - virtual ~CServiceNetwork(); - - // IServiceNetwork interface implementation - virtual void SetVerbosityLevel(const uint32 level); - virtual IServiceNetworkMessage* AllocMessageBuffer(const uint32 size); - virtual struct IDataWriteStream* CreateMessageWriter(); - virtual struct IDataReadStream* CreateMessageReader(const void* pData, const uint32 dataSize); - virtual ServiceNetworkAddress GetHostAddress(const string& addressString, uint16 optionalPort = 0) const; - virtual IServiceNetworkListener* CreateListener(uint16 localPort); - virtual IServiceNetworkConnection* Connect(const ServiceNetworkAddress& remoteAddress); - - // CryRunnable - virtual void Run(); - virtual void Cancel(); - - // Register connection in the connection list (thread safe) - void RegisterConnection(CServiceNetworkConnection& con); - - // Register connection for closing one all of the outgoing messages are sent - void RegisterForDeferredClose(CServiceNetworkConnection& con, const uint32 timeout); - - // Debug print -#ifdef RELEASE - void Log([[maybe_unused]] const char* txt, ...) const {}; - bool CheckVerbose([[maybe_unused]] const uint32 level) const { return false; } -#else - void Log(const char* txt, ...) const; - bool CheckVerbose(const uint32 level) const; -#endif -}; - -//----------------------------------------------------------------------------- diff --git a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.cpp b/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.cpp deleted file mode 100644 index 9e141cc5a5..0000000000 --- a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.cpp +++ /dev/null @@ -1,787 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#ifdef SOFTCODE_SYSTEM_ENABLED - -#ifndef SOFTCODE_ENABLED -// Even if this module isn't built with SC enabled, if the SC system is enabled we define -// it for this compilation unit to ensure we use the correct versions of the IType* interfaces. - #define SOFTCODE_ENABLED -#endif - -#include "SoftCodeMgr.h" -#include -#include -#include -#include // for function<> in find files - -// This should resolve to "GetTypeLibrary" but we export by ordinal to avoid overheads on 360 -// and keep everything consistent. -static const char* DLL_GETTYPELIBRARY = (LPCSTR)1; - -struct CInstanceData -{ - CInstanceData(void* pInstance, size_t memberCount) - : m_pOldInstance(pInstance) - , m_pNewInstance() - { - m_members.resize(memberCount); - } - - ~CInstanceData() - { - // Delete all members - for (TMemberVec::iterator iter(m_members.begin()); - iter != m_members.end(); - ++iter) - { - // TODO: Safe cross module? Same allocator? Use a Destroy() method? - delete *iter; - } - } - - void* Instance() { return m_pOldInstance; } - - void AddMember(size_t index, IExchangeValue& value) - { - // TODO: Add support for members with same name at different hierarchy levels - assert(m_members[index] == NULL); - assert(index != ~0); - - // Support expansion of m_members during while resolving members - if (index >= m_members.size()) - { - m_members.resize(index + 1); - } - - m_members[index] = value.Clone(); - } - - IExchangeValue* GetMember(size_t index) const - { - assert(index < m_members.size()); - return m_members[index]; - } - - void SetNewInstance(void* pNewInstance) { m_pNewInstance = pNewInstance; } - - void* m_pOldInstance; - void* m_pNewInstance; - - typedef std::vector TMemberVec; - TMemberVec m_members; -}; - - -class CExchanger - : public IExchanger -{ -public: - CExchanger() - : m_pInstanceData() - , m_instanceIndex(~0) - , m_state(eState_ResolvingMembers) - {} - - virtual ~CExchanger() - { - DestroyInstanceData(); - } - - virtual bool IsLoading() const { return m_state >= eState_WritingNewMembers; } - virtual size_t InstanceCount() const { return m_instances.size(); } - - virtual bool BeginInstance(void* pInstance) - { - if (IsLoading()) - { - if (++m_instanceIndex < m_instances.size()) - { - m_pInstanceData = m_instances[m_instanceIndex]; - m_pInstanceData->SetNewInstance(pInstance); - } - else - { - m_pInstanceData = NULL; - } - } - else // Reading/resolving members - { - m_instanceIndex = m_instances.size(); - m_pInstanceData = new CInstanceData(pInstance, m_memberMap.size()); - m_instances.push_back(m_pInstanceData); - } - - return m_pInstanceData != NULL; - } - - virtual bool SetValue(const char* name, IExchangeValue& value) - { - assert(!IsLoading()); - - const size_t index = FindMemberIndex(name); - const bool consumingValue = index != ~0; - - if (consumingValue) - { - m_pInstanceData->AddMember(index, value); - } - - return consumingValue; - } - - virtual IExchangeValue* GetValue(const char* name, void* pTarget, size_t targetSize) - { - assert(IsLoading()); - - const size_t index = FindMemberIndex(name); - - // If member resolved (may not be if restoring to old instances) - if (index != ~0) - { - // If member data available (may not be if member is new) - if (IExchangeValue* pValue = m_pInstanceData->GetMember(index)) - { - if (pValue->GetSizeOf() == targetSize) - { - return pValue; - } - else // Member size mismatch - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "SoftCode: Member %s of instance %p has changed size (old: %d new: %d), setting to default value.", - name, m_pInstanceData->Instance(), (int)pValue->GetSizeOf(), (int)targetSize); - } - } - else // Member unknown - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - "SoftCode: Member %s (of instance %p) appears to be new.", - name, m_pInstanceData->Instance()); - - // TODO: Could attempt to validate against a known wipe pattern ie. 0xfefefefe - // This could catch most uninitialized variables... - - if (targetSize <= sizeof(void*)) - { - switch (targetSize) - { - case 1: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %d", *reinterpret_cast(pTarget)); - break; - case 2: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %04x", *reinterpret_cast(pTarget)); - break; - case 4: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %08x", *reinterpret_cast(pTarget)); - break; - case 8: - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %llx", *reinterpret_cast(pTarget)); - break; - } - } - } - } - - // Indicate value should be default constructed - return NULL; - } - - // Used once required members have been established, members not already - // encountered will be ignored. - void LockMemberSet() - { - assert(m_state == eState_ResolvingMembers); - - DestroyInstanceData(); - m_state = eState_ReadingOldMembers; - } - - // Rewinds instance data and prepare for loading - void RewindForLoading() - { - assert(m_state == eState_ReadingOldMembers); - - m_pInstanceData = NULL; - m_instanceIndex = ~0; - m_state = eState_WritingNewMembers; - } - - // Rewinds instance data to prepare to restore old members (UNDO) - void RewindForRestore() - { - assert(m_state == eState_WritingNewMembers); - - m_pInstanceData = NULL; - m_instanceIndex = ~0; - m_state = eState_RestoringOldMembers; - } - - void NotifyListenerOfReplacements(ISoftCodeListener* pListener) - { - for (TInstanceVec::const_iterator iter(m_instances.begin()); iter != m_instances.end(); ++iter) - { - CInstanceData* pInstanceData = *iter; - pListener->InstanceReplaced(pInstanceData->m_pOldInstance, pInstanceData->m_pNewInstance); - } - } - -private: - void DestroyInstanceData() - { - m_pInstanceData = NULL; - m_instanceIndex = ~0; - - for (TInstanceVec::iterator iter(m_instances.begin()); iter != m_instances.end(); ++iter) - { - delete *iter; - } - - m_instances.resize(0); - } - - inline size_t FindMemberIndex(const string& memberName) - { - size_t index = ~0; - - // If needed members have been resolved - if (m_state != eState_ResolvingMembers) - { - TMemberMap::const_iterator iter(m_memberMap.find(memberName)); - if (iter != m_memberMap.end()) - { - index = iter->second; - } - } - else // Add this member to the map with a new index - { - // Ensure there's no member name duplicates - assert(m_memberMap.find(memberName) == m_memberMap.end()); - - // A new entry - index = m_memberMap.size(); - size_t& newIndex = m_memberMap[memberName]; - newIndex = index; - } - - return index; - } - -private: - CInstanceData* m_pInstanceData; - size_t m_instanceIndex; - - typedef std::vector TInstanceVec; - TInstanceVec m_instances; - - // Maps instance members to offsets in instance member vectors - typedef std::map TMemberMap; - TMemberMap m_memberMap; - - enum EState - { - eState_ResolvingMembers = 0, // Record new member names as found - eState_ReadingOldMembers, // Scrape requested member data from old instances - eState_WritingNewMembers, // Write old member data to new instances - eState_RestoringOldMembers, // Restore scraped values to old instances (UNDO) - }; - - EState m_state; -}; - - -// ---- - -DynamicTypeLibrary::DynamicTypeLibrary(const char* name) - : m_name(name) - , m_listeners(1) -{} - -const char* DynamicTypeLibrary::GetName() -{ - return m_name; -} - -void* DynamicTypeLibrary::CreateInstanceVoid(const char* typeName) -{ - TTypeMap::const_iterator typeIter(m_types.find(typeName)); - if (typeIter != m_types.end()) - { - ITypeRegistrar* pRegistrar = typeIter->second; - return pRegistrar->CreateInstance(); - } - - return NULL; -} - -void DynamicTypeLibrary::SetOverride(ITypeLibrary* /*pOverrideLib*/) -{ - CryFatalError("Unsupported: Attempting to SetOverride on a DynamicTypeLibrary!"); -} - -size_t DynamicTypeLibrary::GetTypes([[maybe_unused]] ITypeRegistrar** ppRegistrar, [[maybe_unused]] size_t& count) const -{ - CryFatalError("Unsupported: Attempting to GetTypes on a DynamicTypeLibrary!"); - return 0; -} - -void DynamicTypeLibrary::AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) -{ - // This DynamicTypeLibrary could have been created by this listener request - // So ensure we have a name...! - if (!m_name) - { - m_name = libraryName; - } - - m_listeners.Add(pListener, listenerName); -} - -void DynamicTypeLibrary::RemoveListener(ISoftCodeListener* pListener) -{ - m_listeners.Remove(pListener); -} - -void DynamicTypeLibrary::IntegrateLibrary(ITypeLibrary* pLib, bool isDefault) -{ - typedef std::vector TTypeVec; - - // Resolve our name if we haven't already - if (!m_name) - { - m_name = pLib->GetName(); - } - - // Override the new lib immediately - pLib->SetOverride(this); - - // Query the new library for its types - size_t typeCount = 0; - pLib->GetTypes(NULL, typeCount); - if (typeCount > 0) - { - TTypeVec typeVec; - typeVec.resize(typeCount); - pLib->GetTypes(&(typeVec.front()), typeCount); - - if (!isDefault) - { - CryLogAlways("SoftCode: Integrating %d new types defined in %s...", (int)typeCount, m_name); - } - - // Attempt to integrate each type found - for (TTypeVec::iterator typeIter(typeVec.begin()); typeIter != typeVec.end(); ++typeIter) - { - IntegrateType(*typeIter, isDefault); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: New %s library has no registered types. Nothing to integrate.", pLib->GetName()); - } -} - -ITypeRegistrar* DynamicTypeLibrary::FindTypeForInstance(void* pInstance) const -{ - for (TTypeMap::const_iterator iter(m_types.begin()); iter != m_types.end(); ++iter) - { - ITypeRegistrar* pType = iter->second; - if (pType->HasInstance(pInstance)) - { - return pType; - } - } - - return NULL; -} - -void DynamicTypeLibrary::IntegrateType(ITypeRegistrar* pType, bool isDefault) -{ - const char* typeName = pType->GetName(); - - // If there's an existing registrar - ITypeRegistrar* pExistingType = m_types[typeName]; - assert(pExistingType != pType); // Sanity check - - // If the new type is the default (built-in) type but it's already been overridden - if (isDefault && pExistingType) - { - return; // Nothing to do - } - // TODO: Inform listeners that there's a new library available - // and ask if we should use it immediately or defer - - CExchanger exchanger; - - // If the type can be safely created, visited and destroyed - if (EvaluateType(pType, exchanger)) - { - // Override the type - m_types[typeName] = pType; - - if (!isDefault) - { - CryLogAlways("SoftCode: Overridden %s in library %s", typeName, m_name); - } - - const size_t instanceCount = (pExistingType) ? pExistingType->InstanceCount() : 0; - - // If there are any existing instances - if (instanceCount > 0) - { - CryLogAlways("SoftCode: Attempting to exchange %d %s instances to the new version...", (int)instanceCount, typeName); - - // Read instance members for type (removes data for resolved members) - if (pExistingType->ExchangeInstances(exchanger)) - { - exchanger.RewindForLoading(); - - // Write instance members for type - if (pType->ExchangeInstances(exchanger)) - { - // Success! Tell the listeners to fix up their pointers - for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next()) - { - exchanger.NotifyListenerOfReplacements(*notifier); - } - - CryLogAlways("SoftCode: %d %s instances successfully overridden to latest!", (int)instanceCount, typeName); - - // Clean up old instances - if (!pExistingType->DestroyInstances()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: Failed to destroy old instances of type %s - leak probable.", typeName); - } - } - else // Failed to create & write into new instances - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to create and write into new instances of %s. Attempting restore of old instances...", typeName); - if (!pType->DestroyInstances()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: Failed to destroy new instances of type %s - leak probable.", typeName); - } - - // Restore the original type library as the active one - m_types[typeName] = pExistingType; - - // Attempt to restore the old instances with their original data - exchanger.RewindForRestore(); - if (pExistingType->ExchangeInstances(exchanger)) - { - CryLogAlways("SoftCode: Type %s in library %s successfully restored to previous revision!", typeName, m_name); - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Restore of old %s instances failed. State now undefined!", typeName); - } - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to read members on %s", typeName); - } - } - } -} - -bool DynamicTypeLibrary::EvaluateType(ITypeRegistrar* pType, CExchanger& exchanger) -{ - // Try a full object life-time with a single instance of the - // new type before attempting a member exchange. This also allow the - // exchanger to determine the required members to be removed from the - // old instances. - bool testPassed = false; - - // Create a single test instance of the type - if (pType->CreateInstance()) - { - // Read the instance members (also prepares the exchanger member set) - if (pType->ExchangeInstances(exchanger)) - { - // Destroy the old instance - if (pType->DestroyInstances()) - { - // Indicate required members are now resolved - exchanger.LockMemberSet(); - testPassed = true; - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to destroy test instance of type: %s. New type will be skipped.", pType->GetName()); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to read members in test instance of type: %s. New type will be skipped.", pType->GetName()); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to create test instance of type: %s. New type will be skipped.", pType->GetName()); - } - - return testPassed; -} - -// ---- - -// The export we expect to find in the SoftCode modules -typedef ITypeLibrary* (__stdcall * TGetTypeLibraryFcn)(); - -static void SoftCode_UpdateCmd([[maybe_unused]] IConsoleCmdArgs* pArgs) -{ - gEnv->pSoftCodeMgr->LoadNewModules(); -} - -static int g_autoUpdatePeriod = 0; - -SoftCodeMgr::SoftCodeMgr() -{ - REGISTER_CVAR2("sc_autoupdate", &g_autoUpdatePeriod, 5, VF_CHEAT, "Set the auto-update poll period for new SoftCode modules. Set to zero to disable"); - REGISTER_COMMAND("sc_update", reinterpret_cast(&SoftCode_UpdateCmd), VF_CHEAT, "Loads any new SoftCode modules"); - - // Clear out any old modules - { - typedef std::vector TStringVec; - TStringVec filePaths; - - if (FindSoftCodeFiles("*", filePaths) > 0) - { - for (TStringVec::const_iterator iter(filePaths.begin()); iter != filePaths.end(); ++iter) - { - if (!DeleteFile(iter->c_str())) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to clean %s", iter->c_str()); - } - } - } - } -} - -SoftCodeMgr::~SoftCodeMgr() -{ - if (gEnv->pConsole) - { - gEnv->pConsole->RemoveCommand("sc_update"); - gEnv->pConsole->UnregisterVariable("sc_autoupdate"); - } -} - -// Used to register built-in libraries on first use -void SoftCodeMgr::RegisterLibrary(ITypeLibrary* pDefaultLib) -{ - DynamicTypeLibrary& typeLib = m_libraryMap[pDefaultLib->GetName()]; - typeLib.IntegrateLibrary(pDefaultLib, true); -} - -// Look for new SoftCode modules and load them, adding their types to the registry -void SoftCodeMgr::LoadNewModules() -{ - typedef std::vector TStringVec; - typedef TStringVec::const_iterator TModuleIter; - TStringVec modulePaths; - - // Find modules - FindSoftCodeFiles("*.dll", modulePaths); - - for (TModuleIter libIter(modulePaths.begin()); libIter != modulePaths.end(); ++libIter) - { - const char* moduleName = libIter->c_str(); - LoadModule(moduleName); - } -} - -void SoftCodeMgr::AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) -{ - // Find an existing lib or create a new one to add the listener to - DynamicTypeLibrary& lib = m_libraryMap[libraryName]; - lib.AddListener(libraryName, pListener, listenerName); -} - -void SoftCodeMgr::RemoveListener(const char* libraryName, ISoftCodeListener* pListener) -{ - TLibMap::iterator iter(m_libraryMap.find(libraryName)); - - if (iter != m_libraryMap.end()) - { - iter->second.RemoveListener(pListener); - } -} - -// To be called regularly to poll for library updates -void SoftCodeMgr::PollForNewModules() -{ - if (g_autoUpdatePeriod > 0) - { - const CTimeValue frameStartTime(gEnv->pTimer->GetFrameStartTime(ITimer::ETIMER_UI)); - if (m_nextAutoCheckTime <= frameStartTime) - { - m_nextAutoCheckTime.SetSeconds((int64)g_autoUpdatePeriod); - m_nextAutoCheckTime += frameStartTime; - - // Attempt to find and load any new modules - LoadNewModules(); - } - } -} - -namespace -{ - // Util - class InstanceFixup - : public ISoftCodeListener - { - public: - InstanceFixup(void* pOldInstance) - : m_pOldInstance(pOldInstance) - , m_pNewInstance() {} - - virtual void InstanceReplaced(void* pOldInstance, void* pNewInstance) - { - if (m_pOldInstance == pOldInstance) - { - m_pNewInstance = pNewInstance; - } - } - - void* NewInstance() const { return m_pNewInstance; } - - private: - void* m_pOldInstance; - void* m_pNewInstance; - }; -} - -// Stops thread execution until a new SoftCode module is available -void* SoftCodeMgr::WaitForUpdate(void* pInstance) -{ - DynamicTypeLibrary* pOwningLib = NULL; - ITypeRegistrar* pOldType = NULL; - - // Find existing instance - for (TLibMap::iterator libIter(m_libraryMap.begin()); libIter != m_libraryMap.end(); ++libIter) - { - DynamicTypeLibrary& lib = libIter->second; - if (ITypeRegistrar* pType = lib.FindTypeForInstance(pInstance)) - { - pOwningLib = &lib; - pOldType = pType; - break; - } - } - - if (!pOwningLib) - { - CryFatalError("SoftCode: Attempting to wait for update on an unknown instance!"); - return NULL; - } - - InstanceFixup instanceFixup(pInstance); - pOwningLib->AddListener(pOwningLib->GetName(), &instanceFixup, "InstanceFixup"); - - while (true) - { - // Find and load new modules - LoadNewModules(); - - // Got a new instance? - if (instanceFixup.NewInstance()) - { - break; - } - - // Wait for a new module - CryLogAlways("SoftCode: Pausing execution until class %s in %s library is updated...", pOldType->GetName(), pOwningLib->GetName()); - __debugbreak(); // Stopped here? Check your log! - } - - pOwningLib->RemoveListener(&instanceFixup); - - return instanceFixup.NewInstance(); -} - -bool SoftCodeMgr::LoadModule(const char* moduleName) -{ - bool success = false; - - // If module not yet loaded - if (m_loadedSet.find(moduleName) == m_loadedSet.end()) - { - m_loadedSet.insert(moduleName); - - CryLogAlways("SoftCode: Found new module %s, attempting to load...", moduleName); - - HMODULE hModule = CryLoadLibrary(moduleName); - - if (hModule) - { - TGetTypeLibraryFcn pGetTypeLibraryFcn = reinterpret_cast(GetProcAddress(hModule, DLL_GETTYPELIBRARY)); - if (pGetTypeLibraryFcn) - { - // Add to list of loaded libs & override any earlier TypeLibraries already registered - ITypeLibrary* pTypeLibrary = pGetTypeLibraryFcn(); - if (pTypeLibrary) - { - const char* libraryName = pTypeLibrary->GetName(); - m_libraryMap[libraryName].IntegrateLibrary(pTypeLibrary, false); - - CryLogAlways("SoftCode: Loaded new type library \"%s\" from module %s.", libraryName, moduleName); - success = true; - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to resolve GetTypeLibrary() export in: %s (error: %x)", moduleName, GetLastError()); - } - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load: %s (error: %x)", moduleName, GetLastError()); - } - } - - return success; -} - -size_t SoftCodeMgr::FindSoftCodeFiles(const string& searchName, std::vector& foundPaths) const -{ - foundPaths.clear(); - - stack_string scSoftCodeDir; - - TCHAR modulePath[MAX_PATH]; - GetModuleFileName(NULL, modulePath, sizeof(modulePath)); - scSoftCodeDir = PathUtil::GetParentDirectory(modulePath); - scSoftCodeDir += "\\SoftCode\\"; - - - gEnv->pFileIO->FindFiles(scSoftCodeDir.c_str(), searchName, [&](const char* filePath) -> bool - { - if (!gEnv->pFileIO->IsDirectory(filePath) && !gEnv->pFileIO->IsReadOnly(filePath)) - { - foundPaths.push_back(filePath); - } - - // Keep asking for more files, no early out - return true; - }); - - // Sort the paths into name order - std::sort(foundPaths.begin(), foundPaths.end()); - - return foundPaths.size(); -} - -#endif // SOFTCODE_ENABLED diff --git a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.h b/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.h deleted file mode 100644 index f3f1b931a5..0000000000 --- a/Code/CryEngine/CrySystem/SoftCode/SoftCodeMgr.h +++ /dev/null @@ -1,111 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H -#define CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H -#pragma once - -#include - -#include "ISoftCodeMgr.h" - -struct ITypeLibrary; -struct ITypeRegistrar; -class CExchanger; - -// Internal: Performs the dynamic type management needed for SoftCoding -class DynamicTypeLibrary - : public ITypeLibrary -{ -public: - DynamicTypeLibrary(const char* name = NULL); - - // ITypeLibrary impl. - virtual const char* GetName(); - virtual void* CreateInstanceVoid(const char* typeName); - virtual void SetOverride(ITypeLibrary* pOverrideLib); - virtual size_t GetTypes(ITypeRegistrar** ppRegistrar, size_t& count) const; - - void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName); - void RemoveListener(ISoftCodeListener* pListener); - - // Attempts to add the library types the active set - void IntegrateLibrary(ITypeLibrary* pLib, bool isDefault); - - ITypeRegistrar* FindTypeForInstance(void* pInstance) const; - -private: - // Attempts to add the type the active set - void IntegrateType(ITypeRegistrar* pType, bool isDefault); - // Ensure the type can be safely created, visited, destroyed and prep exchanger - bool EvaluateType(ITypeRegistrar* pType, CExchanger& exchanger); - -private: - typedef std::vector TLibVec; - typedef std::map TTypeMap; - typedef CListenerSet TListeners; - - // The current set of active types - std::map m_types; - // Current set of loaded libraries - TLibVec m_history; - // Set of listeners to SC changes - TListeners m_listeners; - - const char* m_name; // Supplied by the first real library that registers -}; - - -// Implements the global singleton responsible for SoftCode management -class SoftCodeMgr - : public ISoftCodeMgr -{ -public: - SoftCodeMgr(); - virtual ~SoftCodeMgr(); - - // Used to register built-in libraries on first use - virtual void RegisterLibrary(ITypeLibrary* pLib); - - // Look for new SoftCode modules and load them, adding their types to the registry - virtual void LoadNewModules(); - - virtual void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName); - virtual void RemoveListener(const char* libraryName, ISoftCodeListener* pListener); - - // To be called regularly to poll for library updates - virtual void PollForNewModules(); - - // Stops thread execution until a new SoftCode module is available - virtual void* WaitForUpdate(void* pInstance); - -private: - bool LoadModule(const char* moduleName); - size_t FindSoftCodeFiles(const string& searchName, std::vector& foundPaths) const; - -private: - typedef std::map TLibMap; - typedef std::set TLoadedLibSet; - - // Records the history for each TypeLibrary keyed by library name - TLibMap m_libraryMap; - - // Records the library files already loaded - TLoadedLibSet m_loadedSet; - - // Used to determine when the next auto-update will occur - CTimeValue m_nextAutoCheckTime; -}; - - -#endif // CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp b/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp deleted file mode 100644 index 4344af45dc..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.cpp +++ /dev/null @@ -1,410 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#include "CrySystem_precompiled.h" -#include -#include - -#include "AZRequestReadStream.h" -#include -#include -#include -#include "StreamEngine.h" - -AZRequestReadStream* AZRequestReadStream::Allocate(const EStreamTaskType tSource, const char* filename, IStreamCallback* callback, - const StreamReadParams* params) -{ - //Once an async method is available to read file sizes this code should be removed: - // and the file size should be known before calling this method and pass it as a - // parameter to this method. - //REMOVE In the Future START. - AZ::IO::SizeType fileSize = 0; - if (params && params->nSize) - { - fileSize = params->nSize; - } - else - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::Result res = fileIO->Size(filename, fileSize); - if (!res) - { - AZ_Error("AZRequestReadStream", false, "Failed to read file size of %s", filename); - return nullptr; - } - //REMOVE In the Future END. - } - - auto streamer = AZ::Interface::Get(); - - AZRequestReadStream* retReq; - retReq = aznew AZRequestReadStream(); - - retReq->m_Type = tSource; - retReq->m_fileName = filename; - retReq->m_callback = callback; - retReq->m_fileSize = fileSize; - //REMARK: if params->pBuffer is NOT NULL, then retReq->m_buffer - //should become params->pBuffer, this is called stream-in-place. - //The only reason we are not doing this here is because - //some platforms support stream-in-place to WRITE ONLY buffers. - //Because there are no guarantees that low level streaming and decompression apis - //would treat the output buffer as WRITE ONLY, we still allocate the buffer and memcpy - //to params->pBuffer upon the completion callback being called. - //Once LY-98089 is complete/fixed, we should be able to safely - //set retReq->m_buffer = params->pBuffer and skip the memory allocation. - retReq->m_buffer = azmalloc(fileSize, streamer->GetRecommendations().m_memoryAlignment); - if (params) - { - retReq->m_params = *params; - } - - return retReq; -} - -////////////////////////////////////////////////////////////////////////// -AZRequestReadStream::AZRequestReadStream() : m_fileName(""), m_fileRequest(nullptr), - m_buffer(nullptr), m_Type(eStreamTaskTypeTexture), - m_callback(nullptr), m_fileSize(0), m_numBytesRead(0), m_isAsyncCallbackExecuted(false), - m_isSyncCallbackExecuted(false), m_isFileRequestComplete(false), m_isError(false), m_isFinished(false), - m_IOError(0) -{ - AZStd::atomic_init(&m_refCount, 0); - m_params = StreamReadParams(); -} - -////////////////////////////////////////////////////////////////////////// -AZRequestReadStream::~AZRequestReadStream() -{ - azfree(m_buffer); -} - -// tries to stop reading the stream; this is advisory and may have no effect -// all the callbacks will be called after this. If you just destructing object, -// dereference this object and it will automatically abort and release all associated resources. -void AZRequestReadStream::Abort() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - // Increase ref counting to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (m_isFileRequestComplete || m_isError) - { - // It is possible the file I/O request to be completed by AZ::IO::Streamer, - // but if the completion callback is deferred for the main thread then - // the stream is not finished. So, only if it is finished then - // it is safe to do nothing. - if (m_isFinished) - { - return; - } - } - - m_isError = true; - m_IOError = ERROR_USER_ABORT; - m_isFileRequestComplete = true; - m_numBytesRead = 0; - - if (m_fileRequest) - { - auto streamer = AZ::Interface::Get(); - streamer->QueueRequest(streamer->Cancel(m_fileRequest)); - } - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_callback = nullptr; - } - -} - -bool AZRequestReadStream::TryAbort() -{ - // Increase ref counting to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (!m_callbackLock.TryLock()) - { - return false; - } - - if (m_isFileRequestComplete || m_isError) - { - // It is possible the file I/O request to be completed by AZ::IO::Streamer, - // but if the completion callback is deferred for the main thread then - // the stream is not finished. So, only if it is finished then - // it is safe to do nothing. - if (m_isFinished) - { - m_callbackLock.Unlock(); - return false; - } - } - - m_isError = true; - m_IOError = ERROR_USER_ABORT; - m_isFileRequestComplete = true; - m_numBytesRead = 0; - - if (m_fileRequest) - { - auto streamer = AZ::Interface::Get(); - streamer->QueueRequest(streamer->Cancel(m_fileRequest)); - } - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_callback = nullptr; - - m_callbackLock.Unlock(); - - return true; -} - -// tries to raise the priority of the read; this is advisory and may have no effect -void AZRequestReadStream::SetPriority(EStreamTaskPriority ePriority) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (m_params.ePriority != ePriority) - { - m_params.ePriority = ePriority; - if (m_fileRequest) - { - AZ::Interface::Get()->RescheduleRequest(m_fileRequest, AZ::IO::IStreamerTypes::s_noDeadline, - CStreamEngine::CryStreamPriorityToAZStreamPriority(ePriority)); - } - } -} - -// unconditionally waits until the callback is called -// i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback -// is called before return from this function (unless no callback was specified) -void AZRequestReadStream::Wait(int maxWaitMillis) -{ - // lock this object to avoid preliminary destruction - AZRequestReadStream_AutoPtr refCountLock(this); - - if (!m_isFinished && !m_isError && !m_fileRequest) - { - AZ_Error("AZRequestReadStream", false, "Stream for file %s is unwaitable", m_fileName.c_str()); - return; - } - - if (maxWaitMillis > 0) - { - m_wait.try_acquire_for(AZStd::chrono::milliseconds(maxWaitMillis)); - } - else - { - m_wait.acquire(); - } -} - -////////////////////////////////////////////////////////////////////////// -const char* AZRequestReadStream::GetErrorName() const -{ - switch (m_IOError) - { - case ERROR_UNKNOWN_ERROR: - return "Unknown error"; - case ERROR_UNEXPECTED_DESTRUCTION: - return "Unexpected destruction"; - case ERROR_INVALID_CALL: - return "Invalid call"; - case ERROR_CANT_OPEN_FILE: - return "Cannot open the file"; - case ERROR_REFSTREAM_ERROR: - return "Refstream error"; - case ERROR_OFFSET_OUT_OF_RANGE: - return "Offset out of range"; - case ERROR_REGION_OUT_OF_RANGE: - return "Region out of range"; - case ERROR_SIZE_OUT_OF_RANGE: - return "Size out of range"; - case ERROR_CANT_START_READING: - return "Cannot start reading"; - case ERROR_OUT_OF_MEMORY: - return "Out of memory"; - case ERROR_ABORTED_ON_SHUTDOWN: - return "Aborted on shutdown"; - case ERROR_OUT_OF_MEMORY_QUOTA: - return "Out of memory quota"; - case ERROR_ZIP_CACHE_FAILURE: - return "ZIP cache failure"; - case ERROR_USER_ABORT: - return "User aborted"; - } - return "Unrecognized error"; -} - -int AZRequestReadStream::AddRef() -{ - return m_refCount.fetch_add(1) + 1; -} - -int AZRequestReadStream::Release() -{ - int refCount = m_refCount.fetch_sub(1); - -#ifndef _RELEASE - if (refCount < 1) - { - __debugbreak(); - } -#endif - - if (refCount == 1) - { - //UNUSUAL, yet necessary. - //Why "delete this"? - //So, AZRequestReadStream is a replacement of CReadStream. The original design of - //Cry Texture Mips Streaming makes use of CReadStream through IReadStreamPtr, which - //is a smart pointer design that calls AddRef() and Release() but never calls "delete", - //like AZStd::shared_ptr<> does. This means the original Cry design had a memory leak - //because it never called delete on IReadStream objects. If you look at the original - //code of CReadStream (StreamReadStream.cpp) , the static Allocate method has two paths - //to allocate memory, one used a stack based memory allocation hack, and the other path - //was doing a "new CReadStream". Using VS2017 debugger I found both paths to be used, but - //"delete" and hence the destructor of CReadStream is never called causing minor memory leaks. - //The best solution I found was to call "delete this" here and later when we chnage IReadStreamPtr - //for AZstd::smart_ptr then AddRef() and Release() won't be needed anymore and this "delete this" - //hack won't be necessary either. - delete this; - } - - return refCount - 1; -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::ExecuteAsyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_isAsyncCallbackExecuted && m_callback) - { - m_isAsyncCallbackExecuted = true; - m_callback->StreamAsyncOnComplete(this, m_IOError); - } -} - -void AZRequestReadStream::ExecuteSyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_isSyncCallbackExecuted && m_callback && (0 == (m_params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK))) - { - m_isSyncCallbackExecuted = true; - - AZRequestReadStream_AutoPtr refCountLock(this); // Stream can be freed inside the callback! - - m_callback->StreamOnComplete(this, m_IOError); - - m_isFinished = true; - FreeTemporaryMemory(); - } - -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::FreeTemporaryMemory() -{ - // Make sure m_buffer is not freed if the file request is still in flight, as Streamer can still write to m_buffer in that case - if (!m_fileRequest || AZ::Interface::Get()->HasRequestCompleted(m_fileRequest)) - { - azfree(m_buffer); - m_buffer = nullptr; - m_numBytesRead = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -void AZRequestReadStream::OnRequestComplete(AZ::IO::SizeType numBytesRead, [[maybe_unused]] void* buffer, AZ::IO::IStreamerTypes::RequestStatus requestState) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (!m_isFileRequestComplete) - { - switch (requestState) - { - case AZ::IO::IStreamerTypes::RequestStatus::Completed: - m_IOError = 0; - m_numBytesRead = static_cast(numBytesRead); - m_isError = false; - if (m_params.pBuffer) - { - //In some systems, streaming-in-place is supported. The caveat - //is that in some cases, the destination buffer is write-only. This is why - //a final memcpy must be done here until support is added to AZ::IO::Streamer API - //to decompress/load data into write-only buffers. SEE: LY-98089 - AZ_Assert(m_params.pBuffer != m_buffer, "Streaming-In-Place requires destination and source buffers to be different"); - memcpy(m_params.pBuffer, m_buffer, numBytesRead); - } - break; - case AZ::IO::IStreamerTypes::RequestStatus::Canceled: - m_IOError = ERROR_USER_ABORT; - m_numBytesRead = 0; - m_isError = true; - break; - default: - m_IOError = ERROR_UNKNOWN_ERROR; - m_numBytesRead = 0; - m_isError = true; - break; - } - - ExecuteAsyncCallback_CBLocked(); - m_isFileRequestComplete = true; - - if (m_params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) - { - // We do not need FileRequest here anymore, and not its temporary memory. - m_fileRequest = nullptr; - m_isFinished = true; - } - else - { - //The completion must be triggered from MainThread. (Typically only happens when loading Terrain Macro Textures - AddRef(); - AZ::SystemTickBus::QueueFunction([this] { - RequestCompleteOnMainThread(); - }); - } - } - - m_wait.release(); -} - - -void AZRequestReadStream::RequestCompleteOnMainThread() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - // call asynchronous callback function if needed synchronously - { - CryAutoCriticalSection lock(m_callbackLock); - ExecuteSyncCallback_CBLocked(); - } - - //Always called because before enqueuing this call was called AddRef() - Release(); -} - diff --git a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h b/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h deleted file mode 100644 index be925ad6c0..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/AZRequestReadStream.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -* 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. -* -*/ - -// Description : An IReadStream implementation designed to work with AZ::IO::Streamer -// instead of CStreamEngine. - -#pragma once - -#include -#include -#include -#include -#include "IStreamEngine.h" - -namespace AZ -{ - namespace IO - { - class Request; - } -} - -//This class is a wrapper of AZ::IO::Request so Cry Classes can use AZ::IO::Streamer. -//Basicallythis replaces CReadStream. -class AZRequestReadStream - : public IReadStream -{ -public: - AZ_CLASS_ALLOCATOR(AZRequestReadStream, AZ::SystemAllocator, 0); - - static AZRequestReadStream* Allocate(const EStreamTaskType tSource, const char* filename, IStreamCallback* callback, - const StreamReadParams* params); - - int AddRef() override; - int Release() override; - - DWORD_PTR GetUserData() override {return m_params.dwUserData; } - - // set user defined data into stream's params - void SetUserData(DWORD_PTR userData) override { m_params.dwUserData = userData; }; - - // returns true if the file read was not successful. - bool IsError() override { return m_isError; }; - - // returns true if the file read was completed (successfully or unsuccessfully) - // check IsError to check if the whole requested file (piece) was read - bool IsFinished() override { return m_isFinished; }; - - // returns the number of bytes read so far (the whole buffer size if IsFinished()) - unsigned int GetBytesRead([[maybe_unused]] bool bWait) override { return static_cast(m_numBytesRead); }; - - // returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read - const void* GetBuffer() override { return m_buffer; }; - - // tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - void Abort() override; - bool TryAbort() override; - - - - // unconditionally waits until the callback is called - // i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified) - void Wait(int maxWaitMillis = -1) override; - - const StreamReadParams& GetParams() const override {return m_params; } - - const EStreamTaskType GetCallerType() const override { return m_Type; } - - //We must define this one. But it is never used in the context of AZ::IO::Streamer. - //Legacy Cry StreamEngine stuff. - EStreamSourceMediaType GetMediaType() const override { return EStreamSourceMediaType::eStreamSourceTypeUnknown; } - - // return pointer to callback routine(can be NULL) - IStreamCallback* GetCallback() const override { return m_callback; }; - - // return IO error # - unsigned GetError() const override { return m_IOError; }; - - // Returns IO error name - const char* GetErrorName() const override; - - // return stream name - const char* GetName() const override { return m_fileName.c_str(); }; - - void FreeTemporaryMemory() override; - - // tries to raise the priority of the read; this is advisory and may have no effect - void SetPriority(EStreamTaskPriority EPriority); - uint64 GetPriority() const { return m_params.ePriority; }; - - void* GetFileReadBuffer() { return m_buffer; } //GetBuffer from IReadStream is "const void *" - AZStd::size_t GetFileSize() { return m_fileSize; } - - void SetFileRequest(AZ::IO::FileRequestPtr request) { m_fileRequest = AZStd::move(request); } - AZ::IO::FileRequestPtr GetFileRequest() { return m_fileRequest; } - - void OnRequestComplete(AZ::IO::SizeType numBytesRead, void* buffer, AZ::IO::IStreamerTypes::RequestStatus requestState); - -private: - AZRequestReadStream(); - virtual ~AZRequestReadStream(); - - // call the async callback - void ExecuteAsyncCallback_CBLocked(); - void ExecuteSyncCallback_CBLocked(); - void RequestCompleteOnMainThread(); - - AZStd::atomic_int m_refCount; - - CryCriticalSection m_callbackLock; - StreamReadParams m_params; - AZStd::semaphore m_wait; - - CryStringLocal m_fileName; - AZ::IO::FileRequestPtr m_fileRequest; - - // Bytes actually read from media. - void* m_buffer; - - // the type of the task - EStreamTaskType m_Type; - // the initial data from the user - // the callback; may be NULL - IStreamCallback* m_callback; - - AZ::IO::SizeType m_fileSize; //Expected number of bytes to be read. - AZ::IO::SizeType m_numBytesRead; //On a successful read m_nBytesRead == m_fileSize; - - bool m_isAsyncCallbackExecuted; - bool m_isSyncCallbackExecuted; - bool m_isFileRequestComplete; - - bool m_isError; - bool m_isFinished; - unsigned int m_IOError; -}; - -TYPEDEF_AUTOPTR(AZRequestReadStream); diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp deleted file mode 100644 index 61052bc991..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.cpp +++ /dev/null @@ -1,1027 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "StreamAsyncFileRequest.h" - -#include - -#include "StreamEngine.h" -#include "../System.h" -#include -#include - -extern CMTSafeHeap* g_pPakHeap; - -#if defined(STREAMENGINE_ENABLE_STATS) -extern SStreamEngineStatistics* g_pStreamingStatistics; -#endif - -extern SStreamEngineOpenStats* g_pStreamingOpenStatistics; - -volatile int CAsyncIOFileRequest::s_nLiveRequests; -SLockFreeSingleLinkedListHeader CAsyncIOFileRequest::s_freeRequests; - - -#ifdef STREAMENGINE_ENABLE_LISTENER - -class NotifyListenerIO -{ -public: - NotifyListenerIO(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq, AZ::IO::CCachedFileData* pZipEntry, uint32 readSize) - : m_pL(pL) - , m_pReq(pReq) - { - if (m_pL) - { - m_pL->OnStreamBeginIO( - m_pReq, - (pZipEntry && pZipEntry->m_pFileEntry->nMethod) ? pZipEntry->GetFileEntry()->desc.lSizeCompressed : m_pReq->m_nFileSize, - readSize, - pReq->m_eMediaType); - } - } - ~NotifyListenerIO() - { - End(); - } - void End() - { - if (m_pL) - { - m_pL->OnStreamEndIO(m_pReq); - m_pL = NULL; - } - } - -private: - NotifyListenerIO(const NotifyListenerIO&); - NotifyListenerIO& operator = (const NotifyListenerIO&); - -private: - IStreamEngineListener* m_pL; - CAsyncIOFileRequest* m_pReq; -}; - -#endif //STREAMENGINE_ENABLE_LISTENER - -////////////////////////////////////////////////////////////////////////// - -void* CAsyncIOFileRequest::operator new (size_t sz) -{ - return CryModuleMemalign(sz, alignof(CAsyncIOFileRequest)); -} - -void CAsyncIOFileRequest::operator delete(void* p) -{ - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest::CAsyncIOFileRequest() - : m_nRefCount(0) - , m_pMemoryBuffer(NULL) -{ - Reset(); -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest::~CAsyncIOFileRequest() -{ -#ifndef _RELEASE - if (m_pMemoryBuffer) - { - __debugbreak(); - } - if (m_eType) - { - __debugbreak(); - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -uint32 CAsyncIOFileRequest::ConfigureRead(AZ::IO::CCachedFileData* pFileData) -{ - AZ::IO::ZipDir::FileEntry* pFileEntry = pFileData ? pFileData->m_pFileEntry : NULL; - - if (!pFileData || !pFileEntry->IsCompressed()) - { - m_bCompressedBuffer = false; - m_nFileSizeCompressed = m_nFileSize; - m_nSizeOnMedia = m_nRequestedSize; - - m_nPageReadStart = m_nRequestedOffset; - m_nPageReadEnd = m_nRequestedOffset + m_nRequestedSize; - } - else - { - m_bCompressedBuffer = true; - m_nFileSize = pFileEntry->desc.lSizeUncompressed; - m_nFileSizeCompressed = pFileEntry->desc.lSizeCompressed; - m_nSizeOnMedia = m_nFileSizeCompressed; - - m_nPageReadStart = 0; - m_nPageReadEnd = m_nFileSizeCompressed; - } - - if (pFileData && !m_bWriteOnlyExternal) - { - m_crc32FromHeader = pFileEntry->desc.lCRC32; - } - - m_nPageReadCurrent = 0; - - m_bStreamInPlace = !m_bCompressedBuffer || ((!m_pExternalMemoryBuffer || !m_bWriteOnlyExternal) && (m_nFileSize > m_nFileSizeCompressed)); - m_bReadBegun = 1; - - return 0; -} - -bool CAsyncIOFileRequest::CanReadInPages() -{ - bool bReadInBlocks = false; - - if (g_cvars.sys_streaming_in_blocks) - { - //stream is compressed and uncompressed size is greater than one page - if (!m_bCompressedBuffer || m_nFileSizeCompressed > STREAMING_BLOCK_SIZE) - { - bReadInBlocks = true; - } - } - - return bReadInBlocks; -} - -uint32 CAsyncIOFileRequest::AllocateOutput([[maybe_unused]] AZ::IO::CCachedFileData* pZipEntry) -{ - if (!m_bOutputAllocated) - { - uint32 nAllocSize = 0; - uint32 nReadAllocSize = 0; - uint32 nZStreamOffs = 0; - uint32 nLookaheadOffs = 0; - - if (m_pExternalMemoryBuffer) - { - nReadAllocSize = m_bCompressedBuffer - ? (m_nRequestedSize < m_nFileSize ? m_nFileSize : 0) - : 0; - } - else - { - nReadAllocSize = m_bCompressedBuffer - ? m_nFileSize - : m_nRequestedSize; - } - - nAllocSize = Align(nReadAllocSize, BUFFER_ALIGNMENT); - - bool bReadInBlocks = CanReadInPages(); - bool bNeedsLookahead = m_bStreamInPlace; - bool bBlockDecompress = m_bCompressedBuffer && bReadInBlocks; - - if (bBlockDecompress) - { - nZStreamOffs = nAllocSize; - nAllocSize += Align(sizeof(z_stream), BUFFER_ALIGNMENT); - - if (bNeedsLookahead) - { - nLookaheadOffs = nAllocSize; - nAllocSize += Align(sizeof(*m_pLookahead), BUFFER_ALIGNMENT); - } - } - - char* pBuffer = NULL; - - if (nAllocSize) - { - const char* usageHint = "AsyncIO TempBuffer"; - pBuffer = (char*)GetStreamEngine()->TempAlloc(nAllocSize, usageHint, true, IgnoreOutofTmpMem(), BUFFER_ALIGNMENT); - if (!pBuffer) - { - return ERROR_OUT_OF_MEMORY; - } - } - - if (pBuffer) - { - m_pMemoryBuffer = pBuffer; - m_nMemoryBufferSize = nAllocSize; - } - - if (nReadAllocSize) - { - m_pReadMemoryBuffer = pBuffer; - m_nReadMemoryBufferSize = nReadAllocSize; - } - else - { - m_pReadMemoryBuffer = m_pExternalMemoryBuffer; - m_nReadMemoryBufferSize = m_nRequestedSize; - } - - m_pOutputMemoryBuffer = m_pExternalMemoryBuffer - ? m_pExternalMemoryBuffer - : m_pReadMemoryBuffer; - - if (bBlockDecompress) - { - m_pZlibStream = (z_stream*)&pBuffer[nZStreamOffs]; - memset(m_pZlibStream, 0, sizeof(z_stream)); - - if (bNeedsLookahead) - { - m_pLookahead = new (&pBuffer[nLookaheadOffs]) AZ::IO::ZipDir::UncompressLookahead; - } - - m_pZlibStream->zalloc = CMTSafeHeap::StaticAlloc; - m_pZlibStream->zfree = CMTSafeHeap::StaticFree; - m_pZlibStream->opaque = g_pPakHeap; - } - - if (m_bCompressedBuffer) - { - m_pDecompQueue = new SStreamJobQueue; - } - - // Doesn't need to be atomic, as there's no concurrency yet. - int nMemoryBufferUsers = 0; - if (nReadAllocSize > 0) - { - ++nMemoryBufferUsers; - } - if (m_bCompressedBuffer) - { - ++nMemoryBufferUsers; - } - m_nMemoryBufferUsers = nMemoryBufferUsers; - - m_bOutputAllocated = 1; - } - - return 0; -} - -byte* CAsyncIOFileRequest::AllocatePage(size_t sz, bool bOnlyPakMem, SStreamPageHdr*& pHdrOut) -{ - const char* usageHint = "streaming page"; - size_t nSzAligned = Align(sz, BUFFER_ALIGNMENT); - size_t nToAlloc = nSzAligned + sizeof(SStreamPageHdr); - byte* pRet = (byte*)GetStreamEngine()->TempAlloc(nToAlloc, usageHint, true, !bOnlyPakMem, BUFFER_ALIGNMENT); - if (pRet) - { - pHdrOut = new (pRet + nSzAligned)SStreamPageHdr(nToAlloc); - } - - return pRet; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::Cancel() -{ - if (!HasFailed()) - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - CryOptionalAutoLock decompLock(m_externalBufferLockDecompress, m_pExternalMemoryBuffer != NULL); - - Failed(ERROR_USER_ABORT); - } -} - -void CAsyncIOFileRequest::SyncWithDecompress() -{ - m_decompJobExecutor.reset(); // destructor waits on job completion -} - -////////////////////////////////////////////////////////////////////////// -bool CAsyncIOFileRequest::TryCancel() -{ - if (!HasFailed()) - { - bool bExt = false; - if (m_pExternalMemoryBuffer != NULL) - { - if (!m_externalBufferLockRead.TryLock()) - { - return false; - } - if (!m_externalBufferLockDecompress.TryLock()) - { - m_externalBufferLockRead.Unlock(); - return false; - } - bExt = true; - } - - Failed(ERROR_USER_ABORT); - - if (bExt) - { - m_externalBufferLockDecompress.Unlock(); - m_externalBufferLockRead.Unlock(); - } - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::FreeBuffer() -{ - if (m_pZlibStream) - { - //if the stream was cancelled in flight, inform zlib to free internal allocs - if (m_pZlibStream->state) - { - inflateEnd(m_pZlibStream); - } - - m_pZlibStream = NULL; - } - - m_pLookahead = NULL; - - SStreamEngineTempMemStats& tms = GetStreamEngine()->GetTempMemStats(); - - if (m_pDecompQueue) - { - m_pDecompQueue->Flush(tms); - delete m_pDecompQueue; - m_pDecompQueue = NULL; - } - - if (m_pMemoryBuffer) - { - CStreamEngine* pStreamEngine = GetStreamEngine(); - - pStreamEngine->TempFree(m_pMemoryBuffer, m_nMemoryBufferSize); - m_pMemoryBuffer = 0; - } - -#ifdef STREAMENGINE_ENABLE_STATS - // Update Streaming statistics. - if (g_pStreamingStatistics && m_nSizeOnMedia != 0 && m_bStatsUpdated) - { - m_bStatsUpdated = false; - int nSize = (int)m_nSizeOnMedia; - SStreamEngineStatistics& stats = *g_pStreamingStatistics; - CryInterlockedAdd(&stats.nPendingReadBytes, -nSize); - CryInterlockedAdd(&stats.typeInfo[m_eType].nPendingReadBytes, -nSize); - } -#endif -} - -CAsyncIOFileRequest* CAsyncIOFileRequest::Allocate(EStreamTaskType eType) -{ - CAsyncIOFileRequest* pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests)); - IF_UNLIKELY (!pReq) - { - pReq = new CAsyncIOFileRequest; - } - - pReq->Init(eType); - - return pReq; -} - -void CAsyncIOFileRequest::Flush() -{ - for (CAsyncIOFileRequest* pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests)); - pReq; - pReq = static_cast(CryInterlockedPopEntrySList(s_freeRequests))) - { - delete pReq; - } -} - -void CAsyncIOFileRequest::Reset() -{ - m_decompJobExecutor.reset(); // destructor waits on job completion - -#ifndef _RELEASE - if (m_pMemoryBuffer) - { - __debugbreak(); - } -#endif - - m_pReadStream = NULL; - m_strFileName.resize(0); - m_pakFile.resize(0); - - // Reset POD members of the structure - memset(&m_nSortKey, 0, ((char*)(this + 1) - (char*)&m_nSortKey)); -} - -void CAsyncIOFileRequest::Init(EStreamTaskType eType) -{ -#ifndef _RELEASE - if (!eType) - { - __debugbreak(); - } -#endif - - m_eType = eType; - -#ifdef STREAMENGINE_ENABLE_STATS - m_startTime = gEnv->pTimer->GetAsyncTime(); -#endif - - if (g_pStreamingOpenStatistics) - { - SStreamEngineOpenStats& stats = *g_pStreamingOpenStatistics; - CryInterlockedIncrement(&stats.nOpenRequestCount); - CryInterlockedIncrement(&stats.nOpenRequestCountByType[eType]); - } - - CryInterlockedIncrement(&s_nLiveRequests); -} - -void CAsyncIOFileRequest::Finalize() -{ -#ifndef _RELEASE - if (!m_eType) - { - __debugbreak(); - } -#endif - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamDone(this); - } -#endif - - if (g_pStreamingOpenStatistics) - { - SStreamEngineOpenStats& stats = *g_pStreamingOpenStatistics; - CryInterlockedDecrement(&stats.nOpenRequestCount); - CryInterlockedDecrement(&stats.nOpenRequestCountByType[m_eType]); - } - - CryInterlockedDecrement(&s_nLiveRequests); - - FreeBuffer(); - Reset(); -} - -uint32 CAsyncIOFileRequest::OpenFile(CCryFile& file) -{ - auto* pIPak = gEnv ? gEnv->pCryPak : NULL; - PREFAST_ASSUME(pIPak); - - if (m_pReadStream && m_pReadStream->GetParams().nFlags & IStreamEngine::FLAGS_FILE_ON_DISK) - { - pIPak = 0; - } - - file = CCryFile(pIPak); - if (!file.Open(m_strFileName.c_str(), "rb", AZ::IO::IArchive::FOPEN_FORSTREAMING)) - { - return ERROR_CANT_OPEN_FILE; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -uint32 CAsyncIOFileRequest::ReadFile(CStreamingIOThread* pIOThread) -{ - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - CCryFile file; - nError = OpenFile(file); - if (nError) - { - return nError; - } - - m_nFileSize = file.GetLength(); - - if (m_nRequestedOffset >= m_nFileSize) - { - return ERROR_OFFSET_OUT_OF_RANGE; - } - - if (m_nRequestedOffset + m_nRequestedSize > m_nFileSize) - { - return ERROR_SIZE_OUT_OF_RANGE; - } - - if (m_nRequestedSize == 0) - { - // by default, we read the whole file - m_nRequestedSize = m_nFileSize - m_nRequestedOffset; - } - - if (!m_pExternalMemoryBuffer && m_pReadStream) - { - bool bAbortOnFailToAlloc = false; - CReadStream* pReadStream = static_cast(&*m_pReadStream); - m_pExternalMemoryBuffer = pReadStream->OnNeedStorage(m_nFileSize, bAbortOnFailToAlloc); - - if (!m_pExternalMemoryBuffer && bAbortOnFailToAlloc) - { - Cancel(); - m_pReadStream->Abort(); - return ERROR_USER_ABORT; - } - } - - if (HasFailed()) - { - return m_nError; - } - - auto pZipEntry = ((AZ::IO::Archive*)(gEnv->pCryPak))->GetOpenedFileDataInZip(file.GetHandle()); - nError = ConfigureRead(pZipEntry.get()); - if (nError) - { - return nError; - } - - nError = AllocateOutput(pZipEntry.get()); - if (nError) - { - return nError; - } - - return ReadFileInPages(pIOThread, file); -} - -uint32 CAsyncIOFileRequest::ReadFileResume(CStreamingIOThread* pIOThread) -{ - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - CCryFile file; - nError = OpenFile(file); - if (nError) - { - return nError; - } - - auto pZipEntry = ((AZ::IO::Archive*)(gEnv->pCryPak))->GetOpenedFileDataInZip(file.GetHandle()); - - nError = AllocateOutput(pZipEntry.get()); - if (nError) - { - return nError; - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamResumed(this); - } -#endif - - return ReadFileInPages(pIOThread, file); -} - -uint32 CAsyncIOFileRequest::ReadFileInPages(CStreamingIOThread* pIOThread, CCryFile& file) -{ - auto pCryPak = static_cast(gEnv->pCryPak); - auto pZipEntry = pCryPak->GetOpenedFileDataInZip(file.GetHandle()); - - AZ::IO::ZipDir::Cache* pZip = NULL; - unsigned int nZipFlags = 0; - if (pZipEntry) - { - pZip = pZipEntry->GetZip(); - nZipFlags = pZipEntry->m_nArchiveFlags; - } - - if (pIOThread->IsMisscheduled(EStreamSourceMediaType::eStreamSourceTypeHDD)) - { - // We're on the wrong IO thread! - return ERROR_MISSCHEDULED; - } - - bool bReadInPages = CanReadInPages(); - - uint32 nPageReadLen = (m_nPageReadEnd - m_nPageReadStart); - - bool const bCompressed = m_bCompressedBuffer; - bool const bInPlace = m_bStreamInPlace; - bool const bIgnoreOutOfTmp = IgnoreOutofTmpMem(); - - size_t const nReadStartOffset = bCompressed - ? (m_nFileSize - m_nFileSizeCompressed) - : 0; - - byte* const pReadBase = (byte*)m_pReadMemoryBuffer + nReadStartOffset; - byte* const pReadEnd = (byte*)m_pReadMemoryBuffer + m_nReadMemoryBufferSize; - - CStreamEngine* pStreamEngine = static_cast(gEnv->pSystem->GetStreamEngine()); - - uint32 nPageSize = bReadInPages - ? min((uint32)STREAMING_PAGE_SIZE, nPageReadLen - m_nPageReadCurrent) - : nPageReadLen - m_nPageReadCurrent; - - while (nPageSize > 0) - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - - uint32 nError = m_nError; - - if (nError) - { - return nError; - } - - //check if job needs to be pre-empted - nError = ReadFileCheckPreempt(pIOThread); - if (nError) - { - return nError; - } - - byte* pReadTarget = pReadBase + m_nPageReadCurrent; - byte* pReadTargetEnd = pReadTarget + nPageSize; - bool bTemporaryReadTarget = false; - SStreamPageHdr* pTemporaryPageHdr = NULL; - - if (bInPlace) - { - if (pReadTargetEnd > pReadEnd) - { - __debugbreak(); - } - } - else - { - pReadTarget = AllocatePage(nPageSize, !bIgnoreOutOfTmp, pTemporaryPageHdr); - - if (!pReadTarget) - { - return ERROR_OUT_OF_MEMORY; - } - - bTemporaryReadTarget = true; - pTemporaryPageHdr->nRefs = 1; - } - -#ifndef _RELEASE - if (m_nPageReadCurrent + nPageSize > nPageReadLen) - { - __debugbreak(); - } -#endif - - { -#ifdef STREAMENGINE_ENABLE_LISTENER - NotifyListenerIO IOListener(gEnv->pSystem->GetStreamEngine()->GetListener(), this, pZipEntry.get(), nPageSize); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); -#endif - - //printf("[StreamRead] %p %i %p %i %i\n", this, m_bCompressedBuffer, pReadTarget, m_nPageReadStart + m_nPageReadCurrent, nPageSize); - - bool bReadOk = false; - - if (pZipEntry) - { - bReadOk = pZipEntry->m_pZip->ReadFile(pZipEntry->m_pFileEntry, pReadTarget, nullptr) == AZ::IO::ZipDir::ZD_ERROR_SUCCESS; - } - else - { - file.Seek(m_nPageReadStart + m_nPageReadCurrent, SEEK_SET); - bReadOk = file.ReadRaw(pReadTarget, nPageSize) == nPageSize; - } - - if (bReadOk) - { - //send each block to listener -#ifdef STREAMENGINE_ENABLE_LISTENER - IOListener.End(); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - m_readTime += gEnv->pTimer->GetAsyncTime() - t0; -#endif - - //release external mem lock, allows jobs to be cancelled mid stream - readLock.Release(); - } - else - { - if (bTemporaryReadTarget) - { - GetStreamEngine()->TempFree(pReadTarget, pTemporaryPageHdr->nSize); - } - - return ERROR_REFSTREAM_ERROR; - } - - bool bLastBlock = (m_nPageReadCurrent + nPageSize) == nPageReadLen; - - if (bCompressed) - { - PushDecompressPage(pStreamEngine->GetJobEngineState(), pReadTarget, pTemporaryPageHdr, nPageSize, bLastBlock); - } - else if (bTemporaryReadTarget) - { - __debugbreak(); - } - - if (pTemporaryPageHdr && CryInterlockedDecrement(&pTemporaryPageHdr->nRefs) == 0) - { - GetStreamEngine()->TempFree(pReadTarget, pTemporaryPageHdr->nSize); - } - - m_nPageReadCurrent += nPageSize; - nPageSize = min((uint32)STREAMING_PAGE_SIZE, nPageReadLen - m_nPageReadCurrent); - } - } - - return 0; -} - -uint32 CAsyncIOFileRequest::ReadFileCheckPreempt(CStreamingIOThread* pIOThread) -{ - if (m_ePriority != estpUrgent) - { - if (pIOThread->HasUrgentRequests()) - { - //printf("Read Job %s pre-empted mid stream. Progress %d / %d bytes\n", m_strFileName.c_str(), m_nBytesRead, m_nFileSizeCompressed); -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = gEnv->pSystem->GetStreamEngine()->GetListener(); - if (pListener) - { - pListener->OnStreamPreempted(this); - } -#endif - return ERROR_PREEMPTED; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -CStreamEngine* CAsyncIOFileRequest::GetStreamEngine() -{ - return (CStreamEngine*)GetISystem()->GetStreamEngine(); -} - -////////////////////////////////////////////////////////////////////////// -EStreamSourceMediaType CAsyncIOFileRequest::GetMediaType() -{ - EStreamSourceMediaType mediaType = m_eMediaType; - - if (mediaType == eStreamSourceTypeUnknown) - { - if (m_bSortKeyComputed) - { - return mediaType; - } - - if (m_strFileName.empty()) - { - mediaType = eStreamSourceTypeMemory; - return mediaType; - } - - mediaType = gEnv->pCryPak->GetFileMediaType(m_strFileName.c_str()); - } - - return mediaType; -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::ComputeSortKey(uint64 nCurrentKeyInProgress) -{ - if (m_bSortKeyComputed) - { - return; - } - - m_bSortKeyComputed = true; - - if (m_strFileName.empty()) - { - m_eMediaType = eStreamSourceTypeMemory; - m_nSortKey = m_ePriority; - return; - } - if (HasFailed()) - { - m_nSortKey = 0; - return; - } - - const int MaxPath = 0x800; - char szFullPathBuf[MaxPath]; - const char* szFullPath = gEnv->pCryPak->AdjustFileName(m_strFileName.c_str(), szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), AZ::IO::IArchive::FOPEN_HINT_QUIET); - - auto pCryPak = static_cast(gEnv->pCryPak); - - AZ::IO::ZipDir::CachePtr pZip = 0; - unsigned int archFlags = 0; - AZ::IO::ZipDir::FileEntry* pFileEntry = NULL; - - // tests if the given file path refers to an existing file inside registered (opened) packs - // the path must be absolute normalized lower-case with forward-slashes - AZ::IO::ArchiveLocationPriority varPakPriority = pCryPak->GetPakPriority(); - bool willOpenFromPak = (varPakPriority != AZ::IO::ArchiveLocationPriority::ePakPriorityFileFirst) - || !AZ::IO::FileIOBase::GetDirectInstance()->Exists(szFullPath); - - if (willOpenFromPak) - { - pFileEntry = pCryPak->FindPakFileEntry(szFullPath, archFlags, &pZip, false); - } - - EStreamSourceMediaType ssmt = pCryPak->GetFileMediaType(szFullPath); - - if (pFileEntry) - { - pZip->Refresh(pFileEntry); - m_nDiskOffset = (uint64)pFileEntry->nFileDataOffset; - - m_nSizeOnMedia = pFileEntry->desc.lSizeCompressed; - m_nFileSize = pFileEntry->desc.lSizeUncompressed; - - m_pakFile = pZip->GetFilePath(); - } - - m_eMediaType = ssmt; - - if (ssmt != eStreamSourceTypeMemory) - { - int32 nCurrentSweep = (nCurrentKeyInProgress >> 30) & ((1 << 10) - 1); - int32 nCurrentTG = (nCurrentKeyInProgress >> 40) & ((1 << 20) - 1); - - if (pFileEntry && !pFileEntry->IsCompressed()) - { - m_nDiskOffset += m_nRequestedOffset; - } - - // group items by priority, then by snapped request time, then sort by disk offset - m_nTimeGroup = (uint64)(gEnv->pTimer->GetAsyncTime().GetSeconds() / max(1, g_cvars.sys_streaming_requests_grouping_time_period)); - m_nSweep = (m_nTimeGroup == nCurrentTG) - ? nCurrentSweep - : 0; - uint64 nPrioriry = m_ePriority; - - int64 nDiskOffsetKB = m_nDiskOffset >> 10; // KB - m_nSortKey = (nDiskOffsetKB) | (((uint64)m_nTimeGroup) << 40) | ((uint64)m_nSweep << 30) | (nPrioriry << 60); - - // make sure we do not break incremental head movement within time group on every new request - if (m_nSortKey <= nCurrentKeyInProgress) - { - ++m_nSweep; - m_nSortKey = (nDiskOffsetKB) | (((uint64)m_nTimeGroup) << 40) | ((uint64)m_nSweep << 30) | (nPrioriry << 60); - } - } - else - { - m_nSortKey = m_ePriority; - } - -#if defined(STREAMENGINE_ENABLE_STATS) - // Update Streaming statistics. - if (!m_bStatsUpdated && g_pStreamingStatistics && m_nSizeOnMedia != 0) - { - m_bStatsUpdated = true; - SStreamEngineStatistics& stats = *g_pStreamingStatistics; - - // if the file is not compressed then it will only read the requested size - uint32 nReadSize = m_nSizeOnMedia; - if (m_nSizeOnMedia == m_nFileSize) - { - nReadSize = m_nRequestedSize; - } - - CryInterlockedAdd(&stats.nPendingReadBytes, nReadSize); - CryInterlockedAdd(&stats.typeInfo[m_eType].nPendingReadBytes, nReadSize); - } -#endif -} - -void CAsyncIOFileRequest::SetPriority(EStreamTaskPriority estp) -{ - m_ePriority = estp; - - if (m_eMediaType != eStreamSourceTypeMemory) - { - m_nSortKey &= ~(15ULL << 60); - m_nSortKey |= static_cast(estp) << 60; - } - else - { - m_nSortKey = m_ePriority; - } -} - -void CAsyncIOFileRequest::BumpSweep() -{ - ++m_nSweep; - if (m_eMediaType != eStreamSourceTypeMemory) - { - m_nSortKey += 1 << 30; - } -} - -////////////////////////////////////////////////////////////////////////// -bool CAsyncIOFileRequest::IgnoreOutofTmpMem() const -{ - if (m_pReadStream && - (m_pReadStream->GetParams().ePriority == estpUrgent || - m_pReadStream->GetParams().nFlags & IStreamEngine::FLAGS_IGNORE_TMP_OUT_OF_MEM)) - { - return true; - } - - return false; -} - -SStreamRequestQueue::SStreamRequestQueue() -{ - m_requests.reserve(4096); -} - -SStreamRequestQueue::~SStreamRequestQueue() -{ - Reset(); -} - -void SStreamRequestQueue::Reset() -{ - CryAutoLock l(m_lock); - for (size_t i = 0, c = m_requests.size(); i != c; ++i) - { - m_requests[i]->Release(); - } - m_requests.clear(); -} - -bool SStreamRequestQueue::IsEmpty() const -{ - return m_requests.empty(); -} - -bool SStreamRequestQueue::TryPopRequest(CAsyncIOFileRequest_AutoPtr& pOut) -{ - CryAutoLock l(m_lock); - if (!m_requests.empty()) - { - pOut = m_requests.front(); - pOut->Release(); - m_requests.erase(m_requests.begin()); - return true; - } - return false; -} - -void* SStreamEngineTempMemStats::TempAlloc(CMTSafeHeap* pHeap, size_t nSize, const char* szDbgSource, bool bFallBackToMalloc, bool bUrgent, uint32 align) -{ - // Only allow falling back to malloc if the size fits within the stream budget, the request is urgent, or the temp memory is 0 - for those files that are over budget on their own. - long nInUse = m_nTempAllocatedMemory; - bFallBackToMalloc = - bUrgent - || (bFallBackToMalloc && ((nInUse == 0) || (nInUse + static_cast(nSize) <= m_nTempMemoryBudget))) - ; - - void* p = pHeap->TempAlloc(nSize, szDbgSource, bFallBackToMalloc, align); -#if MTSAFE_USE_GENERAL_HEAP - bool bInGenHeap = pHeap->IsInGeneralHeap(p); -#else - bool bInGenHeap = false; -#endif - if (p && !bInGenHeap) - { - ReportTempMemAlloc(nSize, 0, false); - } - - return p; -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h deleted file mode 100644 index 4a112ef68f..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest.h +++ /dev/null @@ -1,571 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Thread for IO - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H -#pragma once - -#include -#include -#include "TimeValue.h" - -#define STREAMENGINE_LL_ALIGN _MS_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) - -class CStreamEngine; -class CAsyncIOFileRequest; -struct z_stream_s; -class CStreamingIOThread; -namespace AZ::IO -{ - struct CCachedFileData; -} -class CCryFile; -struct SStreamJobEngineState; -class CMTSafeHeap; -class CAsyncIOFileRequest_TransferPtr; -struct SStreamEngineTempMemStats; - -#if !defined(USE_EDGE_ZLIB) -// Prevent compilation conflicts - zconf.h (included by zlib.h) defines WINDOWS and WIN32 - those -// definitions conflict with CryEngine's definitions. - -# if defined(CRY_TMP_DEFINED_WINDOWS) || defined(CRY_TMP_DEFINED_WIN32) -# error CRY_TMP_DEFINED_WINDOWS and/or CRY_TMP_DEFINED_WIN32 already defined -# endif - -# if defined(WINDOWS) -# define CRY_TMP_DEFINED_WINDOWS 1 -# endif -# if defined(WIN32) -# define CRY_TMP_DEFINED_WIN32 1 -# endif - -# include - -# if !defined(CRY_TMP_DEFINED_WINDOWS) -# undef WINDOWS -#endif -# undef CRY_TMP_DEFINED_WINDOWS -# if !defined(CRY_TMP_DEFINED_WIN32) -# undef WIN32 -# endif -# undef CRY_TMP_DEFINED_WIN32 - -// Undefine macros defined in zutil.h to prevent compilation errors in 'steamclientpublic.h', 'OVR_Math.h' etc. -# undef Assert -# undef Trace -# undef Tracev -# undef Tracevv -# undef Tracec -# undef Tracecv - -#endif // !defined(USE_EDGE_ZLIB) - -namespace AZ::IO::ZipDir { - struct UncompressLookahead; -} - -struct IAsyncIOFileCallback -{ - virtual ~IAsyncIOFileCallback(){} - // Asynchronous finished event. - // Must be thread safe, can be called from a different thread. - virtual void OnAsyncFinished(CAsyncIOFileRequest* pFileRequest) = 0; -}; - -struct SStreamPageHdr -{ - explicit SStreamPageHdr(int size) - : nRefs() - , nSize(size) - {} - - volatile int nRefs; - int nSize; -}; - -struct SStreamJobQueue -{ - enum - { - MaxJobs = 256, - }; - - struct Job - { - void* pSrc; - SStreamPageHdr* pSrcHdr; - uint32 nOffs; - uint32 nBytes : 31; - uint32 bLast : 1; - }; - - SStreamJobQueue() - : m_sema(MaxJobs, MaxJobs) - { - m_nQueueLen = 0; - m_nPush = 0; - m_nPop = 0; - memset(m_jobs, 0, sizeof(m_jobs)); - } - - void Flush(SStreamEngineTempMemStats& tms); - - int Push(void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast); - int Pop(); - - CryFastSemaphore m_sema; - Job m_jobs[MaxJobs]; - volatile int m_nQueueLen; - volatile int m_nPush; - volatile int m_nPop; -}; - -// This class represent a request to read some file from disk asynchronously via one of the IO threads. -class CAsyncIOFileRequest -{ -public: - enum EStatus - { - eStatusNotReady, - eStatusInFileQueue, - eStatusFailed, - eStatusUnzipComplete, - eStatusDone, - }; - - enum - { - BUFFER_ALIGNMENT = 128, - WINDOW_SIZE = 1 << 15, - -#if defined(ANDROID) - STREAMING_PAGE_SIZE = (128 * 1024), -#else - STREAMING_PAGE_SIZE = (1 * 1024 * 1024), -#endif - -#if defined(ANDROID) - STREAMING_BLOCK_SIZE = (64 * 1024), -#else - STREAMING_BLOCK_SIZE = (32 * 1024), -#endif - }; - -public: - static CAsyncIOFileRequest* Allocate(EStreamTaskType eType); - static void Flush(); - -public: - void AddRef(); - int Release(); - -public: - void Init(EStreamTaskType eType); - void Finalize(); - - void Reset(); - - ILINE bool IsCancelled() const { return m_nError == ERROR_USER_ABORT; } - ILINE bool HasFailed() const { return m_nError != 0; } - void Failed(uint32 nError) - { - CryInterlockedCompareExchange(reinterpret_cast(&m_nError), nError, 0); - } - - uint32 OpenFile(CCryFile& file); - - uint32 ReadFile(CStreamingIOThread* pIOThread); - uint32 ReadFileResume(CStreamingIOThread* pIOThread); - uint32 ReadFileInPages(CStreamingIOThread* pIOThread, CCryFile& file); - uint32 ReadFileCheckPreempt(CStreamingIOThread* pIOThread); - - uint32 ConfigureRead(AZ::IO::CCachedFileData* pFileData); - bool CanReadInPages(); - uint32 AllocateOutput(AZ::IO::CCachedFileData* pZipEntry); - unsigned char* AllocatePage(size_t sz, bool bOnlyPakMem, SStreamPageHdr*& pHdrOut); - - static void JobFinalize_Read(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - - uint32 PushDecompressPage(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nBytes, bool bLast); - uint32 PushDecompressBlock(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast); - static void JobStart_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState, int nSlot); - void DecompressBlockEntry(SStreamJobEngineState engineState, int nJob); - - void Cancel(); - bool TryCancel(); - void SyncWithDecompress(); - void ComputeSortKey(uint64 nCurrentKeyInProgress); - void SetPriority(EStreamTaskPriority estp); - void BumpSweep(); - void FreeBuffer(); - - bool IgnoreOutofTmpMem() const; - - CStreamEngine* GetStreamEngine(); - - EStreamSourceMediaType GetMediaType(); - -private: - void* operator new (size_t sz); - void operator delete(void* p); - -private: - static void JobFinalize_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - static void JobFinalize_Transfer(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState); - -private: - void JobFinalize_Buffer(const SStreamJobEngineState& engineState); - void JobFinalize_Validate(const SStreamJobEngineState& engineState); - -private: - CAsyncIOFileRequest(); - ~CAsyncIOFileRequest(); - -public: - static volatile int s_nLiveRequests; - static SLockFreeSingleLinkedListHeader s_freeRequests; - -public: - // Must be first - STREAMENGINE_LL_ALIGN SLockFreeSingleLinkedListEntry m_nextFree; - - volatile int m_nRefCount; - - // Locks to be held whilst the file is being read, and an external memory buffer is in use - // (to ensure that if cancelled, the stream engine doesn't write to the external buffer) - // Separate locks for read and decomp as they can overlap (block decompress) - // Cancel() must acquire both - CryCriticalSection m_externalBufferLockRead; - CryCriticalSection m_externalBufferLockDecompress; - - CryStringLocal m_strFileName; - string m_pakFile; - - // If request come from stream, it will be not 0. - IReadStreamPtr m_pReadStream; - - AZStd::unique_ptr m_decompJobExecutor; - - // Only POD data should exist beyond this point - will be memsetted to 0 on Reset ! - - uint64 m_nSortKey; - - EStreamTaskPriority m_ePriority; - EStreamSourceMediaType m_eMediaType; - EStreamTaskType m_eType; - - volatile EStatus m_status; - volatile uint32 m_nError; - - uint32 m_nRequestedOffset; - uint32 m_nRequestedSize; - - // the file size, or 0 if the file couldn't be opened - uint32 m_nFileSize; - uint32 m_nFileSizeCompressed; - - void* m_pMemoryBuffer; - uint32 m_nMemoryBufferSize; - volatile int m_nMemoryBufferUsers; - - void* m_pExternalMemoryBuffer; - void* m_pOutputMemoryBuffer; - void* m_pReadMemoryBuffer; - uint32 m_nReadMemoryBufferSize; - - uint32 m_bCompressedBuffer : 1; - uint32 m_bStatsUpdated : 1; - uint32 m_bStreamInPlace : 1; - uint32 m_bWriteOnlyExternal : 1; - uint32 m_bSortKeyComputed : 1; - uint32 m_bOutputAllocated : 1; - uint32 m_bReadBegun : 1; - - // Actual size of the data on the media. - uint32 m_nSizeOnMedia; - - int64 m_nDiskOffset; - int32 m_nReadHeadOffsetKB; // Offset of the Read Head when reading from media. - int32 m_nTimeGroup; - int32 m_nSweep; - - IAsyncIOFileCallback* m_pCallback; - - // - // Block based streaming - // - - uint32 m_nPageReadStart; - uint32 m_nPageReadCurrent; - uint32 m_nPageReadEnd; - - volatile uint32 m_nBytesDecompressed; - - uint32 m_crc32FromHeader; - - volatile LONG m_nFinalised; - - z_stream_s* m_pZlibStream; - AZ::IO::ZipDir::UncompressLookahead* m_pLookahead; - SStreamJobQueue* m_pDecompQueue; - -#ifdef STREAMENGINE_ENABLE_STATS - // Time that read operation took. - CTimeValue m_readTime; - CTimeValue m_unzipTime; - CTimeValue m_verifyTime; - CTimeValue m_startTime; - CTimeValue m_completionTime; - - uint32 m_nReadCounter; -#endif -}; -TYPEDEF_AUTOPTR(CAsyncIOFileRequest); - -struct SStreamRequestQueue -{ - CryCriticalSection m_lock; - std::vector m_requests; - - CryEvent m_awakeEvent; - - SStreamRequestQueue(); - ~SStreamRequestQueue(); - - void Reset(); - bool IsEmpty() const; - - // Transfers ownership (rather than shares ownership) to the queue - void TransferRequest(CAsyncIOFileRequest_TransferPtr& pReq); - bool TryPopRequest(CAsyncIOFileRequest_AutoPtr& pOut); - -private: - SStreamRequestQueue(const SStreamRequestQueue&); - SStreamRequestQueue& operator = (const SStreamRequestQueue&); -}; - -#if defined(STREAMENGINE_ENABLE_STATS) -struct SStreamEngineDecompressStats -{ - uint64 m_nTotalBytesUnziped; - uint64 m_nTempBytesUnziped; - uint64 m_nTotalBytesVerified; - uint64 m_nTempBytesVerified; - - CTimeValue m_totalUnzipTime; - CTimeValue m_tempUnzipTime; - CTimeValue m_totalVerifyTime; - CTimeValue m_tempVerifyTime; -}; -#endif - -class CAsyncIOFileRequest_TransferPtr -{ -public: - explicit CAsyncIOFileRequest_TransferPtr(CAsyncIOFileRequest* p) - : m_p(p) - { - } - - ~CAsyncIOFileRequest_TransferPtr() - { - if (m_p) - { - m_p->Release(); - } - } - - CAsyncIOFileRequest* operator -> () { return m_p; } - CAsyncIOFileRequest& operator * () { return *m_p; } - - const CAsyncIOFileRequest* operator -> () const { return m_p; } - const CAsyncIOFileRequest& operator * () const { return *m_p; } - - operator bool () const { - return m_p != NULL; - } - - CAsyncIOFileRequest* Relinquish() - { - CAsyncIOFileRequest* p = m_p; - m_p = NULL; - return p; - } - - CAsyncIOFileRequest_TransferPtr& operator = (CAsyncIOFileRequest* p) - { -#ifndef _RELEASE - if (m_p) - { - __debugbreak(); - } -#endif - m_p = p; - return *this; - } - -private: - CAsyncIOFileRequest_TransferPtr(const CAsyncIOFileRequest_TransferPtr&); - CAsyncIOFileRequest_TransferPtr& operator = (const CAsyncIOFileRequest_TransferPtr&); - -private: - CAsyncIOFileRequest* m_p; -}; - -class CStreamEngineWakeEvent -{ -public: - CStreamEngineWakeEvent() - : m_state(0) - { - } - - void Set() - { - volatile LONG oldState, newState; - bool bSignalInner; - - do - { - bSignalInner = false; - oldState = m_state; - - newState = oldState | 0x80000000; - if (oldState & 0x7fffffff) - { - bSignalInner = true; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - - if (bSignalInner) - { - m_innerEvent.Set(); - } - } - - bool Wait(uint32 timeout = 0) - { - bool bTimedOut = false; - bool bAcquiredSignal = false; - - while (!bTimedOut && !bAcquiredSignal) - { - volatile long oldState, newState; - do - { - bAcquiredSignal = false; - - oldState = m_state; - if (oldState & 0x80000000) - { - // Signalled - newState = oldState & 0x7fffffff; - bAcquiredSignal = true; - } - else - { - newState = oldState + 1; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - - if (!bAcquiredSignal) - { - if (!timeout) - { - m_innerEvent.Wait(); - } - else - { - bTimedOut = !m_innerEvent.Wait(timeout); - } - - if (!bTimedOut) - { - m_innerEvent.Reset(); - } - - do - { - bAcquiredSignal = false; - - oldState = m_state; - if (!bTimedOut && (oldState & 0x80000000)) - { - newState = (oldState & 0x7fffffff) - 1; - bAcquiredSignal = true; - } - else - { - newState = oldState - 1; - } - } - while (CryInterlockedCompareExchange(&m_state, newState, oldState) != oldState); - } - } - - return bAcquiredSignal; - } - -private: - CStreamEngineWakeEvent(const CStreamEngineWakeEvent&); - CStreamEngineWakeEvent& operator = (const CStreamEngineWakeEvent&); - -private: - volatile LONG m_state; - CryEvent m_innerEvent; -}; - -struct SStreamEngineTempMemStats -{ - enum - { - MaxWakeEvents = 8, - }; - - SStreamEngineTempMemStats() - { - memset(this, 0, sizeof(*this)); - } - - void* TempAlloc(CMTSafeHeap* pHeap, size_t nSize, const char* szDbgSource, bool bFallBackToMalloc = true, bool bUrgent = false, uint32 align = 0); - void TempFree(CMTSafeHeap* pHeap, const void* p, size_t nSize); - void ReportTempMemAlloc(uint32 nSizeAlloc, uint32 nSizeFree, bool bTriggerWake); - - volatile LONG m_nTempAllocatedMemory; - volatile LONG m_nTempAllocatedMemoryFrameMax; - int m_nTempMemoryBudget; - CStreamEngineWakeEvent* m_wakeEvents[MaxWakeEvents]; - int m_nWakeEvents; -}; - -struct SStreamJobEngineState -{ - std::vector* pReportQueues; - -#if defined(STREAMENGINE_ENABLE_STATS) - SStreamEngineStatistics* pStats; - SStreamEngineDecompressStats* pDecompressStats; -#endif - - SStreamEngineTempMemStats* pTempMem; - - CMTSafeHeap* pHeap; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMASYNCFILEREQUEST_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp deleted file mode 100644 index b8bebb49c3..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamAsyncFileRequest_Jobs.cpp +++ /dev/null @@ -1,531 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include - -#include -#include "StreamAsyncFileRequest.h" - -#include "MTSafeAllocator.h" - -namespace AZ::IO::ZipDir::ZipDirStructuresInternal -{ - extern void ZlibInflateElementPartial_Impl( - int* pReturnCode, z_stream* pZStream, ZipDir::UncompressLookahead* pLookahead, - uint8_t* pOutput, size_t nOutputLen, bool bOutputWriteOnly, - const uint8_t* pInput, size_t nInputLen, size_t* pTotalOut); -} - -#ifdef STREAMENGINE_ENABLE_LISTENER -#include "IStreamEngine.h" -class NotifyListener -{ -public: - NotifyListener(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq) - : m_pL(pL) - , m_pReq(pReq) - , m_bInProgress(false) {} - virtual ~NotifyListener() {} -protected: - IStreamEngineListener* m_pL; - CAsyncIOFileRequest* m_pReq; - bool m_bInProgress; -}; -class NotifyListenerInflate - : NotifyListener -{ -public: - NotifyListenerInflate(IStreamEngineListener* pL, CAsyncIOFileRequest* pReq) - : NotifyListener(pL, pReq) - { - if (m_pL) - { - m_pL->OnStreamBeginInflate(m_pReq); - m_bInProgress = true; - } - } - ~NotifyListenerInflate() - { - End(); - } - void End() - { - if (m_bInProgress) - { - m_pL->OnStreamEndInflate(m_pReq); - m_bInProgress = false; - } - } -}; -#endif - -#if defined(STREAMENGINE_ENABLE_STATS) -#define STREAMENGINE_ENABLE_TIMING -#endif - -//#define STREAM_DECOMPRESS_TRACE(...) OutputDebugString(AZStd::string::format(__VA_ARGS__).c_str()); -#define STREAM_DECOMPRESS_TRACE(...) - -void SStreamJobQueue::Flush(SStreamEngineTempMemStats& tms) -{ - extern CMTSafeHeap* g_pPakHeap; - - for (int c = m_nQueueLen, i = m_nPop % MaxJobs; c; --c, i = (i + 1) % MaxJobs) - { - Job& j = m_jobs[i]; - if (j.pSrcHdr && CryInterlockedDecrement(&j.pSrcHdr->nRefs) == 0) - { - tms.TempFree(g_pPakHeap, j.pSrc, j.pSrcHdr->nSize); - } - j.pSrc = NULL; - } -} - -int SStreamJobQueue::Push(void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast) -{ - m_sema.Acquire(); - - int nSlot = (m_nPush++) % MaxJobs; - - Job& j = m_jobs[nSlot]; - j.pSrc = pSrc; - j.pSrcHdr = pSrcHdr; - j.nOffs = nOffs; - j.nBytes = nBytes; - j.bLast = (uint32)bLast; - - bool bStartNext = CryInterlockedIncrement(&m_nQueueLen) == 1; - return bStartNext ? nSlot : -1; -} - -int SStreamJobQueue::Pop() -{ - int nSlot = (++m_nPop) % MaxJobs; - bool bStartNext = CryInterlockedDecrement(&m_nQueueLen) > 0; - - m_sema.Release(); - - return bStartNext ? nSlot : -1; -} - -void CAsyncIOFileRequest::AddRef() -{ - //int nRef = - CryInterlockedIncrement(&m_nRefCount); - STREAM_DECOMPRESS_TRACE("[StreamDecompress],AddRef,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nRef); -} - -int CAsyncIOFileRequest::Release() -{ - int nRef = CryInterlockedDecrement(&m_nRefCount); - STREAM_DECOMPRESS_TRACE("[StreamDecompress],Release,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nRef); - -#ifndef _RELEASE - if (nRef < 0) - { - __debugbreak(); - } -#endif - - if (nRef == 0) - { - Finalize(); - - CryInterlockedPushEntrySList(s_freeRequests, m_nextFree); - } - - return nRef; -} - -void CAsyncIOFileRequest::DecompressBlockEntry(SStreamJobEngineState engineState, int nJob) -{ - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::System); - - STREAM_DECOMPRESS_TRACE("[StreamDecompress],DecompressBlockEntry,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nJob); - - CAsyncIOFileRequest_TransferPtr pSelf(this); - - SStreamJobQueue::Job& job = m_pDecompQueue->m_jobs[nJob]; - - void* pSrc = job.pSrc; - SStreamPageHdr* const pSrcHdr = job.pSrcHdr; - const uint32 nOffs = job.nOffs; - const uint32 nBytes = job.nBytes; - const bool bLast = job.bLast; - const bool bFailed = HasFailed(); - - if (!bFailed) - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liStart; - QueryPerformanceCounter(&liStart); -#endif - - //printf("Inflate: %s Avail in: %d, Avail Out: %d, Next In: 0x%p, Next Out: 0x%p\n", m_strFileName.c_str(), m_pZlibStream->avail_in, m_pZlibStream->avail_out, m_pZlibStream->next_in, m_pZlibStream->next_out); - -#ifdef STREAMENGINE_ENABLE_LISTENER - NotifyListenerInflate inflateListener(gEnv->pSystem->GetStreamEngine()->GetListener(), this); -#endif - - size_t nBytesDecomped = m_nBytesDecompressed; - - STREAM_DECOMPRESS_TRACE ("[StreamDecompress],ZlibInflateElementPartial_Impl,0x%x,%s,0x%p,%i,0x%p,%i,%i\n", - CryGetCurrentThreadId(), - m_strFileName.c_str(), - (uint8_t*)m_pReadMemoryBuffer + nBytesDecomped, - m_nFileSize - nBytesDecomped, - (uint8_t*)pSrc + nOffs, - nBytes, - nBytesDecomped); - - int readStatus = Z_OK; - - { - CryOptionalAutoLock decompLock(m_externalBufferLockDecompress, m_pExternalMemoryBuffer != NULL); - - AZ::IO::ZipDir::ZipDirStructuresInternal::ZlibInflateElementPartial_Impl( - &readStatus, - m_pZlibStream, - m_pLookahead, - (uint8_t*)m_pReadMemoryBuffer + nBytesDecomped, - m_nFileSize - nBytesDecomped, - m_bWriteOnlyExternal, - (uint8_t*)pSrc + nOffs, - nBytes, - &nBytesDecomped - ); - } - - m_nBytesDecompressed = nBytesDecomped; - - //inform listen, so aysnc callback does not overlap -#ifdef STREAMENGINE_ENABLE_LISTENER - inflateListener.End(); -#endif - - if (readStatus == Z_OK || readStatus == Z_STREAM_END) - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liEnd, liFreq; - QueryPerformanceCounter(&liEnd); - QueryPerformanceFrequency(&liFreq); - - m_unzipTime += CTimeValue((int64)((liEnd.QuadPart - liStart.QuadPart) * CTimeValue::TIMEVALUE_PRECISION / liFreq.QuadPart)); -#endif - } - else - { -#ifndef _RELEASE - AZ_Assert(false, "Decomp Error: %s : %s\n", m_strFileName.c_str(), m_pZlibStream ? m_pZlibStream->msg : "m_pZlibStream == NULL, no message available"); -#endif - Failed(ERROR_DECOMPRESSION_FAIL); - } - } - - if (pSrcHdr) - { - if (CryInterlockedDecrement(&pSrcHdr->nRefs) == 0) - { - engineState.pTempMem->TempFree(engineState.pHeap, pSrc, pSrcHdr->nSize); - } - } - - job.pSrc = NULL; - - int nPopSlot = m_pDecompQueue->Pop(); - - // job is no longer valid - - if (HasFailed() || bLast) - { - JobFinalize_Decompress(pSelf, engineState); - } - else if (nPopSlot >= 0) - { - // Chain start the next job, we're responsible for it. - STREAM_DECOMPRESS_TRACE("[StreamDecompress],Chaining,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nPopSlot); - JobStart_Decompress(pSelf, engineState, nPopSlot); - } - -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedDecrement(&engineState.pStats->nCurrentDecompressCount); -#endif -} - -////////////////////////////////////////////////////////////////////////// - -uint32 CAsyncIOFileRequest::PushDecompressPage(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nBytes, bool bLast) -{ - uint32 nError = 0; - - for (uint32 nBlockPos = 0; !nError && (nBlockPos < nBytes); nBlockPos += STREAMING_BLOCK_SIZE) - { - bool bLastBlock = (nBlockPos + STREAMING_BLOCK_SIZE) >= nBytes; - uint32 nBlockSize = min(nBytes - nBlockPos, (uint32)STREAMING_BLOCK_SIZE); - - nError = PushDecompressBlock(engineState, pSrc, pSrcHdr, nBlockPos, nBlockSize, bLast && bLastBlock); - } - - return nError; -} - -uint32 CAsyncIOFileRequest::PushDecompressBlock(const SStreamJobEngineState& engineState, void* pSrc, SStreamPageHdr* pSrcHdr, uint32 nOffs, uint32 nBytes, bool bLast) -{ - uint32 nError = m_nError; - - if (!nError) - { - if (pSrcHdr) - { - CryInterlockedIncrement(&pSrcHdr->nRefs); - } - - int nPushJob = m_pDecompQueue->Push(pSrc, pSrcHdr, nOffs, nBytes, bLast); - if (nPushJob >= 0) - { - STREAM_DECOMPRESS_TRACE("[StreamDecompress],PushDecompressBlock,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), m_strFileName.c_str(), this, nPushJob); - - AddRef(); - CAsyncIOFileRequest_TransferPtr pSelf(this); - JobStart_Decompress(pSelf, engineState, nPushJob); - } - } - - return nError; -} - -void CAsyncIOFileRequest::JobStart_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState, int nJob) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],QueueDecompressBlockAppend,0x%x,%s,0x%p,%i\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, nJob); - -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedIncrement(&engineState.pStats->nCurrentDecompressCount); -#endif - - CAsyncIOFileRequest* request = pSelf.Relinquish(); - if (!request->m_decompJobExecutor) - { - request->m_decompJobExecutor = AZStd::make_unique(); - } - request->m_decompJobExecutor->StartJob([request, engineState, nJob]() - { - request->DecompressBlockEntry(engineState, nJob); - }); // Legacy JobManager priority: eStreamPriority -} - -////////////////////////////////////////////////////////////////////////// -void CAsyncIOFileRequest::JobFinalize_Read(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - if (!pSelf->m_bCompressedBuffer || pSelf->HasFailed()) - { - JobFinalize_Transfer(pSelf, engineState); - } -} - -void CAsyncIOFileRequest::JobFinalize_Decompress(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],FinalizeDecompress,0x%x,%s,0x%p,0x%p,0x%p,0x%p\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, &engineState, engineState.pStats, engineState.pDecompressStats); - - CAsyncIOFileRequest* pReq = &*pSelf; - - if (!pReq->HasFailed()) - { - // Handle reads of subsections of a compressed file, by copying the section to the output - uint8_t* pDst = (uint8_t*)pReq->m_pOutputMemoryBuffer; - uint8_t* pSrc = (uint8_t*)pReq->m_pReadMemoryBuffer + pReq->m_nRequestedOffset; - - if (pDst != pSrc) - { - memmove(pReq->m_pOutputMemoryBuffer, pSrc, pReq->m_nRequestedSize); - } - - pReq->JobFinalize_Validate(engineState); - } - - pReq->JobFinalize_Buffer(engineState); - -#if defined(STREAMENGINE_ENABLE_STATS) && defined(STREAMENGINE_ENABLE_TIMING) - if (pReq->m_unzipTime.GetValue() != 0) - { - engineState.pDecompressStats->m_nTotalBytesUnziped += pReq->m_nFileSize; - engineState.pDecompressStats->m_totalUnzipTime += pReq->m_unzipTime; - - engineState.pDecompressStats->m_nTempBytesUnziped += pReq->m_nFileSize; - engineState.pDecompressStats->m_tempUnzipTime += pReq->m_unzipTime; - } -#endif - - JobFinalize_Transfer(pSelf, engineState); -} - -void CAsyncIOFileRequest::JobFinalize_Buffer(const SStreamJobEngineState& engineState) -{ - if (CryInterlockedDecrement(&m_nMemoryBufferUsers) == 0) - { - z_stream_s* pZlib = m_pZlibStream; - - if (pZlib) - { - //if the stream was cancelled in flight, inform zlib to free internal allocs - if (pZlib->state) - { - inflateEnd(pZlib); - } - - m_pZlibStream = NULL; - } - - if (m_pMemoryBuffer) - { - engineState.pTempMem->TempFree(engineState.pHeap, m_pMemoryBuffer, m_nMemoryBufferSize); - - m_pMemoryBuffer = NULL; - m_nMemoryBufferSize = 0; - } - } -} - -void CAsyncIOFileRequest::JobFinalize_Validate([[maybe_unused]] const SStreamJobEngineState& engineState) -{ -#if defined(SKIP_CHECKSUM_FROM_OPTICAL_MEDIA) - if (m_eMediaType != eStreamSourceTypeDisc) -#endif //SKIP_CHECKSUM_FROM_OPTICAL_MEDIA - { - CryOptionalAutoLock readLock(m_externalBufferLockRead, m_pExternalMemoryBuffer != NULL); - if (!HasFailed()) - { - if (m_crc32FromHeader != 0 && m_nPageReadStart == 0 && m_nRequestedSize == m_nFileSize) //Compute the CRC32 if appropriate. - { -#if defined(STREAMENGINE_ENABLE_TIMING) - LARGE_INTEGER liStart, liEnd, liFreq; - QueryPerformanceCounter(&liStart); -#endif //STREAMENGINE_ENABLE_TIMING - - uint32 nCRC32 = crc32(0, (uint8_t*)m_pReadMemoryBuffer + m_nPageReadStart, m_nRequestedSize); - -#if defined(STREAMENGINE_ENABLE_TIMING) - QueryPerformanceCounter(&liEnd); - QueryPerformanceFrequency(&liFreq); - - m_verifyTime += CTimeValue((int64)((liEnd.QuadPart - liStart.QuadPart) * CTimeValue::TIMEVALUE_PRECISION / liFreq.QuadPart)); - - engineState.pDecompressStats->m_nTotalBytesVerified += m_nFileSize; - engineState.pDecompressStats->m_totalVerifyTime += m_verifyTime; - engineState.pDecompressStats->m_nTempBytesVerified += m_nFileSize; - engineState.pDecompressStats->m_tempVerifyTime += m_verifyTime; -#endif //STREAMENGINE_ENABLE_TIMING - - if (m_crc32FromHeader != nCRC32) - { - //The contents of this file don't match what the header expects -#if !defined(_RELEASE) - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR_DBGBRK, "Streaming Engine Failed to verify a file (%s). Computed CRC32 %d does not match stored CRC32 %d", m_strFileName.c_str(), nCRC32, m_crc32FromHeader); -#endif //!_RELEASE - Failed(ERROR_VERIFICATION_FAIL); - } - } - } - } -} - -void CAsyncIOFileRequest::JobFinalize_Transfer(CAsyncIOFileRequest_TransferPtr& pSelf, const SStreamJobEngineState& engineState) -{ - STREAM_DECOMPRESS_TRACE("[StreamDecompress],FinalizeTransform,0x%x,%s,0x%p,0x%p,0x%p,0x%p\n", CryGetCurrentThreadId(), pSelf->m_strFileName.c_str(), &pSelf, &engineState, engineState.pStats, engineState.pDecompressStats); - - if (CryInterlockedCompareExchange(&pSelf->m_nFinalised, 1, 0) == 0) - { -#if defined(STREAMENGINE_ENABLE_STATS) - CryInterlockedIncrement(&engineState.pStats->nCurrentAsyncCount); -#endif - -#if defined(STREAMENGINE_ENABLE_TIMING) - pSelf->m_completionTime = gEnv->pTimer->GetAsyncTime(); -#endif - - int nCallbackThreads = engineState.pReportQueues->size(); - - EStreamTaskType eType = pSelf->m_eType; - if (nCallbackThreads > 1 && eType == eStreamTaskTypeGeometry) - { - // If we have more then 1 call back threads, use this one for geometry only. - (*engineState.pReportQueues)[1]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 2 && eType == eStreamTaskTypeTexture) - { - // If we have more then 1 call back threads, use this one for textures only. - (*engineState.pReportQueues)[2]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 3 && eType == eStreamTaskTypeMergedMesh) - { - // If we have more then 3 call back threads, use this one for merged meshes only. - (*engineState.pReportQueues)[3]->TransferRequest(pSelf); - } - else if (nCallbackThreads > 0) - { - (*engineState.pReportQueues)[0]->TransferRequest(pSelf); - } - else - { - __debugbreak(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void SStreamRequestQueue::TransferRequest(CAsyncIOFileRequest_TransferPtr& pRequest) -{ - { - CryAutoLock l(m_lock); - - m_requests.push_back(pRequest.Relinquish()); - } - - m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void SStreamEngineTempMemStats::TempFree(CMTSafeHeap* pHeap, const void* p, size_t nSize) -{ -#if MTSAFE_USE_GENERAL_HEAP - bool bInGenHeap = pHeap->IsInGeneralHeap(p); -#else - bool bInGenHeap = false; -#endif - pHeap->FreeTemporary(const_cast(p)); - ReportTempMemAlloc(0, bInGenHeap ? 0 : nSize, true); -} - -void SStreamEngineTempMemStats::ReportTempMemAlloc(uint32 nSizeAlloc, uint32 nSizeFree, bool bTriggerWake) -{ - int nAdd = (int)nSizeAlloc - (int)nSizeFree; - int const nOldSize = CryInterlockedExchangeAdd(&m_nTempAllocatedMemory, nAdd); - int const nNewSize = nOldSize + nAdd; - - LONG nNewMax = 0; - LONG nOldMax = 0; - do - { - nOldMax = m_nTempAllocatedMemoryFrameMax; - nNewMax = (LONG)max((int)nNewSize, (int)nOldMax); - } - while (CryInterlockedCompareExchange(&m_nTempAllocatedMemoryFrameMax, nNewMax, nOldMax) != nOldMax); - - if (bTriggerWake) - { - for (int i = 0, c = m_nWakeEvents; i != c; ++i) - { - m_wakeEvents[i]->Set(); - } - } -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp deleted file mode 100644 index 37a7de8391..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.cpp +++ /dev/null @@ -1,1709 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine implementation - - -#include "CrySystem_precompiled.h" -#include "StreamEngine.h" - -//CReadStream is 99% unused since the introduction of AZRequestReadStream. -//In the near future CReadStream will disappear altogether and StreamReadStream cpp/h -// won't be needed anymore. -#include "StreamReadStream.h" - -#include "AZRequestReadStream.h" -#include "Pak/CryPakUtils.h" - -#include "../System.h" - -#include -#include - -#include -#include - -#define MAX_HEAVY_ASSETS 20 - -#if defined(STREAMENGINE_ENABLE_STATS) -SStreamEngineStatistics* g_pStreamingStatistics = 0; -#endif - -SStreamEngineOpenStats* g_pStreamingOpenStatistics = 0; - -extern CMTSafeHeap* g_pPakHeap; - -////////////////////////////////////////////////////////////////////////// -CStreamEngine::CStreamEngine() - : AzFramework::InputChannelEventListener(AzFramework::InputChannelEventListener::GetPriorityDebug()) -{ - m_nBatchMode = 0; - m_bShutDown = false; - m_bUseOpticalDriveThread = g_cvars.sys_streaming_use_optical_drive_thread != 0; - m_nPausedDataTypesMask = 0; - m_bStreamDataOnHDD = gEnv->pCryPak->IsInstalledToHDD(); - -#ifdef STREAMENGINE_ENABLE_STATS - g_pStreamingStatistics = &m_Statistics; - m_Statistics.nPendingReadBytes = 0; - - m_Statistics.nCurrentAsyncCount = 0; - m_Statistics.nCurrentDecompressCount = 0; - m_Statistics.nCurrentFinishedCount = 0; - - memset(&m_decompressStats, 0, sizeof(m_decompressStats)); - - m_nUnzipBandwidth = 0; - m_nUnzipBandwidthAverage = 0; - m_bStreamingStatsPaused = false; - m_bInputCallback = false; - m_bTempMemOutOfBudget = false; - - ClearStatistics(); -#endif - - memset(&m_OpenStatistics, 0, sizeof(m_OpenStatistics)); - g_pStreamingOpenStatistics = &m_OpenStatistics; - -#ifdef STREAMENGINE_ENABLE_LISTENER - m_pListener = NULL; -#endif - - StartThreads(); - - // register system listener - GetISystem()->GetISystemEventDispatcher()->RegisterListener(this); -} - -////////////////////////////////////////////////////////////////////////// -// MT: Main thread only -CStreamEngine::~CStreamEngine() -{ -#ifdef STREAMENGINE_ENABLE_STATS - g_pStreamingStatistics = 0; - if (m_bInputCallback) - { - AzFramework::InputChannelEventListener::Disconnect(); - } -#endif - g_pStreamingOpenStatistics = NULL; - Shutdown(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::BeginReadGroup() -{ - CryInterlockedIncrement(&m_nBatchMode); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::EndReadGroup() -{ - CryInterlockedDecrement(&m_nBatchMode); - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - // New requests accomulated untill all Start stream requests are submitted and can be properly sorted. - m_pThreadIO[i]->SignalStartWork(false); - } - } -} - -AZ::IO::IStreamerTypes::Priority CStreamEngine::CryStreamPriorityToAZStreamPriority(EStreamTaskPriority cryPriority) -{ - switch (cryPriority) - { - case estpUrgent: - return AZ::IO::IStreamerTypes::s_priorityHighest; - // estpPreempted = 1, //For internal use only - case estpAboveNormal: - return AZ::IO::IStreamerTypes::s_priorityHigh; - case estpNormal: - return AZ::IO::IStreamerTypes::s_priorityMedium; - case estpBelowNormal: - return AZ::IO::IStreamerTypes::s_priorityLow; - case estpIdle: - [[fallthrough]]; - default: - return AZ::IO::IStreamerTypes::s_priorityLowest; - } -} - -AZStd::chrono::milliseconds CStreamEngine::AZDeadlineFromReadParams(const StreamReadParams& params) -{ - - if (params.nLoadTime == 0) - { - // File should be loaded right away. - return AZStd::chrono::milliseconds(0); - } - else - { - return AZStd::chrono::milliseconds(AZStd::max(params.nLoadTime, params.nMaxLoadTime)); - } -} - -////////////////////////////////////////////////////////////////////////// -// Starts asynchronous read from the specified file -// It is expected that the callbacks are called from Main Thread only when -// the async data loading is finished. -IReadStreamPtr CStreamEngine::StartRead (const EStreamTaskType tSource, const char* szFilePath, IStreamCallback* pCallback, const StreamReadParams* pParams) -{ - using namespace AZ::IO; - - if (!szFilePath) - { - CryFatalError("Use of the stream engine without a file is deprecated! Use the job system."); - return NULL; - } - - if (gEnv->IsDedicated()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Attempting to use the stream engine on a dedicated server! Don't do that!"); - return NULL; - } - - if (!m_bShutDown) - { - AZRequestReadStream* pStream = AZRequestReadStream::Allocate(tSource, szFilePath, pCallback, pParams); - if (!pStream) - { - CryFatalError("Failed to create Request Stream for %s", szFilePath); - return nullptr; - } - - size_t offset = pParams ? pParams->nOffset : 0; - AZStd::chrono::microseconds deadline = pParams - ? AZStd::chrono::duration_cast(AZDeadlineFromReadParams(*pParams)) - : AZStd::chrono::microseconds(0); - AZ::IO::IStreamerTypes::Priority priority = pParams - ? CryStreamPriorityToAZStreamPriority(pParams->ePriority) - : AZ::IO::IStreamerTypes::s_priorityHighest; - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - pStream->AddRef(); - - auto callback = [this, pStream](FileRequestHandle request) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRenderDetailed); - auto streamer = AZ::Interface::Get(); - void* buffer = nullptr; - AZ::u64 bytesRead = 0; - [[maybe_unused]] bool result = streamer->GetReadRequestResult(request, buffer, bytesRead); - AZ_Assert(result, "Cry Stream Engine requested a callback on reading, but couldn't retrieve result."); - QueueRequestCompleteJob(pStream, bytesRead, buffer, streamer->GetRequestStatus(request)); - // Release reference that was taken above in order to hold onto stream while job is queued - pStream->Release(); - }; - - // Register stream and start file request. - IReadStreamPtr result = static_cast(pStream); - - auto streamer = AZ::Interface::Get(); - FileRequestPtr azRequest = streamer->Read(szFilePath, pStream->GetFileReadBuffer(), pStream->GetFileSize(), - pStream->GetFileSize(), deadline, priority, offset); - streamer->SetRequestCompleteCallback(azRequest, callback); - pStream->SetFileRequest(azRequest); - streamer->QueueRequest(azRequest); - - return result; - } - - return NULL; -} - -//It is NOT necessary to schedule the callbacks on the main thread. -//Regular async calls is OK. -size_t CStreamEngine::StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback) -{ - using namespace AZ::IO; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - - size_t nValidStreams = 0; - - if (!m_bShutDown) - { - enum - { - MaxStreamsPerBatch = 32 - }; - - size_t nReqIdx = 0; - - // we have requests to evaluate, call the callback before enqueing the requests - if (numReqs > 0 && preRequestCallback != nullptr) - { - (*preRequestCallback)(); - } - - if (numReqs > 0) - { - numReqs = AZStd::min(numReqs, aznumeric_cast(MaxStreamsPerBatch)); - AZStd::vector batch; - - auto streamer = AZ::Interface::Get(); - streamer->CreateRequestBatch(batch, numReqs); - - while (numReqs > 0) - { - const StreamReadBatchParams& args = pReqs[nReqIdx]; - - if (!args.szFile) - { - CryFatalError("Use of the stream engine without a file is deprecated! Use the job system."); - } - - AZRequestReadStream* pStream; - - { - FRAME_PROFILER_FAST("CStreamEngine::StartBatchRead_AllocReadStream", gEnv->pSystem, PROFILE_SYSTEM, gEnv->bProfilerEnabled); - pStream = AZRequestReadStream::Allocate(args.tSource, args.szFile, args.pCallback, &args.params); - } - - if (pStream) - { - FileRequestPtr& request = batch[nValidStreams]; - pStreamsOut[nValidStreams++] = pStream; - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - pStream->AddRef(); - auto callback = [this, pStream](FileRequestHandle request) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRenderDetailed); - auto streamer = AZ::Interface::Get(); - void* buffer = nullptr; - AZ::u64 bytesRead = 0; - [[maybe_unused]] bool result = streamer->GetReadRequestResult(request, buffer, bytesRead); - AZ_Assert(result, "Cry Stream Engine requested a callback on reading, but couldn't retrieve result."); - QueueRequestCompleteJob(pStream, bytesRead, buffer, streamer->GetRequestStatus(request)); - // Release reference that was taken above in order to hold onto stream while job is queued - pStream->Release(); - }; - - streamer->Read(request, args.szFile, pStream->GetFileReadBuffer(), pStream->GetFileSize(), - pStream->GetFileSize(), AZDeadlineFromReadParams(args.params), - CryStreamPriorityToAZStreamPriority(args.params.ePriority), args.params.nOffset); - streamer->SetRequestCompleteCallback(request, callback); - pStream->SetFileRequest(request); - } - else - { - CryFatalError("Failed to create Request Stream for %s at mip number %d", args.szFile, (int)nReqIdx); - } - - --numReqs; - ++nReqIdx; - } - - streamer->QueueRequestBatch(AZStd::move(batch)); - } - } - - return nValidStreams; -} - -void CStreamEngine::QueueRequestCompleteJob(AZRequestReadStream* stream, AZ::IO::SizeType numBytesRead, void* buffer, - AZ::IO::IStreamerTypes::RequestStatus requestState) -{ - // Some graphics APIs don't support multiple threads instancing resources such as textures. To work around this limitation - // the jobs that complete a streaming request are queued and a previous request will kick off the next one. This will cause - // only one job that finishes a streaming request to ever be active without causing mutexes to cause stalls in the job system. - - // Add a ref to stream before binding to the callback. Callback will release the reference when it's invoked. - stream->AddRef(); - auto jobFunction = [this, stream, numBytesRead, buffer, requestState]() - { - stream->OnRequestComplete(numBytesRead, buffer, requestState); - // Release reference that was taken above in order to hold onto stream while job is queued - stream->Release(); - - CryAutoLock lock(m_pendingRequestCompletionsLock); - AZ_Assert(!m_pendingRequestCompletions.empty(), - "CStreamEngine::QueueRequestCompleteJob expects at least one job in the queue as this is this is the job ran from the callback.") - // The top request is always the one that's running, so pop that one of the queue and start any other pending jobs. - m_pendingRequestCompletions.pop(); - if (!m_pendingRequestCompletions.empty()) - { - m_pendingRequestCompletions.front()->Start(); - } - }; - - AZ::Job* job = AZ::CreateJobFunction(jobFunction, true, AZ::JobContext::GetGlobalContext()); - - CryAutoLock lock(m_pendingRequestCompletionsLock); - if (m_pendingRequestCompletions.empty()) - { - m_pendingRequestCompletions.push(job); - job->Start(); - } - else - { - m_pendingRequestCompletions.push(job); - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::ResumePausedStreams_PauseLocked() -{ - for (size_t i = 0; i < (size_t)m_pausedStreams.size(); ) - { - CReadStream* pStream = (CReadStream*)(IReadStream*)m_pausedStreams[i]; - int nStreamMask = 1 << (uint32)pStream->m_Type; - if (0 == (nStreamMask & m_nPausedDataTypesMask)) - { - if (pStream->GetError() == 0) // If was not aborted - { - // This stream must be resumed - m_streams.insert(pStream); - CAsyncIOFileRequest* pFileRequest = pStream->CreateFileRequest(); - if (!StartFileRequest(pFileRequest)) - { - pFileRequest->Release(); - } - } - m_pausedStreams.erase(m_pausedStreams.begin() + i); - } - else - { - i++; - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CStreamEngine::StartFileRequest(CAsyncIOFileRequest* pFileRequest) -{ - bool bStartImmidietly = m_nBatchMode == 0; - - EStreamSourceMediaType eMediaType = pFileRequest->GetMediaType(); - bool bQueued = false; - - CStreamingIOThread* pIO = m_pThreadIO[0]; - - for (size_t i = 1; i < eIOThread_Last; ++i) - { - CStreamingIOThread* pAltIO = m_pThreadIO[i]; - - if (pAltIO && pAltIO->GetMediaType() == eMediaType) - { - pIO = pAltIO; - break; - } - } - - if (pIO) - { -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamEnqueue(pFileRequest, pFileRequest->m_strFileName.c_str(), pFileRequest->m_pReadStream->GetCallerType(), pFileRequest->m_pReadStream->GetParams()); - } -#endif - - pIO->AddRequest(pFileRequest, bStartImmidietly); - bQueued = true; - } - - if (!bQueued) - { - assert(0); // No IO thread. - return false; - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.typeInfo[pFileRequest->m_eType].nTotalStreamingRequestCount++; - - if (g_cvars.sys_streaming_debug == 3) - { - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!pFileRequest->m_strFileName.empty() && !m_bStreamingStatsPaused) - { - if (!sFileFilter || !sFileFilter[0] || strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - CryAutoCriticalSection lock(m_csStats); - m_statsRequestList.insert(m_statsRequestList.begin(), pFileRequest); - } - } - } -#endif - - return true; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::SignalToStartWork(EIOThread e, bool bForce) -{ - if ((e >= 0) && (e < eIOThread_Last)) - { - if (m_pThreadIO[e]) - { - m_pThreadIO[e]->SignalStartWork(bForce); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -#ifdef STREAMENGINE_ENABLE_STATS -void UpdateIOThreadStats( - SStreamEngineStatistics::SMediaTypeInfo* pNotInMemoryInfo, - SStreamEngineStatistics::SMediaTypeInfo* pInMemoryInfo, - CStreamingIOThread* pIOThread, - float fSecSinceLastReset) -{ - if (pNotInMemoryInfo == 0 || pIOThread == 0) - { - return; - } - - // not in memory reading - pNotInMemoryInfo->fActiveDuringLastSecond = pIOThread->m_NotInMemoryStats.m_fReadingDuringLastSecond; - pNotInMemoryInfo->fAverageActiveTime = - pIOThread->m_NotInMemoryStats.m_TotalReadTime.GetSeconds() / fSecSinceLastReset * 100; - - pNotInMemoryInfo->nBytesRead = pIOThread->m_NotInMemoryStats.m_nReadBytesInLastSecond; - pNotInMemoryInfo->nRequestCount = pIOThread->m_NotInMemoryStats.m_nRequestCountInLastSecond; - pNotInMemoryInfo->nTotalBytesRead = pIOThread->m_NotInMemoryStats.m_nTotalReadBytes; - pNotInMemoryInfo->nTotalRequestCount = pIOThread->m_NotInMemoryStats.m_nTotalRequestCount; - - pNotInMemoryInfo->nSeekOffsetLastSecond = pIOThread->m_NotInMemoryStats.m_nReadOffsetInLastSecond; - if (pIOThread->m_NotInMemoryStats.m_nTotalRequestCount > 0) - { - pNotInMemoryInfo->nAverageSeekOffset = pIOThread->m_NotInMemoryStats.m_nTotalReadOffset / - pIOThread->m_NotInMemoryStats.m_nTotalRequestCount; - } - else - { - pNotInMemoryInfo->nAverageSeekOffset = 0; - } - - pNotInMemoryInfo->nCurrentReadBandwidth = pIOThread->m_NotInMemoryStats.m_nCurrentReadBandwith; - pNotInMemoryInfo->nSessionReadBandwidth = (uint32)(pNotInMemoryInfo->nTotalBytesRead / fSecSinceLastReset); - - pNotInMemoryInfo->nActualReadBandwidth = pIOThread->m_NotInMemoryStats.m_nActualReadBandwith; - float fTotalReadTime = pIOThread->m_NotInMemoryStats.m_TotalReadTime.GetSeconds(); - if (fTotalReadTime > 0.0f) - { - pNotInMemoryInfo->nAverageActualReadBandwidth = (uint32)(pNotInMemoryInfo->nTotalBytesRead / fTotalReadTime); - } - - // in memory reading - if (pInMemoryInfo) - { - pInMemoryInfo->nBytesRead = pIOThread->m_InMemoryStats.m_nReadBytesInLastSecond; - pInMemoryInfo->nRequestCount = pIOThread->m_InMemoryStats.m_nRequestCountInLastSecond; - pInMemoryInfo->nTotalBytesRead = pIOThread->m_InMemoryStats.m_nTotalReadBytes; - pInMemoryInfo->nTotalRequestCount = pIOThread->m_InMemoryStats.m_nTotalRequestCount; - } -} -#endif - -void CStreamEngine::Update(uint32 nUpdateTypesBitmask) -{ - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_SYSTEM); - AZ_TRACE_METHOD(); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - // Dispatch completed callbacks. - MainThread_FinalizeIOJobs(nUpdateTypesBitmask); -} - -// Gets called regularly, to finalize those proxies whose jobs have -// already been executed (e.g. to call the callbacks) -// - to be called from the main thread only -// - starts new jobs in the single-threaded model -void CStreamEngine::Update() -{ - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - // Dispatch completed callbacks. - MainThread_FinalizeIOJobs(); - -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_resetstats) - { - ClearStatistics(); - g_cvars.sys_streaming_resetstats = 0; - } - - CTimeValue t = gEnv->pTimer->GetAsyncTime(); - if ((t - m_nLastBandwidthUpdateTime).GetMilliSecondsAsInt64() > 1000) - { - // Repeat every second. - m_nUnzipBandwidth = m_decompressStats.m_tempUnzipTime.GetValue() == 0 ? 0 : (uint32)(m_decompressStats.m_nTempBytesUnziped / m_decompressStats.m_tempUnzipTime.GetSeconds()); - m_nVerifyBandwidth = m_decompressStats.m_tempVerifyTime.GetValue() == 0 ? 0 : (uint32)(m_decompressStats.m_nTempBytesVerified / m_decompressStats.m_tempVerifyTime.GetSeconds()); - - m_decompressStats.m_tempUnzipTime.SetValue(0); - m_decompressStats.m_nTempBytesUnziped = 0; - m_decompressStats.m_tempVerifyTime.SetValue(0); - m_decompressStats.m_nTempBytesVerified = 0; - - m_nLastBandwidthUpdateTime = t; - } - if (m_decompressStats.m_totalUnzipTime.GetValue() != 0) - { - m_nUnzipBandwidthAverage = (uint32)(m_decompressStats.m_nTotalBytesUnziped / m_decompressStats.m_totalUnzipTime.GetSeconds()); - } - if (m_decompressStats.m_totalVerifyTime.GetValue() != 0) - { - m_nVerifyBandwidthAverage = (uint32)(m_decompressStats.m_nTotalBytesVerified / m_decompressStats.m_totalVerifyTime.GetSeconds()); - } - - m_Statistics.nDecompressBandwidth = m_nUnzipBandwidth; - m_Statistics.nVerifyBandwidth = m_nVerifyBandwidth; - m_Statistics.nDecompressBandwidthAverage = m_nUnzipBandwidthAverage; - m_Statistics.nVerifyBandwidthAverage = m_nVerifyBandwidthAverage; - - CTimeValue currentTime = gEnv->pTimer->GetAsyncTime(); - - CTimeValue timeSinceLastReset = currentTime - m_TimeOfLastReset; - float fSecSinceLastReset = timeSinceLastReset.GetSeconds(); - - CTimeValue timeSinceLastUpdate = currentTime - m_TimeOfLastUpdate; - - // update the stats every second - if (timeSinceLastUpdate.GetMilliSecondsAsInt64() > 1000) - { - UpdateIOThreadStats(&m_Statistics.hddInfo, &m_Statistics.memoryInfo, m_pThreadIO[eIOThread_HDD], fSecSinceLastReset); - UpdateIOThreadStats(&m_Statistics.discInfo, 0, m_pThreadIO[eIOThread_Optical], fSecSinceLastReset); - UpdateIOThreadStats(&m_Statistics.memoryInfo, 0, m_pThreadIO[eIOThread_InMemory], fSecSinceLastReset); - - SStreamEngineStatistics::SRequestTypeInfo totals; - - // update stats on all types - for (int i = 0; i < eStreamTaskTypeCount; i++) - { - SStreamEngineStatistics::SRequestTypeInfo& info = m_Statistics.typeInfo[i]; - - if (info.nTotalStreamingRequestCount) - { - info.fAverageCompletionTime = info.fTotalCompletionTime / info.nTotalStreamingRequestCount; - } - else - { - info.fAverageCompletionTime = 0; - } - info.nSessionReadBandwidth = (uint32)(info.nTotalReadBytes / fSecSinceLastReset); - info.nCurrentReadBandwidth = (uint32)(info.nTmpReadBytes / timeSinceLastUpdate.GetSeconds()); - - info.fAverageRequestCount = info.nTotalStreamingRequestCount / fSecSinceLastReset; - - totals.Merge(info); - - info.nTmpReadBytes = 0; - } - - if (totals.nTotalStreamingRequestCount > 0) - { - m_Statistics.fAverageCompletionTime = totals.fTotalCompletionTime / totals.nTotalStreamingRequestCount; - } - - m_Statistics.nTotalSessionReadBandwidth = (uint32)(totals.nTotalReadBytes / fSecSinceLastReset); - m_Statistics.nTotalCurrentReadBandwidth = (uint32)(totals.nTmpReadBytes / timeSinceLastUpdate.GetSeconds()); - m_Statistics.fAverageRequestCount = totals.nTotalStreamingRequestCount / fSecSinceLastReset; - - m_Statistics.nTotalRequestCount = totals.nTotalRequestCount; - m_Statistics.nTotalStreamingRequestCount = totals.nTotalStreamingRequestCount; - m_Statistics.nTotalBytesRead = totals.nTotalReadBytes; - - // update this flag only once a second to be sure it's visible in display info - m_Statistics.bTempMemOutOfBudget = m_bTempMemOutOfBudget; - m_bTempMemOutOfBudget = false; - - m_TimeOfLastUpdate = currentTime; - } - - int nTmpAllocated = m_tempMem.m_nTempAllocatedMemoryFrameMax; - m_Statistics.nMaxTempMemory = max(m_Statistics.nMaxTempMemory, nTmpAllocated); - m_Statistics.nTempMemory = nTmpAllocated; - - m_tempMem.m_nTempAllocatedMemoryFrameMax = m_tempMem.m_nTempAllocatedMemory; - - if (m_Statistics.vecHeavyAssets.size() > MAX_HEAVY_ASSETS) - { - AZStd::sort(m_Statistics.vecHeavyAssets.begin(), m_Statistics.vecHeavyAssets.end()); - m_Statistics.vecHeavyAssets.resize(MAX_HEAVY_ASSETS); - } - - if (g_cvars.sys_streaming_debug) - { - DrawStatistics(); - - if (!m_bInputCallback) - { - AzFramework::InputChannelEventListener::Connect(); - m_bInputCallback = true; - } - } -#endif -} - -////////////////////////////////////////////////////////////////////////// -// Only waits at most the specified amount of time for some IO to complete -void CStreamEngine::UpdateAndWait(bool bAbortAll) -{ - // for stream->Wait sync - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - - if (bAbortAll) - { - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->AbortAll(bAbortAll); - } - } - } - - while (!m_finishedStreams.empty() || !m_streams.empty()) - { - Update(); - // In case we still have cancelled or aborted streams in the queue, - // we wake the io threads here to ensure they are removed correctly; - for (uint32 i = 0; i < (uint32)eIOThread_Last; ++i) - { - SignalToStartWork((EIOThread)i, true); - } - CrySleep(10); - } - - if (bAbortAll) - { - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->AbortAll(false); - } - } - } -} - -// In the Multi-Threaded model (with the IO Worker thread) -// removes the proxies from the IO Queue as needed, and the proxies may call their callbacks -void CStreamEngine::MainThread_FinalizeIOJobs(uint32 type) -{ - static bool bNoReentrant = false; - - if (!bNoReentrant) - { - bNoReentrant = true; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks(); -#endif - - int nCount = 0; - - CryMT::vector finishedStreams; - // Dispatch completed callbacks. - CReadStream_AutoPtr pStream(0); - while (m_finishedStreams.try_pop_front(pStream)) - { - if (pStream->m_Type & type) - { - pStream->MainThread_Finalize(); - -#ifdef STREAMENGINE_ENABLE_STATS - // update statistics - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); - UpdateStatistics(pStream); -#endif - - m_streams.erase(pStream); - - nCount++; - // perform time slicing if requested - if (g_cvars.sys_streaming_max_finalize_per_frame > 0 && - nCount > g_cvars.sys_streaming_max_finalize_per_frame) - { - break; - } - } - else - { - finishedStreams.push_back(pStream); - } - } - - bNoReentrant = false; - - while (finishedStreams.try_pop_front(pStream)) - { - m_finishedStreams.push_back(pStream); - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks() - m_Statistics.nMainStreamingThreadWait; -#endif - } -} - - -// In the Multi-Threaded model (with the IO Worker thread) -// removes the proxies from the IO Queue as needed, and the proxies may call their callbacks -void CStreamEngine::MainThread_FinalizeIOJobs() -{ - static bool bNoReentrant = false; - - if (!bNoReentrant) - { - bNoReentrant = true; - - FUNCTION_PROFILER(GetISystem(), PROFILE_SYSTEM); - LOADING_TIME_PROFILE_SECTION(gEnv->pSystem); - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks(); -#endif - - int nCount = 0; - - //Optim: swap finished streams out into a non MT vector - //avoid expensive push / pop operations. - m_tempFinishedStreams.clear(); - m_finishedStreams.swap(m_tempFinishedStreams); - - int numFinishedStreams = m_tempFinishedStreams.size(); - - // Dispatch completed callbacks. - for (int i = 0; i < numFinishedStreams; i++) - { - CReadStream_AutoPtr pStream = m_tempFinishedStreams[i]; - - //Check for a certain type of error that we need to handle in a TRC compliant way - if (pStream->GetError() == ERROR_VERIFICATION_FAIL) - { -#if !defined(_RELEASE) - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_COMMENT, "Stream error detected."); -#endif //!_RELEASE - } - - pStream->MainThread_Finalize(); - -#ifdef STREAMENGINE_ENABLE_STATS - // update statistics - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); - UpdateStatistics(pStream); -#endif - - m_streams.erase(pStream); - - nCount++; - - // AM: Optim, no longer support this behavior - // perform time slicing if requested - if (g_cvars.sys_streaming_max_finalize_per_frame > 0 && - nCount > g_cvars.sys_streaming_max_finalize_per_frame) - { - CryLogAlways("sys_streaming_max_finalize_per_frame is now deprecated"); - //break; - } - } - - m_tempFinishedStreams.clear(); - - bNoReentrant = false; - -#ifdef STREAMENGINE_ENABLE_STATS - m_Statistics.nMainStreamingThreadWait = CryGetTicks() - m_Statistics.nMainStreamingThreadWait; -#endif - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::UpdateJobPriority(IReadStreamPtr pJobStream) -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->NeedSorting(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::StopThreads() -{ - for (int i = 0; i < eIOThread_Last; i++) - { - m_pThreadIO[i] = 0; - } - - m_asyncCallbackThreads.clear(); - m_tempMem.m_nWakeEvents = 0; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::StartThreads() -{ - StopThreads(); - - m_tempMem.m_nWakeEvents = 0; - - m_pThreadIO[eIOThread_HDD] = new CStreamingIOThread(this, eStreamSourceTypeHDD, "Streaming File IO HDD");//, 160); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_HDD]->GetWakeEvent(); - - if (!(gEnv->IsDedicated())) - { - if (m_bUseOpticalDriveThread) - { - m_pThreadIO[eIOThread_Optical] = new CStreamingIOThread(this, eStreamSourceTypeDisc, "Streaming File IO Optical"); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_Optical]->GetWakeEvent(); - } - - m_pThreadIO[eIOThread_InMemory] = new CStreamingIOThread(this, eStreamSourceTypeMemory, "Streaming File IO InMemory"); - m_tempMem.m_wakeEvents[m_tempMem.m_nWakeEvents++] = &m_pThreadIO[eIOThread_InMemory]->GetWakeEvent(); - } - - // Initialise fallback thread matrix, needed for rescheduling - for (int i = 0; i < eIOThread_Last; ++i) - { - if (!m_pThreadIO[i]) - { - continue; - } - - for (int j = 0; j < eIOThread_Last; ++j) - { - if (i == j) - { - continue; - } - if (!m_pThreadIO[j]) - { - continue; - } - - m_pThreadIO[i]->RegisterFallbackIOThread(m_pThreadIO[j]->GetMediaType(), m_pThreadIO[j]); - } - } - - // More decompress threads can be added here. - m_asyncCallbackQueues.push_back(new SStreamRequestQueue); - m_asyncCallbackThreads.push_back(new CStreamingWorkerThread(this, "Streaming AsyncCallback", CStreamingWorkerThread::eWorkerAsyncCallback, m_asyncCallbackQueues.back())); - - //m_asyncCallbackThreads.push_back( new CStreamingWorkerThread(this,"Streaming AsyncCallback Pak 1",CStreamingWorkerThread::eWorkerAsyncCallback, m_asyncCallbackQueues[eStreamTaskTypePak]) ); -} - -//! Puts the memory statistics into the given sizer object -//! According to the specifications in interface ICrySizer -void CStreamEngine::GetMemoryStatistics(ICrySizer* pSizer) -{ - SIZER_COMPONENT_NAME(pSizer, "CRefStreamEngine"); - - size_t nSize = sizeof(*this); - - pSizer->AddObject(this, nSize); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::AbortJob(CReadStream* pStream) -{ - if (m_finishedStreams.try_remove((CReadStream*)pStream)) - { -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedDecrement(&m_Statistics.nCurrentFinishedCount); -#endif - } - - { - CryAutoLock pausedLock(m_pausedLock); - if (!m_pausedStreams.empty()) - { - std::vector::iterator it = std::find(m_pausedStreams.begin(), m_pausedStreams.end(), pStream); - if (it != m_pausedStreams.end()) - { - m_pausedStreams.erase(it); - } - } - } - - m_streams.erase(pStream); -} - -#if defined(STREAMENGINE_ENABLE_STATS) -SStreamEngineStatistics& CStreamEngine::GetStreamingStatistics() -{ - return m_Statistics; -} -#endif - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::UpdateStatistics(CReadStream* pReadStream) -{ - uint32 nBytesRead = pReadStream->m_nBytesRead; - - SStreamEngineStatistics::SRequestTypeInfo& info = m_Statistics.typeInfo[pReadStream->m_Type]; - info.nTotalRequestCount++; - - // only add to stats if request was valid - const string& name = pReadStream->GetName(); - if (name.length() > 0) - { - info.nTotalReadBytes += nBytesRead; - info.nTmpReadBytes += nBytesRead; - info.nTotalRequestDataSize += pReadStream->m_Params.nSize; - - CTimeValue completionTime = gEnv->pTimer->GetAsyncTime() - pReadStream->GetRequestTime(); - float fCompletionTime = completionTime.GetMilliSeconds(); - info.fTotalCompletionTime += fCompletionTime; - - size_t splitter = name.find_last_of("."); - if (splitter != string::npos) - { - string extension = name.substr(splitter + 1); - TExtensionInfoMap::iterator findRes = m_PerExtensionInfo.find(extension); - if (findRes == m_PerExtensionInfo.end()) - { - m_PerExtensionInfo[extension] = SExtensionInfo(); - findRes = m_PerExtensionInfo.find(extension); - } - - SExtensionInfo& extensionInfo = findRes->second; - extensionInfo.m_fTotalReadTime += pReadStream->m_ReadTime.GetMilliSeconds(); - extensionInfo.m_nTotalRequests++; - extensionInfo.m_nTotalReadSize += nBytesRead; - extensionInfo.m_nTotalRequestSize += pReadStream->m_Params.nSize; - } - } - - if (nBytesRead > 64 * 1024) - { - m_Statistics.vecHeavyAssets.push_back(SStreamEngineStatistics::SAsset(pReadStream->m_strFileName, nBytesRead)); - } -} -#endif - -void CStreamEngine::Shutdown() -{ - m_bShutDown = true; - - // make sure we don't have queued paused streams during shutdown for the audio system - // or we can suffer from deadlocks - uint32 nPauseMask = GetPauseMask(); - uint32 nUnPauseMask = ~(nPauseMask & ~STREAM_TASK_TYPE_AUDIO_ALL); - PauseStreaming(false, nUnPauseMask); - PauseStreaming(true, nPauseMask); - - UpdateAndWait(true); - CancelAll(); - - StopThreads(); - - m_streams.clear(); - m_finishedStreams.clear(); - - // unregister system listener - GetISystem()->GetISystemEventDispatcher()->RemoveListener(this); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::CancelAll() -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->BeginReset(); - } - } - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->EndReset(); - } - } - - for (size_t i = 0; i < m_asyncCallbackThreads.size(); ++i) - { - m_asyncCallbackThreads[i]->BeginReset(); - } - for (size_t i = 0; i < m_asyncCallbackThreads.size(); ++i) - { - m_asyncCallbackThreads[i]->EndReset(); - } - - // make sure we don't check for canceled tasks when destroying the m_finishedStreams container - m_streams.clear(); - stl::free_container(m_finishedStreams); - stl::free_container(m_tempFinishedStreams); - { - CryAutoLock lock(m_pausedLock); - - std::vector paused; - paused.swap(m_pausedStreams); - - for (std::vector::iterator it = paused.begin(), itEnd = paused.end(); it != itEnd; ++it) - { - CReadStream* pStream = &**it; - pStream->AbortShutdown(); - } - } - - CReadStream::Flush(); - CAsyncIOFileRequest::Flush(); -} - - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::ReportAsyncFileRequestComplete(CAsyncIOFileRequest_AutoPtr pFileRequest) -{ - if (!pFileRequest->IsCancelled()) - { -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamBeginAsyncCallback(&*pFileRequest); - } -#endif - - if (pFileRequest->m_pCallback) - { - pFileRequest->m_pCallback->OnAsyncFinished(pFileRequest); - } - if (pFileRequest->m_pReadStream) - { - CReadStream_AutoPtr pStream = (CReadStream*)(IReadStream*)pFileRequest->m_pReadStream; - pStream->OnAsyncFileRequestComplete(); - m_finishedStreams.push_back(pStream); - -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedIncrement(&m_Statistics.nCurrentFinishedCount); -#endif - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - if (m_pListener) - { - m_pListener->OnStreamEndAsyncCallback(&*pFileRequest); - } -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug != 0) - { - if (g_cvars.sys_streaming_debug == 2 || g_cvars.sys_streaming_debug == 4) - { - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!pFileRequest->m_strFileName.empty() && !m_bStreamingStatsPaused) - { - if (!sFileFilter || !sFileFilter[0] || strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - CryAutoCriticalSection lock(m_csStats); - m_statsRequestList.insert(m_statsRequestList.begin(), pFileRequest); - } - } - } - } -#endif - } -} - -////////////////////////////////////////////////////////////////////////// -const char* CStreamEngine::GetStreamTaskTypeName(EStreamTaskType type) -{ - switch (type) - { - case eStreamTaskTypeMusic: - return "Music"; - case eStreamTaskTypeAnimation: - return "Animation"; - case eStreamTaskTypeGeometry: - return "Geometry"; - case eStreamTaskTypeSound: - return "Sound"; - case eStreamTaskTypeTexture: - return "Texture"; - case eStreamTaskTypeShader: - return "Shader"; - case eStreamTaskTypeTerrain: - return "Terrain"; - case eStreamTaskTypeVideo: - return "Video"; - case eStreamTaskTypeFlash: - return "Flash"; - case eStreamTaskTypePak: - return "Pak"; - case eStreamTaskTypeGeomCache: - return "GeomCache"; - case eStreamTaskTypeMergedMesh: - return "MergedMesh"; - } - return ""; -} - -SStreamJobEngineState CStreamEngine::GetJobEngineState() -{ - m_tempMem.m_nTempMemoryBudget = g_cvars.sys_streaming_memory_budget * 1024; - - SStreamJobEngineState state; - state.pReportQueues = &m_asyncCallbackQueues; -#ifdef STREAMENGINE_ENABLE_STATS - state.pStats = &m_Statistics; - state.pDecompressStats = &m_decompressStats; -#endif - state.pHeap = g_pPakHeap; - state.pTempMem = &m_tempMem; - return state; -} - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::GetBandwidthStats(EStreamTaskType type, float* bandwidth) -{ - *bandwidth = m_Statistics.typeInfo[type].nCurrentReadBandwidth / 1024.0f; -} -#endif - -void CStreamEngine::GetStreamingOpenStatistics(SStreamEngineOpenStats& openStatsOut) -{ - openStatsOut = m_OpenStatistics; -} - -#ifdef STREAMENGINE_ENABLE_LISTENER -void CStreamEngine::SetListener(IStreamEngineListener* pListener) -{ - m_pListener = pListener; -} -#endif - -#ifdef STREAMENGINE_ENABLE_LISTENER -IStreamEngineListener* CStreamEngine::GetListener() -{ - return m_pListener; -} -#endif - -////////////////////////////////////////////////////////////////////////// -void* CStreamEngine::TempAlloc(size_t nSize, const char* szDbgSource, bool bFallBackToMalloc, bool bUrgent, uint32 align) -{ - return m_tempMem.TempAlloc(g_pPakHeap, nSize, szDbgSource, bFallBackToMalloc, bUrgent, align); -} - -void CStreamEngine::TempFree(void* p, size_t nSize) -{ - m_tempMem.TempFree(g_pPakHeap, p, nSize); -} - -namespace -{ -#ifdef STREAMENGINE_ENABLE_STATS - void DrawText(const float x, const float y, ColorF c, const char* format, ...) - { - va_list args; - va_start(args, format); - - SDrawTextInfo ti; - ti.flags = eDrawText_FixedSize | eDrawText_2D | eDrawText_Monospace; - ti.xscale = ti.yscale = 1.2f; - ti.color[0] = c.r; - ti.color[1] = c.g; - ti.color[2] = c.b; - ti.color[3] = c.a; - gEnv->pRenderer->DrawTextQueued(Vec3(x, y, 1.0f), ti, format, args); - va_end(args); - } -#endif - - void WriteToStreamingLog([[maybe_unused]] const char* str) - { -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug == 4) - { - // ignore invalid file access when logging steaming data - CDebugAllowFileAccess ignoreInvalidFileAccess; - - static string sFileName; - static bool bFirstTime = true; - if (bFirstTime) - { - char path[AZ::IO::IArchive::MaxPath]; - path[sizeof(path) - 1] = 0; - gEnv->pCryPak->AdjustFileName("@usercache@\\TestResults\\StreamingLog.txt", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING); - sFileName = path; - } - AZ::IO::HandleType fileHandle = fxopen(sFileName, (bFirstTime) ? "wt" : "at"); - bFirstTime = false; - if (fileHandle != AZ::IO::InvalidHandle) - { - AZ::IO::Print(fileHandle, "%s\n", str); - gEnv->pFileIO->Close(fileHandle); - } - } -#endif - } -} - -#ifdef STREAMENGINE_ENABLE_STATS -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::DrawStatistics() -{ - std::vector tempRequests; - - if (g_cvars.sys_streaming_debug == 4) - { - float tx = 0; - float ty = 30; - float ystep = 12.0f; - ColorF clText(1, 0, 0, 1); - - DrawText(tx, ty += ystep, clText, "Recording streaming stats to file ..."); - - { - CryAutoCriticalSection lock(m_csStats); - tempRequests.swap(m_statsRequestList); - } - - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - if (!tempRequests.empty()) - { - for (int i = (int)tempRequests.size() - 1; i >= 0; i--) - { - CAsyncIOFileRequest* pFileRequest = tempRequests[i]; - - if (g_cvars.sys_streaming_debug_filter > 0 && pFileRequest->m_eType != g_cvars.sys_streaming_debug_filter) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter == -1 && pFileRequest->m_eMediaType == eStreamSourceTypeMemory) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter_min_time && (pFileRequest->m_readTime.GetMilliSeconds() < (float)g_cvars.sys_streaming_debug_filter_min_time)) - { - continue; - } - if (sFileFilter && sFileFilter[0] && !strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - continue; - } - - const char* sFlags = (pFileRequest->m_eMediaType == eStreamSourceTypeHDD) ? "HDD" : ((pFileRequest->m_eMediaType == eStreamSourceTypeMemory) ? "mem" : "DVD"); - const char* sPriority = ""; - switch (pFileRequest->m_ePriority) - { - case estpUrgent: - sPriority = " Urgent"; - break; - case estpNormal: - sPriority = " Normal"; - break; - case estpIdle: - sPriority = " Idle"; - break; - case estpPreempted: - sPriority = " Preempted"; - break; - case estpBelowNormal: - sPriority = "BelowNormal"; - break; - case estpAboveNormal: - sPriority = "AboveNormal"; - break; - default: - sPriority = " Unknown"; - break; - } - - string str; - str.Format("[N%6d] [%+8d] [%8d] [%6.2f ms] (%5d|%5d) [%5.3fs] <%3d> <%s> <%s> <%s> %s:", - pFileRequest->m_nReadCounter, - pFileRequest->m_nReadHeadOffsetKB, - pFileRequest->m_nDiskOffset >> 10, - pFileRequest->m_readTime.GetMilliSeconds(), - pFileRequest->m_nSizeOnMedia / 1024, - ((pFileRequest->m_nRequestedSize) ? pFileRequest->m_nRequestedSize : pFileRequest->m_nFileSize) / 1024, - (pFileRequest->m_completionTime - pFileRequest->m_startTime).GetSeconds(), - pFileRequest->m_nTimeGroup, - sPriority, - sFlags, - pFileRequest->m_pakFile.c_str(), - pFileRequest->m_strFileName.c_str()); - - WriteToStreamingLog(str.c_str()); - } - } - - return; - } - - - { - CryAutoCriticalSection lock(m_csStats); - tempRequests = m_statsRequestList; - - size_t nMaxRequests = g_cvars.sys_streaming_debug_filter_min_time ? 1000 : 100; - if (m_statsRequestList.size() > nMaxRequests) - { - m_statsRequestList.resize(nMaxRequests); - } - } - - std::vector& requests = tempRequests; - - stack_string temp; - float tx = 0; - float ty = 30; - float ystep = 12.0f; - float xColumn = 80; - ColorF clText(0, 1, 1, 1); - - SStreamEngineStatistics& stats = m_Statistics; - SStreamEngineOpenStats openStats = m_OpenStatistics; - - const char* sMediaType = m_bStreamDataOnHDD ? "HDD" : "DVD"; - const char* sStatus = (m_bStreamingStatsPaused) ? "Paused" : ""; - DrawText(tx, ty += ystep, clText, "Streaming IO: %.2f|%.2fMB/s, ACT: %3dmsec, Unzip: %.2fMB/s, Verify: %.2fMB/s, Jobs:%5d (%4d) %s %s", - (float)stats.nTotalCurrentReadBandwidth / (1024 * 1024), (float)stats.nTotalSessionReadBandwidth / (1024 * 1024), - (uint32)stats.fAverageCompletionTime, (float)stats.nDecompressBandwidth / (1024 * 1024), (float)stats.nVerifyBandwidth / (1024 * 1024), - (uint32)stats.nTotalStreamingRequestCount, (uint32)(stats.nTotalRequestCount - stats.nTotalStreamingRequestCount), - sMediaType, sStatus); - - DrawText(tx, ty += ystep, clText, "\t Request: Active:%2d (%2.1fMB) Live:%2d Decompress:%2d Async:%2d Finished:%2d Temp Pool Max:%2.1fMB", openStats.nOpenRequestCount, - (float)stats.nPendingReadBytes / (1024 * 1024), CAsyncIOFileRequest::s_nLiveRequests, stats.nCurrentDecompressCount, stats.nCurrentAsyncCount, stats.nCurrentFinishedCount, - (float)stats.nMaxTempMemory / (1024 * 1024)); - - ty += ystep; - - // HDD stats - if (stats.hddInfo.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "HDD : Request: %3d|%5d (%4d MB|%3d KB) - BW: %1.2f|%1.2f Mb/s (Eff: %2.1f|%2.1f Mb/s) \n", - stats.hddInfo.nRequestCount, stats.hddInfo.nTotalRequestCount, (uint32)(stats.hddInfo.nTotalBytesRead / (1024 * 1024)), - (uint32)(stats.hddInfo.nTotalBytesRead / (1024 * stats.hddInfo.nTotalRequestCount)), - (float)stats.hddInfo.nCurrentReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nSessionReadBandwidth / (1024 * 1024), - (float)stats.hddInfo.nActualReadBandwidth / (1024 * 1024), (float)stats.hddInfo.nAverageActualReadBandwidth / (1024 * 1024)); - DrawText(tx, ty += ystep, clText, "\t Seek: %1.2f GB - Active: %2.1f%%(%2.1f%%)", - (float)stats.hddInfo.nAverageSeekOffset / (1024 * 1024), - stats.hddInfo.fActiveDuringLastSecond, stats.hddInfo.fAverageActiveTime); - } - // Optical stats - if (stats.discInfo.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "Disc: Request: %3d|%5d (%4d MB|%3d KB) - BW: %1.2f|%1.2f Mb/s (Eff: %2.1f|%2.1f Mb/s) \n", - stats.discInfo.nRequestCount, stats.discInfo.nTotalRequestCount, (uint32)(stats.discInfo.nTotalBytesRead / (1024 * 1024)), - (uint32)(stats.discInfo.nTotalBytesRead / (1024 * stats.discInfo.nTotalRequestCount)), - (float)stats.discInfo.nCurrentReadBandwidth / (1024 * 1024), (float)stats.discInfo.nSessionReadBandwidth / (1024 * 1024), - (float)stats.discInfo.nActualReadBandwidth / (1024 * 1024), (float)stats.discInfo.nAverageActualReadBandwidth / (1024 * 1024)); - DrawText(tx, ty += ystep, clText, "\t Seek: %1.2f GB - Active: %2.1f%%(%2.1f%%)", - (float)stats.discInfo.nAverageSeekOffset / (1024 * 1024), - stats.discInfo.fActiveDuringLastSecond, stats.discInfo.fAverageActiveTime); - } - DrawText(tx, ty += ystep, clText, "Mem : Request: %3d|%5d (%4d MB)", - stats.memoryInfo.nRequestCount, stats.memoryInfo.nTotalRequestCount, (stats.memoryInfo.nTotalBytesRead / (1024 * 1024))); - - ty += ystep; - - for (int i = eStreamTaskTypeCount - 1; i >= 1; i--) - { - EStreamTaskType eTaskType = (EStreamTaskType)i; - SStreamEngineStatistics::SRequestTypeInfo info = stats.typeInfo[eTaskType]; - - if (g_cvars.sys_streaming_debug > 1 || info.nTotalRequestCount > 0) - { - DrawText(tx, ty += ystep, clText, "%9s: BSize:%3dKb Read:%4dMb BW:%1.2f|%1.2f Mb/s ACT:%5dms %2d(%2.1fMB)|%5d", - gEnv->pSystem->GetStreamEngine()->GetStreamTaskTypeName(eTaskType), - (uint32)(info.nTotalReadBytes / max((uint32)1, info.nTotalStreamingRequestCount) / 1024), - (uint32)(info.nTotalReadBytes / (1024 * 1024)), (float)info.nCurrentReadBandwidth / (1024 * 1024), - (float)info.nSessionReadBandwidth / (1024 * 1024), (uint32)info.fAverageCompletionTime, - openStats.nOpenRequestCountByType[eTaskType], (float)info.nPendingReadBytes / (1024 * 1024), (uint32)info.nTotalStreamingRequestCount); - } - } - - if (g_cvars.sys_streaming_debug == 5) - { - ty += ystep; - ty += ystep; - - DrawText(tx, ty += ystep, clText, "Name | Time(s) | Size(Kb) | Read(Mb) | ReqS(Mb) | Count"); - - for (TExtensionInfoMap::iterator it = m_PerExtensionInfo.begin(); it != m_PerExtensionInfo.end(); ++it) - { - SExtensionInfo& extensionInfo = it->second; - DrawText(tx, ty += ystep, clText, "%4s | %7.3f | %8d | %8.3f | %8.3f | %5d", - it->first.c_str(), extensionInfo.m_fTotalReadTime / 1000, (uint32)(extensionInfo.m_nTotalReadSize / max((size_t)1, extensionInfo.m_nTotalRequests) / 1024), - extensionInfo.m_nTotalReadSize / (1024.0f * 1024.0f), extensionInfo.m_nTotalRequestSize / (1024.0f * 1024.0f), extensionInfo.m_nTotalRequests); - } - } - else if (g_cvars.sys_streaming_debug > 1) - { - ty += ystep; - - DrawText(tx, ty += ystep, clText, "[Offset KB]"); - DrawText(tx + xColumn, ty, clText, "[io ms]\t(read | size) [t sec] [Grp] < Priority> Filename"); - - ty += ystep; - - const char* const sFileFilter = g_cvars.sys_streaming_debug_filter_file_name->GetString(); - - for (size_t i = 0, nRequests = requests.size(); i < nRequests; i++) - { - CAsyncIOFileRequest* pFileRequest = requests[i]; - - if (g_cvars.sys_streaming_debug_filter > 0 && pFileRequest->m_eType != g_cvars.sys_streaming_debug_filter) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter == -1 && pFileRequest->m_eMediaType == eStreamSourceTypeMemory) - { - continue; - } - if (g_cvars.sys_streaming_debug_filter_min_time && (pFileRequest->m_readTime.GetMilliSeconds() < (float)g_cvars.sys_streaming_debug_filter_min_time)) - { - continue; - } - if (sFileFilter != 0 && sFileFilter[0] && !strstr(pFileRequest->m_strFileName.c_str(), sFileFilter)) - { - continue; - } - - { - float fMillis = pFileRequest->m_readTime.GetMilliSeconds(); - const char* sFlags = ""; - switch (pFileRequest->m_eMediaType) - { - case eStreamSourceTypeHDD: - sFlags = "HDD"; - break; - case eStreamSourceTypeDisc: - sFlags = "DVD"; - break; - case eStreamSourceTypeMemory: - sFlags = "MEM"; - break; - } - const char* sPriority = ""; - switch (pFileRequest->m_ePriority) - { - case estpUrgent: - sPriority = " Urgent"; - break; - case estpNormal: - sPriority = " Normal"; - break; - case estpIdle: - sPriority = " Idle"; - break; - case estpPreempted: - sPriority = " Preempted"; - break; - case estpBelowNormal: - sPriority = "BelowNormal"; - break; - case estpAboveNormal: - sPriority = "AboveNormal"; - break; - default: - sPriority = " Unknown"; - break; - } - uint32 nRequestedSize = (pFileRequest->m_nRequestedSize != 0) ? pFileRequest->m_nRequestedSize : pFileRequest->m_nFileSize; - - ////////////////////////////////////////////////////////////////////////// - ColorF colOffset; - if (pFileRequest->m_nReadHeadOffsetKB >= 0) - { - colOffset = ColorF (0, 1, 0, 1); // Green - if (pFileRequest->m_nReadHeadOffsetKB > 32) - { - colOffset = ColorF (0.5f, 1.f, 0, 1.f); // Cyan - } - } - else - { - colOffset = ColorF (1, 0, 0, 1); // Red - } - if (pFileRequest->m_eMediaType != eStreamSourceTypeMemory) - { - DrawText(tx, ty, colOffset, "[%+d]", pFileRequest->m_nReadHeadOffsetKB); - } - ////////////////////////////////////////////////////////////////////////// - - DrawText(tx + xColumn, ty, clText, "[%6.2f]\t(%5d|%5d) [%5.2f] [%3d] <%s> <%s>\t%s", - fMillis, pFileRequest->m_nSizeOnMedia / 1024, nRequestedSize / 1024, (pFileRequest->m_completionTime - pFileRequest->m_startTime).GetSeconds(), - pFileRequest->m_nTimeGroup, sPriority, sFlags, pFileRequest->m_strFileName.c_str()); - - ty += ystep; - } - } - } -} -#endif //STREAMENGINE_ENABLE_STATS - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamEngine::ClearStatistics() -{ - m_TimeOfLastReset = gEnv->pTimer->GetAsyncTime(); - m_TimeOfLastUpdate = m_TimeOfLastReset; - - m_Statistics.hddInfo.ResetStats(); - m_Statistics.discInfo.ResetStats(); - - m_PerExtensionInfo.clear(); - - m_Statistics.nDecompressBandwidth = 0; - m_Statistics.nVerifyBandwidth = 0; - m_Statistics.nDecompressBandwidthAverage = 0; - m_Statistics.nVerifyBandwidthAverage = 0; - - m_Statistics.nTotalBytesRead = 0; - m_Statistics.nTotalRequestCount = 0; - m_Statistics.nTotalStreamingRequestCount = 0; - - m_Statistics.nMaxTempMemory = 0; - - m_Statistics.fAverageCompletionTime = 0; - - for (int i = 0; i < eStreamTaskTypeCount; i++) - { - m_Statistics.typeInfo[i].ResetStats(); - } - m_Statistics.vecHeavyAssets.clear(); - - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->m_InMemoryStats.Reset(); - m_pThreadIO[i]->m_NotInMemoryStats.Reset(); - } - } -} -#endif - -////////////////////////////////////////////////////////////////////////// -bool CStreamEngine::OnInputChannelEventFiltered([[maybe_unused]] const AzFramework::InputChannel& inputChannel) -{ -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_debug) - { - if (inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::Function11) - { - m_bStreamingStatsPaused = true; - } - if (inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::Function12) - { - m_bStreamingStatsPaused = false; - } - } -#endif - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam) -{ - switch (event) - { - case ESYSTEM_EVENT_GAME_POST_INIT_DONE: - { - // unpause the streaming engine, when init phase is done - PauseStreaming(false, -1); - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE: -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - - WriteToStreamingLog("*LEVEL_LOAD_PREPARE"); - break; - - case ESYSTEM_EVENT_LEVEL_LOAD_START: - { - WriteToStreamingLog("*LEVEL_LOAD_START"); - break; - } - case ESYSTEM_EVENT_LEVEL_LOAD_END: - { - WriteToStreamingLog("*LEVEL_LOAD_END"); - break; - } - case ESYSTEM_EVENT_LEVEL_PRECACHE_START: - { - WriteToStreamingLog("*LEVEL_LOAD_PRECACHE_START"); - break; - } - case ESYSTEM_EVENT_LEVEL_PRECACHE_END: - { - WriteToStreamingLog("*LEVEL_LOAD_PRECACHE_END"); - break; - } - case ESYSTEM_EVENT_LEVEL_UNLOAD: - { - UpdateAndWait(true); - CancelAll(); - -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - break; - } - case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: - { - UpdateAndWait(true); - CancelAll(); - -#if defined(STREAMENGINE_ENABLE_STATS) - ClearStatistics(); -#endif - } - break; - case ESYSTEM_EVENT_FAST_SHUTDOWN: - { - Shutdown(); - break; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::PauseStreaming(bool bPause, uint32 nPauseTypesBitmask) -{ - CryAutoLock pausedLock(m_pausedLock); - if (bPause) - { - m_nPausedDataTypesMask |= nPauseTypesBitmask; - } - else - { - m_nPausedDataTypesMask &= ~nPauseTypesBitmask; - ResumePausedStreams_PauseLocked(); - } -} -////////////////////////////////////////////////////////////////////////// -void CStreamEngine::PauseIO(bool bPause) -{ - for (int i = 0; i < eIOThread_Last; i++) - { - if (m_pThreadIO[i]) - { - m_pThreadIO[i]->Pause(bPause); - } - } -} -////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h b/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h deleted file mode 100644 index 57d47b8674..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamEngine.h +++ /dev/null @@ -1,239 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H -#pragma once - - -#include "IStreamEngine.h" -#include "ISystem.h" -#include "TimeValue.h" - -#include -#include "StreamIOThread.h" -#include "StreamReadStream.h" - -#include -#include -#include -#include - -enum EIOThread -{ - eIOThread_HDD = 0, - eIOThread_Optical = 1, - eIOThread_InMemory = 2, - eIOThread_Last = 3, -}; - -////////////////////////////////////////////////////////////////////////// -class CStreamEngine - : public IStreamEngine - , public ISystemEventListener - , public AzFramework::InputChannelEventListener -{ -public: - CStreamEngine(); - ~CStreamEngine(); - - void Shutdown(); - // This is called to cancel all pending requests, without sending callbacks. - void CancelAll(); - - - //Helper added to aid in migration from Cry's CStreamEngine to AZ::IO::Streamer - static AZ::IO::IStreamerTypes::Priority CryStreamPriorityToAZStreamPriority(EStreamTaskPriority cryPriority); - static AZStd::chrono::milliseconds AZDeadlineFromReadParams(const StreamReadParams& params); - - ////////////////////////////////////////////////////////////////////////// - // IStreamEngine interface - ////////////////////////////////////////////////////////////////////////// - IReadStreamPtr StartRead (const EStreamTaskType tSource, const char* szFile, IStreamCallback* pCallback, const StreamReadParams* pParams = NULL); - size_t StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function* preRequestCallback = nullptr); - void BeginReadGroup(); - void EndReadGroup(); - - bool IsStreamDataOnHDD() const { return m_bStreamDataOnHDD; } - void SetStreamDataOnHDD(bool bFlag) { m_bStreamDataOnHDD = bFlag; } - - void Update(); - void UpdateAndWait(bool bAbortAll = false); - void Update(uint32 nUpdateTypesBitmask); - - void GetMemoryStatistics(ICrySizer* pSizer); - -#if defined(STREAMENGINE_ENABLE_STATS) - SStreamEngineStatistics& GetStreamingStatistics(); - void ClearStatistics(); - - void GetBandwidthStats(EStreamTaskType type, float* bandwidth); -#endif - - void GetStreamingOpenStatistics(SStreamEngineOpenStats& openStatsOut); - - const char* GetStreamTaskTypeName(EStreamTaskType type); - - SStreamJobEngineState GetJobEngineState(); - SStreamEngineTempMemStats& GetTempMemStats() { return m_tempMem; } - - // Will pause or unpause streaming of specified by mask data types - void PauseStreaming(bool bPause, uint32 nPauseTypesBitmask); - // Pause/resumes any IO active from the streaming engine - void PauseIO(bool bPause); - - uint32 GetPauseMask() const { return m_nPausedDataTypesMask; } - -#if defined(STREAMENGINE_ENABLE_LISTENER) - void SetListener(IStreamEngineListener* pListener); - IStreamEngineListener* GetListener(); -#endif - - ////////////////////////////////////////////////////////////////////////// - - // updates the job priority of an IO job into the IOQueue while maintaining order in the queue - void UpdateJobPriority(IReadStreamPtr pJobStream); - - void ReportAsyncFileRequestComplete(CAsyncIOFileRequest_AutoPtr pFileRequest); - void AbortJob(CReadStream* pStream); - - - // Dispatches synchrnous callbacks, free temporary memory hold for callbacks. - void MainThread_FinalizeIOJobs(); - void MainThread_FinalizeIOJobs(uint32 type); - - void* TempAlloc(size_t nSize, const char* szDbgSource, bool bFallBackToMalloc = true, bool bUrgent = false, uint32 align = 0); - void TempFree(void* p, size_t nSize); - - uint32 GetCurrentTempMemorySize() const { return m_tempMem.m_nTempAllocatedMemory; } - void FlagTempMemOutOfBudget() - { -#ifdef STREAMENGINE_ENABLE_STATS - m_bTempMemOutOfBudget = true; -#endif - } - - ////////////////////////////////////////////////////////////////////////// - // AzFramework::InputChannelEventListener - ////////////////////////////////////////////////////////////////////////// - bool OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel) override; - ////////////////////////////////////////////////////////////////////////// - - bool StartFileRequest(CAsyncIOFileRequest* pFileRequest); - void SignalToStartWork(EIOThread e, bool bForce); - -private: - void StartThreads(); - void StopThreads(); - - void ResumePausedStreams_PauseLocked(); - -#if defined(STREAMENGINE_ENABLE_STATS) - // add job to current statistics - void UpdateStatistics(CReadStream* pReadStream); - void DrawStatistics(); -#endif - - void QueueRequestCompleteJob(class AZRequestReadStream* stream, AZ::IO::SizeType numBytesRead, void* buffer, - AZ::IO::IStreamerTypes::RequestStatus requestState); - - ////////////////////////////////////////////////////////////////////////// - // ISystemEventListener - ////////////////////////////////////////////////////////////////////////// - virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam); - ////////////////////////////////////////////////////////////////////////// - -private: - - ////////////////////////////////////////////////////////////////////////// - CryMT::set m_streams; - CryMT::vector m_finishedStreams; - std::vector m_tempFinishedStreams; - - CryCriticalSection m_pendingRequestCompletionsLock; - AZStd::queue m_pendingRequestCompletions; - - // 2 IO threads. - _smart_ptr m_pThreadIO[eIOThread_Last]; - std::vector<_smart_ptr > m_asyncCallbackThreads; - std::vector m_asyncCallbackQueues; - - CryCriticalSection m_pausedLock; - std::vector m_pausedStreams; - volatile uint32 m_nPausedDataTypesMask; - - bool m_bStreamDataOnHDD; - bool m_bUseOpticalDriveThread; - - ////////////////////////////////////////////////////////////////////////// - // Streaming statistics. - ////////////////////////////////////////////////////////////////////////// - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* m_pListener; -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - SStreamEngineStatistics m_Statistics; - SStreamEngineDecompressStats m_decompressStats; - CTimeValue m_TimeOfLastReset; - CTimeValue m_TimeOfLastUpdate; - - CryCriticalSection m_csStats; - std::vector m_statsRequestList; - - struct SExtensionInfo - { - SExtensionInfo() - : m_fTotalReadTime(0.0f) - , m_nTotalRequests(0) - , m_nTotalReadSize(0) - , m_nTotalRequestSize(0) - { - } - float m_fTotalReadTime; - size_t m_nTotalRequests; - uint64 m_nTotalReadSize; - uint64 m_nTotalRequestSize; - }; - typedef std::map TExtensionInfoMap; - TExtensionInfoMap m_PerExtensionInfo; - - ////////////////////////////////////////////////////////////////////////// - // Used to calculate unzip/verify bandwidth for statistics. - uint32 m_nUnzipBandwidth; - uint32 m_nUnzipBandwidthAverage; - uint32 m_nVerifyBandwidth; - uint32 m_nVerifyBandwidthAverage; - CTimeValue m_nLastBandwidthUpdateTime; - - bool m_bStreamingStatsPaused; - bool m_bInputCallback; - bool m_bTempMemOutOfBudget; - ////////////////////////////////////////////////////////////////////////// -#endif - - SStreamEngineOpenStats m_OpenStatistics; - - bool m_bShutDown; - - volatile int m_nBatchMode; - - // Memory currently allocated by streaming engine for temporary storage. - SStreamEngineTempMemStats m_tempMem; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMENGINE_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp deleted file mode 100644 index e3d184fc31..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.cpp +++ /dev/null @@ -1,819 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Thread for IO - - -#include "CrySystem_precompiled.h" -#include "StreamIOThread.h" -#include "StreamEngine.h" -#include "../System.h" - -extern SSystemCVars g_cvars; - -//#pragma("control %push O=0") // to disable optimization - -////////////////////////////////////////////////////////////////////////// -CStreamingIOThread::CStreamingIOThread(CStreamEngine* pStreamEngine, EStreamSourceMediaType mediaType, const char* name) -{ - m_pStreamEngine = pStreamEngine; - m_bCancelThreadRequest = false; - m_bNeedSorting = false; - m_bNeedReset = false; - m_bNewRequests = false; - m_name = name; - m_eMediaType = mediaType; - m_nFallbackMTs = 0; - - m_iUrgentRequests = 0; - - m_bPaused = false; - m_bAbortReads = false; - - m_nReadCounter = 0; - m_nStreamingCPU = -1; - - Start((unsigned)(1 << g_cvars.sys_streaming_cpu), name); -} - -CStreamingIOThread::~CStreamingIOThread() -{ - Cancel(); - Stop(); - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::AddRequest(CAsyncIOFileRequest* pRequest, bool bStartImmidietly) -{ - pRequest->AddRef(); // Acquire ownership on file request. - pRequest->m_status = CAsyncIOFileRequest::eStatusInFileQueue; - if (pRequest->m_eMediaType != eStreamSourceTypeMemory) - { - pRequest->m_eMediaType = m_eMediaType; - } - // does this ignore the tmp out of memory - if (pRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - m_newFileRequests.push_back(pRequest); - - if (bStartImmidietly) - { - READ_WRITE_BARRIER - m_bNewRequests = true; - m_awakeEvent.Set(); - } -} - - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::SignalStartWork(bool bForce) -{ - if (!m_newFileRequests.empty() || bForce) - { - READ_WRITE_BARRIER - m_bNewRequests = true; - - m_awakeEvent.Set(); - } -} - -////////////////////////////////////////////////////////////////////////// - -void CStreamingIOThread::Pause(bool bPause) -{ - m_bPaused = bPause; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::Run() -{ - SetName(m_name); - - CTimeValue t0 = gEnv->pTimer->GetAsyncTime(); - - m_nLastReadDiskOffset = 0; - - // - // Main thread loop - while (!m_bCancelThreadRequest) - { - if (m_nStreamingCPU != g_cvars.sys_streaming_cpu) - { - m_nStreamingCPU = g_cvars.sys_streaming_cpu; - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define STREAMIOTHREAD_CPP_SECTION_1 1 -#define STREAMIOTHREAD_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION STREAMIOTHREAD_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(StreamEngine/StreamIOThread_cpp) -#endif - } - - if (m_bNewRequests || !m_newFileRequests.empty()) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - else - { -#if defined(_RELEASE) - m_awakeEvent.Wait(); -#elif defined(STREAMENGINE_ENABLE_STATS) - // compute max time to wait - revive thread every second at least once to update stats - bool bWaiting = true; - while (bWaiting) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - uint64 msec = deltaT.GetMilliSecondsAsInt64(); - if (msec < 1000) - { - bWaiting = !m_awakeEvent.Wait(1000 - (uint32)msec); - } - - if (bWaiting) - { - // update the delta time again - t1 = gEnv->pTimer->GetAsyncTime(); - deltaT = t1 - t0; - - m_InMemoryStats.Update(deltaT); - m_NotInMemoryStats.Update(deltaT); - - t0 = t1; - } - } -#endif - } - - if (m_bNeedReset) - { - ProcessReset(); - } - - bool bIsOOM = false; - - while (!m_bCancelThreadRequest && !m_fileRequestQueue.empty()) - { - CAsyncIOFileRequest_TransferPtr pFileRequest(m_fileRequestQueue.back()); - m_fileRequestQueue.pop_back(); - - assert (&*pFileRequest); - - if (pFileRequest->HasFailed()) - { - // check if request was high prio, then decr open count - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - - continue; - } - - ////////////////////////////////////////////////////////////////////////// - // When temporary memory goes out of budget we must loop here and wait until previous file requests are finished and free up memory. - // Only allow processing of requests which are flagged for processing when out of tmp memory - ////////////////////////////////////////////////////////////////////////// - if (bIsOOM && !m_bCancelThreadRequest) - { - m_pStreamEngine->FlagTempMemOutOfBudget(); - if (m_iUrgentRequests > 0) - { - if (m_bNewRequests || !m_newFileRequests.empty()) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - - // readd the current request - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - - // search for the first request which ignores the current out of mem state - // Search for next highest priority request - std::vector::reverse_iterator rit; - for (rit = m_fileRequestQueue.rbegin(); rit != m_fileRequestQueue.rend(); ++rit) - { - if ((*rit)->IgnoreOutofTmpMem()) - { - pFileRequest = *rit; - std::vector::iterator it(rit.base()); - --it; - m_fileRequestQueue.erase(it); - break; - } - } - } - else - { - // read the current request - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - } - } - - // Simply let the io thread sleep when paused before doing any actual IO - while (m_bPaused) - { - CrySleep(10); - } - - // If at this point, the filerequest is zero, the above prioritization of - // urgent requests couldn't find a new task to displace the current - // one. As the current one had been pushed back previously, we can safely - // assume that restarting the loop will grab it again (eventually). - if (!pFileRequest) - { - break; - } - - // check if request was high prio, then decr open count - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - - bIsOOM = false; - - uint32 nSizeOnMedia = pFileRequest->m_nSizeOnMedia; - uint32 nError = 0; - - // Handle file request. - if (m_bAbortReads) - { - nError = ERROR_ABORTED_ON_SHUTDOWN; - } - else if (pFileRequest->m_bReadBegun) - { - nError = pFileRequest->ReadFileResume(this); - } - else - { - nError = pFileRequest->ReadFile(this); - } - -#ifdef STREAMENGINE_ENABLE_STATS - pFileRequest->m_nReadCounter = m_nReadCounter++; -#endif - - if (nError == 0) - { - if (pFileRequest->m_eMediaType != eStreamSourceTypeMemory) - { - pFileRequest->m_nReadHeadOffsetKB = (int32)(((int64)pFileRequest->m_nDiskOffset - m_nLastReadDiskOffset) >> 10); // in KB - m_nLastReadDiskOffset = pFileRequest->m_nDiskOffset + nSizeOnMedia; - -#ifdef STREAMENGINE_ENABLE_STATS - m_NotInMemoryStats.m_nTempReadOffset += abs(pFileRequest->m_nReadHeadOffsetKB); - m_NotInMemoryStats.m_nTotalReadOffset += abs(pFileRequest->m_nReadHeadOffsetKB); - - m_NotInMemoryStats.m_nTempRequestCount++; - - // Calc IO bandwidth only for non memory files. - m_NotInMemoryStats.m_nTempBytesRead += nSizeOnMedia; - m_NotInMemoryStats.m_TempReadTime += pFileRequest->m_readTime; -#endif - } - else - { -#ifdef STREAMENGINE_ENABLE_STATS - m_InMemoryStats.m_nTempRequestCount++; - - // Calc IO bandwidth only for in memory files. - m_InMemoryStats.m_nTempBytesRead += nSizeOnMedia; - m_InMemoryStats.m_TempReadTime += pFileRequest->m_readTime; -#endif - } - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - } - else - { - switch (nError) - { - case ERROR_OUT_OF_MEMORY: - bIsOOM = true; - - pFileRequest->SetPriority(estpPreempted); - - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - m_bNewRequests = true; - break; - - case ERROR_PREEMPTED: - pFileRequest->SetPriority(estpPreempted); - - if (pFileRequest->IgnoreOutofTmpMem()) - { - CryInterlockedIncrement(&m_iUrgentRequests); - } - - m_fileRequestQueue.push_back(pFileRequest.Relinquish()); - m_bNewRequests = true; - break; - - case ERROR_MISSCHEDULED: - // Request tried to read a file that has changed media type. Reset the sort key - // and reschedule. - pFileRequest->m_bSortKeyComputed = 0; - AddRequest(&*pFileRequest, false); - break; - - default: - pFileRequest->SyncWithDecompress(); - pFileRequest->Failed(nError); - - CAsyncIOFileRequest::JobFinalize_Read(pFileRequest, m_pStreamEngine->GetJobEngineState()); - break; - } - } - - ////////////////////////////////////////////////////////////////////////// - if (m_bNewRequests) - { - READ_WRITE_BARRIER - ProcessNewRequests(); - } - if (m_bNeedReset) - { - ProcessReset(); - } - if (m_bNeedSorting) - { - SortRequests(); - } - - ////////////////////////////////////////////////////////////////////////// -#ifdef STREAMENGINE_ENABLE_STATS - if (g_cvars.sys_streaming_max_bandwidth != 0) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - - // Sleep in case we are streaming too fast. - const float fTheoreticalReadTime = float(nSizeOnMedia) / g_cvars.sys_streaming_max_bandwidth * 0.00000095367431640625f; // / (1024*1024) - - if (fTheoreticalReadTime - deltaT.GetSeconds() > FLT_EPSILON) - { - uint32 nSleepTime = uint32(1000.f * (fTheoreticalReadTime - deltaT.GetSeconds())); - CrySleep(nSleepTime); - } - } - - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - CTimeValue deltaT = t1 - t0; - - // update the stats every second - if (deltaT.GetMilliSecondsAsInt64() > 1000) - { - m_InMemoryStats.Update(deltaT); - m_NotInMemoryStats.Update(deltaT); - - t0 = t1; - } -#endif - } - } -} - -#ifdef STREAMENGINE_ENABLE_STATS -void CStreamingIOThread::SStats::Update(const CTimeValue& deltaT) -{ - m_nReadBytesInLastSecond = (uint32)m_nTempBytesRead; - m_nRequestCountInLastSecond = m_nTempRequestCount; - m_nTotalReadBytes += (uint32)m_nTempBytesRead; - m_nTotalRequestCount += m_nTempRequestCount; - m_TotalReadTime += m_TempReadTime; - - if (m_TempReadTime.GetValue() != 0) - { - m_nActualReadBandwith = (uint32)(m_nTempBytesRead / m_TempReadTime.GetSeconds()); - } - else - { - m_nActualReadBandwith = 0; - } - m_nCurrentReadBandwith = (uint32)(m_nTempBytesRead / deltaT.GetSeconds()); - m_fReadingDuringLastSecond = m_TempReadTime.GetSeconds() / deltaT.GetSeconds() * 100; - - if (m_nTempRequestCount > 0) - { - m_nReadOffsetInLastSecond = m_nTempReadOffset / m_nTempRequestCount; - } - else - { - m_nReadOffsetInLastSecond = 0; - } - - m_TempReadTime.SetValue(0); - m_nTempBytesRead = 0; - m_nTempReadOffset = 0; - m_nTempRequestCount = 0; -} -#endif - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::Cancel() -{ - m_bCancelThreadRequest = true; - m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -struct SCompareAsyncFileRequest -{ - bool operator()(CAsyncIOFileRequest* pFile1, CAsyncIOFileRequest* pFile2) const - { - return pFile1->m_nSortKey > pFile2->m_nSortKey; - } -}; - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::SortRequests() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - std::sort(m_fileRequestQueue.begin(), m_fileRequestQueue.end(), SCompareAsyncFileRequest()); - - /* - int nStartOfQueue = 0; - int64 nDiskOffsetLimit = m_nLastReadDiskOffset - 32*1024; // 32KB less only - - int nCount = (int)m_fileRequestQueue.size(); - for (int i = nCount-1; i >= 0; i--) - { - if (m_fileRequestQueue[i]->m_nDiskOffset > nDiskOffsetLimit) - { - nStartOfQueue = i+1; - break; - } - } - if (nStartOfQueue < nCount && nStartOfQueue > 0) - { - int nElements = nCount - nStartOfQueue; - // Move all elements up to nStartOfQueue, from begining of the request array to the end. - m_temporaryArray.resize(0); - // Copy to temp array elements up to nStartOfQueue - m_temporaryArray.insert( m_temporaryArray.end(),m_fileRequestQueue.begin()+nStartOfQueue,m_fileRequestQueue.end() ); - // Remove elements up to nStartOfQueue from request list - m_fileRequestQueue.erase( m_fileRequestQueue.begin()+nStartOfQueue,m_fileRequestQueue.end() ); - // Add elemenets at the end from temp array. - m_fileRequestQueue.insert( m_fileRequestQueue.begin(),m_temporaryArray.begin(),m_temporaryArray.end() ); - } - */ - m_bNeedSorting = false; -} - -void CStreamingIOThread::NeedSorting() -{ - m_bNeedSorting = true; -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::ProcessNewRequests() -{ - m_bNewRequests = false; - - std::vector temporaryArray; - temporaryArray.reserve(m_newFileRequests.size()); - m_newFileRequests.swap(temporaryArray); - - std::vector& newFiles = temporaryArray; - - if (!newFiles.empty()) - { - uint64 nCurrentKeyInProgress = m_fileRequestQueue.size() ? m_fileRequestQueue.back()->m_nSortKey : 0; - - // Compute sorting key for new file entries. - int iWakeFallback(0); - const TFallbackIOVecConstIt itEnd = m_FallbackIOThreads.end(); - const size_t fallbackNum = m_FallbackIOThreads.size(); - PREFAST_SUPPRESS_WARNING(6255) - uint8 * pFallbackSignals = fallbackNum ? (uint8*)alloca(fallbackNum) : NULL; - for (uint32 fb = 0; fb < fallbackNum; ++fb) - { - pFallbackSignals[fb] = 0; - } - - for (size_t i = 0, num = newFiles.size(); i < num; i++) - { - CAsyncIOFileRequest* pFilepRequest = newFiles[i]; - - pFilepRequest->ComputeSortKey(nCurrentKeyInProgress); - static_cast(&*pFilepRequest->m_pReadStream)->ComputedMediaType(pFilepRequest->m_eMediaType); - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = m_pStreamEngine->GetListener(); - if (pListener) - { - pListener->OnStreamComputedSortKey(pFilepRequest, pFilepRequest->m_nSortKey); - } -#endif - - bool bFallback = false; - int idx = -1; - for (TFallbackIOVecConstIt it = m_FallbackIOThreads.begin(); it != itEnd && !bFallback; ++it) - { - ++idx; - if (it->second == pFilepRequest->GetMediaType()) - { - if (pFilepRequest->IgnoreOutofTmpMem()) - { - CryInterlockedDecrement(&m_iUrgentRequests); - } - (it->first)->AddRequest(pFilepRequest, true); - pFilepRequest->Release(); // Release local ownership of request (moved to fallback IO thread) - iWakeFallback++; - bFallback = true; - pFallbackSignals[idx] = 1; - } - } - if (!bFallback) - { - m_fileRequestQueue.push_back(pFilepRequest); - } - } - - for (uint32 fb = 0; fb < fallbackNum; ++fb) - { - if (pFallbackSignals[fb] != 0) - { - (m_FallbackIOThreads[fb].first)->SignalStartWork(false); - } - } - - SortRequests(); - /* - if (m_fileRequestQueue.back() != pRequest && pRequest != 0) - { - // Highest priority changed. - if (m_fileRequestQueue.back()->m_nDiskOffset < (m_nLastReadDiskOffset-32*1024)) - { - //CryLog( "Bad Offset in Queue" ); - } - } - */ - } -} - -void CStreamingIOThread::ProcessReset() -{ - if (!m_fileRequestQueue.empty()) - { - for (std::vector::iterator it = m_fileRequestQueue.begin(), itEnd = m_fileRequestQueue.end(); it != itEnd; ++it) - { - (*it)->Release(); - } - } - - stl::free_container(m_fileRequestQueue); - - if (!m_temporaryArray.empty()) - { - for (std::vector::iterator it = m_temporaryArray.begin(), itEnd = m_temporaryArray.end(); it != itEnd; ++it) - { - (*it)->Release(); - } - } - - stl::free_container(m_temporaryArray); - - m_bNeedReset = false; - m_resetDoneEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::CancelAll() -{ - { - CryMT::vector::AutoLock lock(m_newFileRequests.get_lock()); - - if (!m_newFileRequests.empty()) - { - CAsyncIOFileRequest* const* it = &m_newFileRequests.front(); - CAsyncIOFileRequest* const* itEnd = it + m_newFileRequests.size(); - for (; it != itEnd; ++it) - { - (*it)->Release(); - } - } - } - - m_newFileRequests.free_memory(); - m_iUrgentRequests = 0; -} - -void CStreamingIOThread::AbortAll(bool bAbort) -{ - m_bAbortReads = bAbort; -} - -void CStreamingIOThread::BeginReset() -{ - CancelAll(); - - m_resetDoneEvent.Reset(); - m_bNeedReset = true; - m_awakeEvent.Set(); -} - -void CStreamingIOThread::EndReset() -{ - m_resetDoneEvent.Wait(); -} -////////////////////////////////////////////////////////////////////////// -void CStreamingIOThread::RegisterFallbackIOThread(EStreamSourceMediaType mediaType, CStreamingIOThread* pIOThread) -{ - //check if media has not yet been registered - if (!pIOThread) - { - return;//no need for NULL register anymore - } - const TFallbackIOVecConstIt itEnd = m_FallbackIOThreads.end(); - for (TFallbackIOVecConstIt it = m_FallbackIOThreads.begin(); it != itEnd; ++it) - { - if (it->second == mediaType) - { - return; - } - } - m_FallbackIOThreads.push_back(std::make_pair(pIOThread, mediaType)); - m_nFallbackMTs |= 1 << mediaType; -} - -bool CStreamingIOThread::HasUrgentRequests() -{ - bool ret = false; - - if (m_iUrgentRequests > 0) - { - //lock to prevent list modification whilst traversing - m_newFileRequests.get_lock().Lock(); - - int nRequests = m_newFileRequests.size(); - - if (nRequests) - { - for (int i = 0; i < nRequests; i++) - { - if (m_newFileRequests[i]->m_ePriority == estpUrgent) - { - //printf("Urgent task pending: %s\n", m_newFileRequests[i]->m_strFileName.c_str()); - ret = true; - break; - } - } - } - m_newFileRequests.get_lock().Unlock(); - } - return ret; -} - -bool CStreamingIOThread::IsMisscheduled(EStreamSourceMediaType mt) const -{ - if (mt == m_eMediaType) - { - return false; - } - - if (m_nFallbackMTs & (1 << mt)) - { - return true; - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -CStreamingWorkerThread::CStreamingWorkerThread(CStreamEngine* pStreamEngine, const char* name, EWorkerType type, SStreamRequestQueue* pQueue) -{ - m_type = type; - m_name = name; - m_pStreamEngine = pStreamEngine; - m_pQueue = pQueue; - m_bCancelThreadRequest = false; - m_bNeedsReset = false; - - Start((unsigned)1 << g_cvars.sys_streaming_cpu_worker, name); -} - -CStreamingWorkerThread::~CStreamingWorkerThread() -{ - Cancel(); - Stop(); - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::Run() -{ - SetName(m_name); - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION STREAMIOTHREAD_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(StreamEngine/StreamIOThread_cpp) -#endif - - // Main thread loop - while (!m_bCancelThreadRequest) - { - m_pQueue->m_awakeEvent.Wait(); - m_pQueue->m_awakeEvent.Reset(); - - CAsyncIOFileRequest_AutoPtr pFileRequest; - while (!m_bCancelThreadRequest && !m_bNeedsReset && m_pQueue->TryPopRequest(pFileRequest)) - { - switch (m_type) - { - case eWorkerAsyncCallback: - { -#ifndef _RELEASE - float fTime = gEnv->pTimer->GetAsyncCurTime(); -#endif - - m_pStreamEngine->ReportAsyncFileRequestComplete(pFileRequest); -#ifndef _RELEASE - float fTime1 = gEnv->pTimer->GetAsyncCurTime(); -#endif - -#ifdef STREAMENGINE_ENABLE_STATS - CryInterlockedDecrement(&m_pStreamEngine->GetStreamingStatistics().nCurrentAsyncCount); -#endif - -#ifndef _RELEASE - if ((fTime1 - fTime) > 1.f && !pFileRequest->m_strFileName.empty()) - { - string str; - str.Format("[ACALL] %s time=%.5f\n", pFileRequest->m_strFileName.c_str(), (fTime1 - fTime)); - if (gEnv && gEnv->pSystem && gEnv->pLog) - { - gEnv->pLog->Log(str.c_str()); - } - } -#endif - } - break; - } - } - - if (m_bNeedsReset) - { - m_pQueue->Reset(); - m_bNeedsReset = false; - m_resetDoneEvent.Set(); - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::Cancel() -{ - m_bCancelThreadRequest = true; - m_pQueue->m_awakeEvent.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CStreamingWorkerThread::CancelAll() -{ - m_pQueue->Reset(); -} - -void CStreamingWorkerThread::BeginReset() -{ - CancelAll(); - - m_resetDoneEvent.Reset(); - m_bNeedsReset = true; - m_pQueue->m_awakeEvent.Set(); -} - -void CStreamingWorkerThread::EndReset() -{ - m_resetDoneEvent.Wait(); -} diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h b/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h deleted file mode 100644 index 14bac3a372..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamIOThread.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Thread for IO - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H -#pragma once - -#include -#include "StreamAsyncFileRequest.h" - - -class CStreamEngine; - -////////////////////////////////////////////////////////////////////////// -// Thread that performs IO operations. -////////////////////////////////////////////////////////////////////////// -class CStreamingIOThread - : public CrySimpleThread - , public CMultiThreadRefCount -{ -public: - CStreamingIOThread(CStreamEngine* pStreamEngine, EStreamSourceMediaType mediaType, const char* name); - ~CStreamingIOThread(); - - void CancelAll(); - void AbortAll(bool bAbort); - - void BeginReset(); - void EndReset(); - - void AddRequest(CAsyncIOFileRequest* pRequest, bool bStartImmidietly); - int GetRequestCount() const { return m_fileRequestQueue.size(); }; - void SortRequests(); - void NeedSorting(); - void SignalStartWork(bool bForce); - bool HasUrgentRequests(); - EStreamSourceMediaType GetMediaType() const { return m_eMediaType; } - bool IsMisscheduled(EStreamSourceMediaType mt) const; - - void Pause(bool bPause); - - void RegisterFallbackIOThread(EStreamSourceMediaType mediaType, CStreamingIOThread* pIOThread); - - CStreamEngineWakeEvent& GetWakeEvent() { return m_awakeEvent; } - - ////////////////////////////////////////////////////////////////////////// - // CrySimpleThread - ////////////////////////////////////////////////////////////////////////// - virtual void Run(); - virtual void Cancel(); - ////////////////////////////////////////////////////////////////////////// - -protected: - - void ProcessNewRequests(); - void ProcessReset(); - -public: - -#ifdef STREAMENGINE_ENABLE_STATS - struct SStats - { - SStats() - : m_nTotalReadBytes(0) - , m_nCurrentReadBandwith(0) - , m_nReadBytesInLastSecond(0) - , m_fReadingDuringLastSecond(.0f) - , m_nTempBytesRead(0) - , m_nActualReadBandwith(0) - , m_nTempReadOffset(0) - , m_nTotalReadOffset(0) - , m_nReadOffsetInLastSecond(0) - , m_nTempRequestCount(0) - , m_nTotalRequestCount(0) - , m_nRequestCountInLastSecond(0) - {} - - void Update(const CTimeValue& deltaT); - - void Reset() - { - m_nTotalReadBytes = 0; - m_nTotalReadOffset = 0; - m_nTotalRequestCount = 0; - m_TotalReadTime.SetValue(0); - } - - float m_fReadingDuringLastSecond; - CTimeValue m_TotalReadTime; - uint64 m_nTotalReadBytes; - uint64 m_nTotalReadOffset; - uint32 m_nTotalRequestCount; - uint32 m_nCurrentReadBandwith; // Read bandwidth over one second - uint32 m_nActualReadBandwith; // Actual read bandwidth extrapolated over one second - uint32 m_nReadBytesInLastSecond; - uint32 m_nRequestCountInLastSecond; - uint64 m_nReadOffsetInLastSecond; - - uint32 m_nTempRequestCount; - uint64 m_nTempBytesRead; - uint64 m_nTempReadOffset; - CTimeValue m_TempReadTime; - }; - - SStats m_InMemoryStats; - SStats m_NotInMemoryStats; -#endif - - int64 m_nLastReadDiskOffset; - int m_nStreamingCPU; - -private: - CStreamEngine* m_pStreamEngine; - std::vector m_fileRequestQueue; - std::vector m_temporaryArray; - CryMT::vector m_newFileRequests; - - EStreamSourceMediaType m_eMediaType; - uint32 m_nFallbackMTs; - - typedef std::pair TFallbackIOPair; - typedef std::vector TFallbackIOVec; - typedef TFallbackIOVec::iterator TFallbackIOVecConstIt; - TFallbackIOVec m_FallbackIOThreads; - - volatile bool m_bCancelThreadRequest; - volatile bool m_bNeedSorting; - volatile bool m_bNewRequests; - volatile bool m_bPaused; - volatile bool m_bNeedReset; - volatile bool m_bAbortReads; - - volatile int m_iUrgentRequests; - - CStreamEngineWakeEvent m_awakeEvent; - CryEvent m_resetDoneEvent; - string m_name; - uint32 m_nReadCounter; -}; - -////////////////////////////////////////////////////////////////////////// -// Thread that performs IO operations. -////////////////////////////////////////////////////////////////////////// -class CStreamingWorkerThread - : public CrySimpleThread - , public CMultiThreadRefCount -{ -public: - enum EWorkerType - { - eWorkerAsyncCallback, - }; - CStreamingWorkerThread(CStreamEngine* pStreamEngine, const char* name, EWorkerType type, SStreamRequestQueue* pQueue); - ~CStreamingWorkerThread(); - - void BeginReset(); - void EndReset(); - - void CancelAll(); - - ////////////////////////////////////////////////////////////////////////// - // CrySimpleThread - ////////////////////////////////////////////////////////////////////////// - virtual void Run(); - virtual void Cancel(); - ////////////////////////////////////////////////////////////////////////// - -private: - EWorkerType m_type; - CStreamEngine* m_pStreamEngine; - SStreamRequestQueue* m_pQueue; - - volatile bool m_bCancelThreadRequest; - volatile bool m_bNeedsReset; - - CryEvent m_resetDoneEvent; - string m_name; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMIOTHREAD_H diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp b/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp deleted file mode 100644 index 729f268d78..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#include "CrySystem_precompiled.h" -#include -#include - -#include "StreamReadStream.h" -#include "StreamEngine.h" -#include "MTSafeAllocator.h" - -extern CMTSafeHeap* g_pPakHeap; -SLockFreeSingleLinkedListHeader CReadStream::s_freeRequests; - -CReadStream* CReadStream::Allocate(CStreamEngine* pEngine, const EStreamTaskType tSource, const char* szFilename, IStreamCallback* pCallback, const StreamReadParams* pParams) -{ - char* pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests)); - - CReadStream* pReq; - IF_LIKELY (pFree) - { - AZ_PUSH_DISABLE_WARNING(,"-Winvalid-offsetof") - ptrdiff_t offs = offsetof(CReadStream, m_nextFree); - AZ_POP_DISABLE_WARNING - pReq = reinterpret_cast(pFree - offs); - } - else - { - pReq = new CReadStream; - } - - pReq->m_pEngine = pEngine; - pReq->m_Type = tSource; - pReq->m_strFileName = szFilename; - pReq->m_pCallback = pCallback; - if (pParams) - { - pReq->m_Params = *pParams; - } - pReq->m_pBuffer = pReq->m_Params.pBuffer; - -#ifdef STREAMENGINE_ENABLE_STATS - pReq->m_requestTime = gEnv->pTimer->GetAsyncTime(); -#endif - - return pReq; -} - -void CReadStream::Flush() -{ - AZ_PUSH_DISABLE_WARNING(, "-Winvalid-offsetof") - ptrdiff_t offs = offsetof(CReadStream, m_nextFree); - AZ_POP_DISABLE_WARNING - - for (char* pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests)); - pFree; - pFree = reinterpret_cast(CryInterlockedPopEntrySList(s_freeRequests))) - { - CReadStream* pReq = reinterpret_cast(pFree - offs); - delete pReq; - } -} - -////////////////////////////////////////////////////////////////////////// -CReadStream::CReadStream() -{ - Reset(); -} - -////////////////////////////////////////////////////////////////////////// -CReadStream::~CReadStream() -{ -} - -// returns true if the file read was completed (successfully or unsuccessfully) -// check IsError to check if the whole requested file (piece) was read -bool CReadStream::IsFinished() -{ - return m_bFinished; -} - -// returns the number of bytes read so far (the whole buffer size if IsFinished()) -unsigned int CReadStream::GetBytesRead ([[maybe_unused]] bool bWait) -{ - if (!m_bError) - { - return m_Params.nSize; - } - return 0; -} - - -// returns the buffer into which the data has been or will be read -// at least GetBytesRead() bytes in this buffer are guaranteed to be already read -const void* CReadStream::GetBuffer () -{ - return m_pBuffer; -} - -void CReadStream::AbortShutdown() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - - m_bError = true; - m_nIOError = ERROR_ABORTED_ON_SHUTDOWN; - m_bFileRequestComplete = true; - - if (m_pFileRequest) - { - __debugbreak(); - } - } - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - { - CryAutoCriticalSection lock(m_callbackLock); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - } -} - -// tries to stop reading the stream; this is advisory and may have no effect -// all the callbacks will be called after this. If you just destructing object, -// dereference this object and it will automatically abort and release all associated resources. -void CReadStream::Abort() -{ - { - CryAutoCriticalSection lock(m_callbackLock); - - m_bError = true; - m_nIOError = ERROR_USER_ABORT; - m_bFileRequestComplete = true; - - if (m_pFileRequest) - { - m_pFileRequest->Cancel(); - m_pFileRequest = 0; - } - } - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - { - CryAutoCriticalSection lock(m_callbackLock); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - } - - m_pEngine->AbortJob(this); -} - -bool CReadStream::TryAbort() -{ - if (!m_callbackLock.TryLock()) - { - return false; - } - - if (m_pFileRequest && !m_pFileRequest->TryCancel()) - { - m_callbackLock.Unlock(); - return false; - } - - m_bError = true; - m_nIOError = ERROR_USER_ABORT; - m_bFileRequestComplete = true; - m_pFileRequest = 0; - - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - // all the callbacks have to handle error cases and needs to be called anyway, even if the stream I/O is aborted - ExecuteAsyncCallback_CBLocked(); - ExecuteSyncCallback_CBLocked(); - - m_pCallback = NULL; - - m_callbackLock.Unlock(); - - m_pEngine->AbortJob(this); - - return true; -} - -// tries to raise the priority of the read; this is advisory and may have no effect -void CReadStream::SetPriority (EStreamTaskPriority ePriority) -{ - if (m_Params.ePriority != ePriority) - { - m_Params.ePriority = ePriority; - if (m_pFileRequest && m_pFileRequest->m_status == CAsyncIOFileRequest::eStatusInFileQueue) - { - m_pEngine->UpdateJobPriority(this); - } - } -} - -// unconditionally waits until the callback is called -// i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback -// is called before return from this function (unless no callback was specified) -void CReadStream::Wait(int nMaxWaitMillis) -{ - // lock this object to avoid preliminary destruction - CReadStream_AutoPtr pLock(this); - - bool bNeedFinalize = (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) == 0; - - if (!m_bFinished && !m_bError && !m_pFileRequest) - { - assert(m_pFileRequest != NULL); // If we want to Wait for stream its file request must not be NULL. - // This will almost certainly cause Dead-Lock - CryFatalError("Waiting for stream when StreamingEngine is paused"); - } - - CTimeValue t0; - - if (nMaxWaitMillis > 0) - { - t0 = gEnv->pTimer->GetAsyncTime(); - } - - while (!m_bFinished && !m_bError) - { - if (bNeedFinalize) - { - m_pEngine->MainThread_FinalizeIOJobs(); - } - if (!m_bFileRequestComplete) - { - CrySleep(5); - } - - if (nMaxWaitMillis > 0) - { - CTimeValue t1 = gEnv->pTimer->GetAsyncTime(); - if (CTimeValue(t1 - t0).GetMilliSeconds() > nMaxWaitMillis) - { - // Break if we are waiting for too long. - break; - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -uint64 CReadStream::GetPriority() const -{ - return 0; -} - -// this gets called upon the IO has been executed to call the callbacks -void CReadStream::MainThread_Finalize() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - // call asynchronous callback function if needed synchronously - { - CryAutoCriticalSection lock(m_callbackLock); - ExecuteSyncCallback_CBLocked(); - } - m_pFileRequest = 0; -} - -IStreamCallback* CReadStream::GetCallback() const -{ - return m_pCallback; -} - -unsigned CReadStream::GetError() const -{ - return m_nIOError; -} - -const char* CReadStream::GetErrorName() const -{ - switch (m_nIOError) - { - case ERROR_UNKNOWN_ERROR: - return "Unknown error"; - case ERROR_UNEXPECTED_DESTRUCTION: - return "Unexpected destruction"; - case ERROR_INVALID_CALL: - return "Invalid call"; - case ERROR_CANT_OPEN_FILE: - return "Cannot open the file"; - case ERROR_REFSTREAM_ERROR: - return "Refstream error"; - case ERROR_OFFSET_OUT_OF_RANGE: - return "Offset out of range"; - case ERROR_REGION_OUT_OF_RANGE: - return "Region out of range"; - case ERROR_SIZE_OUT_OF_RANGE: - return "Size out of range"; - case ERROR_CANT_START_READING: - return "Cannot start reading"; - case ERROR_OUT_OF_MEMORY: - return "Out of memory"; - case ERROR_ABORTED_ON_SHUTDOWN: - return "Aborted on shutdown"; - case ERROR_OUT_OF_MEMORY_QUOTA: - return "Out of memory quota"; - case ERROR_ZIP_CACHE_FAILURE: - return "ZIP cache failure"; - case ERROR_USER_ABORT: - return "User aborted"; - } - return "Unrecognized error"; -} - -int CReadStream::AddRef() -{ - return CryInterlockedIncrement(&m_nRefCount); -} - -int CReadStream::Release() -{ - int nRef = CryInterlockedDecrement(&m_nRefCount); - -#ifndef _RELEASE - if (nRef < 0) - { - __debugbreak(); - } -#endif - - if (nRef == 0) - { - Reset(); - CryInterlockedPushEntrySList(s_freeRequests, m_nextFree); - } - - return nRef; -} - -void CReadStream::Reset() -{ - m_strFileName.clear(); - m_pFileRequest = NULL; - m_Params = StreamReadParams(); - memset((void*)&m_nRefCount, 0, (char*)(this + 1) - (char*)(&m_nRefCount)); -} - -void CReadStream::SetUserData(DWORD_PTR dwUserData) -{ - m_Params.dwUserData = dwUserData; -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::ExecuteAsyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_bIsAsyncCallbackExecuted && m_pCallback) - { - m_bIsAsyncCallbackExecuted = true; - m_pCallback->StreamAsyncOnComplete(this, m_nIOError); - } -} - -void CReadStream::ExecuteSyncCallback_CBLocked() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - if (!m_bIsSyncCallbackExecuted && m_pCallback && (0 == (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK))) - { - m_bIsSyncCallbackExecuted = true; - - CReadStream_AutoPtr protectMe(this); // Stream can be freed inside the callback! - - m_pCallback->StreamOnComplete(this, m_nIOError); - - // We do not need FileRequest here anymore, and not its temporary memory. - m_pFileRequest = 0; - m_pBuffer = NULL; - m_bFinished = true; - } - else - { - m_pFileRequest = 0; - m_pBuffer = NULL; - m_bFinished = true; - } - -#ifdef STREAMENGINE_ENABLE_LISTENER - IStreamEngineListener* pListener = m_pEngine->GetListener(); - if (pListener) - { - pListener->OnStreamDone(this); - } -#endif -} - -void* CReadStream::operator new (size_t sz) -{ - return CryModuleMemalign(sz, alignof(CReadStream)); -} - -void CReadStream::operator delete(void* p) -{ - CryModuleMemalignFree(p); -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::FreeTemporaryMemory() -{ - // Free temporary block. - if (m_pFileRequest) - { - m_pFileRequest->SyncWithDecompress(); - m_pFileRequest->FreeBuffer(); - } - m_pBuffer = 0; -} - -////////////////////////////////////////////////////////////////////////// -bool CReadStream::IsReqReading() -{ - if (m_strFileName.empty()) - { - return false; - } - return true; -} - -////////////////////////////////////////////////////////////////////////// -CAsyncIOFileRequest* CReadStream::CreateFileRequest() -{ - m_pFileRequest = CAsyncIOFileRequest::Allocate(m_Type); - m_pFileRequest->m_nRequestedSize = m_Params.nSize; - m_pFileRequest->m_nRequestedOffset = m_Params.nOffset; - m_pFileRequest->m_pExternalMemoryBuffer = m_pBuffer; - m_pFileRequest->m_bWriteOnlyExternal = (m_Params.nFlags & IStreamEngine::FLAGS_WRITE_ONLY_EXTERNAL_BUFFER) != 0; - m_pFileRequest->m_pReadStream = this; - m_pFileRequest->m_strFileName = m_strFileName; - m_pFileRequest->m_ePriority = m_Params.ePriority; - m_pFileRequest->m_eMediaType = m_Params.eMediaType; - - m_bFileRequestComplete = false; - return m_pFileRequest; -} - -void* CReadStream::OnNeedStorage(size_t size, bool& bAbortOnFailToAlloc) -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (m_pCallback) - { - return m_pCallback->StreamOnNeedStorage(this, size, bAbortOnFailToAlloc); - } - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -void CReadStream::OnAsyncFileRequestComplete() -{ - CryAutoCriticalSection lock(m_callbackLock); - - if (!m_bFileRequestComplete) - { - if (m_pFileRequest) - { - m_Params.nSize = m_pFileRequest->m_nRequestedSize; - m_pBuffer = m_pFileRequest->m_pOutputMemoryBuffer; - m_nBytesRead = m_pFileRequest->m_nSizeOnMedia; - m_nIOError = m_pFileRequest->m_nError; - m_bError = m_nIOError != 0; - if (m_bError) - { - m_nBytesRead = 0; - } - -#ifdef STREAMENGINE_ENABLE_STATS - m_ReadTime = m_pFileRequest->m_readTime; -#endif - } - - ExecuteAsyncCallback_CBLocked(); - - if (m_Params.nFlags & IStreamEngine::FLAGS_NO_SYNC_CALLBACK) - { - // We do not need FileRequest here anymore, and not its temporary memory. - m_pFileRequest = 0; - m_bFinished = true; - } - - m_bFileRequestComplete = true; - } -} - - diff --git a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h b/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h deleted file mode 100644 index cf6ee25d97..0000000000 --- a/Code/CryEngine/CrySystem/StreamEngine/StreamReadStream.h +++ /dev/null @@ -1,178 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Streaming Engine - - -#ifndef CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H -#define CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H -#pragma once - - -#include "IStreamEngine.h" -#include "StreamAsyncFileRequest.h" - -class CStreamEngine; - -class CReadStream - : public IReadStream -{ - friend class CStreamEngine; - -public: - static CReadStream* Allocate(CStreamEngine* pEngine, const EStreamTaskType tSource, const char* szFilename, IStreamCallback* pCallback, const StreamReadParams* pParams); - static void Flush(); - -public: - CReadStream(); - virtual ~CReadStream (); - - virtual int AddRef(); - virtual int Release(); - - virtual DWORD_PTR GetUserData() {return m_Params.dwUserData; } - - // set user defined data into stream's params - virtual void SetUserData(DWORD_PTR dwUserData); - - // returns true if the file read was not successful. - virtual bool IsError() { return m_bError; }; - - // returns true if the file read was completed (successfully or unsuccessfully) - // check IsError to check if the whole requested file (piece) was read - virtual bool IsFinished(); - - // returns the number of bytes read so far (the whole buffer size if IsFinished()) - virtual unsigned int GetBytesRead (bool bWait); - - // returns the buffer into which the data has been or will be read - // at least GetBytesRead() bytes in this buffer are guaranteed to be already read - virtual const void* GetBuffer (); - - void AbortShutdown(); - - // tries to stop reading the stream; this is advisory and may have no effect - // but the callback will not be called after this. If you just destructing object, - // dereference this object and it will automatically abort and release all associated resources. - virtual void Abort(); - virtual bool TryAbort(); - - // tries to raise the priority of the read; this is advisory and may have no effect - virtual void SetPriority (EStreamTaskPriority EPriority); - - // unconditionally waits until the callback is called - // i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback - // is called before return from this function (unless no callback was specified) - virtual void Wait(int nMaxWaitMillis = -1); - - virtual uint64 GetPriority() const; - - virtual const StreamReadParams& GetParams() const {return m_Params; } - - virtual const EStreamTaskType GetCallerType() const { return m_Type; } - - virtual EStreamSourceMediaType GetMediaType() const { return m_MediaType; } - - // return pointer to callback routine(can be NULL) - virtual IStreamCallback* GetCallback() const; - - // return IO error # - virtual unsigned GetError() const; - - // Returns IO error name - virtual const char* GetErrorName() const; - - // return stream name - virtual const char* GetName() const { return m_strFileName.c_str(); }; - - virtual void FreeTemporaryMemory(); - - // this gets called upon the IO has been executed to call the callbacks - void MainThread_Finalize(); - - bool IsReqReading(); - -#ifdef STREAMENGINE_ENABLE_STATS - void SetRequestTime(CTimeValue& time) { m_requestTime = time; } - const CTimeValue& GetRequestTime() { return m_requestTime; } -#endif - - // decompression of zip-compressed files with default behavior - CAsyncIOFileRequest* CreateFileRequest(); - void ComputedMediaType(EStreamSourceMediaType eMT) { m_MediaType = eMT; } - void* OnNeedStorage(size_t size, bool& bAbortOnFailToAlloc); - void OnAsyncFileRequestComplete(); - CAsyncIOFileRequest* GetFileRequest() { return m_pFileRequest; } - -private: - void Reset(); - - // call the async callback - void ExecuteAsyncCallback_CBLocked(); - - // call the sync callback - void ExecuteSyncCallback_CBLocked(); - -private: - void* operator new (size_t sz); - void operator delete(void* p); - -private: - static SLockFreeSingleLinkedListHeader s_freeRequests; - -private: - STREAMENGINE_LL_ALIGN SLockFreeSingleLinkedListEntry m_nextFree; - - CryStringLocal m_strFileName; - CryCriticalSection m_callbackLock; - CAsyncIOFileRequest_AutoPtr m_pFileRequest; - - StreamReadParams m_Params; - - // Only POD types must exist below here. They will be memset! - - volatile int m_nRefCount; - CStreamEngine* m_pEngine; - - // the type of the task - EStreamTaskType m_Type; - EStreamSourceMediaType m_MediaType; - // the initial data from the user - // the callback; may be NULL - IStreamCallback* m_pCallback; - - // Bytes actually read from media. - uint32 m_nBytesRead; - - volatile bool m_bIsAsyncCallbackExecuted; - volatile bool m_bIsSyncCallbackExecuted; - volatile bool m_bFileRequestComplete; - - // the actual buffer to read to - void* m_pBuffer; - - volatile bool m_bError; - volatile bool m_bFinished; - unsigned int m_nIOError; - -#ifdef STREAMENGINE_ENABLE_STATS - // time when request was made - CTimeValue m_requestTime; - // Time for actual reading - CTimeValue m_ReadTime; -#endif -}; - -TYPEDEF_AUTOPTR(CReadStream); - -#endif // CRYINCLUDE_CRYSYSTEM_STREAMENGINE_STREAMREADSTREAM_H diff --git a/Code/CryEngine/CrySystem/SyncLock.cpp b/Code/CryEngine/CrySystem/SyncLock.cpp deleted file mode 100644 index 4fb30e2ee2..0000000000 --- a/Code/CryEngine/CrySystem/SyncLock.cpp +++ /dev/null @@ -1,246 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "SyncLock.h" - -SSyncLock::SSyncLock(const char* name, int id, bool own) -{ - stack_string ss; - ss.Format("%s_%d", name, id); - - Open(ss); - if (own) - { - if (!IsValid()) - { - Create(ss); - number = id; - } - else - { - Close(); - } - } - else - { - number = id; - } -} - -SSyncLock::SSyncLock(const char* name, int minId, int maxId) -{ - ev = 0; - stack_string ss; - for (int i = minId; i < maxId; ++i) - { - ss.Format("%s_%d", name, i); - if (Open(ss)) - { - Close(); - continue; - } - if (Create(ss)) - { - number = i; - } - break; - } -} - -SSyncLock::~SSyncLock() -{ - Close(); -} - -void SSyncLock::Own(const char* name) -{ - o_name.Format("%s_%d", name, number); -} - -#if defined(LINUX) || defined(APPLE) - -bool SSyncLock::Open(const char* name) -{ - ev = sem_open(name, 0); - if (ev != SEM_FAILED) - { - CryLogAlways("Opened semaphore %p %s", ev, name); - } - return IsValid(); -} - -bool SSyncLock::Create(const char* name) -{ - ev = sem_open(name, O_CREAT | O_EXCL, 0777, 0); - if (ev != SEM_FAILED) - { - CryLogAlways("Created semaphore %p %s", ev, name); - } - else - { - CryLogAlways("Failed to create semaphore %s %d", name, errno); - } - return IsValid(); -} - -void SSyncLock::Signal() -{ - if (ev) - { - sem_post(ev); - } -} - -bool SSyncLock::Wait(int ms) -{ - if (!ev) - { - return false; - } - - timespec t = { 0 }; -#if defined(LINUX) - clock_gettime(CLOCK_REALTIME, &t); -#elif defined(APPLE) - // On OSX/iOS there is no sem_timedwait() - // We use repeated sem_trywait() instead - if (sem_trywait(ev) == 0) - { - return true; - } -#endif - - static const long NANOSECS_IN_MSEC = 1000000L; - static const long NANOSECS_IN_SEC = 1000000000L; - - t.tv_sec += ms / 1000; - t.tv_nsec += (ms % 1000) * NANOSECS_IN_MSEC; - if (t.tv_nsec > NANOSECS_IN_SEC) - { - t.tv_nsec -= NANOSECS_IN_SEC; - ++t.tv_sec; - } -#if defined(LINUX) - return sem_timedwait(ev, &t) == 0; //ETIMEDOUT for timeout -#elif defined (APPLE) - // t = time left, interval = max time between tries, elapsed = actual time elapsed during a try - const int num_ms_interval = 50; // poll time, in ms - const timespec interval = { 0, NANOSECS_IN_MSEC * num_ms_interval }; - while (t.tv_sec >= 0 || t.tv_nsec > interval.tv_nsec) - { - timespec remaining; - timespec elapsed = interval; - if (nanosleep(&interval, &remaining) == -1) - { - elapsed.tv_nsec -= remaining.tv_nsec; - } - t.tv_nsec -= elapsed.tv_nsec; - if (t.tv_nsec < 0L) - { - t.tv_nsec += NANOSECS_IN_SEC; - t.tv_sec -= 1; - } - if (sem_trywait(ev) == 0) - { - return true; - } - } - nanosleep(&t, NULL); - return sem_trywait(ev) == 0; -#else -#error Not implemented -#endif -} - -void SSyncLock::Close() -{ - if (ev) - { - sem_close(ev); - ev = nullptr; - if (!o_name.empty()) - { - sem_unlink(o_name); - } - } -} - -#else // defined(LINUX) || defined(APPLE) - -bool SSyncLock::Open(const char* name) -{ - ev = OpenEvent(SYNCHRONIZE, FALSE, name); - if (ev) - { - CryLogAlways("Opened event %p %s", ev, name); - } - return IsValid(); -} - -bool SSyncLock::Create(const char* name) -{ - ev = CreateEvent(NULL, FALSE, FALSE, name); - if (ev) - { - CryLogAlways("Created event %p %s", ev, name); - } - else - { - CryLogAlways("Failed to create event %s", name); - } - return IsValid(); -} - -bool SSyncLock::Wait(int ms) -{ - // CryLogAlways("Waiting %p", ev); - DWORD res = WaitForSingleObject(ev, ms); - if (res != WAIT_OBJECT_0) - { - CryLogAlways("WFS result %d", res); - } - return res == WAIT_OBJECT_0; -} - -void SSyncLock::Signal() -{ - //CryLogAlways("Signaled %p", ev); - if (!SetEvent(ev)) - { - CryLogAlways("Error signalling!"); - } -} - -void SSyncLock::Close() -{ - if (ev) - { - CryLogAlways("Closed event %p", ev); - CloseHandle(ev); - ev = 0; - } -} - -#endif // defined(LINUX) || defined(APPLE) - -bool SSyncLock::IsValid() const -{ - return ev != 0; -} - -#endif // defined(MAP_LOADING_SLICING) diff --git a/Code/CryEngine/CrySystem/SyncLock.h b/Code/CryEngine/CrySystem/SyncLock.h deleted file mode 100644 index 5e22797a6b..0000000000 --- a/Code/CryEngine/CrySystem/SyncLock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SYNCLOCK_H -#define CRYINCLUDE_CRYSYSTEM_SYNCLOCK_H - -#pragma once - -#if defined(LINUX) || defined(APPLE) -#include -#endif - -struct SSyncLock -{ -#if defined(LINUX) || defined(APPLE) - typedef sem_t* HandleType; -#else - typedef HANDLE HandleType; -#endif - - SSyncLock(const char* name, int id, bool own); - SSyncLock(const char* name, int minId, int maxId); - ~SSyncLock(); - - void Own(const char* name); - bool Open(const char* name); - bool Create(const char* name); - void Signal(); - bool Wait(int ms); - void Close(); - bool IsValid() const; - - HandleType ev; - int number; - string o_name; -}; - -#endif // CRYINCLUDE_CRYSYSTEM_SYNCLOCK_H diff --git a/Code/CryEngine/CrySystem/System.cpp b/Code/CryEngine/CrySystem/System.cpp index af9b674f6a..6fcbc32b72 100644 --- a/Code/CryEngine/CrySystem/System.cpp +++ b/Code/CryEngine/CrySystem/System.cpp @@ -121,13 +121,9 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include #include -#include #include #include #include -#include -#include -#include "VisRegTest.h" #include #include @@ -135,40 +131,21 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) #include #include "XConsole.h" #include "Log.h" -#include "CrySizerStats.h" -#include "CrySizerImpl.h" -#include "NotificationNetwork.h" -#include "ProfileLog.h" #include "XML/xml.h" #include "XML/ReadWriteXMLSink.h" -#include "StreamEngine/StreamEngine.h" -#include "PhysRenderer.h" - #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" -#include "Serialization/ArchiveHost.h" #include "SystemEventDispatcher.h" -#include "ServerThrottle.h" -#include "ResourceManager.h" #include "HMDBus.h" -#include "OverloadSceneManager/OverloadSceneManager.h" -#include -#include "IZLibCompressor.h" -#include "IZlibDecompressor.h" -#include "ILZ4Decompressor.h" -#include "IZStdDecompressor.h" #include "zlib.h" #include "RemoteConsole/RemoteConsole.h" #include #include -#include "CryWaterMark.h" -WATERMARKDATA(_m); -#include "ImageHandler.h" #include #include #include @@ -184,13 +161,8 @@ WATERMARKDATA(_m); #include #endif -#if USE_STEAM -#include "Steamworks/public/steam/steam_api.h" -#endif - #include -#include #include // profilers api. @@ -200,19 +172,6 @@ VTuneFunction VTPause = NULL; // Define global cvars. SSystemCVars g_cvars; -#include "ITextModeConsole.h" - -extern int CryMemoryGetAllocatedSize(); - -// these heaps are used by underlying System structures -// to allocate, accordingly, small (like elements of std::set<..*>) and big (like memory for reading files) objects -// hopefully someday we'll have standard MT-safe heap -//CMTSafeHeap g_pakHeap; -CMTSafeHeap* g_pPakHeap = 0;// = &g_pakHeap; - -////////////////////////////////////////////////////////////////////////// -#include "Validator.h" - #include #include @@ -273,27 +232,10 @@ namespace } #endif -#if defined(CVARS_WHITELIST) -struct SCVarsWhitelistConfigSink - : public ILoadConfigurationEntrySink -{ - virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup) - { - ICVarsWhitelist* pCVarsWhitelist = gEnv->pSystem->GetCVarsWhiteList(); - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(szKey, false) : true; - if (whitelisted) - { - gEnv->pConsole->LoadConfigVar(szKey, szValue); - } - } -} g_CVarsWhitelistConfigSink; -#endif // defined(CVARS_WHITELIST) - ///////////////////////////////////////////////////////////////////////////////// // System Implementation. ////////////////////////////////////////////////////////////////////////// CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) - : m_imageHandler(std::make_unique()) { CrySystemRequestBus::Handler::BusConnect(); @@ -318,11 +260,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pSystemEventDispatcher->RegisterListener(this); } -#ifdef WIN32 - m_hInst = NULL; - m_hWnd = NULL; -#endif - ////////////////////////////////////////////////////////////////////////// // Clear environment. ////////////////////////////////////////////////////////////////////////// @@ -333,31 +270,14 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_env.pSystem = this; m_env.pTimer = &m_Time; m_env.pNameTable = &m_nameTable; - m_env.bServer = false; - m_env.bMultiplayer = false; - m_env.bHostMigrating = false; m_env.bIgnoreAllAsserts = false; m_env.bNoAssertDialog = false; - m_env.bTesting = false; m_env.pSharedEnvironment = pSharedEnvironment; - - m_env.SetFMVIsPlaying(false); - m_env.SetCutsceneIsPlaying(false); - - m_env.szDebugStatus[0] = '\0'; - -#if !defined(CONSOLE) - m_env.SetIsClient(false); -#endif ////////////////////////////////////////////////////////////////////////// - m_pStreamEngine = NULL; - m_PhysThread = 0; - m_pIFont = NULL; m_pIFontUi = NULL; - m_pVisRegTest = NULL; m_rWidth = NULL; m_rHeight = NULL; m_rWidthAndHeightAsFractionOfScreenSize = NULL; @@ -368,22 +288,12 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_cvSSInfo = NULL; m_rStencilBits = NULL; m_rFullscreen = NULL; - m_rDriver = NULL; m_sysNoUpdate = NULL; - m_pMemoryManager = NULL; m_pProcess = NULL; - - m_pValidator = NULL; m_pCmdLine = NULL; - m_pDefaultValidator = NULL; m_pLevelSystem = NULL; m_pViewSystem = NULL; - m_pIZLibCompressor = NULL; - m_pIZLibDecompressor = NULL; - m_pILZ4Decompressor = NULL; - m_pIZStdDecompressor = nullptr; m_pLocalizationManager = NULL; - m_sys_physics_CPU = 0; #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_2 #include AZ_RESTRICTED_FILE(System_cpp) @@ -391,29 +301,20 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_sys_min_step = 0; m_sys_max_step = 0; - m_pNotificationNetwork = NULL; - m_cvAIUpdate = NULL; m_pUserCallback = NULL; -#if defined(CVARS_WHITELIST) - m_pCVarsWhitelist = NULL; - m_pCVarsWhitelistConfigSink = &g_CVarsWhitelistConfigSink; -#endif // defined(CVARS_WHITELIST) m_sys_memory_debug = NULL; m_sysWarnings = NULL; m_sysKeyboard = NULL; - m_sys_GraphicsQuality = NULL; m_sys_firstlaunch = NULL; m_sys_enable_budgetmonitoring = NULL; m_sys_preload = NULL; // m_sys_filecache = NULL; m_gpu_particle_physics = NULL; - m_pCpu = NULL; m_bInitializedSuccessfully = false; - m_bShaderCacheGenMode = false; m_bRelaunch = false; m_iLoadingMode = 0; m_bTestMode = false; @@ -423,16 +324,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_bNoCrashDialog = false; m_bNoErrorReportWindow = false; -#ifndef _RELEASE - m_checkpointLoadCount = 0; - m_loadOrigin = eLLO_Unknown; - m_hasJustResumed = false; - m_expectingMapCommand = false; -#endif - - // no mem stats at the moment - m_pMemStats = NULL; - m_pSizer = NULL; m_pCVarQuit = NULL; m_bForceNonDevMode = false; @@ -446,13 +337,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_nServerConfigSpec = CONFIG_VERYHIGH_SPEC; m_nMaxConfigSpec = CONFIG_VERYHIGH_SPEC; - //m_hPhysicsThread = INVALID_HANDLE_VALUE; - //m_hPhysicsActive = INVALID_HANDLE_VALUE; - //m_bStopPhysics = 0; - //m_bPhysicsActive = 0; - - m_pProgressListener = 0; - m_bPaused = false; m_bNoUpdate = false; m_nUpdateCounter = 0; @@ -460,18 +344,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) m_pXMLUtils = new CXmlUtils(this); - m_pArchiveHost = Serialization::CreateArchiveHost(); - m_pMemoryManager = CryGetIMemoryManager(); - m_pThreadTaskManager = new CThreadTaskManager; - m_pResourceManager = new CResourceManager; - m_pTextModeConsole = NULL; - - InitThreadSystem(); - - m_pMiniGUI = NULL; - m_pPerfHUD = NULL; - - g_pPakHeap = new CMTSafeHeap; if (!AZ::AllocatorInstance::IsReady()) { @@ -485,13 +357,11 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) AZ::Debug::Trace::Instance().Init(); } - m_UpdateTimesIdx = 0U; m_bNeedDoWorkDuringOcclusionChecks = false; m_eRuntimeState = ESYSTEM_EVENT_LEVEL_UNLOAD; m_bHasRenderedErrorMessage = false; - m_bIsSteamInitialized = false; m_pDataProbe = nullptr; #if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_MESSAGE_HANDLER @@ -499,15 +369,12 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment) #endif m_ConfigPlatform = CONFIG_INVALID_PLATFORM; - - AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect(); } ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// CSystem::~CSystem() { - AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect(); ShutDown(); #if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_MESSAGE_HANDLER @@ -516,21 +383,8 @@ CSystem::~CSystem() CRY_ASSERT(m_windowMessageHandlers.empty() && "There exists a dangling window message handler somewhere"); - SAFE_DELETE(m_pVisRegTest); SAFE_DELETE(m_pXMLUtils); - SAFE_DELETE(m_pArchiveHost); - SAFE_DELETE(m_pThreadTaskManager); - SAFE_DELETE(m_pResourceManager); SAFE_DELETE(m_pSystemEventDispatcher); - // SAFE_DELETE(m_pMemoryManager); - - if (gEnv && gEnv->pThreadManager) - { - gEnv->pThreadManager->UnRegisterThirdPartyThread("Main"); - } - ShutDownThreadSystem(); - - SAFE_DELETE(g_pPakHeap); AZCoreLogSink::Disconnect(); if (m_initedSysAllocator) @@ -571,12 +425,6 @@ void CSystem::FreeLib(AZStd::unique_ptr& hLibModule) } } -////////////////////////////////////////////////////////////////////////// -IStreamEngine* CSystem::GetStreamEngine() -{ - return m_pStreamEngine; -} - ////////////////////////////////////////////////////////////////////////// IRemoteConsole* CSystem::GetIRemoteConsole() { @@ -632,16 +480,6 @@ void CSystem::ShutDown() GetIRemoteConsole()->Stop(); } - // clean up properly the console - if (m_pTextModeConsole) - { - m_pTextModeConsole->OnShutdown(); - } - - SAFE_DELETE(m_pTextModeConsole); - - KillPhysicsThread(); - if (m_sys_firstlaunch) { m_sys_firstlaunch->Set("0"); @@ -678,39 +516,22 @@ void CSystem::ShutDown() // Shutdown any running VR devices. EBUS_EVENT(AZ::VR::HMDInitRequestBus, Shutdown); - // Shutdown resource manager. - m_pResourceManager->Shutdown(); - if (gEnv && gEnv->pLyShine) { gEnv->pLyShine->Release(); gEnv->pLyShine = nullptr; } - SAFE_DELETE(m_env.pResourceCompilerHelper); - SAFE_RELEASE(m_env.pMovieSystem); - SAFE_DELETE(m_env.pServiceNetwork); SAFE_RELEASE(m_env.pLyShine); SAFE_RELEASE(m_env.pCryFont); if (m_env.pConsole) { ((CXConsole*)m_env.pConsole)->FreeRenderResources(); } - SAFE_RELEASE(m_pIZLibCompressor); - SAFE_RELEASE(m_pIZLibDecompressor); - SAFE_RELEASE(m_pILZ4Decompressor); - SAFE_RELEASE(m_pIZStdDecompressor); SAFE_RELEASE(m_pViewSystem); SAFE_RELEASE(m_pLevelSystem); - //Can't kill renderer before we delete CryFont, 3DEngine, etc - if (GetIRenderer()) - { - GetIRenderer()->ShutDown(); - SAFE_RELEASE(m_env.pRenderer); - } - if (m_env.pLog) { m_env.pLog->UnregisterConsoleVariables(); @@ -731,14 +552,11 @@ void CSystem::ShutDown() SAFE_RELEASE(m_cvSSInfo); SAFE_RELEASE(m_rStencilBits); SAFE_RELEASE(m_rFullscreen); - SAFE_RELEASE(m_rDriver); SAFE_RELEASE(m_sysWarnings); SAFE_RELEASE(m_sysKeyboard); - SAFE_RELEASE(m_sys_GraphicsQuality); SAFE_RELEASE(m_sys_firstlaunch); SAFE_RELEASE(m_sys_enable_budgetmonitoring); - SAFE_RELEASE(m_sys_physics_CPU); #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_3 @@ -748,25 +566,8 @@ void CSystem::ShutDown() SAFE_RELEASE(m_sys_min_step); SAFE_RELEASE(m_sys_max_step); - SAFE_RELEASE(m_pNotificationNetwork); - - SAFE_DELETE(m_env.pSoftCodeMgr); - SAFE_DELETE(m_pMemStats); - SAFE_DELETE(m_pSizer); - SAFE_DELETE(m_pDefaultValidator); - m_pValidator = nullptr; - - SAFE_DELETE(m_env.pOverloadSceneManager); - SAFE_DELETE(m_pLocalizationManager); - //DebugStats(false, false);//true); - //CryLogAlways(""); - //CryLogAlways("release mode memory manager stats:"); - //DumpMMStats(true); - - SAFE_DELETE(m_pCpu); - delete m_pCmdLine; m_pCmdLine = 0; @@ -774,12 +575,10 @@ void CSystem::ShutDown() // Shut down audio as late as possible but before the streaming system and console get released! Audio::Gem::AudioSystemGemRequestBus::Broadcast(&Audio::Gem::AudioSystemGemRequestBus::Events::Release); - // Shut down the streaming system and console as late as possible and after audio! - SAFE_DELETE(m_pStreamEngine); + // Shut down console as late as possible and after audio! SAFE_RELEASE(m_env.pConsole); // Log must be last thing released. - SAFE_RELEASE(m_env.pProfileLogSystem); if (m_env.pLog) { m_env.pLog->FlushAndClose(); @@ -788,10 +587,6 @@ void CSystem::ShutDown() ShutdownFileSystem(); -#if defined(MAP_LOADING_SLICING) - delete gEnv->pSystemScheduler; -#endif // defined(MAP_LOADING_SLICING) - ShutdownModuleLibraries(); EBUS_EVENT(CrySystemEventBus, OnCrySystemPostShutdown); @@ -816,11 +611,6 @@ void CSystem::Quit() m_pUserCallback->OnQuit(); } - if (GetIRenderer()) - { - GetIRenderer()->RestoreGamma(); - } - gEnv->pLog->FlushAndClose(); // Latest possible place to flush any pending messages to disk before the forceful termination. @@ -882,273 +672,6 @@ ISystem* CSystem::GetCrySystem() return this; } -////////////////////////////////////////////////////////////////////////// -// Physics thread task -////////////////////////////////////////////////////////////////////////// -class CPhysicsThreadTask - : public IThreadTask -{ -public: - - CPhysicsThreadTask() - { - m_bStopRequested = 0; - m_bIsActive = 0; - m_stepRequested = 0; - m_bProcessing = 0; - m_doZeroStep = 0; - m_lastStepTimeTaken = 0U; - m_lastWaitTimeTaken = 0U; - } - - ////////////////////////////////////////////////////////////////////////// - // IThreadTask implementation. - ////////////////////////////////////////////////////////////////////////// - virtual void OnUpdate() - { - Run(); - // At the end.. delete the task - delete this; - } - virtual void Stop() - { - Cancel(); - } - virtual SThreadTaskInfo* GetTaskInfo() { return &m_TaskInfo; } - ////////////////////////////////////////////////////////////////////////// - - virtual void Run() - { - m_bStopRequested = 0; - m_bIsActive = 1; - - float step, timeTaken, kSlowdown = 1.0f; - int nSlowFrames = 0; - int64 timeStart; -#ifdef ENABLE_LW_PROFILERS - LARGE_INTEGER stepStart, stepEnd; -#endif - LARGE_INTEGER waitStart, waitEnd; - MarkThisThreadForDebugging("Physics"); - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE(System_cpp) -#endif - while (true) - { - QueryPerformanceCounter(&waitStart); - m_FrameEvent.Wait(); // Wait untill new frame - QueryPerformanceCounter(&waitEnd); - m_lastWaitTimeTaken = waitEnd.QuadPart - waitStart.QuadPart; - - if (m_bStopRequested) - { - UnmarkThisThreadFromDebugging(); - return; - } - bool stepped = false; -#ifdef ENABLE_LW_PROFILERS - QueryPerformanceCounter(&stepStart); -#endif - while ((step = m_stepRequested) > 0 || m_doZeroStep) - { - stepped = true; - m_stepRequested = 0; - m_bProcessing = 1; - m_doZeroStep = 0; - - if (kSlowdown != 1.0f) - { - step = max(1, FtoI(step * kSlowdown * 50 - 0.5f)) * 0.02f; - } - timeStart = CryGetTicks(); - timeTaken = gEnv->pTimer->TicksToSeconds(CryGetTicks() - timeStart); - if (timeTaken > step * 0.9f) - { - if (++nSlowFrames > 5) - { - kSlowdown = step * 0.9f / timeTaken; - } - } - else - { - kSlowdown = 1.0f, nSlowFrames = 0; - } - m_bProcessing = 0; - //int timeSleep = (int)((m_timeTarget-gEnv->pTimer->GetAsyncTime()).GetMilliSeconds()*0.9f); - //Sleep(max(0,timeSleep)); - } - if (!stepped) - { - Sleep(0); - } - m_FrameDone.Set(); -#ifdef ENABLE_LW_PROFILERS - QueryPerformanceCounter(&stepEnd); - m_lastStepTimeTaken = stepEnd.QuadPart - stepStart.QuadPart; -#endif - } - } - virtual void Cancel() - { - Pause(); - m_bStopRequested = 1; - m_FrameEvent.Set(); - m_bIsActive = 0; - } - - int Pause() - { - if (m_bIsActive) - { - AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::System); - m_bIsActive = 0; - while (m_bProcessing) - { - ; - } - return 1; - } - return 0; - } - int Resume() - { - if (!m_bIsActive) - { - m_bIsActive = 1; - return 1; - } - return 0; - } - int IsActive() { return m_bIsActive; } - int RequestStep(float dt) - { - if (m_bIsActive && dt > FLT_EPSILON) - { - m_stepRequested += dt; - if (dt <= 0.0f) - { - m_doZeroStep = 1; - } - m_FrameEvent.Set(); - } - - return m_bProcessing; - } - float GetRequestedStep() { return m_stepRequested; } - - uint64 LastStepTaken() const - { - return m_lastStepTimeTaken; - } - - uint64 LastWaitTime() const - { - return m_lastWaitTimeTaken; - } - - void EnsureStepDone() - { - FRAME_PROFILER("SysUpdate:PhysicsEnsureDone", gEnv->pSystem, PROFILE_SYSTEM); - if (m_bIsActive) - { - while (m_stepRequested > 0.0f || m_bProcessing) - { - m_FrameDone.Wait(); - } - } - } - -protected: - - volatile int m_bStopRequested; - volatile int m_bIsActive; - volatile float m_stepRequested; - volatile int m_bProcessing; - volatile int m_doZeroStep; - volatile uint64 m_lastStepTimeTaken; - volatile uint64 m_lastWaitTimeTaken; - - CryEvent m_FrameEvent; - CryEvent m_FrameDone; - - SThreadTaskInfo m_TaskInfo; -}; - -void CSystem::CreatePhysicsThread() -{ - if (!m_PhysThread) - { - ////////////////////////////////////////////////////////////////////////// - SThreadTaskParams threadParams; - threadParams.name = "Physics"; - threadParams.nFlags = THREAD_TASK_BLOCKING; - threadParams.nStackSizeKB = PHYSICS_STACK_SIZE >> 10; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_6 -#include AZ_RESTRICTED_FILE(System_cpp) -#endif - - { - m_PhysThread = new CPhysicsThreadTask; - GetIThreadTaskManager()->RegisterTask(m_PhysThread, threadParams); - } - } - -} - -void CSystem::KillPhysicsThread() -{ - if (m_PhysThread) - { - GetIThreadTaskManager()->UnregisterTask(m_PhysThread); - m_PhysThread = 0; - } -} - -/////////////////////////////////////////////////////////////////////////// -// AzFramework::Terrain::TerrainDataNotificationBus START -void CSystem::OnTerrainDataCreateBegin() -{ - KillPhysicsThread(); -} - -void CSystem::OnTerrainDataDestroyBegin() -{ - OnTerrainDataCreateBegin(); -} - -// AzFramework::Terrain::TerrainDataNotificationBus END -/////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -int CSystem::SetThreadState(ESubsystem subsys, bool bActive) -{ - switch (subsys) - { - case ESubsys_Physics: - { - if (m_PhysThread) - { - return bActive ? ((CPhysicsThreadTask*)m_PhysThread)->Resume() : ((CPhysicsThreadTask*)m_PhysThread)->Pause(); - } - } - break; - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::SleepIfInactive() -{ - // ProcessSleep() - if (m_bDedicatedServer || m_bEditor || gEnv->bMultiplayer) - { - return; - } -} - ////////////////////////////////////////////////////////////////////////// void CSystem::SleepIfNeeded() { @@ -1221,16 +744,10 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) // do the dedicated sleep earlier than the frame profiler to avoid having it counted if (gEnv->IsDedicated()) { -#if defined(MAP_LOADING_SLICING) - gEnv->pSystemScheduler->SchedulingSleepIfNeeded(); -#else SleepIfNeeded(); -#endif // defined(MAP_LOADING_SLICING) } #endif //EXCLUDE_UPDATE_ON_CONSOLE - gEnv->pOverloadSceneManager->Update(); - #ifdef WIN32 // enable/disable SSE fp exceptions (#nan and /0) // need to do it each frame since sometimes they are being reset @@ -1242,15 +759,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) m_nUpdateCounter++; #ifndef EXCLUDE_UPDATE_ON_CONSOLE - if (!m_sDelayedScreeenshot.empty()) - { - gEnv->pRenderer->ScreenShot(m_sDelayedScreeenshot.c_str()); - m_sDelayedScreeenshot.clear(); - } - - // Check if game needs to be sleeping when not active. - SleepIfInactive(); - if (m_pUserCallback) { m_pUserCallback->OnUpdate(); @@ -1265,7 +773,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) prev_sys_float_exceptions = g_cvars.sys_float_exceptions; EnableFloatExceptions(g_cvars.sys_float_exceptions); - UpdateFPExceptionsMaskForThreads(); } #endif //EXCLUDE_UPDATE_ON_CONSOLE ////////////////////////////////////////////////////////////////////////// @@ -1278,27 +785,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) #ifdef USE_REMOTE_CONSOLE GetIRemoteConsole()->Update(); #endif - - if (!gEnv->IsEditor() && gEnv->pRenderer) - { - // If the dimensions of the render target change, - // or are different from the camera defaults, - // we need to update the camera frustum. - CCamera& viewCamera = GetViewCamera(); - const int renderTargetWidth = m_rWidth->GetIVal(); - const int renderTargetHeight = m_rHeight->GetIVal(); - - if (renderTargetWidth != viewCamera.GetViewSurfaceX() || - renderTargetHeight != viewCamera.GetViewSurfaceZ()) - { - viewCamera.SetFrustum(renderTargetWidth, - renderTargetHeight, - viewCamera.GetFov(), - viewCamera.GetNearPlane(), - viewCamera.GetFarPlane(), - gEnv->pRenderer->GetPixelAspectRatio()); - } - } if (nPauseMode != 0) { m_bPaused = true; @@ -1333,66 +819,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } #endif //PROFILE_WITH_VTUNE -#ifdef SOFTCODE_SYSTEM_ENABLED - if (m_env.pSoftCodeMgr) - { - m_env.pSoftCodeMgr->PollForNewModules(); - } -#endif - - if (m_pStreamEngine) - { - FRAME_PROFILER("StreamEngine::Update()", this, PROFILE_SYSTEM); - m_pStreamEngine->Update(); - } - - if (g_cvars.az_streaming_stats) - { - SDrawTextInfo ti; - ti.flags = eDrawText_FixedSize | eDrawText_2D | eDrawText_Monospace; - ti.xscale = ti.yscale = 1.2f; - - const int viewportHeight = GetViewCamera().GetViewSurfaceZ(); - -#if defined(AZ_RESTRICTED_PLATFORM) - #define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_8 -#include AZ_RESTRICTED_FILE(System_cpp) -#else - float y = static_cast(viewportHeight) - 85.0f; -#endif - - AZStd::vector stats; - AZ::Interface::Get()->CollectStatistics(stats); - - for (AZ::IO::Statistic& stat : stats) - { - switch (stat.GetType()) - { - case AZ::IO::Statistic::Type::FloatingPoint: - gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti, - AZStd::string::format("%s/%s: %.3f", stat.GetOwner().data(), stat.GetName().data(), stat.GetFloatValue()).c_str()); - break; - case AZ::IO::Statistic::Type::Integer: - gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti, - AZStd::string::format("%s/%s: %lli", stat.GetOwner().data(), stat.GetName().data(), stat.GetIntegerValue()).c_str()); - break; - case AZ::IO::Statistic::Type::Percentage: - gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti, - AZStd::string::format("%s/%s: %.2f (percent)", stat.GetOwner().data(), stat.GetName().data(), stat.GetPercentage()).c_str()); - break; - default: - gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti, AZStd::string::format("Unsupported stat type: %i", static_cast(stat.GetType())).c_str()); - break; - } - y -= 12.0f; - if (y < 0.0f) - { - //Exit the loop because there's no purpose on rendering text outside of the visible area. - break; - } - } - } - #ifndef EXCLUDE_UPDATE_ON_CONSOLE if (m_bIgnoreUpdates) { @@ -1407,7 +833,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) if (m_sysNoUpdate && m_sysNoUpdate->GetIVal()) { bNoUpdate = true; - updateFlags = ESYSUPDATE_IGNORE_PHYSICS; } m_bNoUpdate = bNoUpdate; @@ -1469,19 +894,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) //update time subsystem m_Time.UpdateOnFrameStart(); - ////////////////////////////////////////////////////////////////////// - // update rate limiter for dedicated server - if (m_pServerThrottle.get()) - { - m_pServerThrottle->Update(); - } - - ////////////////////////////////////////////////////////////////////////// - if (m_env.pRenderer && m_env.pRenderer->GetIStereoRenderer()->IsRenderingToHMD()) - { - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, UpdateInternalState); - } - ////////////////////////////////////////////////////////////////////// //update console system if (m_env.pConsole) @@ -1496,16 +908,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) return false; } -#ifndef EXCLUDE_UPDATE_ON_CONSOLE - - ////////////////////////////////////////////////////////////////////// - //update notification network system - if (m_pNotificationNetwork) - { - FRAME_PROFILER("SysUpdate:NotificationNetwork", this, PROFILE_SYSTEM); - m_pNotificationNetwork->Update(); - } -#endif //EXCLUDE_UPDATE_ON_CONSOLE ////////////////////////////////////////////////////////////////////// //update sound system Part 1 if in Editor / in Game Mode Viewsystem updates the Listeners if (!m_env.IsEditorGameMode()) @@ -1524,93 +926,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode) } } - ////////////////////////////////////////////////////////////////////////// - // Update Threads Task Manager. - ////////////////////////////////////////////////////////////////////////// - { - FRAME_PROFILER("SysUpdate:ThreadTaskManager", this, PROFILE_SYSTEM); - m_pThreadTaskManager->OnUpdate(); - } - - ////////////////////////////////////////////////////////////////////////// - // Update Resource Manager. - ////////////////////////////////////////////////////////////////////////// - { - FRAME_PROFILER("SysUpdate:ResourceManager", this, PROFILE_SYSTEM); - m_pResourceManager->Update(); - } - - ////////////////////////////////////////////////////////////////////// - // update physic system - //static float time_zero = 0; - if (m_sys_physics_CPU->GetIVal() > 0 && !gEnv->IsDedicated()) - { - CreatePhysicsThread(); - } - else - { - KillPhysicsThread(); - } - - static int g_iPausedPhys = 0; - - CPhysicsThreadTask* pPhysicsThreadTask = ((CPhysicsThreadTask*)m_PhysThread); - if (!pPhysicsThreadTask) - { - FRAME_PROFILER_LEGACYONLY("SysUpdate:AllAIAndPhysics", this, PROFILE_SYSTEM); - AZ_TRACE_METHOD_NAME("SysUpdate::AllAIAndPhysics"); - - ////////////////////////////////////////////////////////////////////// - // update entity system (a little bit) before physics - if (nPauseMode != 1) - { - if (!bNoUpdate) - { - EBUS_EVENT(CrySystemEventBus, OnCrySystemPrePhysicsUpdate); - } - } - - // intermingle physics/AI updates so that if we get a big timestep (frame rate glitch etc) the - // AI gets to steer entities before they travel over cliffs etc. - const float maxTimeStep = 0.25f; - int maxSteps = 1; - //float fCurTime = m_Time.GetCurrTime(); - float timeToDo = m_Time.GetFrameTime();//fCurTime - fPrevTime; - if (m_env.bMultiplayer) - { - timeToDo = m_Time.GetRealFrameTime(); - } - - - - while (timeToDo > 0.0001f && maxSteps-- > 0) - { - float thisStep = min(maxTimeStep, timeToDo); - timeToDo -= thisStep; - - - EBUS_EVENT(CrySystemEventBus, OnCrySystemPostPhysicsUpdate); - } - - } - else - { - - // In multithreaded physics mode, post physics fires after physics events are dispatched on the main thread. - EBUS_EVENT(CrySystemEventBus, OnCrySystemPostPhysicsUpdate); - - ////////////////////////////////////////////////////////////////////// - // update entity system (a little bit) before physics - if (nPauseMode != 1) - { - if (!bNoUpdate) - { - EBUS_EVENT(CrySystemEventBus, OnCrySystemPrePhysicsUpdate); - } - } - - } - // Use UI timer for CryMovie, because it should not be affected by pausing game time const float fMovieFrameTime = m_Time.GetFrameTime(ITimer::ETIMER_UI); @@ -1672,8 +987,6 @@ bool CSystem::UpdatePostTickBus(int updateFlags, int /*nPauseMode*/) m_updateTimes.push_back(std::make_pair(cur_time, updateTime)); } - UpdateUpdateTimes(); - { FRAME_PROFILER("SysUpdate - SystemEventDispatcher::Update", this, PROFILE_SYSTEM); m_pSystemEventDispatcher->Update(); @@ -1910,21 +1223,6 @@ void CSystem::WarningV(EValidatorModule module, EValidatorSeverity severity, int m_env.pLog->LogWithType(ltype, flags | VALIDATOR_FLAG_SKIP_VALIDATOR, "%s", szBuffer); } - //if(file) - //m_env.pLog->LogWithType( ltype, " ... caused by file '%s'",file); - - if (m_pValidator && (flags & VALIDATOR_FLAG_SKIP_VALIDATOR) == 0) - { - SValidatorRecord record; - record.file = file; - record.text = szBuffer; - record.module = module; - record.severity = severity; - record.flags = flags; - record.assetScope = m_env.pLog->GetAssetScopeString(); - m_pValidator->Report(record); - } - if (bDbgBreak && g_cvars.sys_error_debugbreak) { AZ::Debug::Trace::Break(); @@ -2000,36 +1298,12 @@ void CSystem::Relaunch(bool bRelaunch) SaveConfiguration(); } -////////////////////////////////////////////////////////////////////////// -ICrySizer* CSystem::CreateSizer() -{ - return new CrySizerImpl; -} - -////////////////////////////////////////////////////////////////////////// -uint32 CSystem::GetUsedMemory() -{ - return CryMemoryGetAllocatedSize(); -} - ////////////////////////////////////////////////////////////////////////// ILocalizationManager* CSystem::GetLocalizationManager() { return m_pLocalizationManager; } -////////////////////////////////////////////////////////////////////////// -IThreadTaskManager* CSystem::GetIThreadTaskManager() -{ - return m_pThreadTaskManager; -} - -////////////////////////////////////////////////////////////////////////// -IResourceManager* CSystem::GetIResourceManager() -{ - return m_pResourceManager; -} - ////////////////////////////////////////////////////////////////////////// void CSystem::debug_GetCallStackRaw(void** callstack, uint32& callstackLength) { @@ -2069,12 +1343,6 @@ void CSystem::ExecuteCommandLine(bool deferred) m_executedCommandLine = true; - // auto detect system spec (overrides profile settings) - if (m_pCmdLine->FindArg(eCLAT_Pre, "autodetect")) - { - AutoDetectSpec(false); - } - // execute command line arguments e.g. +g_gametype ASSAULT +map "testy" ICmdLine* pCmdLine = GetICmdLine(); @@ -2088,10 +1356,6 @@ void CSystem::ExecuteCommandLine(bool deferred) if (pCmd->GetType() == eCLAT_Post) { string sLine = pCmd->GetName(); - -#if defined(CVARS_WHITELIST) - if (!GetCVarsWhiteList() || GetCVarsWhiteList()->IsWhiteListed(sLine, false)) -#endif { if (pCmd->GetValue()) { @@ -2101,67 +1365,12 @@ void CSystem::ExecuteCommandLine(bool deferred) GetILog()->Log("Executing command from command line: \n%s\n", sLine.c_str()); // - the actual command might be executed much later (e.g. level load pause) GetIConsole()->ExecuteString(sLine.c_str(), false, deferred); } -#if defined(CVARS_WHITELIST) - else if (gEnv->IsDedicated()) - { - GetILog()->LogError("Failed to execute command: '%s' as it is not whitelisted\n", sLine.c_str()); - } -#endif } } //gEnv->pConsole->ExecuteString("sys_RestoreSpec test*"); // to get useful debugging information about current spec settings to the log file } -void CSystem::DumpMemoryCoverage() -{ - m_MemoryFragmentationProfiler.DumpMemoryCoverage(); -} - -ITextModeConsole* CSystem::GetITextModeConsole() -{ - if (m_bDedicatedServer) - { - return m_pTextModeConsole; - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -ESystemConfigSpec CSystem::GetConfigSpec(bool bClient) -{ - if (bClient) - { - if (m_sys_GraphicsQuality) - { - return (ESystemConfigSpec)m_sys_GraphicsQuality->GetIVal(); - } - return CONFIG_VERYHIGH_SPEC; // highest spec. - } - else - { - return m_nServerConfigSpec; - } -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient) -{ - if (bClient) - { - if (m_sys_GraphicsQuality) - { - SetConfigPlatform(platform); - m_sys_GraphicsQuality->Set(static_cast(spec)); - } - } - else - { - m_nServerConfigSpec = spec; - } -} - ////////////////////////////////////////////////////////////////////////// ESystemConfigSpec CSystem::GetMaxConfigSpec() const { @@ -2211,136 +1420,6 @@ void CProfilingSystem::VTunePause() #endif } -////////////////////////////////////////////////////////////////////////// -sUpdateTimes& CSystem::GetCurrentUpdateTimeStats() -{ - return m_UpdateTimes[m_UpdateTimesIdx]; -} - -////////////////////////////////////////////////////////////////////////// -const sUpdateTimes* CSystem::GetUpdateTimeStats(uint32& index, uint32& num) -{ - index = m_UpdateTimesIdx; - num = NUM_UPDATE_TIMES; - return m_UpdateTimes; -} - -void CSystem::UpdateUpdateTimes() -{ - sUpdateTimes& sample = m_UpdateTimes[m_UpdateTimesIdx]; - if (m_PhysThread) - { - static uint64 lastPhysTime = 0U; - static uint64 lastMainTime = 0U; - static uint64 lastYields = 0U; - static uint64 lastPhysWait = 0U; - uint64 physTime = 0, mainTime = 0; - uint32 yields = 0; - physTime = ((CPhysicsThreadTask*)m_PhysThread)->LastStepTaken(); - mainTime = CryGetTicks() - lastMainTime; - lastMainTime = mainTime; - lastPhysWait = ((CPhysicsThreadTask*)m_PhysThread)->LastWaitTime(); - sample.PhysStepTime = physTime; - sample.SysUpdateTime = mainTime; - sample.PhysYields = yields; - sample.physWaitTime = lastPhysWait; - } - ++m_UpdateTimesIdx; - if (m_UpdateTimesIdx >= NUM_UPDATE_TIMES) - { - m_UpdateTimesIdx = 0; - } -} - - -#ifndef _RELEASE -void CSystem::GetCheckpointData(ICheckpointData& data) -{ - data.m_totalLoads = m_checkpointLoadCount; - data.m_loadOrigin = m_loadOrigin; -} - -void CSystem::IncreaseCheckpointLoadCount() -{ - if (!m_hasJustResumed) - { - ++m_checkpointLoadCount; - } - - m_hasJustResumed = false; -} - -void CSystem::SetLoadOrigin(LevelLoadOrigin origin) -{ - switch (origin) - { - case eLLO_NewLevel: // Intentional fall through - case eLLO_Level2Level: - m_expectingMapCommand = true; - break; - - case eLLO_Resumed: - m_hasJustResumed = true; - break; - - case eLLO_MapCmd: - if (m_expectingMapCommand) - { - // We knew a map command was coming, so don't process this. - m_expectingMapCommand = false; - return; - } - break; - } - - m_loadOrigin = origin; - m_checkpointLoadCount = 0; -} -#endif - -bool CSystem::SteamInit() -{ -#if USE_STEAM - if (m_bIsSteamInitialized) - { - return true; - } - - AZStd::string_view exePath; - AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder); - - //////////////////////////////////////////////////////////////////////////// - // ** DEVELOPMENT ONLY ** - creates the appropriate steam_appid.txt file needed to call SteamAPI_Init() -#if !defined(RELEASE) - AZStd::string appidPath = AZStd::string::format("%.*s/steam_appid.txt", aznumeric_cast(exePath.size()), exePath.data()); - azfopen(&pSteamAppID, appidPath.c_str(), "wt"); - fprintf(pSteamAppID, "%d", g_cvars.sys_steamAppId); - fclose(pSteamAppID); -#endif // !defined(RELEASE) - // ** END DEVELOPMENT ONLY ** - //////////////////////////////////////////////////////////////////////////// - - if (!SteamAPI_Init()) - { - CryLog("[STEAM] SteamApi_Init failed"); - return false; - } - - //////////////////////////////////////////////////////////////////////////// - // ** DEVELOPMENT ONLY ** - deletes the appropriate steam_appid.txt file as it's no longer needed -#if !defined(RELEASE) - remove(appidPath.c_str()); -#endif // !defined(RELEASE) - // ** END DEVELOPMENT ONLY ** - //////////////////////////////////////////////////////////////////////////// - - m_bIsSteamInitialized = true; - return true; -#else - return false; -#endif -} - ////////////////////////////////////////////////////////////////////// void CSystem::OnLanguageCVarChanged(ICVar* language) { diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index f5235f2ea8..a258030f70 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -23,18 +23,12 @@ #include "CmdLine.h" #include "CryName.h" -#include "MTSafeAllocator.h" -#include "CPUDetect.h" #include -#include "MemoryFragmentationProfiler.h" // CMemoryFragmentationProfiler -#include "ThreadTask.h" #include "RenderBus.h" #include -#include #include -#include namespace AzFramework { @@ -42,17 +36,7 @@ namespace AzFramework } struct IConsoleCmdArgs; -class CServerThrottle; -struct ICryFactoryRegistryImpl; -struct IZLibCompressor; class CWatchdogThread; -class CThreadManager; - -struct ICryPerfHUD; -namespace minigui -{ - struct IMiniGUI; -} #if defined(AZ_RESTRICTED_PLATFORM) #undef AZ_RESTRICTED_SECTION @@ -62,18 +46,6 @@ namespace minigui #define SYSTEM_H_SECTION_4 4 #endif -#if defined(ANDROID) -#define USE_ANDROIDCONSOLE -#elif defined(MAC) // || defined(LINUX) -#define USE_UNIXCONSOLE -#elif defined(IOS) -#define USE_IOSCONSOLE -#elif defined(WIN32) || defined(WIN64) -#define USE_WINDOWSCONSOLE -#else -#define USE_NULLCONSOLE -#endif - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_H_SECTION_1 #include AZ_RESTRICTED_FILE(System_h) @@ -191,30 +163,19 @@ namespace minigui #include "CryLibrary.h" #endif -#define NUM_UPDATE_TIMES (128U) - #ifdef WIN32 typedef void* WIN_HMODULE; #else typedef void* WIN_HMODULE; #endif -#if !defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync); -#else -CRY_ASYNC_MEMCPY_API void cryAsyncMemcpyDelegate(void* dst, const void* src, size_t size, int nFlags, volatile int* sync); -#endif - - //forward declarations namespace Audio { struct IAudioSystem; struct IMusicSystem; } // namespace Audio -struct SDefaultValidator; struct IDataProbe; -class CVisRegTest; #define PHSYICS_OBJECT_ENTITY 0 @@ -227,7 +188,6 @@ extern VTuneFunction VTPause; struct SSystemCVars { - int az_streaming_stats; int sys_streaming_requests_grouping_time_period; int sys_streaming_sleep; int sys_streaming_memory_budget; @@ -251,7 +211,6 @@ struct SSystemCVars int sys_WER; int sys_dump_type; int sys_ai; - int sys_physics; int sys_entitysystem; int sys_trackview; int sys_vtune; @@ -270,23 +229,8 @@ struct SSystemCVars int sys_error_debugbreak; int sys_FilesystemCaseSensitivity; - int sys_rendersplashscreen; - const char* sys_splashscreen; - - enum SplashScreenScaleMode - { - SplashScreenScaleMode_Fit = 0, - SplashScreenScaleMode_Fill - }; - int sys_splashScreenScaleMode; int sys_deferAudioUpdateOptim; -#if USE_STEAM -#ifndef RELEASE - int sys_steamAppId; -#endif // RELEASE - int sys_useSteamCloudForPlatformSaving; -#endif // USE_STEAM AZ::IO::ArchiveVars archiveVars; @@ -301,33 +245,6 @@ extern SSystemCVars g_cvars; class CSystem; -struct SmallModuleInfo -{ - string name; - CryModuleMemoryInfo memInfo; -}; - -struct SCryEngineStatsModuleInfo -{ - string name; - CryModuleMemoryInfo memInfo; - uint32 moduleStaticSize; - uint32 usedInModule; - uint32 SizeOfCode; - uint32 SizeOfInitializedData; - uint32 SizeOfUninitializedData; -}; - -struct SCryEngineStatsGlobalMemInfo -{ - int totalUsedInModules; - int totalCodeAndStatic; - int countedMemoryModules; - uint64 totalAllocatedInModules; - int totalNumAllocsInModules; - std::vector modules; -}; - struct CProfilingSystem : public IProfilingSystem { @@ -361,20 +278,8 @@ class CSystem , public IWindowMessageHandler , public AZ::RenderNotificationsBus::Handler , public CrySystemRequestBus::Handler - , private AzFramework::Terrain::TerrainDataNotificationBus::Handler { public: - - inline void* operator new(std::size_t) - { - size_t allocated = 0; - return CryMalloc(sizeof(CSystem), allocated, 64); - } - inline void operator delete(void* p) - { - CryFree(p, 64); - } - CSystem(SharedEnvironmentInstance* pSharedEnvironment); ~CSystem(); @@ -408,34 +313,11 @@ public: virtual void DoWorkDuringOcclusionChecks(); virtual bool NeedDoWorkDuringOcclusionChecks() { return m_bNeedDoWorkDuringOcclusionChecks; } - //Called when the renderer finishes rendering the scene - void OnScene3DEnd() override; - //////////////////////////////////////////////////////////////////////// // CrySystemRequestBus interface implementation ISystem* GetCrySystem() override; //////////////////////////////////////////////////////////////////////// - //! Update screen during loading. - void UpdateLoadingScreen(); - - //! Update screen and call some important tick functions during loading. - void SynchronousLoadingTick(const char* pFunc, int line); - - uint32 GetUsedMemory(); - - virtual void DumpMemoryUsageStatistics(bool bUseKB); - virtual void DumpMemoryCoverage(); - void CollectMemInfo(SCryEngineStatsGlobalMemInfo&); - -#ifndef _RELEASE - virtual void GetCheckpointData(ICheckpointData& data); - virtual void IncreaseCheckpointLoadCount(); - virtual void SetLoadOrigin(LevelLoadOrigin origin); -#endif - - virtual bool SteamInit(); - void Relaunch(bool bRelaunch); bool IsRelaunch() const { return m_bRelaunch; }; @@ -444,63 +326,29 @@ public: void Quit(); bool IsQuitting() const; void ShutdownFileSystem(); // used to cleanup any file resources, such as cache handle. - bool IsShaderCacheGenMode() const { return m_bShaderCacheGenMode; } void SetAffinity(); virtual const char* GetUserName(); virtual int GetApplicationInstance(); int GetApplicationLogInstance(const char* logFilePath) override; - virtual sUpdateTimes& GetCurrentUpdateTimeStats(); - virtual const sUpdateTimes* GetUpdateTimeStats(uint32&, uint32&); - IRenderer* GetIRenderer(){ return m_env.pRenderer; } ITimer* GetITimer(){ return m_env.pTimer; } AZ::IO::IArchive* GetIPak() { return m_env.pCryPak; }; IConsole* GetIConsole() { return m_env.pConsole; }; IRemoteConsole* GetIRemoteConsole(); IMovieSystem* GetIMovieSystem() { return m_env.pMovieSystem; }; - IMemoryManager* GetIMemoryManager(){ return m_pMemoryManager; } - IThreadManager* GetIThreadManager() override {return m_env.pThreadManager; } ICryFont* GetICryFont(){ return m_env.pCryFont; } ILog* GetILog(){ return m_env.pLog; } ICmdLine* GetICmdLine(){ return m_pCmdLine; } - IStreamEngine* GetStreamEngine(); - IValidator* GetIValidator() { return m_pValidator; }; INameTable* GetINameTable() { return m_env.pNameTable; }; IViewSystem* GetIViewSystem(); ILevelSystem* GetILevelSystem(); ISystemEventDispatcher* GetISystemEventDispatcher() { return m_pSystemEventDispatcher; } - IThreadTaskManager* GetIThreadTaskManager(); - IResourceManager* GetIResourceManager(); - ITextModeConsole* GetITextModeConsole(); - IFileChangeMonitor* GetIFileChangeMonitor() { return m_env.pFileChangeMonitor; } - IVisualLog* GetIVisualLog() { return m_env.pVisualLog; } - INotificationNetwork* GetINotificationNetwork() { return m_pNotificationNetwork; } IProfilingSystem* GetIProfilingSystem() { return &m_ProfilingSystem; } - ICryPerfHUD* GetPerfHUD() { return m_pPerfHUD; } - IZLibCompressor* GetIZLibCompressor() { return m_pIZLibCompressor; } - IZLibDecompressor* GetIZLibDecompressor() { return m_pIZLibDecompressor; } - ILZ4Decompressor* GetLZ4Decompressor() { return m_pILZ4Decompressor; } - IZStdDecompressor* GetZStdDecompressor() { return m_pIZStdDecompressor; } - WIN_HWND GetHWND(){ return m_hWnd; } ////////////////////////////////////////////////////////////////////////// // retrieves the perlin noise singleton instance CPNoise3* GetNoiseGen(); virtual uint64 GetUpdateCounter() { return m_nUpdateCounter; }; - virtual void SetLoadingProgressListener(ILoadingProgressListener* pLoadingProgressListener) - { - m_pProgressListener = pLoadingProgressListener; - }; - - virtual ILoadingProgressListener* GetLoadingProgressListener() const - { - return m_pProgressListener; - }; - - void SetIMaterialEffects(IMaterialEffects* pMaterialEffects) { m_env.pMaterialEffects = pMaterialEffects; } - void SetIOpticsManager(IOpticsManager* pOpticsManager) { m_env.pOpticsManager = pOpticsManager; } - void SetIFileChangeMonitor(IFileChangeMonitor* pFileChangeMonitor) { m_env.pFileChangeMonitor = pFileChangeMonitor; } - void SetIVisualLog(IVisualLog* pVisualLog) { m_env.pVisualLog = pVisualLog; } void DetectGameFolderAccessRights(); virtual void ExecuteCommandLine(bool deferred=true); @@ -514,50 +362,9 @@ public: virtual IXmlUtils* GetXmlUtils(); ////////////////////////////////////////////////////////////////////////// - virtual Serialization::IArchiveHost* GetArchiveHost() const { return m_pArchiveHost; } - void SetViewCamera(CCamera& Camera){ m_ViewCamera = Camera; } CCamera& GetViewCamera() { return m_ViewCamera; } - virtual int GetCPUFlags() - { - int Flags = 0; - if (!m_pCpu) - { - return Flags; - } - if (m_pCpu->hasMMX()) - { - Flags |= CPUF_MMX; - } - if (m_pCpu->hasSSE()) - { - Flags |= CPUF_SSE; - } - if (m_pCpu->hasSSE2()) - { - Flags |= CPUF_SSE2; - } - if (m_pCpu->has3DNow()) - { - Flags |= CPUF_3DNOW; - } - if (m_pCpu->hasF16C()) - { - Flags |= CPUF_F16C; - } - - return Flags; - } - virtual int GetLogicalCPUCount() - { - if (m_pCpu) - { - return m_pCpu->GetLogicalCPUCount(); - } - return 0; - } - void IgnoreUpdates(bool bIgnore) { m_bIgnoreUpdates = bIgnore; }; void SetIProcess(IProcess* process); @@ -568,8 +375,6 @@ public: void SleepIfNeeded(); - virtual void DisplayErrorMessage(const char* acMessage, float fTime, const float* pfColor = 0, bool bHardError = true); - virtual void FatalError(const char* format, ...) PRINTF_PARAMS(2, 3); virtual void ReportBug(const char* format, ...) PRINTF_PARAMS(2, 3); // Validator Warning. @@ -578,32 +383,17 @@ public: virtual int ShowMessage(const char* text, const char* caption, unsigned int uType); bool CheckLogVerbosity(int verbosity); - virtual void DebugStats(bool checkpoint, bool leaks); - void DumpWinHeaps(); - - virtual int DumpMMStats(bool log); - //! Return pointer to user defined callback. ISystemUserCallback* GetUserCallback() const { return m_pUserCallback; }; -#if defined(CVARS_WHITELIST) - virtual ICVarsWhitelist* GetCVarsWhiteList() const { return m_pCVarsWhitelist; }; - virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const { return m_pCVarsWhitelistConfigSink; } -#else - virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const { return nullptr; } -#endif // defined(CVARS_WHITELIST) ////////////////////////////////////////////////////////////////////////// virtual void SaveConfiguration(); virtual void LoadConfiguration(const char* sFilename, ILoadConfigurationEntrySink* pSink = 0, bool warnIfMissing = true); - virtual ESystemConfigSpec GetConfigSpec(bool bClient = true); - virtual void SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient); virtual ESystemConfigSpec GetMaxConfigSpec() const; virtual ESystemConfigPlatform GetConfigPlatform() const; virtual void SetConfigPlatform(ESystemConfigPlatform platform); ////////////////////////////////////////////////////////////////////////// - virtual int SetThreadState(ESubsystem subsys, bool bActive); - virtual ICrySizer* CreateSizer(); virtual bool IsPaused() const { return m_bPaused; }; virtual ILocalizationManager* GetLocalizationManager(); @@ -613,29 +403,11 @@ public: // static as memReplay needs it before CSystem has been setup - expose a ISystem interface to this function if you need it outside CrySystem static void debug_GetCallStackRaw(void** callstack, uint32& callstackLength); - virtual ICryFactoryRegistry* GetCryFactoryRegistry() const; - public: - // this enumeration describes the purpose for which the statistics is gathered. - // if it's gathered to be dumped, then some different rules may be applied - enum MemStatsPurposeEnum - { - nMSP_ForDisplay, nMSP_ForDump, nMSP_ForCrashLog, nMSP_ForBudget - }; - // collects the whole memory statistics into the given sizer object - void CollectMemStats (class ICrySizer* pSizer, MemStatsPurposeEnum nPurpose = nMSP_ForDisplay, std::vector* pStats = 0); - void GetExeSizes (ICrySizer* pSizer, MemStatsPurposeEnum nPurpose = nMSP_ForDisplay); - //! refreshes the m_pMemStats if necessary; creates it if it's not created - void TickMemStats(MemStatsPurposeEnum nPurpose = nMSP_ForDisplay, IResourceCollector* pResourceCollector = 0); - #if !defined(RELEASE) void SetVersionInfo(const char* const szVersion); #endif - virtual bool InitializeEngineModule(const char* dllName, const char* moduleClassName, const SSystemInitParams& initParams) override; - virtual bool UnloadEngineModule(const char* dllName, const char* moduleClassName); - virtual const IImageHandler* GetImageHandler() const override { return m_imageHandler.get(); } - void ShutdownModuleLibraries(); #if defined(WIN32) @@ -656,8 +428,6 @@ private: // Release all resources. void ShutDown(); - void SleepIfInactive(); - bool LoadEngineDLLs(); //! @name Initialization routines @@ -665,22 +435,14 @@ private: bool InitConsole(); bool InitFileSystem(); bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams); - bool InitStreamEngine(); bool InitAudioSystem(const SSystemInitParams& initParams); bool InitShine(const SSystemInitParams& initParams); //@} - ////////////////////////////////////////////////////////////////////////// - // Threading functions. - ////////////////////////////////////////////////////////////////////////// - void InitThreadSystem(); - void ShutDownThreadSystem(); - ////////////////////////////////////////////////////////////////////////// // Helper functions. ////////////////////////////////////////////////////////////////////////// - void CreateRendererVars(const SSystemInitParams& startupParams); void CreateSystemVars(); void CreateAudioVars(); @@ -694,15 +456,11 @@ private: void LogBuildInfo(); void SetDevMode(bool bEnable); - void CreatePhysicsThread(); - void KillPhysicsThread(); - #ifndef _RELEASE static void SystemVersionChanged(ICVar* pCVar); #endif // #ifndef _RELEASE bool ReLaunchMediaCenter(); - void LogSystemInfo(); void UpdateAudioSystems(); void AddCVarGroupDirectory(const string& sPath); @@ -725,25 +483,7 @@ public: virtual bool GetForceNonDevMode() const; virtual bool WasInDevMode() const { return m_bWasInDevMode; }; virtual bool IsDevMode() const { return m_bInDevMode && !GetForceNonDevMode(); } - virtual bool IsMinimalMode() const { return m_bMinimal; } - virtual bool IsMODValid(const char* szMODName) const - { - if (!szMODName || strstr(szMODName, ".") || strstr(szMODName, "\\")) - { - return (false); - } - return (true); - } - virtual void AutoDetectSpec(bool detectResolution); - virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync) - { -#if !defined(CRY_ASYNC_MEMCPY_DELEGATE_TO_CRYSYSTEM) - cryAsyncMemcpy(dst, src, size, nFlags, sync); -#else - cryAsyncMemcpyDelegate(dst, src, size, nFlags, sync); -#endif - } virtual void SetConsoleDrawEnabled(bool enabled) { m_bDrawConsole = enabled; } virtual void SetUIDrawEnabled(bool enabled) { m_bDrawUI = enabled; } @@ -753,32 +493,11 @@ public: //! recreates the variable if necessary ICVar* attachVariable (const char* szVarName, int* pContainer, const char* szComment, int dwFlags = 0); - CCpuFeatures* GetCPUFeatures() { return m_pCpu; }; - - string& GetDelayedScreeenshot() {return m_sDelayedScreeenshot; } - - CVisRegTest*& GetVisRegTestPtrRef() {return m_pVisRegTest; } - const CTimeValue& GetLastTickTime(void) const { return m_lastTickTime; } const ICVar* GetDedicatedMaxRate(void) const { return m_svDedicatedMaxRate; } - const char* GetRenderingDriverName(void) const - { - if(m_rDriver) - { - return m_rDriver->GetString(); - } - return nullptr; - } - - std::shared_ptr CreateLocalFileIO(); - // Gets the dimensions (in pixels) of the primary physical display. - // Returns true if this info is available, returns false otherwise. - bool GetPrimaryPhysicalDisplayDimensions(int& o_widthPixels, int& o_heightPixels); - bool IsTablet(); - private: // ------------------------------------------------------ // System environment. @@ -787,50 +506,29 @@ private: // ------------------------------------------------------ CTimer m_Time; //!< CCamera m_ViewCamera; //!< bool m_bInitializedSuccessfully; //!< true if the system completed all initialization steps - bool m_bShaderCacheGenMode;//!< true if the application runs in shader cache generation mode bool m_bRelaunch; //!< relaunching the app or not (true beforerelaunch) int m_iLoadingMode; //!< Game is loading w/o changing context (0 not, 1 quickloading, 2 full loading) bool m_bTestMode; //!< If running in testing mode. - bool m_bMinimal; //!< If running in 'minimal mode'. bool m_bEditor; //!< If running in Editor. bool m_bNoCrashDialog; bool m_bNoErrorReportWindow; bool m_bPreviewMode; //!< If running in Preview mode. bool m_bDedicatedServer; //!< If running as Dedicated server. bool m_bIgnoreUpdates; //!< When set to true will ignore Update and Render calls, - IValidator* m_pValidator; //!< Pointer to validator interface. bool m_bForceNonDevMode; //!< true when running on a cheat protected server or a client that is connected to it (not used in singlplayer) bool m_bWasInDevMode; //!< Set to true if was in dev mode. bool m_bInDevMode; //!< Set to true if was in dev mode. bool m_bGameFolderWritable;//!< True when verified that current game folder have write access. - SDefaultValidator* m_pDefaultValidator; //!< - string m_sDelayedScreeenshot;//!< to delay a screenshot call for a frame - CCpuFeatures* m_pCpu; //!< CPU features int m_ttMemStatSS; //!< Time to memstat screenshot - string m_szCmdLine; - - int m_iTraceAllocations; - -#ifndef _RELEASE - int m_checkpointLoadCount;// Total times game has loaded from a checkpoint - LevelLoadOrigin m_loadOrigin; // Where the load was initiated from - bool m_hasJustResumed; // Has resume game just been called - bool m_expectingMapCommand; -#endif bool m_bDrawConsole; //!< Set to true if OK to draw the console. bool m_bDrawUI; //!< Set to true if OK to draw UI. std::map > m_moduleDLLHandles; - //! THe streaming engine - class CStreamEngine* m_pStreamEngine; - //! current active process IProcess* m_pProcess; - IMemoryManager* m_pMemoryManager; - CCamera m_PhysRendererCamera; ICVar* m_p_draw_helpers_str; int m_iJumpToPhysProfileEnt; @@ -852,23 +550,9 @@ private: // ------------------------------------------------------ //! System to manage views. IViewSystem* m_pViewSystem; - //! System to access zlib compressor - IZLibCompressor* m_pIZLibCompressor; - - //! System to access zlib decompressor - IZLibDecompressor* m_pIZLibDecompressor; - - //! System to access lz4 hc decompressor - ILZ4Decompressor* m_pILZ4Decompressor; - - //! System access to zstd decompressor - IZStdDecompressor* m_pIZStdDecompressor; - // XML Utils interface. class CXmlUtils* m_pXMLUtils; - Serialization::IArchiveHost* m_pArchiveHost; - int m_iApplicationInstance; //! to hold the values stored in system.cfg @@ -917,7 +601,6 @@ private: // ------------------------------------------------------ ICVar* m_rFullscreen; ICVar* m_rFullscreenWindow; ICVar* m_rFullscreenNativeRes; - ICVar* m_rDriver; ICVar* m_rDisplayInfo; ICVar* m_rOverscanBordersDrawDebugView; ICVar* m_sysNoUpdate; @@ -930,13 +613,10 @@ private: // ------------------------------------------------------ ICVar* m_sysWarnings; //!< might be 0, "sys_warnings" - Treat warning as errors. ICVar* m_cvSSInfo; //!< might be 0, "sys_SSInfo" 0/1 - get file sourcesafe info ICVar* m_svDedicatedMaxRate; - ICVar* m_sys_GraphicsQuality; ICVar* m_sys_firstlaunch; ICVar* m_sys_asset_processor; ICVar* m_sys_load_files_to_memory; - ICVar* m_sys_physics_CPU; - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEM_H_SECTION_4 #include AZ_RESTRICTED_FILE(System_h) @@ -959,26 +639,6 @@ private: // ------------------------------------------------------ //! User define callback for system events. ISystemUserCallback* m_pUserCallback; -#if defined(CVARS_WHITELIST) - ////////////////////////////////////////////////////////////////////////// - //! User define callback for whitelisting cvars - ICVarsWhitelist* m_pCVarsWhitelist; - ILoadConfigurationEntrySink* m_pCVarsWhitelistConfigSink; -#endif // defined(CVARS_WHITELIST) - - WIN_HWND m_hWnd; - WIN_HINSTANCE m_hInst; - - // this is the memory statistics that is retained in memory between frames - // in which it's not gathered - class CrySizerStats* m_pMemStats; - class CrySizerImpl* m_pSizer; - - ICryPerfHUD* m_pPerfHUD; - minigui::IMiniGUI* m_pMiniGUI; - - //int m_nCurrentLogVerbosity; - SFileVersion m_fileVersion; SFileVersion m_productVersion; SFileVersion m_buildVersion; @@ -989,17 +649,11 @@ private: // ------------------------------------------------------ // Name table. CNameTable m_nameTable; - IThreadTask* m_PhysThread; - ESystemConfigSpec m_nServerConfigSpec; ESystemConfigSpec m_nMaxConfigSpec; ESystemConfigPlatform m_ConfigPlatform; - std::unique_ptr m_pServerThrottle; - CProfilingSystem m_ProfilingSystem; - sUpdateTimes m_UpdateTimes[NUM_UPDATE_TIMES]; - uint32 m_UpdateTimesIdx; // Pause mode. bool m_bPaused; @@ -1023,9 +677,6 @@ public: virtual const SFileVersion& GetProductVersion(); virtual const SFileVersion& GetBuildVersion(); - bool CompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize, int level); - bool DecompressDataBlock(const void* input, size_t inputSize, void* output, size_t& outputSize); - bool InitVTuneProfiler(); void OpenBasicPaks(); @@ -1070,35 +721,18 @@ private: ESystemGlobalState m_systemGlobalState; static const char* GetSystemGlobalStateName(const ESystemGlobalState systemGlobalState); - /////////////////////////////////////////////////////////////////////////// - // AzFramework::Terrain::TerrainDataNotificationBus START - void OnTerrainDataCreateBegin() override; - void OnTerrainDataDestroyBegin() override; - // AzFramework::Terrain::TerrainDataNotificationBus END - /////////////////////////////////////////////////////////////////////////// - public: void InitLocalization(); - void UpdateUpdateTimes(); protected: // ------------------------------------------------------------- - ILoadingProgressListener* m_pProgressListener; CCmdLine* m_pCmdLine; - CVisRegTest* m_pVisRegTest; - CThreadManager* m_pThreadManager; - CThreadTaskManager* m_pThreadTaskManager; - class CResourceManager* m_pResourceManager; - ITextModeConsole* m_pTextModeConsole; - INotificationNetwork* m_pNotificationNetwork; string m_currentLanguageAudio; - string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_es3.cfg or system_android_opengl.cfg or system_windows_pc.cfg + string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_android.cfg or system_windows_pc.cfg std::vector< std::pair > m_updateTimes; - CMemoryFragmentationProfiler m_MemoryFragmentationProfiler; - struct SErrorMessage { string m_Message; @@ -1114,16 +748,7 @@ protected: // ------------------------------------------------------------- ESystemEvent m_eRuntimeState; bool m_bIsAsserting; - friend struct SDefaultValidator; - friend struct SCryEngineFoldersLoader; - // friend void ScreenshotCmd( IConsoleCmdArgs *pParams ); - - bool m_bIsSteamInitialized; - - std::unique_ptr m_imageHandler; std::vector m_windowMessageHandlers; bool m_initedOSAllocator = false; bool m_initedSysAllocator = false; - - AZStd::unique_ptr m_thermalInfoHandler; }; diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 22445ec4a5..52744519bb 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -12,7 +12,7 @@ // Original file Copyright Crytek GMBH or its affiliates, used under license. #include "CrySystem_precompiled.h" -#include "SystemInit.h" +#include "System.h" #if defined(AZ_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) #undef AZ_RESTRICTED_SECTION @@ -35,19 +35,13 @@ #define SYSTEMINIT_CPP_SECTION_17 17 #endif -#if defined(MAP_LOADING_SLICING) -#include "SystemScheduler.h" -#endif // defined(MAP_LOADING_SLICING) #include "CryLibrary.h" #include "CryPath.h" #include -#include #include #include -#include -#include #include // for AZ_MAX_PATH_LEN #include #include @@ -95,37 +89,13 @@ #include #include #include -#include "HMDCVars.h" #include -#include #include "XConsole.h" #include "Log.h" #include "XML/xml.h" -#include "StreamEngine/StreamEngine.h" -#include "PhysRenderer.h" #include "LocalizedStringManager.h" #include "SystemEventDispatcher.h" -#include "ThreadConfigManager.h" -#include "Validator.h" -#include "ServerThrottle.h" -#include "SystemCFG.h" -#include "AutoDetectSpec.h" -#include "ResourceManager.h" -#include "VisRegTest.h" -#include "MTSafeAllocator.h" -#include "NotificationNetwork.h" -#include "ExtensionSystem/CryFactoryRegistryImpl.h" -#include "ExtensionSystem/TestCases/TestExtensions.h" -#include "ProfileLogSystem.h" -#include "SoftCode/SoftCodeMgr.h" -#include "ZLibCompressor.h" -#include "ZLibDecompressor.h" -#include "ZStdDecompressor.h" -#include "LZ4Decompressor.h" -#include "OverloadSceneManager/OverloadSceneManager.h" -#include "ServiceNetwork.h" -#include "RemoteCommand.h" #include "LevelSystem/LevelSystem.h" #include "LevelSystem/SpawnableLevelSystem.h" #include "ViewSystem/ViewSystem.h" @@ -134,34 +104,10 @@ #include #include -#include "PerfHUD.h" -#include "MiniGUI/MiniGUI.h" - -#if USE_STEAM -#include "Steamworks/public/steam/steam_api.h" -#include "Steamworks/public/steam/isteamremotestorage.h" -#endif - -#if defined(IOS) -#include "IOSConsole.h" -#endif - #if defined(ANDROID) #include - #include "AndroidConsole.h" -#if !defined(AZ_RELEASE_BUILD) - #include "ThermalInfoAndroid.h" -#endif // !defined(AZ_RELEASE_BUILD) #endif -#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS) -#include "MobileDetectSpec.h" -#endif - -#include "IDebugCallStack.h" - -#include "WindowsConsole.h" - #if defined(EXTERNAL_CRASH_REPORTING) #include #endif @@ -175,11 +121,6 @@ # include #endif -// if we enable the built-in local version instead of remote: -#if defined(CRY_ENABLE_RC_HELPER) -#include "ResourceCompilerHelper.h" -#endif - #ifdef WIN32 extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers); #endif @@ -226,12 +167,6 @@ void CryEngineSignalHandler(int signal) #endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER -#if defined(USE_UNIXCONSOLE) -#if defined(LINUX) && !defined(ANDROID) -CUNIXConsole* pUnixConsole; -#endif -#endif // USE_UNIXCONSOLE - ////////////////////////////////////////////////////////////////////////// #define DEFAULT_LOG_FILENAME "@log@/Log.txt" @@ -272,8 +207,6 @@ CUNIXConsole* pUnixConsole; #define AZ_TRACE_SYSTEM_WINDOW AZ::Debug::Trace::GetDefaultSystemWindow() -extern CMTSafeHeap* g_pPakHeap; - #ifdef WIN32 extern HMODULE gDLLHandle; #endif @@ -301,7 +234,6 @@ struct SCVarsClientConfigSink ////////////////////////////////////////////////////////////////////////// static inline void InlineInitializationProcessing([[maybe_unused]] const char* sDescription) { - assert(CryMemory::IsHeapValid()); if (gEnv->pLog) { gEnv->pLog->UpdateLoadingScreen(0); @@ -366,26 +298,6 @@ static void CmdCrashTest(IConsoleCmdArgs* pArgs) } AZ_POP_DISABLE_WARNING -#if USE_STEAM -////////////////////////////////////////////////////////////////////////// -static void CmdWipeSteamCloud(IConsoleCmdArgs* pArgs) -{ - if (!gEnv->pSystem->SteamInit()) - { - return; - } - - int32 fileCount = SteamRemoteStorage()->GetFileCount(); - for (int i = 0; i < fileCount; i++) - { - int32 size = 0; - const char* name = SteamRemoteStorage()->GetFileNameAndSize(i, &size); - bool success = SteamRemoteStorage()->FileDelete(name); - CryLog("Deleting file: %s - success: %d", name, success); - } -} -#endif - ////////////////////////////////////////////////////////////////////////// struct SysSpecOverrideSink : public ILoadConfigurationEntrySink @@ -412,26 +324,20 @@ struct SysSpecOverrideSink } else { - // This could bypass the restricted/whitelisted cvar checks that exist elsewhere depending on + // This could bypass the restricted cvar checks that exist elsewhere depending on // the calling code so we also need check here before setting. bool isConst = pCvar->IsConstCVar(); bool isCheat = ((pCvar->GetFlags() & (VF_CHEAT | VF_CHEAT_NOCHECK | VF_CHEAT_ALWAYS_CHECK)) != 0); bool isReadOnly = ((pCvar->GetFlags() & VF_READONLY) != 0); bool isDeprecated = ((pCvar->GetFlags() & VF_DEPRECATED) != 0); bool allowApplyCvar = true; - bool whitelisted = true; - -#if defined CVARS_WHITELIST - ICVarsWhitelist* cvarWhitelist = gEnv->pSystem->GetCVarsWhiteList(); - whitelisted = cvarWhitelist ? cvarWhitelist->IsWhiteListed(szKey, true) : true; -#endif if ((isConst || isCheat || isReadOnly) || isDeprecated) { allowApplyCvar = !isDeprecated && (gEnv->pSystem->IsDevMode()) || (gEnv->IsEditor()); } - if ((allowApplyCvar && whitelisted) || ALLOW_CONST_CVAR_MODIFICATIONS) + if ((allowApplyCvar) || ALLOW_CONST_CVAR_MODIFICATIONS) { applyCvar = true; } @@ -505,297 +411,6 @@ static ESystemConfigPlatform GetDevicePlatform() #endif } -static void GetSpecConfigFileToLoad(ICVar* pVar, AZStd::string& cfgFile, ESystemConfigPlatform platform) -{ - switch (platform) - { - case CONFIG_PC: - cfgFile = "pc"; - break; - case CONFIG_ANDROID: - cfgFile = "android"; - break; - case CONFIG_IOS: - cfgFile = "ios"; - break; -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, jasper) -#endif -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, provo) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, salem) -#endif - case CONFIG_OSX_METAL: - cfgFile = "osx_metal"; - break; - case CONFIG_OSX_GL: - // Spec level is hardcoded for these platforms - cfgFile = ""; - return; - default: - AZ_Assert(false, "Platform not supported"); - return; - } - - switch (pVar->GetIVal()) - { - case CONFIG_AUTO_SPEC: - // Spec level is set for autodetection - cfgFile = ""; - break; - case CONFIG_LOW_SPEC: - cfgFile += "_low.cfg"; - break; - case CONFIG_MEDIUM_SPEC: - cfgFile += "_medium.cfg"; - break; - case CONFIG_HIGH_SPEC: - cfgFile += "_high.cfg"; - break; - case CONFIG_VERYHIGH_SPEC: -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_4 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif - cfgFile += "_veryhigh.cfg"; - break; - default: - AZ_Assert(false, "Invalid value for r_GraphicsQuality"); - break; - } -} - -static void LoadDetectedSpec(ICVar* pVar) -{ - CDebugAllowFileAccess ignoreInvalidFileAccess; - SysSpecOverrideSink sysSpecOverrideSink; - ILoadConfigurationEntrySink* pSysSpecOverrideSinkConsole = nullptr; - -#if !defined(CONSOLE) - SysSpecOverrideSinkConsole sysSpecOverrideSinkConsole; - pSysSpecOverrideSinkConsole = &sysSpecOverrideSinkConsole; -#endif - - // g_sysSpecChanged = true; - static int no_recursive = false; - if (no_recursive) - { - return; - } - no_recursive = true; - - int spec = pVar->GetIVal(); - ESystemConfigPlatform platform = GetDevicePlatform(); - if (gEnv->IsEditor()) - { - ESystemConfigPlatform configPlatform = GetISystem()->GetConfigPlatform(); - // Check if the config platform is set first. - if (configPlatform != CONFIG_INVALID_PLATFORM) - { - platform = configPlatform; - } - } - - AZStd::string configFile; - GetSpecConfigFileToLoad(pVar, configFile, platform); - if (configFile.length()) - { - GetISystem()->LoadConfiguration(configFile.c_str(), platform == CONFIG_PC ? &sysSpecOverrideSink : pSysSpecOverrideSinkConsole); - } - else - { - // Automatically sets graphics quality - spec level autodetected for ios/android, hardcoded for all other platforms - - switch (platform) - { - case CONFIG_PC: - { - // TODO: add support for autodetection - pVar->Set(CONFIG_VERYHIGH_SPEC); - GetISystem()->LoadConfiguration("pc_veryhigh.cfg", &sysSpecOverrideSink); - break; - } - case CONFIG_ANDROID: - { -#if defined(AZ_PLATFORM_ANDROID) - AZStd::string file; - if (MobileSysInspect::GetAutoDetectedSpecName(file)) - { - if (file == "android_low.cfg") - { - pVar->Set(CONFIG_LOW_SPEC); - } - if (file == "android_medium.cfg") - { - pVar->Set(CONFIG_MEDIUM_SPEC); - } - if (file == "android_high.cfg") - { - pVar->Set(CONFIG_HIGH_SPEC); - } - if (file == "android_veryhigh.cfg") - { - pVar->Set(CONFIG_VERYHIGH_SPEC); - } - GetISystem()->LoadConfiguration(file.c_str(), pSysSpecOverrideSinkConsole); - } - else - { - float totalRAM = MobileSysInspect::GetDeviceRamInGB(); - if (totalRAM < MobileSysInspect::LOW_SPEC_RAM) - { - pVar->Set(CONFIG_LOW_SPEC); - GetISystem()->LoadConfiguration("android_low.cfg", pSysSpecOverrideSinkConsole); - } - else if (totalRAM < MobileSysInspect::MEDIUM_SPEC_RAM) - { - pVar->Set(CONFIG_MEDIUM_SPEC); - GetISystem()->LoadConfiguration("android_medium.cfg", pSysSpecOverrideSinkConsole); - } - else if (totalRAM < MobileSysInspect::HIGH_SPEC_RAM) - { - pVar->Set(CONFIG_HIGH_SPEC); - GetISystem()->LoadConfiguration("android_high.cfg", pSysSpecOverrideSinkConsole); - } - else - { - pVar->Set(CONFIG_VERYHIGH_SPEC); - GetISystem()->LoadConfiguration("android_veryhigh.cfg", pSysSpecOverrideSinkConsole); - } - } -#endif - break; - } - case CONFIG_IOS: - { -#if defined(AZ_PLATFORM_IOS) - AZStd::string file; - if (MobileSysInspect::GetAutoDetectedSpecName(file)) - { - if (file == "ios_low.cfg") - { - pVar->Set(CONFIG_LOW_SPEC); - } - if (file == "ios_medium.cfg") - { - pVar->Set(CONFIG_MEDIUM_SPEC); - } - if (file == "ios_high.cfg") - { - pVar->Set(CONFIG_HIGH_SPEC); - } - if (file == "ios_veryhigh.cfg") - { - pVar->Set(CONFIG_VERYHIGH_SPEC); - } - GetISystem()->LoadConfiguration(file.c_str(), pSysSpecOverrideSinkConsole); - } - else - { - pVar->Set(CONFIG_MEDIUM_SPEC); - GetISystem()->LoadConfiguration("ios_medium.cfg", pSysSpecOverrideSinkConsole); - } -#endif - break; - } -#if defined(AZ_PLATFORM_JASPER) || defined(TOOLS_SUPPORT_JASPER) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, jasper) -#endif -#if defined(AZ_PLATFORM_PROVO) || defined(TOOLS_SUPPORT_PROVO) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, provo) -#endif -#if defined(AZ_PLATFORM_SALEM) || defined(TOOLS_SUPPORT_SALEM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_5 -#include AZ_RESTRICTED_FILE_EXPLICIT(SystemInit_cpp, salem) -#endif - - case CONFIG_OSX_GL: - { - pVar->Set(CONFIG_HIGH_SPEC); - GetISystem()->LoadConfiguration("osx_gl.cfg", pSysSpecOverrideSinkConsole); - break; - } - case CONFIG_OSX_METAL: - { - pVar->Set(CONFIG_HIGH_SPEC); - GetISystem()->LoadConfiguration("osx_metal_high.cfg", pSysSpecOverrideSinkConsole); - break; - } - default: - AZ_Assert(false, "Platform not supported"); - break; - } - } - - // make sure editor specific settings are not changed - if (gEnv->IsEditor()) - { - GetISystem()->LoadConfiguration("editor.cfg"); - } - - bool bMultiGPUEnabled = false; - if (gEnv->pRenderer) - { - gEnv->pRenderer->EF_Query(EFQ_MultiGPUEnabled, bMultiGPUEnabled); - -#if defined(AZ_PLATFORM_ANDROID) - AZStd::string gpuConfigFile; - const AZStd::string& adapterDesc = gEnv->pRenderer->GetAdapterDescription(); - const AZStd::string& apiver = gEnv->pRenderer->GetApiVersion(); - - if (!adapterDesc.empty()) - { - MobileSysInspect::GetSpecForGPUAndAPI(adapterDesc, apiver, gpuConfigFile); - GetISystem()->LoadConfiguration(gpuConfigFile.c_str(), pSysSpecOverrideSinkConsole); - } -#endif - } - if (bMultiGPUEnabled) - { - GetISystem()->LoadConfiguration("mgpu.cfg"); - } - - // override cvars just loaded based on current API version/GPU - - GetISystem()->SetConfigSpec(static_cast(spec), platform, false); - - no_recursive = false; -} - -////////////////////////////////////////////////////////////////////////// -struct SCryEngineLanguageConfigLoader - : public ILoadConfigurationEntrySink -{ - CSystem* m_pSystem; - string m_language; - string m_pakFile; - - SCryEngineLanguageConfigLoader(CSystem* pSystem) { m_pSystem = pSystem; } - void Load(const char* sCfgFilename) - { - CSystemConfiguration cfg(sCfgFilename, m_pSystem, this); // Parse folders config file. - } - virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, [[maybe_unused]] const char* szGroup) - { - if (azstricmp(szKey, "Language") == 0) - { - m_language = szValue; - } - else if (azstricmp(szKey, "PAK") == 0) - { - m_pakFile = szValue; - } - } - virtual void OnLoadConfigurationEntry_End() {} -}; - ////////////////////////////////////////////////////////////////////////// #if !defined(AZ_MONOLITHIC_BUILD) @@ -884,148 +499,6 @@ bool CSystem::UnloadDLL(const char* dllName) return isSuccess; } -////////////////////////////////////////////////////////////////////////// -bool CSystem::InitializeEngineModule(const char* dllName, const char* moduleClassName, const SSystemInitParams& initParams) -{ - bool bResult = false; - - stack_string msg; - msg = "Initializing "; - AZStd::string dll = dllName; - - // Strip off Cry if the dllname is Cry - if (dll.find("Cry") == 0) - { - msg += dll.substr(3).c_str(); - } - else - { - msg += dllName; - } - msg += "..."; - - if (m_pUserCallback) - { - m_pUserCallback->OnInitProgress(msg.c_str()); - } - AZ_TracePrintf(moduleClassName, "%s", msg.c_str()); - - IMemoryManager::SProcessMemInfo memStart, memEnd; - if (GetIMemoryManager()) - { - GetIMemoryManager()->GetProcessMemInfo(memStart); - } - else - { - ZeroStruct(memStart); - } - - stack_string dllfile = ""; - - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_16 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - - dllfile.append(dllName); - -#if defined(LINUX) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "so"); -#ifndef LINUX - dllfile.MakeLower(); -#endif -#elif defined(AZ_PLATFORM_MAC) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "dylib"); -#elif defined(AZ_PLATFORM_IOS) - PathUtil::RemoveExtension(dllfile); -#else - dllfile = PathUtil::ReplaceExtension(dllfile, "dll"); -#endif - -#endif - -#if !defined(AZ_MONOLITHIC_BUILD) - - m_moduleDLLHandles.insert(std::make_pair(dllfile.c_str(), LoadDLL(dllfile.c_str()))); - if (!m_moduleDLLHandles[dllfile.c_str()]) - { - return bResult; - } - -#endif // #if !defined(AZ_MONOLITHIC_BUILD) - - AZStd::shared_ptr pModule; - if (CryCreateClassInstance(moduleClassName, pModule)) - { - bResult = pModule->Initialize(m_env, initParams); - - // After initializing the module, give it a chance to register any AZ console vars - // declared within the module. - pModule->RegisterConsoleVars(); - } - - if (GetIMemoryManager()) - { - GetIMemoryManager()->GetProcessMemInfo(memEnd); - -#if defined(AZ_ENABLE_TRACING) - uint64 memUsed = memEnd.WorkingSetSize - memStart.WorkingSetSize; -#endif - AZ_TracePrintf(AZ_TRACE_SYSTEM_WINDOW, "Initializing %s %s, MemUsage=%uKb", dllName, pModule ? "done" : "failed", uint32(memUsed / 1024)); - } - - return bResult; -} - -////////////////////////////////////////////////////////////////////////// -bool CSystem::UnloadEngineModule(const char* dllName, const char* moduleClassName) -{ - bool isSuccess = false; - - // Remove the factory. - ICryFactoryRegistryImpl* const pReg = static_cast(GetCryFactoryRegistry()); - - if (pReg != nullptr) - { - ICryFactory* pICryFactory = pReg->GetFactory(moduleClassName); - - if (pICryFactory != nullptr) - { - pReg->UnregisterFactory(pICryFactory); - } - } - - stack_string msg; - msg = "Unloading "; - msg += dllName; - msg += "..."; - - AZ_TracePrintf(AZ_TRACE_SYSTEM_WINDOW, "%s", msg.c_str()); - - stack_string dllfile = dllName; - -#if defined(LINUX) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "so"); -#ifndef LINUX - dllfile.MakeLower(); -#endif -#elif defined(APPLE) - dllfile = "lib" + PathUtil::ReplaceExtension(dllfile, "dylib"); -#else - dllfile = PathUtil::ReplaceExtension(dllfile, "dll"); -#endif - -#if !defined(AZ_MONOLITHIC_BUILD) - isSuccess = UnloadDLL(dllfile.c_str()); -#endif // #if !defined(AZ_MONOLITHIC_BUILD) - - return isSuccess; -} - ////////////////////////////////////////////////////////////////////////// void CSystem::ShutdownModuleLibraries() { @@ -1204,7 +677,6 @@ bool CSystem::InitFileSystem() // get the DirectInstance FileIOBase which should be the AZ::LocalFileIO m_env.pFileIO = AZ::IO::FileIOBase::GetDirectInstance(); - m_env.pResourceCompilerHelper = nullptr; m_env.pCryPak = AZ::Interface::Get(); m_env.pFileIO = AZ::IO::FileIOBase::GetInstance(); @@ -1279,12 +751,11 @@ void CSystem::ShutdownFileSystem() } ///////////////////////////////////////////////////////////////////////////////// -bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams) +bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&) { LOADING_TIME_PROFILE_SECTION; { - ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink(); - LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink); + LoadConfiguration(m_systemConfigName.c_str()); AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Loading system configuration from %s...", m_systemConfigName.c_str()); } @@ -1294,25 +765,13 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initPara GetISystem()->SetConfigPlatform(GetDevicePlatform()); -#if defined(CRY_ENABLE_RC_HELPER) - if (!m_env.pResourceCompilerHelper) - { - m_env.pResourceCompilerHelper = new CResourceCompilerHelper(); - } -#endif - auto projectPath = AZ::Utils::GetProjectPath(); AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Path: %s\n", projectPath.empty() ? "None specified" : projectPath.c_str()); auto projectName = AZ::Utils::GetProjectName(); AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Name: %s\n", projectName.empty() ? "None specified" : projectName.c_str()); - // simply open all paks if fast load pak can't be found - if (!m_pResourceManager->LoadFastLoadPaks(true)) - { - OpenBasicPaks(); - } - + OpenBasicPaks(); // Load game-specific folder. LoadConfiguration("game.cfg"); @@ -1320,31 +779,12 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initPara static const char* g_additionalConfig = gEnv->IsDedicated() ? "server_cfg" : "client_cfg"; LoadConfiguration(g_additionalConfig, nullptr, false); - if (initParams.bShaderCacheGen) - { - LoadConfiguration("shadercachegen.cfg"); - } // We do not use CVar groups on the consoles AddCVarGroupDirectory("Config/CVarGroups"); return (true); } -////////////////////////////////////////////////////////////////////////// -bool CSystem::InitStreamEngine() -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - if (m_pUserCallback) - { - m_pUserCallback->OnInitProgress("Initializing Stream Engine..."); - } - - m_pStreamEngine = new CStreamEngine(); - - return true; -} - ////////////////////////////////////////////////////////////////////////// bool CSystem::InitAudioSystem(const SSystemInitParams& initParams) { @@ -1359,8 +799,6 @@ bool CSystem::InitAudioSystem(const SSystemInitParams& initParams) bool useRealAudioSystem = false; if (!initParams.bPreview - && !initParams.bShaderCacheGen - && !initParams.bMinimal && !m_bDedicatedServer && m_sys_audio_disable->GetIVal() == 0) { @@ -1426,11 +864,6 @@ bool CSystem::InitShine([[maybe_unused]] const SSystemInitParams& initParams) EBUS_EVENT(UiSystemBus, InitializeSystem); - if (!m_env.pLyShine) - { - AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "LYShine System did not initialize correctly. Please check that the LyShine gem is enabled for this project in ProjectConfigurator."); - return false; - } return true; } @@ -1511,8 +944,6 @@ void CSystem::OpenBasicPaks() ////////////////////////////////////////////////////////////////////////// const char* const assetsDir = "@assets@"; - const char* shaderCachePakDir = "@assets@/shadercache.pak"; - const char* shaderCacheStartupPakDir = "@assets@/shadercachestartup.pak"; // After game paks to have same search order as with files on disk m_env.pCryPak->OpenPack(assetsDir, "Engine.pak"); @@ -1522,11 +953,6 @@ void CSystem::OpenBasicPaks() #include AZ_RESTRICTED_FILE(SystemInit_cpp) #endif - m_env.pCryPak->OpenPack(assetsDir, shaderCachePakDir); - m_env.pCryPak->OpenPack(assetsDir, shaderCacheStartupPakDir); - m_env.pCryPak->OpenPack(assetsDir, "Shaders.pak"); - m_env.pCryPak->OpenPack(assetsDir, "ShadersBin.pak"); - #ifdef AZ_PLATFORM_ANDROID // Load Android Obb files if available const char* obbStorage = AZ::Android::Utils::GetObbStoragePath(); @@ -1538,22 +964,6 @@ void CSystem::OpenBasicPaks() InlineInitializationProcessing("CSystem::OpenBasicPaks OpenPacks( Engine... )"); - ////////////////////////////////////////////////////////////////////////// - // Open paks in MOD subfolders. - ////////////////////////////////////////////////////////////////////////// -#if !defined(_RELEASE) - if (const ICmdLineArg* pModArg = GetICmdLine()->FindArg(eCLAT_Pre, "MOD")) - { - if (IsMODValid(pModArg->GetValue())) - { - AZStd::string modFolder = "Mods\\"; - modFolder += pModArg->GetValue(); - modFolder += "\\*.pak"; - GetIPak()->OpenPacks(assetsDir, modFolder, AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::INestedArchive::FLAGS_OVERRIDE_PAK); - } - } -#endif // !defined(_RELEASE) - // Load paks required for game init to mem gEnv->pCryPak->LoadPakToMemory("Engine.pak", AZ::IO::IArchive::eInMemoryPakLocale_GPU); } @@ -1653,96 +1063,6 @@ string GetUniqueLogFileName(string logFileName) return logFileName; } - -#if defined(WIN32) || defined(WIN64) -static wstring GetErrorStringUnsupportedCPU() -{ - static const wchar_t s_EN[] = L"Unsupported CPU detected. CPU needs to support SSE, SSE2, SSE3 and SSE4.1."; - static const wchar_t s_FR[] = { 0 }; - static const wchar_t s_RU[] = { 0 }; - static const wchar_t s_ES[] = { 0 }; - static const wchar_t s_DE[] = { 0 }; - static const wchar_t s_IT[] = { 0 }; - - const size_t fullLangID = (size_t) GetKeyboardLayout(0); - const size_t primLangID = fullLangID & 0x3FF; - const wchar_t* pFmt = s_EN; - - /*switch (primLangID) - { - case 0x07: // German - pFmt = s_DE; - break; - case 0x0a: // Spanish - pFmt = s_ES; - break; - case 0x0c: // French - pFmt = s_FR; - break; - case 0x10: // Italian - pFmt = s_IT; - break; - case 0x19: // Russian - pFmt = s_RU; - break; - case 0x09: // English - default: - break; - }*/ - wchar_t msg[1024]; - msg[0] = L'\0'; - msg[sizeof(msg) / sizeof(msg[0]) - 1] = L'\0'; - azsnwprintf(msg, sizeof(msg) / sizeof(msg[0]) - 1, pFmt); - return msg; -} -#endif - -static bool CheckCPURequirements([[maybe_unused]] CCpuFeatures* pCpu, [[maybe_unused]] CSystem* pSystem) -{ -#if defined(WIN32) || defined(WIN64) - if (!gEnv->IsDedicated()) - { - if (!(pCpu->hasSSE() && pCpu->hasSSE2() && pCpu->hasSSE3() && pCpu->hasSSE41())) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Unsupported CPU! Need SSE, SSE2, SSE3 and SSE4.1 instructions to be available."); - -#if !defined(_RELEASE) - const bool allowPrompts = pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "noprompt") == 0; -#else - const bool allowPrompts = true; -#endif // !defined(_RELEASE) - if (allowPrompts) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Asking user if they wish to continue..."); - const int mbRes = MessageBoxW(0, GetErrorStringUnsupportedCPU().c_str(), L"Open 3D Engine", MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 | MB_DEFAULT_DESKTOP_ONLY); - if (mbRes == IDCANCEL) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to cancel startup."); - return false; - } - } - else - { -#if !defined(_RELEASE) - const bool obeyCPUCheck = pSystem->GetICmdLine()->FindArg(eCLAT_Pre, "anycpu") == 0; -#else - const bool obeyCPUCheck = true; -#endif // !defined(_RELEASE) - if (obeyCPUCheck) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "No prompts allowed and unsupported CPU check active. Treating unsupported CPU as error and exiting."); - return false; - } - } - - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "User chose to continue despite unsupported CPU!"); - } - } -#endif - return true; -} - - class AzConsoleToCryConsoleBinder final { public: @@ -1853,13 +1173,8 @@ bool CSystem::Init(const SSystemInitParams& startupParams) gEnv->mMainThreadId = GetCurrentThreadId(); //Set this ASAP on startup InlineInitializationProcessing("CSystem::Init start"); - m_szCmdLine = startupParams.szSystemCmdLine; - m_env.szCmdLine = m_szCmdLine.c_str(); - m_env.bTesting = startupParams.bTesting; - m_env.bNoAssertDialog = startupParams.bTesting; - m_env.bNoRandomSeed = startupParams.bNoRandom; - m_bShaderCacheGenMode = startupParams.bShaderCacheGen; + m_env.bNoAssertDialog = false; m_bNoCrashDialog = gEnv->IsDedicated(); @@ -1904,14 +1219,6 @@ bool CSystem::Init(const SSystemInitParams& startupParams) m_systemConfigName += ".cfg"; } - AZ_Assert(CryMemory::IsHeapValid(), "Memory heap must be valid before continuing SystemInit."); - -#ifdef EXTENSION_SYSTEM_INCLUDE_TESTCASES - TestExtensions(&CCryFactoryRegistryImpl::Access()); -#endif - - //_controlfp(0, _EM_INVALID|_EM_ZERODIVIDE | _PC_64 ); - #if defined(WIN32) || defined(WIN64) // check OS version - we only want to run on XP or higher - talk to Martin Mittring if you want to change this { @@ -1932,29 +1239,18 @@ AZ_POP_DISABLE_WARNING } #endif - m_pResourceManager->Init(); - // Get file version information. QueryVersionInfo(); DetectGameFolderAccessRights(); - m_hInst = (WIN_HINSTANCE)startupParams.hInstance; - m_hWnd = (WIN_HWND)startupParams.hWnd; - m_bEditor = startupParams.bEditor; m_bPreviewMode = startupParams.bPreview; m_bTestMode = startupParams.bTestMode; m_pUserCallback = startupParams.pUserCallback; - m_bMinimal = startupParams.bMinimal; -#if defined(CVARS_WHITELIST) - m_pCVarsWhitelist = startupParams.pCVarsWhitelist; -#endif // defined(CVARS_WHITELIST) m_bDedicatedServer = startupParams.bDedicatedServer; m_currentLanguageAudio = ""; - memcpy(gEnv->pProtectedFunctions, startupParams.pProtectedFunctions, sizeof(startupParams.pProtectedFunctions)); - #if !defined(CONSOLE) m_env.SetIsEditor(m_bEditor); m_env.SetIsEditorGameMode(false); @@ -1962,7 +1258,6 @@ AZ_POP_DISABLE_WARNING #endif m_env.SetToolMode(startupParams.bToolMode); - m_env.bIsOutOfMemory = false; if (m_bEditor) { @@ -1978,16 +1273,6 @@ AZ_POP_DISABLE_WARNING } } - if (!startupParams.pValidator) - { - m_pDefaultValidator = new SDefaultValidator(this); - m_pValidator = m_pDefaultValidator; - } - else - { - m_pValidator = startupParams.pValidator; - } - #if !defined(_RELEASE) if (!m_bDedicatedServer) { @@ -2003,79 +1288,6 @@ AZ_POP_DISABLE_WARNING gEnv->SetIsDedicated(m_bDedicatedServer); #endif -#if !defined(CONSOLE) -#if !defined(_RELEASE) - bool isDaemonMode = (m_pCmdLine->FindArg(eCLAT_Pre, "daemon") != 0); -#endif // !defined(_RELEASE) - -#if defined(USE_DEDICATED_SERVER_CONSOLE) - -#if !defined(_RELEASE) - bool isSimpleConsole = (m_pCmdLine->FindArg(eCLAT_Pre, "simple_console") != 0); - - if (!(isDaemonMode || isSimpleConsole)) -#endif // !defined(_RELEASE) - { -#if defined(USE_UNIXCONSOLE) - CUNIXConsole* pConsole = new CUNIXConsole(); -#if defined(LINUX) - pUnixConsole = pConsole; -#endif -#elif defined(USE_IOSCONSOLE) - CIOSConsole* pConsole = new CIOSConsole(); -#elif defined(USE_WINDOWSCONSOLE) - CWindowsConsole* pConsole = new CWindowsConsole(); -#elif defined(USE_ANDROIDCONSOLE) - CAndroidConsole* pConsole = new CAndroidConsole(); -#else - CNULLConsole* pConsole = new CNULLConsole(false); -#endif - m_pTextModeConsole = static_cast(pConsole); - - if (m_pUserCallback == nullptr && m_bDedicatedServer) - { - char headerString[128]; - m_pUserCallback = pConsole; - pConsole->SetRequireDedicatedServer(true); - - azstrcpy( - headerString, - AZ_ARRAY_SIZE(headerString), - "Open 3D Engine - " -#if defined(LINUX) - "Linux " -#elif defined(MAC) - "MAC " -#elif defined(IOS) - "iOS " -#endif - "Dedicated Server" - " - Version "); - - char* str = headerString + strlen(headerString); - GetProductVersion().ToString(str, sizeof(headerString) - (str - headerString)); - pConsole->SetHeader(headerString); - } - } -#if !defined(_RELEASE) - else -#endif -#endif - -#if !(defined(USE_DEDICATED_SERVER_CONSOLE) && defined(_RELEASE)) - { - CNULLConsole* pConsole = new CNULLConsole(isDaemonMode); - m_pTextModeConsole = pConsole; - - if (m_pUserCallback == nullptr && m_bDedicatedServer) - { - m_pUserCallback = pConsole; - } - } -#endif - -#endif // !defined(CONSOLE) - { EBUS_EVENT(CrySystemEventBus, OnCrySystemPreInitialize, *this, startupParams); @@ -2126,23 +1338,6 @@ AZ_POP_DISABLE_WARNING // so we log this immediately after setting the log filename LogVersion(); - //here we should be good to ask Crypak to do something - - // Initialise after pLog and CPU feature initialization - // AND after console creation (Editor only) - // May need access to engine folder .pak files - gEnv->pThreadManager->GetThreadConfigManager()->LoadConfig("config/engine_core.thread_config"); - - if (m_bEditor) - { - gEnv->pThreadManager->GetThreadConfigManager()->LoadConfig("config/engine_sandbox.thread_config"); - } - - // Setup main thread - void* pThreadHandle = 0; // Let system figure out thread handle - gEnv->pThreadManager->RegisterThirdPartyThread(pThreadHandle, "Main"); - m_env.pProfileLogSystem = new CProfileLogSystem(); - bool devModeEnable = true; #if defined(_RELEASE) @@ -2158,22 +1353,6 @@ AZ_POP_DISABLE_WARNING SetDevMode(devModeEnable); - ////////////////////////////////////////////////////////////////////////// - // CREATE NOTIFICATION NETWORK - ////////////////////////////////////////////////////////////////////////// - m_pNotificationNetwork = nullptr; -#ifndef _RELEASE - #ifndef LINUX - - if (!startupParams.bMinimal) - { - m_pNotificationNetwork = CNotificationNetwork::Create(); - } - #endif//LINUX -#endif // _RELEASE - - InlineInitializationProcessing("CSystem::Init NotificationNetwork"); - ////////////////////////////////////////////////////////////////////////// // CREATE CONSOLE ////////////////////////////////////////////////////////////////////////// @@ -2226,16 +1405,8 @@ AZ_POP_DISABLE_WARNING InlineInitializationProcessing("CSystem::Init Create console"); - if (!startupParams.bSkipRenderer) - { - CreateRendererVars(startupParams); - } - // Need to load the engine.pak that includes the config files needed during initialization m_env.pCryPak->OpenPack("@assets@", "Engine.pak"); -#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS) - MobileSysInspect::LoadDeviceSpecMapping(); -#endif InitFileSystem_LoadEngineFolders(startupParams); @@ -2244,23 +1415,6 @@ AZ_POP_DISABLE_WARNING GetIRemoteConsole()->Update(); #endif - // CPU features detection. - m_pCpu = new CCpuFeatures; - m_pCpu->Detect(); - m_env.pi.numCoresAvailableToProcess = m_pCpu->GetCPUCount(); - m_env.pi.numLogicalProcessors = m_pCpu->GetLogicalCPUCount(); - - // Check hard minimum CPU requirements - if (!CheckCPURequirements(m_pCpu, this)) - { - return false; - } - - if (!startupParams.bSkipConsole) - { - LogSystemInfo(); - } - InlineInitializationProcessing("CSystem::Init Load Engine Folders"); ////////////////////////////////////////////////////////////////////////// @@ -2298,28 +1452,15 @@ AZ_POP_DISABLE_WARNING } { - ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink(); - // We have to load this file again since first time we did it without devmode - LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink); + LoadConfiguration(m_systemConfigName.c_str()); // Optional user defined overrides - LoadConfiguration("user.cfg", pCVarsWhiteListConfigSink); - - if (!startupParams.bSkipRenderer) - { - // Load the hmd.cfg if it exists. This will enable optional stereo rendering. - LoadConfiguration("hmd.cfg"); - } - - if (startupParams.bShaderCacheGen) - { - LoadConfiguration("shadercachegen.cfg", pCVarsWhiteListConfigSink); - } + LoadConfiguration("user.cfg"); #if defined(ENABLE_STATS_AGENT) if (m_pCmdLine->FindArg(eCLAT_Pre, "useamblecfg")) { - LoadConfiguration("amble.cfg", pCVarsWhiteListConfigSink); + LoadConfiguration("amble.cfg"); } #endif } @@ -2338,144 +1479,25 @@ AZ_POP_DISABLE_WARNING gEnv->bNoAssertDialog = true; } - ////////////////////////////////////////////////////////////////////////// - // Stream Engine - ////////////////////////////////////////////////////////////////////////// - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Stream Engine Initialization"); - InitStreamEngine(); - InlineInitializationProcessing("CSystem::Init StreamEngine"); - - - { - if (m_pCmdLine->FindArg(eCLAT_Pre, "NullRenderer")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "NULL"); - } - else if (m_pCmdLine->FindArg(eCLAT_Pre, "DX11")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "DX11"); - } - else if (m_pCmdLine->FindArg(eCLAT_Pre, "GL")) - { - m_env.pConsole->LoadConfigVar("r_Driver", "GL"); - } - } - LogBuildInfo(); InlineInitializationProcessing("CSystem::Init LoadConfigurations"); - m_env.pOverloadSceneManager = new COverloadSceneManager; - - if (m_bDedicatedServer && m_rDriver) - { - m_sSavedRDriver = m_rDriver->GetString(); - m_rDriver->Set("NULL"); - } - -#if defined(WIN32) || defined(WIN64) - if (!startupParams.bSkipRenderer) - { - if (azstricmp(m_rDriver->GetString(), "Auto") == 0) - { - m_rDriver->Set("DX11"); - } - } - - if (gEnv->IsEditor() && azstricmp(m_rDriver->GetString(), "DX12") == 0) - { - AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, "DX12 mode is not supported in the editor. Reverting to DX11 mode."); - m_rDriver->Set("DX11"); - } -#endif - #ifdef WIN32 - if ((g_cvars.sys_WER) && (!startupParams.bMinimal)) + if (g_cvars.sys_WER) { SetUnhandledExceptionFilter(CryEngineExceptionFilterWER); } #endif - ////////////////////////////////////////////////////////////////////////// // Localization ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bMinimal) { InitLocalization(); } InlineInitializationProcessing("CSystem::Init InitLocalizations"); -#if !defined(AZ_RELEASE_BUILD) && defined(AZ_PLATFORM_ANDROID) - m_thermalInfoHandler = AZStd::make_unique(); -#endif - - if (g_cvars.sys_rendersplashscreen && !startupParams.bEditor && !startupParams.bShaderCacheGen) - { - if (m_env.pRenderer) - { - LOADING_TIME_PROFILE_SECTION_NAMED("Rendering Splash Screen"); - ITexture* pTex = m_env.pRenderer->EF_LoadTexture(g_cvars.sys_splashscreen, FT_DONT_STREAM | FT_NOMIPS | FT_USAGE_ALLOWREADSRGB); - //check the width and height as extra verification hack. This texture is loaded before the replace me, so there is - //no backup if it fails to load. - if (pTex && pTex->GetWidth() && pTex->GetHeight()) - { - const int splashWidth = pTex->GetWidth(); - const int splashHeight = pTex->GetHeight(); - - const int screenWidth = m_env.pRenderer->GetOverlayWidth(); - const int screenHeight = m_env.pRenderer->GetOverlayHeight(); - - const float scaleX = (float)screenWidth / (float)splashWidth; - const float scaleY = (float)screenHeight / (float)splashHeight; - - float scale = 1.0f; - switch (g_cvars.sys_splashScreenScaleMode) - { - case SSystemCVars::SplashScreenScaleMode_Fit: - { - scale = AZStd::GetMin(scaleX, scaleY); - } - break; - case SSystemCVars::SplashScreenScaleMode_Fill: - { - scale = AZStd::GetMax(scaleX, scaleY); - } - break; - } - - const float w = splashWidth * scale; - const float h = splashHeight * scale; - const float x = (screenWidth - w) * 0.5f; - const float y = (screenHeight - h) * 0.5f; - - const float vx = (800.0f / (float) screenWidth); - const float vy = (600.0f / (float) screenHeight); - - m_env.pRenderer->SetViewport(0, 0, screenWidth, screenHeight); - -#if defined(AZ_PLATFORM_IOS) || defined(AZ_PLATFORM_MAC) - // Pump system events in order to update the screen - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::PumpSystemEventLoopUntilEmpty); -#endif - - pTex->Release(); - } - - #if defined(AZ_PLATFORM_ANDROID) - bool engineSplashEnabled = (g_cvars.sys_rendersplashscreen != 0); - if (engineSplashEnabled) - { - AZ::Android::Utils::DismissSplashScreen(); - } - #endif - } - else - { - AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, "Could not load startscreen image: %s.", g_cvars.sys_splashscreen); - } - } - ////////////////////////////////////////////////////////////////////////// // Open basic pak files after intro movie playback started ////////////////////////////////////////////////////////////////////////// @@ -2484,7 +1506,6 @@ AZ_POP_DISABLE_WARNING ////////////////////////////////////////////////////////////////////////// // AUDIO ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bMinimal) { if (InitAudioSystem(startupParams)) { @@ -2507,27 +1528,6 @@ AZ_POP_DISABLE_WARNING m_pUserCallback->OnInitProgress("First time asset processing - may take a minute..."); } - ////////////////////////////////////////////////////////////////////////// - // POST RENDERER - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bSkipRenderer && m_env.pRenderer) - { - m_env.pRenderer->PostInit(); - - if (!startupParams.bShaderCacheGen) - { - // try to do a flush to keep the renderer busy during loading - m_env.pRenderer->TryFlush(); - } - } - InlineInitializationProcessing("CSystem::Init Renderer::PostInit"); - -#ifdef SOFTCODE_SYSTEM_ENABLED - m_env.pSoftCodeMgr = new SoftCodeMgr(); -#else - m_env.pSoftCodeMgr = nullptr; -#endif - ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // System cursor @@ -2537,10 +1537,7 @@ AZ_POP_DISABLE_WARNING // - System cursor has to be enabled manually by the Game if needed; the custom UiCursor will typically be used instead if (!gEnv->IsDedicated() && - m_env.pRenderer && - !gEnv->IsEditor() && - !startupParams.bTesting && - !m_pCmdLine->FindArg(eCLAT_Pre, "nomouse")) + !gEnv->IsEditor()) { AzFramework::InputSystemCursorRequestBus::Event(AzFramework::InputDeviceMouse::Id, &AzFramework::InputSystemCursorRequests::SetSystemCursorState, @@ -2561,7 +1558,7 @@ AZ_POP_DISABLE_WARNING ////////////////////////////////////////////////////////////////////////// // UI. Should be after input and hardware mouse ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bShaderCacheGen && !m_bDedicatedServer) + if (!m_bDedicatedServer) { AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "UI system initialization"); INDENT_LOG_DURING_SCOPE(); @@ -2572,23 +1569,6 @@ AZ_POP_DISABLE_WARNING } InlineInitializationProcessing("CSystem::Init InitShine"); - - ////////////////////////////////////////////////////////////////////////// - // Create MiniGUI - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bMinimal) - { - minigui::IMiniGUIPtr pMiniGUI; - if (CryCreateClassInstanceForInterface(cryiidof(), pMiniGUI)) - { - m_pMiniGUI = pMiniGUI.get(); - m_pMiniGUI->Init(); - } - } - - InlineInitializationProcessing("CSystem::Init InitMiniGUI"); - - ////////////////////////////////////////////////////////////////////////// // CONSOLE ////////////////////////////////////////////////////////////////////////// if (!InitConsole()) @@ -2596,78 +1576,6 @@ AZ_POP_DISABLE_WARNING return false; } - ////////////////////////////////////////////////////////////////////////// - // SERVICE NETWORK - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bSkipNetwork && !startupParams.bMinimal) - { - m_env.pServiceNetwork = new CServiceNetwork(); - } - - ////////////////////////////////////////////////////////////////////////// - // REMOTE COMMAND SYTSTEM - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bSkipNetwork && !startupParams.bMinimal) - { - m_env.pRemoteCommandManager = new CRemoteCommandManager(); - } - - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // VR SYSTEM INITIALIZATION - ////////////////////////////////////////////////////////////////////////// - if ((!startupParams.bSkipRenderer) && (!startupParams.bMinimal)) - { - if (m_pUserCallback) - { - m_pUserCallback->OnInitProgress("Initializing VR Systems..."); - } - - AZStd::vector devices; - AZ::VR::HMDInitRequestBus::EnumerateHandlers([&devices](AZ::VR::HMDInitBus* device) - { - devices.emplace_back(device); - return true; - }); - - // Order the devices so that devices that only support one type of HMD are ordered first as we want - // to use any device-specific drivers over more general ones. - std::sort(devices.begin(), devices.end(), [](AZ::VR::HMDInitBus* left, AZ::VR::HMDInitBus* right) - { - return left->GetInitPriority() > right->GetInitPriority(); - }); - - //Start up a job to init the HMDs since they may take a while to start up - AZ::JobContext* jobContext = nullptr; - EBUS_EVENT_RESULT(jobContext, AZ::JobManagerBus, GetGlobalContext); - AZ::Job* hmdJob = AZ::CreateJobFunction([devices]() - { - // Loop through the attached devices and attempt to initialize them. We'll use the first - // one that succeeds since we currently only support a single HMD. - for (AZ::VR::HMDInitBus* device : devices) - { - if (device->AttemptInit()) - { - // At this point if any device connected to the HMDDeviceRequestBus then we are good to go for VR. - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, OutputHMDInfo); - EBUS_EVENT(AZ::VR::HMDDeviceRequestBus, EnableDebugging, false); - - // Since this was a job and we may have beaten the level's output_to_hmd cvar initialization - // We just want to retrigger the callback to this cvar - ICVar* outputToHMD = gEnv->pConsole->GetCVar("output_to_hmd"); - if (outputToHMD != nullptr) - { - int outputToHMDVal = gEnv->pConsole->GetCVar("output_to_hmd")->GetIVal(); - gEnv->pConsole->GetCVar("output_to_hmd")->Set(outputToHMDVal); - } - break; - } - } - }, true, jobContext); - hmdJob->Start(); - } - if (m_pUserCallback) { m_pUserCallback->OnInitProgress("Initializing additional systems..."); @@ -2701,69 +1609,6 @@ AZ_POP_DISABLE_WARNING InlineInitializationProcessing("CSystem::Init View System"); - ////////////////////////////////////////////////////////////////////////// - // Zlib compressor - m_pIZLibCompressor = new CZLibCompressor(); - - InlineInitializationProcessing("CSystem::Init ZLibCompressor"); - - ////////////////////////////////////////////////////////////////////////// - // Zlib decompressor - m_pIZLibDecompressor = new CZLibDecompressor(); - - InlineInitializationProcessing("CSystem::Init ZLibDecompressor"); - - ////////////////////////////////////////////////////////////////////////// - // LZ4 decompressor - m_pILZ4Decompressor = new CLZ4Decompressor(); - - InlineInitializationProcessing("CSystem::Init LZ4Decompressor"); - - ////////////////////////////////////////////////////////////////////////// - // ZStd decompressor - m_pIZStdDecompressor = new CZStdDecompressor(); - - InlineInitializationProcessing("CSystem::Init ZStdDecompressor"); - ////////////////////////////////////////////////////////////////////////// - // Create PerfHUD - ////////////////////////////////////////////////////////////////////////// - -#if defined(USE_PERFHUD) - if (!gEnv->bTesting && !gEnv->IsInToolMode()) - { - //Create late in Init so that associated CVars have already been created - ICryPerfHUDPtr pPerfHUD; - if (CryCreateClassInstanceForInterface(cryiidof(), pPerfHUD)) - { - m_pPerfHUD = pPerfHUD.get(); - m_pPerfHUD->Init(); - } - } -#endif - - - ////////////////////////////////////////////////////////////////////////// - // Initialize task threads. - ////////////////////////////////////////////////////////////////////////// - if (!startupParams.bSkipRenderer) - { - m_pThreadTaskManager->InitThreads(); - - SetAffinity(); - AZ_Assert(CryMemory::IsHeapValid(), "CryMemory heap must be valid before initializing VTune."); - - - if (strstr(startupParams.szSystemCmdLine, "-VTUNE") != 0 || g_cvars.sys_vtune != 0) - { - if (!InitVTuneProfiler()) - { - return false; - } - } - } - - InlineInitializationProcessing("CSystem::Init InitTaskThreads"); - if (m_env.pLyShine) { m_env.pLyShine->PostInit(); @@ -2775,12 +1620,6 @@ AZ_POP_DISABLE_WARNING AZ::Interface::Get()->VisitRegisteredFunctors([](AZ::ConsoleFunctorBase* functor) { AzConsoleToCryConsoleBinder::Visit(functor); }); AzConsoleToCryConsoleBinder::s_commandRegisteredHandler.Connect(AZ::Interface::Get()->GetConsoleCommandRegisteredEvent()); - // final tryflush to be sure that all framework init request have been processed - if (!startupParams.bShaderCacheGen && m_env.pRenderer) - { - m_env.pRenderer->TryFlush(); - } - if (g_cvars.sys_float_exceptions > 0) { if (g_cvars.sys_float_exceptions == 3 && gEnv->IsEditor()) // Turn off float exceptions in editor if sys_float_exceptions = 3 @@ -2793,8 +1632,6 @@ AZ_POP_DISABLE_WARNING } } EnableFloatExceptions(g_cvars.sys_float_exceptions); - - MarkThisThreadForDebugging("Main"); } InlineInitializationProcessing("CSystem::Init End"); @@ -2811,9 +1648,6 @@ AZ_POP_DISABLE_WARNING LoadConfiguration("client.cfg", &CVarsClientConfigSink); } - // All CVars should be registered by this point, we must now flush the cvar groups - LoadDetectedSpec(m_sys_GraphicsQuality); - //Connect to the render bus AZ::RenderNotificationsBus::Handler::BusConnect(); @@ -2849,8 +1683,7 @@ static void LoadConfigurationCmd(IConsoleCmdArgs* pParams) return; } - ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetISystem()->GetCVarsWhiteListConfigSink(); - GetISystem()->LoadConfiguration(string("Config/") + pParams->GetArg(1), pCVarsWhiteListConfigSink); + GetISystem()->LoadConfiguration(string("Config/") + pParams->GetArg(1)); } @@ -2874,99 +1707,6 @@ static string ConcatPath(const char* szPart1, const char* szPart2) return ret; } -static void ScreenshotCmd(IConsoleCmdArgs* pParams) -{ - assert(pParams); - - uint32 dwCnt = pParams->GetArgCount(); - - if (dwCnt <= 1) - { - if (!gEnv->IsEditing()) - { - // open console one line only - - //line should lie within title safe area, so calculate overscan border - Vec2 overscanBorders = Vec2(0.0f, 0.0f); - gEnv->pRenderer->EF_Query(EFQ_OverscanBorders, overscanBorders); - float yDelta = /*((float)gEnv->pRenderer->GetHeight())*/ 600.0f * overscanBorders.y; - - //set console height depending on top/bottom overscan border - gEnv->pConsole->ShowConsole(true, (int)(16 + yDelta)); - gEnv->pConsole->SetInputLine("Screenshot "); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, "Screenshot missing - no screenshot was done"); - } - } - else - { - static int iScreenshotNumber = -1; - - const char* szPrefix = "Screenshot"; - uint32 dwPrefixSize = strlen(szPrefix); - - char path[AZ::IO::IArchive::MaxPath]; - path[sizeof(path) - 1] = 0; - gEnv->pCryPak->AdjustFileName("@user@/ScreenShots", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING); - - if (iScreenshotNumber == -1) // first time - find max number to start - { - auto pCryPak = gEnv->pCryPak; - - AZ::IO::ArchiveFileIterator handle = pCryPak->FindFirst((string(path) + "/*").c_str()); // mastercd folder - if (handle) - { - do - { - int iCurScreenshotNumber; - - if (_strnicmp(handle.m_filename.data(), szPrefix, dwPrefixSize) == 0) - { - int iCnt = azsscanf(handle.m_filename.data() + dwPrefixSize, "%d", &iCurScreenshotNumber); - - if (iCnt) - { - iScreenshotNumber = max(iCurScreenshotNumber, iScreenshotNumber); - } - } - - handle = pCryPak->FindNext(handle); - } while (handle); - pCryPak->FindClose(handle); - } - } - - ++iScreenshotNumber; - - char szNumber[16]; - azsprintf(szNumber, "%.4d ", iScreenshotNumber); - - string sScreenshotName = string(szPrefix) + szNumber; - - for (uint32 dwI = 1; dwI < dwCnt; ++dwI) - { - if (dwI > 1) - { - sScreenshotName += "_"; - } - - sScreenshotName += pParams->GetArg(dwI); - } - - sScreenshotName.replace("\\", "_"); - sScreenshotName.replace("/", "_"); - sScreenshotName.replace(":", "_"); - sScreenshotName.replace(".", "_"); - - gEnv->pConsole->ShowConsole(false); - - CSystem* pCSystem = (CSystem*)(gEnv->pSystem); - pCSystem->GetDelayedScreeenshot() = string(path) + "/" + sScreenshotName;// to delay a screenshot call for a frame - } -} - // Helper to maintain backwards compatibility with our CVar but not force our new code to // pull in CryCommon by routing through an environment variable void CmdSetAwsLogLevel(IConsoleCmdArgs* pArgs) @@ -2981,153 +1721,6 @@ void CmdSetAwsLogLevel(IConsoleCmdArgs* pArgs) } } -static void SysRestoreSpecCmd(IConsoleCmdArgs* pParams) -{ - assert(pParams); - - if (pParams->GetArgCount() == 2) - { - const char* szArg = pParams->GetArg(1); - - ICVar* pCVar = gEnv->pConsole->GetCVar("sys_spec_Full"); - - if (!pCVar) - { - gEnv->pLog->LogWithType(ILog::eInputResponse, "sys_RestoreSpec: no action"); // e.g. running Editor in shder compile mode - return; - } - - ICVar::EConsoleLogMode mode = ICVar::eCLM_Off; - - if (azstricmp(szArg, "test") == 0) - { - mode = ICVar::eCLM_ConsoleAndFile; - } - else if (azstricmp(szArg, "test*") == 0) - { - mode = ICVar::eCLM_FileOnly; - } - else if (azstricmp(szArg, "info") == 0) - { - mode = ICVar::eCLM_FullInfo; - } - - if (mode != ICVar::eCLM_Off) - { - bool bFileOrConsole = (mode == ICVar::eCLM_FileOnly || mode == ICVar::eCLM_FullInfo); - - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" "); - } - else - { - CryLog(" "); - } - - int iSysSpec = pCVar->GetRealIVal(); - - if (iSysSpec == -1) - { - iSysSpec = ((CSystem*)gEnv->pSystem)->GetMaxConfigSpec(); - - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" sys_spec = Custom (assuming %d)", iSysSpec); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, " $3sys_spec = $6Custom (assuming %d)", iSysSpec); - } - } - else - { - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" sys_spec = %d", iSysSpec); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, " $3sys_spec = $6%d", iSysSpec); - } - } - - pCVar->DebugLog(iSysSpec, mode); - - if (bFileOrConsole) - { - gEnv->pLog->LogToFile(" "); - } - else - { - gEnv->pLog->LogWithType(ILog::eInputResponse, " "); - } - - return; - } - else if (strcmp(szArg, "apply") == 0) - { - const char* szPrefix = "sys_spec_"; - - ESystemConfigSpec originalSpec = CONFIG_AUTO_SPEC; - ESystemConfigPlatform originalPlatform = GetDevicePlatform(); - - if (gEnv->IsEditor()) - { - originalSpec = gEnv->pSystem->GetConfigSpec(true); - } - - std::vector cmds; - - cmds.resize(gEnv->pConsole->GetSortedVars(0, 0, szPrefix)); - gEnv->pConsole->GetSortedVars(&cmds[0], cmds.size(), szPrefix); - - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, " "); - - std::vector::const_iterator it, end = cmds.end(); - - for (it = cmds.begin(); it != end; ++it) - { - const char* szName = *it; - - if (azstricmp(szName, "sys_spec_Full") == 0) - { - continue; - } - - pCVar = gEnv->pConsole->GetCVar(szName); - assert(pCVar); - - if (!pCVar) - { - continue; - } - - bool bNeeded = pCVar->GetIVal() != pCVar->GetRealIVal(); - - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, " $3%s = $6%d ... %s", - szName, pCVar->GetIVal(), - bNeeded ? "$4restored" : "valid"); - - if (bNeeded) - { - pCVar->Set(pCVar->GetIVal()); - } - } - - gEnv->pLog->LogWithType(IMiniLog::eInputResponse, " "); - - if (gEnv->IsEditor()) - { - gEnv->pSystem->SetConfigSpec(originalSpec, originalPlatform, true); - } - return; - } - } - - gEnv->pLog->LogWithType(ILog::eInputResponse, "ERROR: sys_RestoreSpec invalid arguments"); -} - void CmdDrillToFile(IConsoleCmdArgs* pArgs) { if (azstricmp(pArgs->GetArg(0), "DrillerStop") == 0) @@ -3168,32 +1761,6 @@ void CmdDrillToFile(IConsoleCmdArgs* pArgs) } } -void ChangeLogAllocations(ICVar* pVal) -{ - g_iTraceAllocations = pVal->GetIVal(); - - if (g_iTraceAllocations == 2) - { - IDebugCallStack::instance()->StartMemLog(); - } - else - { - IDebugCallStack::instance()->StopMemLog(); - } -} - -static void VisRegTest(IConsoleCmdArgs* pParams) -{ - CSystem* pCSystem = (CSystem*)(gEnv->pSystem); - CVisRegTest*& visRegTest = pCSystem->GetVisRegTestPtrRef(); - if (!visRegTest) - { - visRegTest = new CVisRegTest(); - } - - visRegTest->Init(pParams); -} - ////////////////////////////////////////////////////////////////////////// void CSystem::CreateSystemVars() { @@ -3251,9 +1818,6 @@ void CSystem::CreateSystemVars() m_cvAIUpdate = REGISTER_INT("ai_NoUpdate", 0, VF_CHEAT, "Disables AI system update when 1"); - m_iTraceAllocations = g_iTraceAllocations; - REGISTER_CVAR2_CB("sys_logallocations", &m_iTraceAllocations, m_iTraceAllocations, VF_DUMPTODISK, "Save allocation call stack", ChangeLogAllocations); - m_cvMemStats = REGISTER_INT("MemStats", 0, 0, "0/x=refresh rate in milliseconds\n" "Use 1000 to switch on and 0 to switch off\n" @@ -3278,28 +1842,10 @@ void CSystem::CreateSystemVars() attachVariable("sys_PakLogAllFileAccess", &g_cvars.archiveVars.nLogAllFileAccess, "Log all file access allowing you to easily see whether a file has been loaded directly, or which pak file."); #endif attachVariable("sys_PakValidateFileHash", &g_cvars.archiveVars.nValidateFileHashes, "Validate file hashes in pak files for collisions"); - attachVariable("sys_LoadFrontendShaderCache", &g_cvars.archiveVars.nLoadFrontendShaderCache, "Load frontend shader cache (on/off)"); attachVariable("sys_UncachedStreamReads", &g_cvars.archiveVars.nUncachedStreamReads, "Enable stream reads via an uncached file handle"); attachVariable("sys_PakDisableNonLevelRelatedPaks", &g_cvars.archiveVars.nDisableNonLevelRelatedPaks, "Disables all paks that are not required by specific level; This is used with per level splitted assets."); attachVariable("sys_PakWarnOnPakAccessFailures", &g_cvars.archiveVars.nWarnOnPakAccessFails, "If 1, access failure for Paks is treated as a warning, if zero it is only a log message."); - - { - int nDefaultRenderSplashScreen = 1; -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_10 -#include AZ_RESTRICTED_FILE(SystemInit_cpp) -#endif - REGISTER_CVAR2("sys_rendersplashscreen", &g_cvars.sys_rendersplashscreen, nDefaultRenderSplashScreen, VF_NULL, - "Render the splash screen during game initialization"); - REGISTER_CVAR2("sys_splashscreenscalemode", &g_cvars.sys_splashScreenScaleMode, static_cast(SSystemCVars::SplashScreenScaleMode_Fill), VF_NULL, - "0 - scale to fit (letterbox)\n" - "1 - scale to fill (cropped)\n" - "Default is 1"); - REGISTER_CVAR2("sys_splashscreen", &g_cvars.sys_splashscreen, "EngineAssets/Textures/startscreen.tif", VF_NULL, - "The splash screen to render during game initialization"); - } - static const int fileSystemCaseSensitivityDefault = 0; REGISTER_CVAR2("sys_FilesystemCaseSensitivity", &g_cvars.sys_FilesystemCaseSensitivity, fileSystemCaseSensitivityDefault, VF_NULL, "0 - CryPak lowercases all input file names\n" @@ -3311,14 +1857,6 @@ void CSystem::CreateSystemVars() "1 - enable optimisation\n" "Default is 1"); -#if USE_STEAM -#ifndef RELEASE - REGISTER_CVAR2("sys_steamAppId", &g_cvars.sys_steamAppId, 0, VF_NULL, "steam appId used for development testing"); - REGISTER_COMMAND("sys_wipeSteamCloud", CmdWipeSteamCloud, VF_CHEAT, "Delete all files from steam cloud for this user"); -#endif // RELEASE - REGISTER_CVAR2("sys_useSteamCloudForPlatformSaving", &g_cvars.sys_useSteamCloudForPlatformSaving, 0, VF_NULL, "Use steam cloud for save games and profile on PC (instead of the user folder)"); -#endif - m_sysNoUpdate = REGISTER_INT("sys_noupdate", 0, VF_CHEAT, "Toggles updating of system with sys_script_debugger.\n" "Usage: sys_noupdate [0/1]\n" @@ -3382,9 +1920,6 @@ void CSystem::CreateSystemVars() #else const uint32 nJobSystemDefaultCoreNumber = 4; #endif - m_sys_GraphicsQuality = REGISTER_INT_CB("r_GraphicsQuality", 0, VF_ALWAYSONCHANGE, - "Specifies the system cfg spec. 1=low, 2=med, 3=high, 4=very high)", - LoadDetectedSpec); m_sys_firstlaunch = REGISTER_INT("sys_firstlaunch", 0, 0, "Indicates that the game was run for the first time."); @@ -3410,16 +1945,6 @@ void CSystem::CreateSystemVars() m_sys_TaskThread_CPU[5] = REGISTER_INT("sys_TaskThread5_CPU", 1, 0, "Specifies the physical CPU index taskthread5 will run on"); - //if physics thread is excluded all locks inside are mapped to NO_LOCK - //var must be not visible to accidentally get enabled -#if defined(EXCLUDE_PHYSICS_THREAD) - m_sys_physics_CPU = REGISTER_INT("sys_physics_CPU_disabled", 0, 0, - "Specifies the physical CPU index physics will run on"); -#else - m_sys_physics_CPU = REGISTER_INT("sys_physics_CPU", 1, 0, - "Specifies the physical CPU index physics will run on"); -#endif - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_12 #include AZ_RESTRICTED_FILE(SystemInit_cpp) @@ -3452,10 +1977,6 @@ void CSystem::CreateSystemVars() REGISTER_CVAR2("sys_streaming_max_finalize_per_frame", &g_cvars.sys_streaming_max_finalize_per_frame, 0, VF_NULL, "Maximum stream finalizing calls per frame to reduce the CPU impact on main thread (0 to disable)"); REGISTER_CVAR2("sys_streaming_max_bandwidth", &g_cvars.sys_streaming_max_bandwidth, 0, VF_NULL, "Enables capping of max streaming bandwidth in MB/s"); - REGISTER_CVAR2("az_streaming_stats", &g_cvars.az_streaming_stats, 0, VF_NULL, "Show stats from AZ::IO::Streamer\n" - "0=off\n" - "1=on\n" - ); REGISTER_CVAR2("sys_streaming_debug", &g_cvars.sys_streaming_debug, 0, VF_NULL, "Enable streaming debug information\n" "0=off\n" "1=Streaming Stats\n" @@ -3496,8 +2017,8 @@ void CSystem::CreateSystemVars() REGISTER_CVAR2("sys_streaming_in_blocks", &g_cvars.sys_streaming_in_blocks, 1, VF_NULL, "Streaming of large files happens in blocks"); -#if (defined(WIN32) || defined(WIN64)) && !defined(_RELEASE) - REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 3, 0, "Use or not use floating point exceptions."); +#if (defined(WIN32) || defined(WIN64)) && defined(_DEBUG) + REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 2, 0, "Use or not use floating point exceptions."); #else // Float exceptions by default disabled for console builds. REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 0, 0, "Use or not use floating point exceptions."); #endif @@ -3580,12 +2101,6 @@ void CSystem::CreateSystemVars() m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F12", "Screenshot"); m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F11", "RecordClip"); - // screenshot functionality in system as console - REGISTER_COMMAND("Screenshot", &ScreenshotCmd, VF_BLOCKFRAME, - "Create a screenshot with annotation\n" - "e.g. Screenshot beach scene with shark\n" - "Usage: Screenshot "); - /* // experimental feature? - needs to be created very early m_sys_filecache = REGISTER_INT("sys_FileCache",0,0, @@ -3593,7 +2108,6 @@ void CSystem::CreateSystemVars() "0=off / 1=enabled"); */ REGISTER_CVAR2("sys_AI", &g_cvars.sys_ai, 1, 0, "Enables AI Update"); - REGISTER_CVAR2("sys_physics", &g_cvars.sys_physics, 1, 0, "Enables Physics Update"); REGISTER_CVAR2("sys_entities", &g_cvars.sys_entitysystem, 1, 0, "Enables Entities Update"); REGISTER_CVAR2("sys_trackview", &g_cvars.sys_trackview, 1, 0, "Enables TrackView Update"); @@ -3601,14 +2115,6 @@ void CSystem::CreateSystemVars() REGISTER_STRING_CB("g_language", "", VF_NULL, "Defines which language pak is loaded", CSystem::OnLanguageCVarChanged); REGISTER_STRING_CB("g_languageAudio", "", VF_NULL, "Will automatically match g_language setting unless specified otherwise", CSystem::OnLanguageAudioCVarChanged); - REGISTER_COMMAND("sys_RestoreSpec", &SysRestoreSpecCmd, 0, - "Restore or test the cvar settings of game specific spec settings,\n" - "'test*' and 'info' log to the log file only\n" - "Usage: sys_RestoreSpec [test|test*|apply|info]"); - - REGISTER_COMMAND("VisRegTest", &VisRegTest, 0, "Run visual regression test.\n" - "Usage: VisRegTest [=test] [=visregtest.xml] [quit=false]"); - #if defined(WIN32) REGISTER_CVAR2("sys_display_threads", &g_cvars.sys_display_threads, 0, 0, "Displays Thread info"); #elif defined(AZ_RESTRICTED_PLATFORM) @@ -3629,15 +2135,8 @@ void CSystem::CreateSystemVars() REGISTER_CVAR2("sys_error_debugbreak", &g_cvars.sys_error_debugbreak, 0, VF_CHEAT, "__debugbreak() if a VALIDATOR_ERROR_DBGBREAK message is hit"); - // [VR] - AZ::VR::HMDCVars::Register(); - REGISTER_STRING("dlc_directory", "", 0, "Holds the path to the directory where DLC should be installed to and read from"); -#if defined(MAP_LOADING_SLICING) - CreateSystemScheduler(this); -#endif // defined(MAP_LOADING_SLICING) - #if defined(WIN32) || defined(WIN64) REGISTER_INT("sys_screensaver_allowed", 0, VF_NULL, "Specifies if screen saver is allowed to start up while the game is running."); #endif @@ -3694,11 +2193,6 @@ void CSystem::AddCVarGroupDirectory(const string& sPath) string sCVarName = sFilePath; PathUtil::RemoveExtension(sCVarName); - - if (m_env.pConsole != 0) - { - ((CXConsole*)m_env.pConsole)->RegisterCVarGroup(PathUtil::GetFile(sCVarName), sFilePath); - } } } while (handle = gEnv->pCryPak->FindNext(handle)); diff --git a/Code/CryEngine/CrySystem/SystemInit.h b/Code/CryEngine/CrySystem/SystemInit.h deleted file mode 100644 index 55eecb97db..0000000000 --- a/Code/CryEngine/CrySystem/SystemInit.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SYSTEMINIT_H -#define CRYINCLUDE_CRYSYSTEM_SYSTEMINIT_H -#pragma once - - -#include "System.h" - -#if defined(AZ_PLATFORM_ANDROID) - #include "AndroidConsole.h" - -// let the java code know the native renderer is taking over now -extern "C" DLL_EXPORT void OnEngineRendererTakeover(bool engineSplashActive); -#endif - -#include "UnixConsole.h" - -#if defined(USE_UNIXCONSOLE) -#if defined(LINUX) && !defined(ANDROID) -extern __attribute__((visibility("default"))) CUNIXConsole* pUnixConsole; -#endif -#endif // USE_UNIXCONSOLE - -#endif // CRYINCLUDE_CRYSYSTEM_SYSTEMINIT_H diff --git a/Code/CryEngine/CrySystem/SystemRender.cpp b/Code/CryEngine/CrySystem/SystemRender.cpp deleted file mode 100644 index 68045a86ea..0000000000 --- a/Code/CryEngine/CrySystem/SystemRender.cpp +++ /dev/null @@ -1,306 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : CryENGINE system core - - -#include "CrySystem_precompiled.h" -#include "System.h" - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -#endif - -#if defined(AZ_PLATFORM_IOS) -#import -#endif - -#include -#include -#include -#include "Log.h" -#include "XConsole.h" -#include -#include "PhysRenderer.h" -#include - -#include "CrySizerStats.h" -#include "CrySizerImpl.h" -#include "VisRegTest.h" -#include "ITextModeConsole.h" -#include -#include - -#include "MiniGUI/MiniGUI.h" -#include "PerfHUD.h" -#include "ThreadInfo.h" - -#include - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define SYSTEMRENDERER_CPP_SECTION_1 1 -#define SYSTEMRENDERER_CPP_SECTION_2 2 -#endif - -extern CMTSafeHeap* g_pPakHeap; -#if defined(AZ_PLATFORM_ANDROID) -#include -#endif - -extern int CryMemoryGetAllocatedSize(); - -///////////////////////////////////////////////////////////////////////////////// -static void VerifySizeRenderVar(ICVar* pVar) -{ - const int size = pVar->GetIVal(); - if (size <= 0) - { - AZ_Error("Console Variable", false, "'%s' set to invalid value: %i. Setting to nearest safe value: 1.", pVar->GetName(), size); - pVar->Set(1); - } -} - -///////////////////////////////////////////////////////////////////////////////// -bool CSystem::GetPrimaryPhysicalDisplayDimensions([[maybe_unused]] int& o_widthPixels, [[maybe_unused]] int& o_heightPixels) -{ -#if defined(AZ_PLATFORM_WINDOWS) - o_widthPixels = GetSystemMetrics(SM_CXSCREEN); - o_heightPixels = GetSystemMetrics(SM_CYSCREEN); - return true; -#elif defined(AZ_PLATFORM_ANDROID) - return AZ::Android::Utils::GetWindowSize(o_widthPixels, o_heightPixels); -#else - return false; -#endif -} - - -bool CSystem::IsTablet() -{ -//TODO: Add support for Android tablets -#if defined(AZ_PLATFORM_IOS) - return [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad; -#else - return false; -#endif -} - -///////////////////////////////////////////////////////////////////////////////// -void CSystem::CreateRendererVars(const SSystemInitParams& startupParams) -{ - int iFullScreenDefault = 1; - int iDisplayInfoDefault = 0; - int iWidthDefault = 1280; - int iHeightDefault = 720; -#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS) - GetPrimaryPhysicalDisplayDimensions(iWidthDefault, iHeightDefault); -#elif defined(WIN32) || defined(WIN64) - iFullScreenDefault = 0; - iWidthDefault = GetSystemMetrics(SM_CXFULLSCREEN) * 2 / 3; - iHeightDefault = GetSystemMetrics(SM_CYFULLSCREEN) * 2 / 3; -#endif - - if (IsDevMode()) - { - iFullScreenDefault = 0; - iDisplayInfoDefault = 1; - } - - // load renderer settings from engine.ini - m_rWidth = REGISTER_INT_CB("r_Width", iWidthDefault, VF_DUMPTODISK, - "Sets the display width, in pixels. Default is 1280.\n" - "Usage: r_Width [800/1024/..]", VerifySizeRenderVar); - m_rHeight = REGISTER_INT_CB("r_Height", iHeightDefault, VF_DUMPTODISK, - "Sets the display height, in pixels. Default is 720.\n" - "Usage: r_Height [600/768/..]", VerifySizeRenderVar); - m_rWidthAndHeightAsFractionOfScreenSize = REGISTER_FLOAT("r_WidthAndHeightAsFractionOfScreenSize", 1.0f, VF_DUMPTODISK, - "(iOS/Android only) Sets the display width and height as a fraction of the physical screen size. Default is 1.0.\n" - "Usage: rWidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]"); - m_rTabletWidthAndHeightAsFractionOfScreenSize = REGISTER_FLOAT("r_TabletWidthAndHeightAsFractionOfScreenSize", 1.0f, VF_DUMPTODISK, - "(iOS only) NOTE: TABLETS ONLY Sets the display width and height as a fraction of the physical screen size. Default is 1.0.\n" - "Usage: rTabletWidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]"); - m_rMaxWidth = REGISTER_INT("r_MaxWidth", 0, VF_DUMPTODISK, - "(iOS/Android only) Sets the maximum display width while maintaining the device aspect ratio.\n" - "Usage: r_MaxWidth [1024/1920/..] (0 for no max), combined with r_WidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]"); - m_rMaxHeight = REGISTER_INT("r_MaxHeight", 0, VF_DUMPTODISK, - "(iOS/Android only) Sets the maximum display height while maintaining the device aspect ratio.\n" - "Usage: r_MaxHeight [768/1080/..] (0 for no max), combined with r_WidthAndHeightAsFractionOfScreenSize [0.1 - 1.0]"); - m_rColorBits = REGISTER_INT("r_ColorBits", 32, VF_DUMPTODISK, - "Sets the color resolution, in bits per pixel. Default is 32.\n" - "Usage: r_ColorBits [32/24/16/8]"); - m_rDepthBits = REGISTER_INT("r_DepthBits", 24, VF_DUMPTODISK | VF_REQUIRE_APP_RESTART, - "Sets the depth precision, in bits per pixel. Default is 24.\n" - "Usage: r_DepthBits [32/24]"); - m_rStencilBits = REGISTER_INT("r_StencilBits", 8, VF_DUMPTODISK, - "Sets the stencil precision, in bits per pixel. Default is 8.\n"); - - // Needs to be initialized as soon as possible due to swap chain creation modifications.. - m_rHDRDolby = REGISTER_INT_CB("r_HDRDolby", 0, VF_DUMPTODISK, - "HDR dolby output mode\n" - "Usage: r_HDRDolby [Value]\n" - "0: Off (default)\n" - "1: Dolby maui output\n" - "2: Dolby vision output\n", - [] (ICVar* cvar) - { - eDolbyVisionMode mode = static_cast(cvar->GetIVal()); - - if (mode == eDVM_Vision && gEnv->IsEditor()) - { - cvar->Set(static_cast(eDVM_Disabled)); - } - }); - // Restrict the limits of this cvar to the eDolbyVisionMode values - m_rHDRDolby->SetLimits(static_cast(eDVM_Disabled), static_cast(eDVM_Vision)); - -#if defined(WIN32) || defined(WIN64) - REGISTER_INT("r_overrideDXGIAdapter", -1, VF_REQUIRE_APP_RESTART, - "Specifies index of the preferred video adapter to be used for rendering (-1=off, loops until first suitable adapter is found).\n" - "Use this to resolve which video card to use if more than one DX11 capable GPU is available in the system."); -#endif - -#if defined(WIN32) || defined(WIN64) - const char* p_r_DriverDef = "Auto"; -#elif defined(APPLE) - const char* p_r_DriverDef = "METAL"; -#elif defined(ANDROID) - const char* p_r_DriverDef = "GL"; -#elif defined(LINUX) - const char* p_r_DriverDef = "GL"; - if (gEnv->IsDedicated()) - { - p_r_DriverDef = "NULL"; - } -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMRENDERER_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(SystemRender_cpp) -#else - const char* p_r_DriverDef = "DX9"; // required to be deactivated for final release -#endif - if (startupParams.pCvarsDefault) - { // hack to customize the default value of r_Driver - SCvarsDefault* pCvarsDefault = startupParams.pCvarsDefault; - if (pCvarsDefault->sz_r_DriverDef && pCvarsDefault->sz_r_DriverDef[0]) - { - p_r_DriverDef = startupParams.pCvarsDefault->sz_r_DriverDef; - } - } - - m_rDriver = REGISTER_STRING("r_Driver", p_r_DriverDef, VF_DUMPTODISK | VF_INVISIBLE, - "Sets the renderer driver ( DX11/AUTO/NULL ).\n" - "Specify in bootstrap.cfg like this: r_Driver = \"DX11\""); - - m_rFullscreen = REGISTER_INT("r_Fullscreen", iFullScreenDefault, VF_DUMPTODISK, - "Toggles fullscreen mode. Default is 1 in normal game and 0 in DevMode.\n" - "Usage: r_Fullscreen [0=window/1=fullscreen]"); - - m_rFullscreenWindow = REGISTER_INT("r_FullscreenWindow", 0, VF_DUMPTODISK, - "Toggles fullscreen-as-window mode. Fills screen but allows seamless switching. Default is 0.\n" - "Usage: r_FullscreenWindow [0=locked fullscreen/1=fullscreen as window]"); - - m_rFullscreenNativeRes = REGISTER_INT("r_FullscreenNativeRes", 0, VF_DUMPTODISK, ""); - - m_rDisplayInfo = REGISTER_INT("r_DisplayInfo", iDisplayInfoDefault, VF_RESTRICTEDMODE | VF_DUMPTODISK, - "Toggles debugging information display.\n" - "Usage: r_DisplayInfo [0=off/1=show/2=enhanced/3=compact]"); - - m_rOverscanBordersDrawDebugView = REGISTER_INT("r_OverscanBordersDrawDebugView", 0, VF_RESTRICTEDMODE | VF_DUMPTODISK, - "Toggles drawing overscan borders.\n" - "Usage: r_OverscanBordersDrawDebugView [0=off/1=show]"); -} - -void CSystem::OnScene3DEnd() -{ - //Render Console - if (m_bDrawConsole && gEnv->pConsole) - { - gEnv->pConsole->Draw(); - } -} - - -//! Update screen and call some important tick functions during loading. -void CSystem::SynchronousLoadingTick([[maybe_unused]] const char* pFunc, [[maybe_unused]] int line) -{ - LOADING_TIME_PROFILE_SECTION; - if (gEnv && gEnv->bMultiplayer && !gEnv->IsEditor()) - { - //UpdateLoadingScreen currently contains a couple of tick functions that need to be called regularly during the synchronous level loading, - //when the usual engine and game ticks are suspended. - UpdateLoadingScreen(); - -#if defined(MAP_LOADING_SLICING) - GetISystemScheduler()->SliceAndSleep(pFunc, line); -#endif - } -} - - -////////////////////////////////////////////////////////////////////////// -void CSystem::UpdateLoadingScreen() -{ - // Do not update the network thread from here - it will cause context corruption - use the NetworkStallTicker thread system - - if (GetCurrentThreadId() != gEnv->mMainThreadId) - { - return; - } - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMRENDERER_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(SystemRender_cpp) -#endif - -#if AZ_LOADSCREENCOMPONENT_ENABLED - EBUS_EVENT(LoadScreenBus, UpdateAndRender); -#endif // if AZ_LOADSCREENCOMPONENT_ENABLED - - if (!m_bEditor && !IsQuitting()) - { - if (m_pProgressListener) - { - m_pProgressListener->OnLoadingProgress(0); - } - } -} - -////////////////////////////////////////////////////////////////////////// - -void CSystem::DisplayErrorMessage(const char* acMessage, - [[maybe_unused]] float fTime, - const float* pfColor, - bool bHardError) -{ - SErrorMessage message; - message.m_Message = acMessage; - if (pfColor) - { - memcpy(message.m_Color, pfColor, 4 * sizeof(float)); - } - else - { - message.m_Color[0] = 1.0f; - message.m_Color[1] = 0.0f; - message.m_Color[2] = 0.0f; - message.m_Color[3] = 1.0f; - } - message.m_HardFailure = bHardError; -#ifdef _RELEASE - message.m_fTimeToShow = fTime; -#else - message.m_fTimeToShow = 1.0f; -#endif - m_ErrorMessages.push_back(message); -} diff --git a/Code/CryEngine/CrySystem/SystemScheduler.cpp b/Code/CryEngine/CrySystem/SystemScheduler.cpp deleted file mode 100644 index 5cee6d5529..0000000000 --- a/Code/CryEngine/CrySystem/SystemScheduler.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Implementation of the CSystemScheduler class - - -#include "CrySystem_precompiled.h" - -#include "ProjectDefines.h" -#if defined(MAP_LOADING_SLICING) - -#include "SystemScheduler.h" - -#include "MiniQueue.h" -#include "ClientHandler.h" -#include "ServerHandler.h" - -void CreateSystemScheduler(CSystem* pSystem) -{ - gEnv->pSystemScheduler = new CSystemScheduler(pSystem); -} - -CSystemScheduler::CSystemScheduler(CSystem* pSystem) - : m_pSystem(pSystem) - , m_lastSliceCheckTime(0.0f) - , m_sliceLoadingRef(0) -{ - int defaultSchedulingMode = 0; - if (gEnv->IsDedicated()) - { - defaultSchedulingMode = 2; - } - - m_svSchedulingMode = REGISTER_INT("sv_scheduling", defaultSchedulingMode, 0, "Scheduling mode\n" - " 0: Normal mode\n" - " 1: Client\n" - " 2: Server\n"); - - m_svSchedulingBucket = REGISTER_INT("sv_schedulingBucket", 0, 0, "Scheduling bucket\n"); - - m_svSchedulingAffinity = REGISTER_INT("sv_SchedulingAffinity", 0, 0, "Scheduling affinity\n"); - - m_svSchedulingClientTimeout = REGISTER_INT("sv_schedulingClientTimeout", 1000, 0, "Client wait server\n"); - m_svSchedulingServerTimeout = REGISTER_INT("sv_schedulingServerTimeout", 100, 0, "Server wait server\n"); - -#if defined(MAP_LOADING_SLICING) - m_svSliceLoadEnable = REGISTER_INT("sv_sliceLoadEnable", 1, 0, "Enable/disable slice loading logic\n"); - ; - m_svSliceLoadBudget = REGISTER_INT("sv_sliceLoadBudget", 10, 0, "Slice budget\n"); - ; - m_svSliceLoadLogging = REGISTER_INT("sv_sliceLoadLogging", 0, 0, "Enable/disable slice loading logging\n"); -#endif - - m_pLastSliceName = "INACTIVE"; - m_lastSliceLine = 0; -} - -CSystemScheduler::~CSystemScheduler(void) -{ -} - -void CSystemScheduler::SliceLoadingBegin() -{ - m_lastSliceCheckTime = gEnv->pTimer->GetAsyncTime(); - m_sliceLoadingRef++; - m_pLastSliceName = "START"; - m_lastSliceLine = 0; -} - -void CSystemScheduler::SliceLoadingEnd() -{ - m_sliceLoadingRef--; - m_pLastSliceName = "INACTIVE"; - m_lastSliceLine = 0; -} - -void CSystemScheduler::SliceAndSleep(const char* sliceName, int line) -{ -#if defined(MAP_LOADING_SLICING) - if (!gEnv->IsDedicated()) - { - return; - } - - if (!m_sliceLoadingRef) - { - return; - } - - if (!m_svSliceLoadEnable->GetIVal()) - { - return; - } - - SchedulingModeUpdate(); - - CTimeValue currTime = gEnv->pTimer->GetAsyncTime(); - - float sliceBudget = CLAMP(m_svSliceLoadBudget->GetFVal(), 0, 1000.0f / m_pSystem->GetDedicatedMaxRate()->GetFVal()); - bool doSleep = true; - if ((currTime - m_pSystem->GetLastTickTime()).GetMilliSeconds() < sliceBudget) - { - m_lastSliceCheckTime = currTime; - doSleep = false; - } - - if (doSleep) - { - if (m_svSliceLoadLogging->GetIVal()) - { - float diff = (currTime - m_lastSliceCheckTime).GetMilliSeconds(); - if (diff > sliceBudget) - { - CryLogAlways("[SliceAndSleep]: Interval between slice [%s:%i] and [%s:%i] was [%f] out of budget [%f]", m_pLastSliceName, m_lastSliceLine, sliceName, line, diff, sliceBudget); - } - } - - m_pSystem->SleepIfNeeded(); - } - - m_pLastSliceName = sliceName; - m_lastSliceLine = line; -#endif -} - -void CSystemScheduler::SchedulingSleepIfNeeded() -{ - if (!gEnv->IsDedicated()) - { - return; - } - - SchedulingModeUpdate(); - m_pSystem->SleepIfNeeded(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Scheduling mode routines -// -/////////////////////////////////////////////////////////////////////////////////////////////////// - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Scheduling mode update logic -// -/////////////////////////////////////////////////////////////////////////////////////////////////// - -void CSystemScheduler::SchedulingModeUpdate() -{ - static std::unique_ptr m_client; - static std::unique_ptr m_server; - - if (int scheduling = m_svSchedulingMode->GetIVal()) - { - if (scheduling == 1) //client - { - if (!m_client.get()) - { - m_server.reset(); - m_client.reset(new ClientHandler(m_svSchedulingBucket->GetString(), m_svSchedulingAffinity->GetIVal(), m_svSchedulingClientTimeout->GetIVal())); - } - if (m_client->Sync()) - { - return; - } - } - else if (scheduling == 2) //server - { - if (!m_server.get()) - { - m_client.reset(); - m_server.reset(new ServerHandler(m_svSchedulingBucket->GetString(), m_svSchedulingAffinity->GetIVal(), m_svSchedulingServerTimeout->GetIVal())); - } - if (m_server->Sync()) - { - return; - } - } - } - else - { - m_client.reset(); - m_server.reset(); - } -} - -#endif // defined(MAP_LOADING_SLICING) - -extern "C" void SliceAndSleep(const char* pFunc, int line) -{ - if (GetISystemScheduler()) - { - GetISystemScheduler()->SliceAndSleep(pFunc, line); - } -} - diff --git a/Code/CryEngine/CrySystem/SystemScheduler.h b/Code/CryEngine/CrySystem/SystemScheduler.h deleted file mode 100644 index feb6e2850c..0000000000 --- a/Code/CryEngine/CrySystem/SystemScheduler.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H -#define CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H - -#pragma once - -#include "System.h" -#include - -class CSystemScheduler - : public ISystemScheduler -{ -public: - CSystemScheduler(CSystem* pSystem); - virtual ~CSystemScheduler(void); - - // ISystemScheduler - virtual void SliceAndSleep(const char* sliceName, int line); - virtual void SliceLoadingBegin(); - virtual void SliceLoadingEnd(); - - virtual void SchedulingSleepIfNeeded(void); - // ~ISystemScheduler - -protected: - void SchedulingModeUpdate(void); - -private: - CSystem* m_pSystem; - ICVar* m_svSchedulingAffinity; - ICVar* m_svSchedulingClientTimeout; - ICVar* m_svSchedulingServerTimeout; - ICVar* m_svSchedulingBucket; - ICVar* m_svSchedulingMode; - ICVar* m_svSliceLoadEnable; - ICVar* m_svSliceLoadBudget; - ICVar* m_svSliceLoadLogging; - - CTimeValue m_lastSliceCheckTime; - - int m_sliceLoadingRef; - - const char* m_pLastSliceName; - int m_lastSliceLine; -}; - -// Summary: -// Creates the system scheduler interface. -void CreateSystemScheduler(CSystem* pSystem); - -#endif // CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H diff --git a/Code/CryEngine/CrySystem/SystemThreading.cpp b/Code/CryEngine/CrySystem/SystemThreading.cpp deleted file mode 100644 index 9354e4e1c3..0000000000 --- a/Code/CryEngine/CrySystem/SystemThreading.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "ThreadConfigManager.h" -#include "IThreadManager.h" -#include -#include "CryUtils.h" - -#define INCLUDED_FROM_SYSTEM_THREADING_CPP - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define SYSTEMTHREADING_CPP_SECTION_1 1 -#define SYSTEMTHREADING_CPP_SECTION_2 2 -#define SYSTEMTHREADING_CPP_SECTION_3 3 -#endif - -#if defined(WIN32) || defined(WIN64) - #include "CryThreadUtil_win32_thread.h" -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(SystemThreading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - #include "CryThreadUtil_pthread.h" -#endif -#undef INCLUDED_FROM_SYSTEM_THREADING_CPP - -////////////////////////////////////////////////////////////////////////// -static void ApplyThreadConfig(CryThreadUtil::TThreadHandle pThreadHandle, const SThreadConfig& rThreadDesc) -{ - // Apply config - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) - { - CryThreadUtil::CrySetThreadName(pThreadHandle, rThreadDesc.szThreadName); - } - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) - { - CryThreadUtil::CrySetThreadAffinityMask(pThreadHandle, rThreadDesc.affinityFlag); - } - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) - { - CryThreadUtil::CrySetThreadPriority(pThreadHandle, rThreadDesc.priority); - } - if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) - { - CryThreadUtil::CrySetThreadPriorityBoost(pThreadHandle, !rThreadDesc.bDisablePriorityBoost); - } - - CryComment(" Configured thread \"%s\" %s | AffinityMask: %u %s | Priority: %i %s | PriorityBoost: %s %s", - rThreadDesc.szThreadName, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) ? "" : "(ignored)", - rThreadDesc.affinityFlag, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) ? "" : "(ignored)", - rThreadDesc.priority, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) ? "" : "(ignored)", - !rThreadDesc.bDisablePriorityBoost ? "enabled" : "disabled", (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) ? "" : "(ignored)"); -} - -////////////////////////////////////////////////////////////////////////// -struct SThreadMetaData - : public CMultiThreadRefCount -{ - SThreadMetaData() - : m_pThreadTask(0) - , m_threadHandle(0) - , m_threadId(0) - , m_threadName("Cry_UnnamedThread") - , m_isRunning(false) - { - } - - IThread* m_pThreadTask; // Pointer to thread task to be executed - CThreadManager* m_pThreadMngr; // Pointer to thread manager - - CryThreadUtil::TThreadHandle m_threadHandle; // Thread handle - threadID m_threadId; // The active threadId, 0 = Invalid Id - - CryMutex m_threadExitMutex; // Mutex used to safeguard thread exit condition signaling - CryConditionVariable m_threadExitCondition; // Signaled when the thread is about to exit - - CryFixedStringT m_threadName; // Thread name - volatile bool m_isRunning; // Indicates the thread is not ready to exit yet -}; - -////////////////////////////////////////////////////////////////////////// -class CThreadManager - : public IThreadManager -{ -public: - // - virtual ~CThreadManager() - { - } - - virtual bool SpawnThread(IThread* pThread, const char* sThreadName, ...) override; - virtual bool JoinThread(IThread* pThreadTask, EJoinMode eJoinMode) override; - - virtual bool RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) override; - virtual bool UnRegisterThirdPartyThread(const char* sThreadName, ...) override; - - virtual const char* GetThreadName(threadID nThreadId) override; - virtual threadID GetThreadId(const char* sThreadName, ...) override; - - virtual void ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData = 0) override; - - virtual void EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId = 0) override; - virtual void EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) override; - - virtual uint GetFloatingPointExceptionMask() override; - virtual void SetFloatingPointExceptionMask(uint nMask) override; - - IThreadConfigManager* GetThreadConfigManager() override - { - return &m_threadConfigManager; - } - // -private: -#if defined(WIN32) || defined(WIN64) - static unsigned __stdcall RunThread(void* thisPtr); -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(SystemThreading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else - static void* RunThread(void* thisPtr); -#endif - -private: - bool UnregisterThread(IThread* pThreadTask); - - bool SpawnThreadImpl(IThread* pThread, const char* sThreadName); - - bool RegisterThirdPartyThreadImpl(CryThreadUtil::TThreadHandle pThreadHandle, const char* sThreadName); - bool UnRegisterThirdPartyThreadImpl(const char* sThreadName); - - threadID GetThreadIdImpl(const char* sThreadName); - -private: - // Note: Guard SThreadMetaData with a _smart_ptr and lock to ensure that a thread waiting to be signaled by another still - // has access to valid SThreadMetaData even though the other thread terminated and as a result unregistered itself from the CThreadManager. - // An example would be the join method. Where one thread waits on a signal from an other thread to terminate and release its SThreadMetaData, - // sharing the same SThreadMetaData condition variable. - typedef std::map > SpawnedThreadMap; - typedef std::map >::iterator SpawnedThreadMapIter; - typedef std::map >::const_iterator SpawnedThreadMapConstIter; - typedef std::pair > ThreadMapPair; - - typedef std::map, _smart_ptr > SpawnedThirdPartyThreadMap; - typedef std::map, _smart_ptr >::iterator SpawnedThirdPartyThreadMapIter; - typedef std::map, _smart_ptr >::const_iterator SpawnedThirdPartyThreadMapConstIter; - typedef std::pair, _smart_ptr > ThirdPartyThreadMapPair; - - CryCriticalSection m_spawnedThreadsLock; // Use lock for the rare occasion a thread is created/destroyed - SpawnedThreadMap m_spawnedThreads; // Holds information of all spawned threads (through this system) - - CryCriticalSection m_spawnedThirdPartyThreadsLock; // Use lock for the rare occasion a thread is created/destroyed - SpawnedThirdPartyThreadMap m_spawnedThirdPartyThread; // Holds information of all registered 3rd party threads (through this system) - - CThreadConfigManager m_threadConfigManager; -}; - -////////////////////////////////////////////////////////////////////////// -#if defined(WIN32) || defined(WIN64) -unsigned __stdcall CThreadManager::RunThread(void* thisPtr) -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_3 -#include AZ_RESTRICTED_FILE(SystemThreading_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -void* CThreadManager::RunThread(void* thisPtr) -#endif -{ - // Check that we are not spawning a thread before gEnv->pSystem has been set - // Otherwise we cannot enable floating point exceptions - if (!gEnv || !gEnv->pSystem) - { - CryFatalError("[Error]: CThreadManager::RunThread requires gEnv->pSystem to be initialized."); - } - - IThreadConfigManager* pThreadConfigMngr = gEnv->pThreadManager->GetThreadConfigManager(); - - SThreadMetaData* pThreadData = reinterpret_cast(thisPtr); - pThreadData->m_threadId = CryThreadUtil::CryGetCurrentThreadId(); - - // Apply config - const SThreadConfig* pThreadConfig = pThreadConfigMngr->GetThreadConfig(pThreadData->m_threadName.c_str()); - ApplyThreadConfig(pThreadData->m_threadHandle, *pThreadConfig); - - // Config not found, append thread name with no config tag - if (pThreadConfig == pThreadConfigMngr->GetDefaultThreadConfig()) - { - CryFixedStringT tmpString(pThreadData->m_threadName); - const char* cNoConfigAppendix = "(NoCfgFound)"; - int nNumCharsToReplace = strlen(cNoConfigAppendix); - - // Replace thread name ending - if (pThreadData->m_threadName.size() > THREAD_NAME_LENGTH_MAX - nNumCharsToReplace) - { - tmpString.replace(THREAD_NAME_LENGTH_MAX - nNumCharsToReplace, nNumCharsToReplace, cNoConfigAppendix, nNumCharsToReplace); - } - else - { - tmpString.append(cNoConfigAppendix); - } - - // Print to log - if (pThreadConfigMngr->ConfigLoaded()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " No Thread config found for thread %s using ... default config.", pThreadData->m_threadName.c_str()); - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, " Thread config not loaded yet. Hence no thread config was found for thread %s ... using default config.", pThreadData->m_threadName.c_str()); - } - - // Rename Thread - CryThreadUtil::CrySetThreadName(pThreadData->m_threadHandle, tmpString.c_str()); - } - - // Enable FPEs - gEnv->pThreadManager->EnableFloatExceptions((EFPE_Severity)g_cvars.sys_float_exceptions); - - // Execute thread code - pThreadData->m_pThreadTask->ThreadEntry(); - - // Disable FPEs - gEnv->pThreadManager->EnableFloatExceptions(eFPE_None); - - // Signal imminent thread end - pThreadData->m_threadExitMutex.Lock(); - pThreadData->m_isRunning = false; - pThreadData->m_threadExitCondition.Notify(); - pThreadData->m_threadExitMutex.Unlock(); - - // Unregister thread - // Note: Unregister after m_threadExitCondition.Notify() to ensure pThreadData is still valid - pThreadData->m_pThreadMngr->UnregisterThread(pThreadData->m_pThreadTask); - - CryThreadUtil::CryThreadExitCall(); - - return NULL; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::JoinThread(IThread* pThreadTask, EJoinMode eJoinMode) -{ - // Get thread object - _smart_ptr pThreadImpl = 0; - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask); - if (res == m_spawnedThreads.end()) - { - // Thread has already finished and unregistered itself. - // As it is complete we cannot wait for it. - // Hence return true. - return true; - } - - pThreadImpl = res->second; // Keep object alive - } - - // On try join, exit if the thread is not in a state to exit - if (eJoinMode == eJM_TryJoin && pThreadImpl->m_isRunning) - { - return false; - } - - // Wait for completion of the target thread exit condition - pThreadImpl->m_threadExitMutex.Lock(); - while (pThreadImpl->m_isRunning) - { - pThreadImpl->m_threadExitCondition.Wait(pThreadImpl->m_threadExitMutex); - } - pThreadImpl->m_threadExitMutex.Unlock(); - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::UnregisterThread(IThread* pThreadTask) -{ - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask); - if (res == m_spawnedThreads.end()) - { - // Duplicate thread deletion - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": UnregisterThread: Unable to unregister thread. Thread name could not be found. Double deletion? IThread pointer: %p", pThreadTask); - return false; - } - - m_spawnedThreads.erase(res); - return true; -} - -////////////////////////////////////////////////////////////////////////// -const char* CThreadManager::GetThreadName(threadID nThreadId) -{ - // Loop over internally spawned threads - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapConstIter iter = m_spawnedThreads.begin(); - SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId == nThreadId) - { - return iter->second->m_threadName.c_str(); - } - } - } - - // Loop over third party threads - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin(); - SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId == nThreadId) - { - return iter->second->m_threadName.c_str(); - } - } - } - - return ""; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData) -{ - threadID nCurThreadId = CryThreadUtil::CryGetCurrentThreadId(); - - // Loop over internally spawned threads - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapConstIter iter = m_spawnedThreads.begin(); - SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId != nCurThreadId) - { - fpThreadModiFunction(iter->second->m_threadId, pFuncData); - } - } - } - - // Loop over third party threads - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin(); - SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadId != nCurThreadId) - { - fpThreadModiFunction(iter->second->m_threadId, pFuncData); - } - } - } -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::SpawnThread(IThread* pThreadTask, const char* sThreadName, ...) -{ - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1 || cNumCharsNeeded < 0) - { - strThreadName[THREAD_NAME_LENGTH_MAX - 1] = '\0'; // The WinApi only null terminates if strLen < bufSize - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Spawn thread - bool ret = SpawnThreadImpl(pThreadTask, strThreadName); - - if (!ret) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": CSystem::SpawnThread error spawning thread: \"%s\" ", strThreadName); - } - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::SpawnThreadImpl(IThread* pThreadTask, const char* sThreadName) -{ - if (pThreadTask == NULL) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, ": SpawnThread '%s' ThreadTask is NULL : ignoring", sThreadName); - return false; - } - - // Init thread meta data - SThreadMetaData* pThreadMetaData = new SThreadMetaData(); - pThreadMetaData->m_pThreadTask = pThreadTask; - pThreadMetaData->m_pThreadMngr = this; - pThreadMetaData->m_threadName = sThreadName; - - // Add thread to map - { - AUTO_LOCK(m_spawnedThreadsLock); - SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask); - if (res != m_spawnedThreads.end()) - { - // Thread with same name already spawned - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": SpawnThread: Thread \"%s\" already exists.", sThreadName); - delete pThreadMetaData; - return false; - } - - // Insert thread data - m_spawnedThreads.insert(ThreadMapPair(pThreadTask, pThreadMetaData)); - } - - // Load config if we can and if no config has been defined to be loaded - const SThreadConfig* pThreadConfig = gEnv->pThreadManager->GetThreadConfigManager()->GetThreadConfig(sThreadName); - - // Create thread description - CryThreadUtil::SThreadCreationDesc desc = {sThreadName, RunThread, pThreadMetaData, pThreadConfig->paramActivityFlag & SThreadConfig::eThreadParamFlag_StackSize ? pThreadConfig->stackSizeBytes : 0}; - - // Spawn new thread - pThreadMetaData->m_isRunning = CryThreadUtil::CryCreateThread(&(pThreadMetaData->m_threadHandle), desc); - - // Validate thread creation - if (!pThreadMetaData->m_isRunning) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": SpawnThread: Could not spawn thread \"%s\" .", sThreadName); - - // Remove thread from map (also releases SThreadMetaData _smart_ptr) - m_spawnedThreads.erase(m_spawnedThreads.find(pThreadTask)); - return false; - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) -{ - if (!pThreadHandle) - { - pThreadHandle = reinterpret_cast(CryThreadUtil::CryGetCurrentThreadHandle()); - } - - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Register 3rd party thread - bool ret = RegisterThirdPartyThreadImpl(reinterpret_cast(pThreadHandle), strThreadName); - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::RegisterThirdPartyThreadImpl(CryThreadUtil::TThreadHandle threadHandle, const char* sThreadName) -{ - if (strcmp(sThreadName, "") == 0) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": CThreadManager::RegisterThirdPartyThread error registering third party thread. No name provided."); - return false; - } - // Init thread meta data - SThreadMetaData* pThreadMetaData = new SThreadMetaData(); - pThreadMetaData->m_pThreadTask = 0; - pThreadMetaData->m_pThreadMngr = this; - pThreadMetaData->m_threadName = sThreadName; - pThreadMetaData->m_threadHandle = CryThreadUtil::CryDuplicateThreadHandle(threadHandle); // Ensure that we are not storing a pseudo handle - pThreadMetaData->m_threadId = CryThreadUtil::CryGetThreadId(pThreadMetaData->m_threadHandle); - - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - // Check for duplicate - SpawnedThirdPartyThreadMapConstIter res = m_spawnedThirdPartyThread.find(sThreadName); - if (res != m_spawnedThirdPartyThread.end()) - { - CryFatalError("CThreadManager::RegisterThirdPartyThread - Unable to register thread \"%s\"" - "because another third party thread with the same name \"%s\" has already been registered with ThreadHandle: %p", - sThreadName, res->second->m_threadName.c_str(), reinterpret_cast(threadHandle)); - - delete pThreadMetaData; - return false; - } - - // Insert thread data - m_spawnedThirdPartyThread.insert(ThirdPartyThreadMapPair(pThreadMetaData->m_threadName.c_str(), pThreadMetaData)); - } - - // Get thread config - const SThreadConfig* pThreadConfig = gEnv->pThreadManager->GetThreadConfigManager()->GetThreadConfig(sThreadName); - - // Apply config (if not default config) - if (strcmp(pThreadConfig->szThreadName, sThreadName) == 0) - { - ApplyThreadConfig(threadHandle, *pThreadConfig); - } - - // Update FP exception mask for 3rd party thread - if (pThreadMetaData->m_threadId) - { - CryThreadUtil::EnableFloatExceptions(pThreadMetaData->m_threadId, (EFPE_Severity)g_cvars.sys_float_exceptions); - } - - return true; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::UnRegisterThirdPartyThread(const char* sThreadName, ...) -{ - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Unregister 3rd party thread - bool ret = UnRegisterThirdPartyThreadImpl(strThreadName); - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadManager::UnRegisterThirdPartyThreadImpl(const char* sThreadName) -{ - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapIter res = m_spawnedThirdPartyThread.find(sThreadName); - if (res == m_spawnedThirdPartyThread.end()) - { - // Duplicate thread deletion - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": UnRegisterThirdPartyThread: Unable to unregister thread. Thread name \"%s\" could not be found. Double deletion? ", sThreadName); - return false; - } - - // Close thread handle - CryThreadUtil::CryCloseThreadHandle(res->second->m_threadHandle); - - // Delete reference from container - m_spawnedThirdPartyThread.erase(res); - return true; -} - -////////////////////////////////////////////////////////////////////////// -threadID CThreadManager::GetThreadId(const char* sThreadName, ...) -{ - va_list args; - va_start(args, sThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Get thread name - threadID ret = GetThreadIdImpl(strThreadName); - - va_end(args); - return ret; -} - -////////////////////////////////////////////////////////////////////////// -threadID CThreadManager::GetThreadIdImpl(const char* sThreadName) -{ - // Loop over internally spawned threads - { - AUTO_LOCK(m_spawnedThreadsLock); - - SpawnedThreadMapConstIter iter = m_spawnedThreads.begin(); - SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadName.compare(sThreadName) == 0) - { - return iter->second->m_threadId; - } - } - } - - // Loop over third party threads - { - AUTO_LOCK(m_spawnedThirdPartyThreadsLock); - - SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin(); - SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end(); - - for (; iter != iterEnd; ++iter) - { - if (iter->second->m_threadName.compare(sThreadName) == 0) - { - return iter->second->m_threadId; - } - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////////////////////////////////////////// -static void EnableFPExceptionsForThread(threadID nThreadId, void* pData) -{ - EFPE_Severity eFPESeverity = *(EFPE_Severity*)pData; - CryThreadUtil::EnableFloatExceptions(nThreadId, eFPESeverity); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId /*=0*/) -{ - CryThreadUtil::EnableFloatExceptions(nThreadId, eFPESeverity); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) -{ - ForEachOtherThread(EnableFPExceptionsForThread, &eFPESeverity); -} - -////////////////////////////////////////////////////////////////////////// -uint CThreadManager::GetFloatingPointExceptionMask() -{ - return CryThreadUtil::GetFloatingPointExceptionMask(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadManager::SetFloatingPointExceptionMask(uint nMask) -{ - CryThreadUtil::SetFloatingPointExceptionMask(nMask); -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::InitThreadSystem() -{ - m_pThreadManager = new CThreadManager(); - m_env.pThreadManager = m_pThreadManager; -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::ShutDownThreadSystem() -{ - SAFE_DELETE(m_pThreadManager); -} diff --git a/Code/CryEngine/CrySystem/SystemWin32.cpp b/Code/CryEngine/CrySystem/SystemWin32.cpp index ce352966ac..eb6aa17532 100644 --- a/Code/CryEngine/CrySystem/SystemWin32.cpp +++ b/Code/CryEngine/CrySystem/SystemWin32.cpp @@ -53,12 +53,8 @@ #endif #include "XConsole.h" -#include "CrySizerStats.h" -#include "CrySizerImpl.h" -#include "StreamEngine/StreamEngine.h" #include "LocalizedStringManager.h" #include "XML/XmlUtils.h" -#include "AutoDetectSpec.h" #if defined(WIN32) __pragma(comment(lib, "wininet.lib")) @@ -66,54 +62,9 @@ __pragma(comment(lib, "Winmm.lib")) #endif #if defined(APPLE) -#include "SystemUtilsApple.h" +#include #endif - - -static AZStd::vector GetModuleNames() -{ - AZStd::vector moduleNames; - if (moduleNames.empty()) - { -# ifdef MODULE_EXTENSION -# error MODULE_EXTENSION already defined! -# endif -# if defined(LINUX) -# define MODULE_EXTENSION ".so" -# elif defined(APPLE) -# define MODULE_EXTENSION ".dylib" -# else -# define MODULE_EXTENSION ".dll" -# endif - - moduleNames.push_back("Cry3DEngine" MODULE_EXTENSION); - moduleNames.push_back("CryFont" MODULE_EXTENSION); - moduleNames.push_back("CrySystem" MODULE_EXTENSION); - -#undef MODULE_EXTENSION - -# if defined(LINUX) - moduleNames.push_back("CryRenderNULL.so"); -# elif defined(APPLE) - moduleNames.push_back("CryRenderNULL.dylib"); -# else - moduleNames.push_back("Editor.exe"); - moduleNames.push_back("CryRenderD3D9.dll"); - moduleNames.push_back("CryRenderD3D10.dll"); - moduleNames.push_back("CryRenderNULL.dll"); - //TODO: launcher? -# endif - } - - return moduleNames; -} - -static bool QueryModuleMemoryInfo([[maybe_unused]] SCryEngineStatsModuleInfo& moduleInfo, [[maybe_unused]] int index) -{ - return false; -} - // this is the list of modules that can be loaded into the game process // Each array element contains 2 strings: the name of the module (case-insensitive) // and the name of the group the module belongs to @@ -158,30 +109,6 @@ void CSystem::SetAffinity() #endif } - - - - -//! dumps the memory usage statistics to the log -////////////////////////////////////////////////////////////////////////// -void CSystem::DumpMemoryUsageStatistics(bool bUseKB) -{ - // CResourceCollector ResourceCollector; - - // TickMemStats(nMSP_ForDump,&ResourceCollector); - TickMemStats(nMSP_ForDump); - - CrySizerStatsRenderer StatsRenderer (this, m_pMemStats, 10, 0); - StatsRenderer.dump(bUseKB); - - // since we've recalculated this mem stats for dumping, we'll want to calculate it anew the next time it's rendered - SAFE_DELETE(m_pMemStats); -} - -// collects the whole memory statistics into the given sizer object -////////////////////////////////////////////////////////////////////////// - - #if defined(WIN32) #pragma pack(push,1) struct PEHeader_DLL @@ -194,175 +121,6 @@ struct PEHeader_DLL #pragma pack(pop) #endif -const SmallModuleInfo* FindModuleInfo(std::vector& vec, const char* name) -{ - for (size_t i = 0; i < vec.size(); ++i) - { - if (!vec[i].name.compareNoCase(name)) - { - return &vec[i]; - } - } - - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CSystem::CollectMemInfo(SCryEngineStatsGlobalMemInfo& m_stats) -{ - m_stats.totalUsedInModules = 0; - m_stats.totalCodeAndStatic = 0; - m_stats.countedMemoryModules = 0; - m_stats.totalAllocatedInModules = 0; - m_stats.totalNumAllocsInModules = 0; - - AZStd::vector szModules = GetModuleNames(); - const int numModules = szModules.size(); - - ////////////////////////////////////////////////////////////////////////// - // Hardcoded value for the OS memory allocation. - ////////////////////////////////////////////////////////////////////////// - for (int i = 0; i < numModules; i++) - { - const char* szModule = szModules[i].c_str(); - - SCryEngineStatsModuleInfo moduleInfo; - ZeroStruct(moduleInfo.memInfo); - moduleInfo.moduleStaticSize = moduleInfo.SizeOfCode = moduleInfo.SizeOfInitializedData = moduleInfo.SizeOfUninitializedData = moduleInfo.usedInModule = 0; - moduleInfo.name = szModule; - - if (!QueryModuleMemoryInfo(moduleInfo, i)) - { - continue; - } - - m_stats.totalNumAllocsInModules += moduleInfo.memInfo.num_allocations; - m_stats.totalAllocatedInModules += moduleInfo.memInfo.allocated; - m_stats.totalUsedInModules += moduleInfo.usedInModule; - m_stats.countedMemoryModules++; - m_stats.totalCodeAndStatic += moduleInfo.moduleStaticSize; - - m_stats.modules.push_back(moduleInfo); - } -} - - -void CSystem::CollectMemStats (ICrySizer* pSizer, MemStatsPurposeEnum nPurpose, std::vector* pStats) -{ - std::vector stats; - if (pStats) - { - pStats->assign(stats.begin(), stats.end()); - } - - if (nMSP_ForCrashLog == nPurpose || nMSP_ForBudget == nPurpose) - { - return; - } - - { - SIZER_COMPONENT_NAME(pSizer, "CrySystem"); - { - pSizer->AddObject(this, sizeof(*this)); - { - //SIZER_COMPONENT_NAME (pSizer, "$Allocations waste"); - //const SmallModuleInfo* info = FindModuleInfo(stats, "CrySystem.dll"); - //if (info) - //pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested ); - } - - { - SIZER_COMPONENT_NAME(pSizer, "VFS"); - if (m_pStreamEngine) - { - SIZER_COMPONENT_NAME(pSizer, "Stream Engine"); - m_pStreamEngine->GetMemoryStatistics(pSizer); - } - } - { - SIZER_COMPONENT_NAME(pSizer, "Localization Data"); - m_pLocalizationManager->GetMemoryUsage(pSizer); - } - { - SIZER_COMPONENT_NAME(pSizer, "XML"); - m_pXMLUtils->GetMemoryUsage(pSizer); - } - if (m_env.pConsole) - { - SIZER_COMPONENT_NAME (pSizer, "Console"); - m_env.pConsole->GetMemoryUsage (pSizer); - } - - if (m_env.pLog) - { - SIZER_COMPONENT_NAME (pSizer, "Log"); - m_env.pLog->GetMemoryUsage(pSizer); - } - } - } - - if (m_env.pRenderer) - { - SIZER_COMPONENT_NAME(pSizer, "CryRenderer"); - { - { - SIZER_COMPONENT_NAME (pSizer, "$Allocations waste D3D9"); - const SmallModuleInfo* info = FindModuleInfo(stats, "CryRenderD3D9.dll"); - if (info) - { - pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested); - } - } - { - SIZER_COMPONENT_NAME (pSizer, "$Allocations waste D3D10"); - const SmallModuleInfo* info = FindModuleInfo(stats, "CryRenderD3D10.dll"); - if (info) - { - pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested); - } - } - - m_env.pRenderer->GetMemoryUsage(pSizer); - } - } - - if (m_env.pCryFont) - { - SIZER_COMPONENT_NAME(pSizer, "CryFont"); - { - { - SIZER_COMPONENT_NAME (pSizer, "$Allocations waste"); - const SmallModuleInfo* info = FindModuleInfo(stats, "CryFont.dll"); - if (info) - { - pSizer->AddObject(info, info->memInfo.allocated - info->memInfo.requested); - } - } - - m_env.pCryFont->GetMemoryUsage(pSizer); - // m_pIFont and m_pIFontUi are both counted in pCryFont sizing if they exist. - // no need to manually add them here. - } - } - - { - SIZER_COMPONENT_NAME(pSizer, "UserData"); - if (m_pUserCallback) - { - m_pUserCallback->GetMemoryUsage(pSizer); - } - } - -#ifdef WIN32 - { - SIZER_COMPONENT_NAME(pSizer, "Code"); - GetExeSizes (pSizer, nPurpose); - } -#endif - - pSizer->End(); -} - ////////////////////////////////////////////////////////////////////////// const char* CSystem::GetUserName() { @@ -460,76 +218,6 @@ int CSystem::GetApplicationLogInstance([[maybe_unused]] const char* logFilePath) #endif } - -// refreshes the m_pMemStats if necessary; creates it if it's not created -////////////////////////////////////////////////////////////////////////// -void CSystem::TickMemStats(MemStatsPurposeEnum nPurpose, IResourceCollector* pResourceCollector) -{ - // gather the statistics, if required - // if there's no object, or if it's time to recalculate, or if it's for dump, then recalculate it - if (!m_pMemStats || (m_env.pRenderer->GetFrameID(false) % m_cvMemStats->GetIVal()) == 0 || nPurpose == nMSP_ForDump) - { - if (!m_pMemStats) - { - if (m_cvMemStats->GetIVal() < 4 && m_cvMemStats->GetIVal()) - { - GetILog()->LogToConsole("memstats is too small (%d). Performance impact can be significant. Please set to a greater value.", m_cvMemStats->GetIVal()); - } - m_pMemStats = new CrySizerStats(); - } - - if (!m_pSizer) - { - m_pSizer = new CrySizerImpl(); - } - - m_pSizer->SetResourceCollector(pResourceCollector); - - m_pMemStats->startTimer(0, GetITimer()); - CollectMemStats (m_pSizer, nPurpose); - m_pMemStats->stopTimer(0, GetITimer()); - - m_pMemStats->startTimer(1, GetITimer()); - CrySizerStatsBuilder builder (m_pSizer); - builder.build (m_pMemStats); - m_pMemStats->stopTimer(1, GetITimer()); - - m_pMemStats->startTimer(2, GetITimer()); - m_pSizer->clear(); - m_pMemStats->stopTimer(2, GetITimer()); - } - else - { - m_pMemStats->incAgeFrames(); - } -} - -//#define __HASXP - -// these 2 functions are duplicated in System.cpp in editor -////////////////////////////////////////////////////////////////////////// -#if !defined(LINUX) -extern int CryStats(char* buf); -#endif -int CSystem::DumpMMStats(bool log) -{ -#if defined(LINUX) - return 0; -#else - if (log) - { - char buf[1024]; - int n = CryStats(buf); - GetILog()->Log(buf); - return n; - } - else - { - return CryStats(NULL); - }; -#endif -}; - ////////////////////////////////////////////////////////////////////////// struct CryDbgModule { @@ -539,273 +227,7 @@ struct CryDbgModule DWORD dwSize; }; -////////////////////////////////////////////////////////////////////////// -void CSystem::DebugStats([[maybe_unused]] bool checkpoint, [[maybe_unused]] bool leaks) -{ #ifdef WIN32 - std::vector dbgmodules; - - ////////////////////////////////////////////////////////////////////////// - // Use windows Performance Monitoring API to enumerate all modules of current process. - ////////////////////////////////////////////////////////////////////////// - HANDLE hSnapshot; - hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); - if (hSnapshot != INVALID_HANDLE_VALUE) - { - MODULEENTRY32 me; - memset (&me, 0, sizeof(me)); - me.dwSize = sizeof(me); - - if (Module32First (hSnapshot, &me)) - { - // the sizes of each module group - do - { - CryDbgModule module; - module.handle = me.hModule; - module.name = me.szModule; - module.dwSize = me.modBaseSize; - dbgmodules.push_back(module); - } while (Module32Next(hSnapshot, &me)); - } - CloseHandle (hSnapshot); - } - ////////////////////////////////////////////////////////////////////////// - - int nolib = 0; - -#ifdef _DEBUG - ILog* log = GetILog(); - int totalal = 0; - int totalbl = 0; - int extrastats[10]; -#endif - - int totalUsedInModules = 0; - int countedMemoryModules = 0; - for (int i = 0; i < (int)(dbgmodules.size()); i++) - { - if (!dbgmodules[i].handle) - { - CryLogAlways("WARNING: CSystem::DebugStats: NULL handle for %s", dbgmodules[i].name.c_str()); - nolib++; - continue; - } - ; - - typedef int (* PFN_MODULEMEMORY)(); - PFN_MODULEMEMORY fpCryModuleGetAllocatedMemory = (PFN_MODULEMEMORY)::GetProcAddress((HMODULE)dbgmodules[i].handle, "CryModuleGetAllocatedMemory"); - if (fpCryModuleGetAllocatedMemory) - { - int allocatedMemory = fpCryModuleGetAllocatedMemory(); - totalUsedInModules += allocatedMemory; - countedMemoryModules++; - CryLogAlways("%8d K used in Module %s: ", allocatedMemory / 1024, dbgmodules[i].name.c_str()); - } - -#ifdef _DEBUG - typedef void (* PFNUSAGESUMMARY)(ILog* log, const char*, int*); - typedef void (* PFNCHECKPOINT)(); - PFNUSAGESUMMARY fpu = (PFNUSAGESUMMARY)::GetProcAddress((HMODULE)dbgmodules[i].handle, "UsageSummary"); - PFNCHECKPOINT fpc = (PFNCHECKPOINT)::GetProcAddress((HMODULE)dbgmodules[i].handle, "CheckPoint"); - if (fpu && fpc) - { - if (checkpoint) - { - fpc(); - } - else - { - extrastats[2] = (int)leaks; - fpu(log, dbgmodules[i].name.c_str(), extrastats); - totalal += extrastats[0]; - totalbl += extrastats[1]; - }; - } - else - { - CryLogAlways("WARNING: CSystem::DebugStats: could not retrieve function from DLL %s", dbgmodules[i].name.c_str()); - nolib++; - }; -#endif - - typedef HANDLE(* PFNGETDLLHEAP)(); - PFNGETDLLHEAP fpg = (PFNGETDLLHEAP)::GetProcAddress((HMODULE)dbgmodules[i].handle, "GetDLLHeap"); - if (fpg) - { - dbgmodules[i].heap = fpg(); - } - ; - } - ; - - CryLogAlways("-------------------------------------------------------"); - CryLogAlways("%8d K Total Memory Allocated in %d Modules", totalUsedInModules / 1024, countedMemoryModules); -#ifdef _DEBUG - CryLogAlways("$8GRAND TOTAL: %d k, %d blocks (%d dlls not included)", totalal / 1024, totalbl, nolib); - CryLogAlways("estimated debugalloc overhead: between %d k and %d k", totalbl * 36 / 1024, totalbl * 72 / 1024); -#endif - - ////////////////////////////////////////////////////////////////////////// - // Get HeapQueryInformation pointer if on windows XP. - ////////////////////////////////////////////////////////////////////////// - typedef BOOL (WINAPI * FUNC_HeapQueryInformation)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T); - FUNC_HeapQueryInformation pFnHeapQueryInformation = NULL; - HMODULE hKernelInstance = CryLoadLibrary("Kernel32.dll"); - if (hKernelInstance) - { - pFnHeapQueryInformation = (FUNC_HeapQueryInformation)(::GetProcAddress(hKernelInstance, "HeapQueryInformation")); - } - ////////////////////////////////////////////////////////////////////////// - - const int MAXHANDLES = 100; - HANDLE handles[MAXHANDLES]; - int realnumh = GetProcessHeaps(MAXHANDLES, handles); - char hinfo[1024]; - PROCESS_HEAP_ENTRY phe; - CryLogAlways("$6--------------------- dump of windows heaps ---------------------"); - int nTotalC = 0, nTotalCP = 0, nTotalUC = 0, nTotalUCP = 0, totalo = 0; - for (int i = 0; i < realnumh; i++) - { - HANDLE hHeap = handles[i]; - HeapCompact(hHeap, 0); - hinfo[0] = 0; - if (pFnHeapQueryInformation) - { - pFnHeapQueryInformation(hHeap, HeapCompatibilityInformation, hinfo, 1024, NULL); - } - else - { - for (int m = 0; m < (int)(dbgmodules.size()); m++) - { - if (dbgmodules[m].heap == handles[i]) - { - azstrcpy(hinfo, AZ_ARRAY_SIZE(hinfo), dbgmodules[m].name.c_str()); - } - } - } - phe.lpData = NULL; - int nCommitted = 0, nUncommitted = 0, nOverhead = 0; - int nCommittedPieces = 0, nUncommittedPieces = 0; -#if !defined(NDEBUG) - int nPrevRegionIndex = -1; -#endif - while (HeapWalk(hHeap, &phe)) - { - if (phe.wFlags & PROCESS_HEAP_REGION) - { - assert (++nPrevRegionIndex == phe.iRegionIndex); - nCommitted += phe.Region.dwCommittedSize; - nUncommitted += phe.Region.dwUnCommittedSize; - assert (phe.cbData == 0 || (phe.wFlags & PROCESS_HEAP_ENTRY_BUSY)); - } - else - if (phe.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) - { - nUncommittedPieces += phe.cbData; - } - else - { - //if (phe.wFlags & PROCESS_HEAP_ENTRY_BUSY) - nCommittedPieces += phe.cbData; - } - - - { - /* - MEMORY_BASIC_INFORMATION mbi; - if (VirtualQuery(phe.lpData, &mbi,sizeof(mbi)) == sizeof(mbi)) - { - if (mbi.State == MEM_COMMIT) - nCommittedPieces += phe.cbData;//mbi.RegionSize; - //else - // nUncommitted += mbi.RegionSize; - } - else - nCommittedPieces += phe.cbData; - */ - } - - nOverhead += phe.cbOverhead; - } - - CryLogAlways("* heap %8x: %6d (or ~%6d) K in use, %6d..%6d K uncommitted, %6d K overhead (%s)\n", - handles[i], nCommittedPieces / 1024, nCommitted / 1024, nUncommittedPieces / 1024, nUncommitted / 1024, nOverhead / 1024, hinfo); - - nTotalC += nCommitted; - nTotalCP += nCommittedPieces; - nTotalUC += nUncommitted; - nTotalUCP += nUncommittedPieces; - totalo += nOverhead; - } - ; - CryLogAlways("$6----------------- total in heaps: %d megs committed (win stats shows ~%d) (%d..%d uncommitted, %d k overhead) ---------------------", nTotalCP / 1024 / 1024, nTotalC / 1024 / 1024, nTotalUCP / 1024 / 1024, nTotalUC / 1024 / 1024, totalo / 1024); - -#endif //WIN32 -}; - -#ifdef WIN32 -struct DumpHeap32Stats -{ - DumpHeap32Stats() - : dwFree(0) - , dwMoveable(0) - , dwFixed(0) - , dwUnknown(0) - { - } - void operator += (const DumpHeap32Stats& right) - { - dwFree += right.dwFree; - dwMoveable += right.dwMoveable; - dwFixed += right.dwFixed; - dwUnknown += right.dwUnknown; - } - DWORD dwFree; - DWORD dwMoveable; - DWORD dwFixed; - DWORD dwUnknown; -}; -static void DumpHeap32 (const HEAPLIST32& hl, DumpHeap32Stats& stats) -{ - HEAPENTRY32 he; - memset (&he, 0, sizeof(he)); - he.dwSize = sizeof(he); - - if (Heap32First (&he, hl.th32ProcessID, hl.th32HeapID)) - { - DumpHeap32Stats heap; - do - { - if (he.dwFlags & LF32_FREE) - { - heap.dwFree += he.dwBlockSize; - } - else - if (he.dwFlags & LF32_MOVEABLE) - { - heap.dwMoveable += he.dwBlockSize; - } - else - if (he.dwFlags & LF32_FIXED) - { - heap.dwFixed += he.dwBlockSize; - } - else - { - heap.dwUnknown += he.dwBlockSize; - } - } while (Heap32Next (&he)); - - CryLogAlways ("%08X %6d %6d %6d (%d)", hl.th32HeapID, heap.dwFixed / 0x400, heap.dwFree / 0x400, heap.dwMoveable / 0x400, heap.dwUnknown / 0x400); - stats += heap; - } - else - { - CryLogAlways ("%08X empty or invalid"); - } -} - ////////////////////////////////////////////////////////////////////////// class CStringOrder { @@ -839,141 +261,8 @@ const char* GetModuleGroup (const char* szString) return "Other"; } -////////////////////////////////////////////////////////////////////////// -void CSystem::GetExeSizes (ICrySizer* pSizer, MemStatsPurposeEnum nPurpose) -{ - HANDLE hSnapshot; - hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - CryLogAlways ("Cannot get the module snapshot, error code %d", GetLastError()); - return; - } - - DWORD dwProcessID = GetCurrentProcessId(); - - MODULEENTRY32 me; - memset (&me, 0, sizeof(me)); - me.dwSize = sizeof(me); - - if (Module32First (hSnapshot, &me)) - { - // the sizes of each module group - StringToSizeMap mapGroupSize; - do - { - dwProcessID = me.th32ProcessID; - const char* szGroup = GetModuleGroup (me.szModule); - SIZER_COMPONENT_NAME(pSizer, szGroup); - if (nPurpose == nMSP_ForDump) - { - SIZER_COMPONENT_NAME(pSizer, me.szModule); - pSizer->AddObject(me.modBaseAddr, me.modBaseSize); - } - else - { - pSizer->AddObject(me.modBaseAddr, me.modBaseSize); - } - } while (Module32Next(hSnapshot, &me)); - } - else - { - CryLogAlways ("No modules to dump"); - } - - CloseHandle (hSnapshot); -} - #endif -////////////////////////////////////////////////////////////////////////// -void CSystem::DumpWinHeaps() -{ -#ifdef WIN32 - // - // Retrieve modules and log them; remember the process id - - HANDLE hSnapshot; - hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - CryLogAlways ("Cannot get the module snapshot, error code %d", GetLastError()); - return; - } - - DWORD dwProcessID = GetCurrentProcessId(); - - MODULEENTRY32 me; - memset (&me, 0, sizeof(me)); - me.dwSize = sizeof(me); - - if (Module32First (hSnapshot, &me)) - { - // the sizes of each module group - StringToSizeMap mapGroupSize; - DWORD dwTotalModuleSize = 0; - CryLogAlways ("base size module"); - do - { - dwProcessID = me.th32ProcessID; - const char* szGroup = GetModuleGroup (me.szModule); - CryLogAlways ("%08X %8X %25s - %s", me.modBaseAddr, me.modBaseSize, me.szModule, azstricmp(szGroup, "Other") ? szGroup : ""); - dwTotalModuleSize += me.modBaseSize; - AddSize (mapGroupSize, szGroup, me.modBaseSize); - } while (Module32Next(hSnapshot, &me)); - - CryLogAlways ("------------------------------------"); - for (StringToSizeMap::iterator it = mapGroupSize.begin(); it != mapGroupSize.end(); ++it) - { - CryLogAlways (" %6.3f Mbytes - %s", double(it->second) / 0x100000, it->first); - } - CryLogAlways ("------------------------------------"); - CryLogAlways (" %6.3f Mbytes - TOTAL", double(dwTotalModuleSize) / 0x100000); - CryLogAlways ("------------------------------------"); - } - else - { - CryLogAlways ("No modules to dump"); - } - - CloseHandle (hSnapshot); - - // - // Retrieve the heaps and dump each of them with a special function - - hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) - { - CryLogAlways ("Cannot get the heap LIST snapshot, error code %d", GetLastError()); - return; - } - - HEAPLIST32 hl; - memset (&hl, 0, sizeof(hl)); - hl.dwSize = sizeof(hl); - - CryLogAlways ("__Heap__ fixed free move (unknown)"); - if (Heap32ListFirst (hSnapshot, &hl)) - { - DumpHeap32Stats stats; - do - { - DumpHeap32 (hl, stats); - } while (Heap32ListNext (hSnapshot, &hl)); - - CryLogAlways ("-------------------------------------------------"); - CryLogAlways ("$6 %6.3f %6.3f %6.3f (%.3f) Mbytes", double(stats.dwFixed) / 0x100000, double(stats.dwFree) / 0x100000, double(stats.dwMoveable) / 0x100000, double(stats.dwUnknown) / 0x100000); - CryLogAlways ("-------------------------------------------------"); - } - else - { - CryLogAlways ("No heaps to dump"); - } - - CloseHandle(hSnapshot); -#endif -} - // Make system error message string ////////////////////////////////////////////////////////////////////////// //! \return pointer to the null terminated error string or 0 @@ -1059,31 +348,16 @@ void CSystem::FatalError(const char* format, ...) assert(szBuffer[0] >= ' '); // strcpy(szBuffer,szBuffer+1); // remove verbosity tag since it is not supported by ::MessageBox - LogSystemInfo(); - - CollectMemStats(0, nMSP_ForCrashLog); - OutputDebugString(szBuffer); #ifdef WIN32 OnFatalError(szBuffer); if (!g_cvars.sys_no_crash_dialog) { - ICVar* pFullscreen = (gEnv && gEnv->pConsole) ? gEnv->pConsole->GetCVar("r_Fullscreen") : 0; - if (pFullscreen && pFullscreen->GetIVal() != 0 && gEnv->pRenderer && gEnv->pRenderer->GetHWND()) - { - ::ShowWindow((HWND)gEnv->pRenderer->GetHWND(), SW_MINIMIZE); - } ::MessageBox(NULL, szBuffer, "Open 3D Engine Error", MB_OK | MB_ICONERROR | MB_SYSTEMMODAL); } // Dump callstack. -#endif -#if defined (WIN32) - //Triggers a fatal error, so the DebugCallstack can create the error.log and terminate the application IDebugCallStack::instance()->FatalError(szBuffer); -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION SYSTEMWIN32_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(SystemWin32_cpp) #endif CryDebugBreak(); @@ -1169,12 +443,6 @@ void CSystem::debug_LogCallStack(int nMaxFuncs, [[maybe_unused]] int nFlags) // Print call stack for each find. const char* funcs[32]; int nCount = nMaxFuncs; - int nCurFrame = 0; - if (m_env.pRenderer) - { - nCurFrame = (int)m_env.pRenderer->GetFrameID(false); - } - CryLogAlways(" ----- CallStack (Frame: %d) -----", nCurFrame); GetISystem()->debug_GetCallStack(funcs, nCount); for (int i = 1; i < nCount; i++) // start from 1 to skip this function. { @@ -1221,150 +489,6 @@ bool CSystem::ReLaunchMediaCenter() } #endif //defined(WIN32) -////////////////////////////////////////////////////////////////////////// -#if defined(WIN32) -void CSystem::LogSystemInfo() -{ - ////////////////////////////////////////////////////////////////////// - // Write the system informations to the log - ////////////////////////////////////////////////////////////////////// - - char szBuffer[1024]; - char szProfileBuffer[128]; - char szLanguageBuffer[64]; - //char szCPUModel[64]; - - MEMORYSTATUSEX MemoryStatus; - MemoryStatus.dwLength = sizeof(MemoryStatus); - - DEVMODE DisplayConfig; - OSVERSIONINFO OSVerInfo; - OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - - // log Windows type - Win32SysInspect::GetOS(m_env.pi.winVer, m_env.pi.win64Bit, szBuffer, sizeof(szBuffer)); - CryLogAlways(szBuffer); - - // log system language - GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, szLanguageBuffer, sizeof(szLanguageBuffer)); - azsprintf(szBuffer, "System language: %s", szLanguageBuffer); - CryLogAlways(szBuffer); - - // log Windows directory - GetWindowsDirectory(szBuffer, sizeof(szBuffer)); - string str = "Windows Directory: \""; - str += szBuffer; - str += "\""; - CryLogAlways(str); - - ////////////////////////////////////////////////////////////////////// - // Send system time & date - ////////////////////////////////////////////////////////////////////// - - str = "Local time is "; - azstrtime(szBuffer); - str += szBuffer; - str += " "; - _strdate_s(szBuffer); - str += szBuffer; - azsprintf(szBuffer, ", system running for %lu minutes", GetTickCount() / 60000); - str += szBuffer; - CryLogAlways(str); - - ////////////////////////////////////////////////////////////////////// - // Send system memory status - ////////////////////////////////////////////////////////////////////// - - GlobalMemoryStatusEx(&MemoryStatus); - azsprintf(szBuffer, "%I64dMB physical memory installed, %I64dMB available, %I64dMB virtual memory installed, %ld percent of memory in use", - MemoryStatus.ullTotalPhys / 1048576 + 1, - MemoryStatus.ullAvailPhys / 1048576, - MemoryStatus.ullTotalVirtual / 1048576, - MemoryStatus.dwMemoryLoad); - CryLogAlways(szBuffer); - - if (GetISystem()->GetIMemoryManager()) - { - IMemoryManager::SProcessMemInfo memCounters; - GetISystem()->GetIMemoryManager()->GetProcessMemInfo(memCounters); - - uint64 PagefileUsage = memCounters.PagefileUsage; - uint64 PeakPagefileUsage = memCounters.PeakPagefileUsage; - uint64 WorkingSetSize = memCounters.WorkingSetSize; - azsprintf(szBuffer, "PageFile usage: %I64dMB, Working Set: %I64dMB, Peak PageFile usage: %I64dMB,", - (uint64)PagefileUsage / (1024 * 1024), - (uint64)WorkingSetSize / (1024 * 1024), - (uint64)PeakPagefileUsage / (1024 * 1024)); - CryLogAlways(szBuffer); - } - - ////////////////////////////////////////////////////////////////////// - // Send display settings - ////////////////////////////////////////////////////////////////////// - - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DisplayConfig); - GetPrivateProfileString("boot.description", "display.drv", - "(Unknown graphics card)", szProfileBuffer, sizeof(szProfileBuffer), - "system.ini"); - azsprintf(szBuffer, "Current display mode is %lux%lux%lu, %s", - DisplayConfig.dmPelsWidth, DisplayConfig.dmPelsHeight, - DisplayConfig.dmBitsPerPel, szProfileBuffer); - CryLogAlways(szBuffer); - - ////////////////////////////////////////////////////////////////////// - // Send input device configuration - ////////////////////////////////////////////////////////////////////// - - str = ""; - // Detect the keyboard type - switch (GetKeyboardType(0)) - { - case 1: - str = "IBM PC/XT (83-key)"; - break; - case 2: - str = "ICO (102-key)"; - break; - case 3: - str = "IBM PC/AT (84-key)"; - break; - case 4: - str = "IBM enhanced (101/102-key)"; - break; - case 5: - str = "Nokia 1050"; - break; - case 6: - str = "Nokia 9140"; - break; - case 7: - str = "Japanese"; - break; - default: - str = "Unknown"; - break; - } - - // Any mouse attached ? - if (!GetSystemMetrics(SM_MOUSEPRESENT)) - { - CryLogAlways(str + " keyboard and no mouse installed"); - } - else - { - azsprintf(szBuffer, " keyboard and %i+ button mouse installed", - GetSystemMetrics(SM_CMOUSEBUTTONS)); - CryLogAlways(str + szBuffer); - } - - CryLogAlways("--------------------------------------------------------------------------------"); -} -#else -void CSystem::LogSystemInfo() -{ -} -#endif - #if (defined(WIN32) || defined(WIN64)) ////////////////////////////////////////////////////////////////////////// bool CSystem::GetWinGameFolder(char* szMyDocumentsPath, int maxPathSize) diff --git a/Code/CryEngine/CrySystem/Tests/Test_CLog.cpp b/Code/CryEngine/CrySystem/Tests/Test_CLog.cpp deleted file mode 100644 index e792ba095f..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_CLog.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" - -#include -#include - -#include -#include - -#include // for max path decl -#include -#include -#include -#include - -namespace CLogUnitTests -{ - using ::testing::NiceMock; - using ::testing::_; - using ::testing::Return; - - // for fuzzing test, how much work to do? Not much, as this must be fast. - const int NumTrialsToPerform = 16000; - - class CLogUnitTests - : public ::testing::Test - { - public: - - using CryPrimitivesAllocatorScope = AZ::AllocatorScope; - - void SetUp() override - { - m_primitiveAllocators.ActivateAllocators(); - - m_priorEnv = gEnv; - m_priorFileIO = AZ::IO::FileIOBase::GetInstance(); - m_priorDirectFileIO = AZ::IO::FileIOBase::GetDirectInstance(); - - m_data = AZStd::make_unique(); - m_data->m_stubEnv.pSystem = &m_data->m_system; - - gEnv = &m_data->m_stubEnv; - - // for FileIO, you must set the instance to null before changing it. - // this is a way to tell the singleton system that you mean to replace a singleton and its - // not a mistake. - AZ::IO::FileIOBase::SetInstance(nullptr); - AZ::IO::FileIOBase::SetInstance(&m_data->m_fileIOMock); - AZ::IO::FileIOBase::SetDirectInstance(nullptr); - AZ::IO::FileIOBase::SetDirectInstance(&m_data->m_fileIOMock); - - ON_CALL(m_data->m_system, GetIRemoteConsole()) - .WillByDefault( - Return(&m_data->m_remoteConsoleMock)); - - AZ::IO::MockFileIOBase::InstallDefaultReturns(m_data->m_fileIOMock); - } - - void TearDown() override - { - AZ::IO::FileIOBase::SetInstance(nullptr); - AZ::IO::FileIOBase::SetInstance(m_priorFileIO); - AZ::IO::FileIOBase::SetDirectInstance(nullptr); - AZ::IO::FileIOBase::SetDirectInstance(m_priorDirectFileIO); - - m_data.reset(); - - // restore state. - gEnv = m_priorEnv; - m_primitiveAllocators.DeactivateAllocators(); - } - - struct DataMembers - { - SSystemGlobalEnvironment m_stubEnv; - NiceMock m_system; - NiceMock m_fileIOMock; - NiceMock m_remoteConsoleMock; - }; - - AZStd::unique_ptr m_data; - SSystemGlobalEnvironment* m_priorEnv = nullptr; - ISystem* m_priorSystem = nullptr; - AZ::IO::FileIOBase* m_priorFileIO = nullptr; - AZ::IO::FileIOBase* m_priorDirectFileIO = nullptr; - CryPrimitivesAllocatorScope m_primitiveAllocators; - }; - - TEST_F(CLogUnitTests, LogAlways_InvalidString_Asserts) - { - AZ_TEST_START_TRACE_SUPPRESSION; - CLog testLog(&m_data->m_system); - testLog.LogAlways(nullptr); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - TEST_F(CLogUnitTests, LogAlways_EmptyString_IgnoresWithoutCrashing) - { - CLog testLog(&m_data->m_system); - testLog.LogAlways(""); - } - - TEST_F(CLogUnitTests, LogAlways_NormalString_NoFileName_DoesNotCrash) - { - CLog testLog(&m_data->m_system); - testLog.LogAlways("test"); - } - - TEST_F(CLogUnitTests, LogAlways_SetFileName_Empty_DoesNotCrash) - { - CLog testLog(&m_data->m_system); - testLog.SetFileName("", false); - testLog.LogAlways("test"); - } - -#if AZ_TRAIT_DISABLE_LOG_ALWAYS_FUZZ_TEST - TEST_F(CLogUnitTests, DISABLED_LogAlways_FuzzTest) -#else - TEST_F(CLogUnitTests, LogAlways_FuzzTest) -#endif // AZ_TRAIT_DISABLE_LOG_ALWAYS_FUZZ_TEST - { - CLog testLog(&m_data->m_system); - AZStd::string randomJunkName; - - randomJunkName.resize(128, '\0'); - - // expect the mock to repeatedly get called. If we fail this expectation - // it means the code is early-outing somewhere and we are not getting coverage. - EXPECT_CALL(m_data->m_fileIOMock, Write(_, _, _, _)) - .WillRepeatedly( - Return(AZ::IO::Result(AZ::IO::ResultCode::Success))); - - // don't rely on randomness in unit tests, they need to be repeatable. - // the following random generator is not seeded by the time, but by a constant (default 1234). - AZ::SimpleLcgRandom randGen; - - for (int trialNumber = 0; trialNumber < NumTrialsToPerform; ++trialNumber) - { - for (int randomChar = 0; randomChar < randomJunkName.size(); ++randomChar) - { - // note that this is intentionally allowing null characters to generate. - // note that this also puts characters AFTER the null, if a null appears in the mddle. - // so that if there are off by one errors they could include cruft afterwards. - - if (randomChar > trialNumber % randomJunkName.size()) - { - // choose this point for the nulls to begin. It makes sure we test every size of string. - randomJunkName[randomChar] = 0; - } - else - { - randomJunkName[randomChar] = (char)(randGen.GetRandom() % 256); // this will trigger invalid UTF8 decoding too - } - } - testLog.LogAlways("%s", randomJunkName.c_str()); - } - } - - TEST_F(CLogUnitTests, LogAlways_SetFileName_Correct_DoesNotCrash_WritesToFile) - { - CLog testLog(&m_data->m_system); - testLog.SetFileName("logfile.log", false); - - // EXPECT a call to the file system - if we dont get a call here, it means something went wrong. - // it also expects exactly one call to write. One call to log should be one call to write, - // or else performance will suffer. - - EXPECT_CALL(m_data->m_fileIOMock, Write(_, _, _, _)) - .WillOnce( - Return(AZ::IO::Result(AZ::IO::ResultCode::Success))); - - testLog.LogAlways("test"); - } -} // end namespace CLogUnitTests - - diff --git a/Code/CryEngine/CrySystem/Tests/Test_CommandRegistration.cpp b/Code/CryEngine/CrySystem/Tests/Test_CommandRegistration.cpp deleted file mode 100644 index d54ba87446..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_CommandRegistration.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" - -#include - -#include - -#include -#include -#include -#include - -#include - -namespace UnitTests -{ - class RemoteConsoleMock - : public IRemoteConsole - { - public: - MOCK_METHOD0(RegisterConsoleVariables, void()); - MOCK_METHOD0(UnregisterConsoleVariables, void()); - MOCK_METHOD0(Start, void()); - MOCK_METHOD0(Stop, void()); - MOCK_CONST_METHOD0(IsStarted, bool()); - MOCK_METHOD1(AddLogMessage, void(const char*)); - MOCK_METHOD1(AddLogWarning, void(const char*)); - MOCK_METHOD1(AddLogError, void(const char*)); - MOCK_METHOD0(Update, void()); - MOCK_METHOD2(RegisterListener, void(IRemoteConsoleListener*, const char*)); - MOCK_METHOD1(UnregisterListener, void(IRemoteConsoleListener*)); - }; - - struct TestTraceMessageCapture - : public AZ::Debug::TraceMessageBus::Handler - { - using Callback = AZStd::function; - Callback m_callback; - - TestTraceMessageCapture() - { - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - } - - ~TestTraceMessageCapture() - { - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - - bool OnError(const char* window, const char* message) override - { - if (m_callback) - { - m_callback(window, message); - } - return false; - } - - bool OnWarning(const char* window, const char* message) override - { - if (m_callback) - { - m_callback(window, message); - } - return false; - } - }; - - using SystemAllocatorScope = AZ::AllocatorScope; - - struct CommandRegistrationUnitTests - : public ::testing::Test - , public SystemAllocatorScope - { - CommandRegistrationUnitTests() - { - EXPECT_CALL(m_system, GetIRemoteConsole()) - .WillRepeatedly(::testing::Return(&m_remoteConsole)); - } - - void SetUp() override - { - SystemAllocatorScope::ActivateAllocators(); - - memset(&m_stubEnv, 0, sizeof(SSystemGlobalEnvironment)); - m_stubEnv.pSystem = &m_system; - m_priorEnv = gEnv; - gEnv = &m_stubEnv; - - // now it safe to set up the console - m_console = AZStd::make_unique(); - m_stubEnv.pConsole = m_console.get(); - - EXPECT_CALL(m_system, GetIConsole()) - .WillRepeatedly(::testing::Return(m_stubEnv.pConsole)); - } - - void TearDown() override - { - m_console.reset(); - gEnv = m_priorEnv; - SystemAllocatorScope::DeactivateAllocators(); - } - - ::testing::NiceMock m_system; - ::testing::NiceMock m_remoteConsole; - AZStd::unique_ptr m_console; - SSystemGlobalEnvironment m_stubEnv; - SSystemGlobalEnvironment* m_priorEnv = nullptr; - }; - - TEST_F(CommandRegistrationUnitTests, RegisterUnregisterTest) - { - using namespace AzFramework; - - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "foo", "", 0, [](const AZStd::vector&) -> CommandResult - { - return CommandResult::Success; - }); - EXPECT_TRUE(result); - } - - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "foo"); - EXPECT_TRUE(result); - } - } - - TEST_F(CommandRegistrationUnitTests, RegisterUnregisterNegativeTest) - { - using namespace AzFramework; - - // register too many times - { - auto fnFoo = [](const AZStd::vector&) -> CommandResult - { - return CommandResult::Success; - }; - - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "foo", "", 0, fnFoo); - EXPECT_TRUE(result); - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "foo", "", 0, fnFoo); - EXPECT_FALSE(result); - } - - // unregister too many times - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "foo"); - EXPECT_TRUE(result); - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "foo"); - EXPECT_FALSE(result); - } - - // a null callback should fail - { - AZ_TEST_START_TRACE_SUPPRESSION; - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "shouldfail", "", 0, nullptr); - EXPECT_FALSE(result); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - - // a null identifier should fail - { - AZ_TEST_START_TRACE_SUPPRESSION; - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "", "", 0, nullptr); - EXPECT_FALSE(result); - AZ_TEST_STOP_TRACE_SUPPRESSION(1); - } - } - - TEST_F(CommandRegistrationUnitTests, DoCallback) - { - using namespace AzFramework; - - int count = 0; - - { - auto fnCommand = [&count](const AZStd::vector&) -> CommandResult - { - ++count; - return CommandResult::Success; - }; - - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "bar", "bar docs", CommandFlags::Development, fnCommand); - EXPECT_TRUE(result); - } - - const bool bSilentMode = true; - const bool bDeferExecution = false; - m_console->ExecuteString("bar", bSilentMode, bDeferExecution); - EXPECT_EQ(1, count); - - { - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "bar"); - EXPECT_TRUE(result); - } - } - - TEST_F(CommandRegistrationUnitTests, DoCallbackNegativeTests) - { - using namespace AzFramework; - - bool result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::RegisterCommand, "bar", "", 0, [](const AZStd::vector& args) - { - if (args.size() > 1) - { - return CommandResult::ErrorWrongNumberOfArguments; - } - return CommandResult::Error; - }); - EXPECT_TRUE(result); - - const bool bSilentMode = true; - const bool bDeferExecution = false; - - // general error - { - int found = 0; - TestTraceMessageCapture capture; - capture.m_callback = [&found](const char* window, const char* message) - { - if (azstrnicmp(window, "console", AZ_ARRAY_SIZE("console") - 1) == 0) - { - if (azstrnicmp(message, "Command returned a generic error\n", AZ_ARRAY_SIZE("Command returned a generic error\n") - 1) == 0) - { - ++found; - } - } - }; - m_console->ExecuteString("bar", bSilentMode, bDeferExecution); - EXPECT_EQ(1, found); - } - - // too many args - { - int found = 0; - TestTraceMessageCapture capture; - capture.m_callback = [&found](const char* window, const char* message) - { - if (azstrnicmp(window, "console", AZ_ARRAY_SIZE("console") - 1) == 0) - { - if (azstrnicmp(message, "Command does not have the right number of arguments (send = 4)\n", AZ_ARRAY_SIZE("Command does not have the right number of arguments (send = 4)\n") - 1) == 0) - { - ++found; - } - } - }; - m_console->ExecuteString("bar 1 2 3", bSilentMode, bDeferExecution); - EXPECT_EQ(1, found); - } - - // clean up - { - result = false; - CommandRegistrationBus::BroadcastResult(result, &CommandRegistrationBus::Events::UnregisterCommand, "bar"); - EXPECT_TRUE(result); - } - } - -} // namespace UnitTests - - diff --git a/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp b/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp deleted file mode 100644 index 2e6e646548..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_CryPrimitives.cpp +++ /dev/null @@ -1,479 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include -#include - -TEST(StringTests, CUT_Strings) -{ - bool bOk; - char bf[4]; - - // cry_strcpy() - - bOk = cry_strcpy(0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, 0, 1); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, ""); - EXPECT_TRUE(!bOk); - - bOk = cry_strcpy(0, 1, "", 1); - EXPECT_TRUE(!bOk); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 0, ""); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 0, "", 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 1, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 1, 0, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty"); - EXPECT_TRUE(!bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 3); - EXPECT_TRUE(!bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 2); - EXPECT_TRUE(bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "q\000cd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, 3, "qwerty", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty"); - EXPECT_TRUE(!bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty", 3); - EXPECT_TRUE(bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwerty", 2); - EXPECT_TRUE(bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwe"); - EXPECT_TRUE(bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qwe", 4); - EXPECT_TRUE(bOk && !memcmp(bf, "qwe\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, "qw", 3); - EXPECT_TRUE(bOk && !memcmp(bf, "qw\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, sizeof(bf), "q"); - EXPECT_TRUE(bOk && !memcmp(bf, "q\000cd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcpy(bf, sizeof(bf), "q", 2); - EXPECT_TRUE(bOk && !memcmp(bf, "q\000cd", 4)); - - // cry_strcat() - - bOk = cry_strcat(0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 0, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, 0, 0); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, ""); - EXPECT_TRUE(!bOk); - - bOk = cry_strcat(0, 1, "", 1); - EXPECT_TRUE(!bOk); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 0, "xy"); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 0, "xy", 3); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 0, "xy", 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "abcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz", 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, "xyz", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, 1, 0, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "\000bcd", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz", 2); - EXPECT_TRUE(!bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, 3, "xyz", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "ax\000d", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz", 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "abcd", 4); - bOk = cry_strcat(bf, "xyz", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "abc\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz"); - EXPECT_TRUE(!bOk && !memcmp(bf, "abx\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz", 4); - EXPECT_TRUE(!bOk && !memcmp(bf, "abx\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "abx\000", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, "xyz", 0); - EXPECT_TRUE(bOk && !memcmp(bf, "ab\000d", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, 0, 0); - EXPECT_TRUE(!bOk && !memcmp(bf, "ab\000d", 4)); - - memcpy(bf, "ab\000d", 4); - bOk = cry_strcat(bf, 0, 1); - EXPECT_TRUE(!bOk && !memcmp(bf, "ab\000d", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, sizeof(bf), "xy"); - EXPECT_TRUE(bOk && !memcmp(bf, "axy\000", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, sizeof(bf), "xy", 3); - EXPECT_TRUE(bOk && !memcmp(bf, "axy\000", 4)); - - memcpy(bf, "a\000cd", 4); - bOk = cry_strcat(bf, sizeof(bf), "xy", 1); - EXPECT_TRUE(bOk && !memcmp(bf, "ax\000d", 4)); -} - -using CryPrimitivesAllocatorScope = AZ::AllocatorScope; - -class CryPrimitives - : public ::testing::Test -{ -public: - void SetUp() override - { - m_memory.ActivateAllocators(); - } - - void TearDown() override - { - m_memory.DeactivateAllocators(); - } - - CryPrimitivesAllocatorScope m_memory; -}; - -TEST_F(CryPrimitives, CUT_CryString) -{ - ////////////////////////////////////////////////////////////////////////// - // Based on MS documentation of find_last_of - string strTestFindLastOfOverload1("abcd-1234-abcd-1234"); - string strTestFindLastOfOverload2("ABCD-1234-ABCD-1234"); - string strTestFindLastOfOverload3("456-EFG-456-EFG"); - string strTestFindLastOfOverload4("12-ab-12-ab"); - - const char* cstr2 = "B1"; - const char* cstr2b = "D2"; - const char* cstr3a = "5E"; - string str4a("ba3"); - string str4b("a2"); - - size_t nPosition(string::npos); - - nPosition = strTestFindLastOfOverload1.find_last_of('d', 14); - EXPECT_TRUE(nPosition == 13); - - - nPosition = strTestFindLastOfOverload2.find_last_of(cstr2, 12); - EXPECT_TRUE(nPosition == 11); - - - nPosition = strTestFindLastOfOverload2.find_last_of(cstr2b); - EXPECT_TRUE(nPosition == 16); - - - nPosition = strTestFindLastOfOverload3.find_last_of(cstr3a, 8, 2); - EXPECT_TRUE(nPosition == 4); - - - nPosition = strTestFindLastOfOverload4.find_last_of(str4a, 8); - EXPECT_TRUE(nPosition == 4); - - - nPosition = strTestFindLastOfOverload4.find_last_of(str4b); - EXPECT_TRUE(nPosition == 9); - - ////////////////////////////////////////////////////////////////////////// - // Based on MS documentation of find_last_not_of - string strTestFindLastNotOfOverload1("dddd-1dd4-abdd"); - string strTestFindLastNotOfOverload2("BBB-1111"); - string strTestFindLastNotOfOverload3("444-555-GGG"); - string strTestFindLastNotOfOverload4("12-ab-12-ab"); - - const char* cstr2NF = "B1"; - const char* cstr3aNF = "45G"; - const char* cstr3bNF = "45G"; - - string str4aNF("b-a"); - string str4bNF("12"); - - nPosition = strTestFindLastNotOfOverload1.find_last_not_of('d', 7); - EXPECT_TRUE(nPosition == 5); - - nPosition = strTestFindLastNotOfOverload1.find_last_not_of("d"); - EXPECT_TRUE(nPosition == 11); - - nPosition = strTestFindLastNotOfOverload2.find_last_not_of(cstr2NF, 6); - EXPECT_TRUE(nPosition == 3); - - nPosition = strTestFindLastNotOfOverload3.find_last_not_of(cstr3aNF); - EXPECT_TRUE(nPosition == 7); - - nPosition = strTestFindLastNotOfOverload3.find_last_not_of(cstr3bNF, 6, 3);//nPosition - 1 ); - EXPECT_TRUE(nPosition == 3); - - nPosition = strTestFindLastNotOfOverload4.find_last_not_of(str4aNF, 5); - EXPECT_TRUE(nPosition == 1); - - nPosition = strTestFindLastNotOfOverload4.find_last_not_of(str4bNF); - EXPECT_TRUE(nPosition == 10); -} - - -TEST_F(CryPrimitives, CUT_FixedString) -{ - CryStackStringT str1; - CryStackStringT str2; - CryStackStringT str3; - CryStackStringT str4; - CryStackStringT str5; - CryStackStringT wstr1; - CryStackStringT wstr2; - CryFixedStringT<100> fixedString100; - CryFixedStringT<200> fixedString200; - - typedef CryStackStringT T; - T* pStr = new T; - *pStr = "adads"; - delete pStr; - - str1 = "abcd"; - EXPECT_EQ(str1, "abcd"); - - str2 = "efg"; - EXPECT_EQ(str2, "efg"); - - str2 = str1; - EXPECT_EQ(str2, "abcd"); - - str1 += "XY"; - EXPECT_EQ(str1, "abcdXY"); - - str2 += "efghijk"; - EXPECT_EQ(str2, "abcdefghijk"); - - str1.replace("bc", ""); - EXPECT_EQ(str1, "adXY"); - - str1.replace("XY", "1234"); - EXPECT_EQ(str1, "ad1234"); - - str1.replace("1234", "1234567890"); - EXPECT_EQ(str1, "ad1234567890"); - - str1.reserve(200); - EXPECT_EQ(str1, "ad1234567890"); - EXPECT_TRUE(str1.capacity() == 200); - - str1.reserve(0); - EXPECT_EQ(str1, "ad1234567890"); - EXPECT_TRUE(str1.capacity() == str1.length()); - - str1.erase(7); // doesn't change capacity - EXPECT_EQ(str1, "ad12345"); - - str4.assign("abc"); - EXPECT_EQ(str4, "abc"); - str4.reserve(9); - EXPECT_TRUE(str4.capacity() >= 9); // capacity is always >= MAX_SIZE-1 - str4.reserve(0); - EXPECT_TRUE(str4.capacity() >= 9); // capacity is always >= MAX_SIZE-1 - - size_t idx = str1.find("123"); - EXPECT_TRUE(idx == 2); - - idx = str1.find("123", 3); - EXPECT_TRUE(idx == str1.npos); - - wstr1 = L"abc"; - EXPECT_EQ(wstr1, L"abc"); - EXPECT_TRUE(wstr1.compare(L"aBc") > 0); - EXPECT_TRUE(wstr1.compare(L"babc") < 0); - EXPECT_TRUE(wstr1.compareNoCase(L"aBc") == 0); - - str1.Format("This is a %s %ls with %d params", "mixed", L"string", 3); - str2.Format("This is a %ls %s with %d params", L"mixed", "string", 3); - EXPECT_EQ(str1, "This is a mixed string with 3 params"); - EXPECT_EQ(str1, str2); - - wstr1.Format(L"This is a %ls %hs with %d params", L"mixed", "string", 3); - wstr2.Format(L"This is a %hs %ls with %d params", "mixed", L"string", 3); - EXPECT_EQ(wstr1, L"This is a mixed string with 3 params"); - - str5.FormatFast("%s", "12345"); - EXPECT_EQ("1234", str5); - - // we expect here that the string gets cut since it doesn't fit into the string buffer - str5.FormatFast("%s", "012345"); - EXPECT_EQ("0123", str5); -} - -////////////////////////////////////////////////////////////////////////// -// Unit Testing of aligned_vector -////////////////////////////////////////////////////////////////////////// -TEST_F(CryPrimitives, CUT_AlignedVector) -{ - stl::aligned_vector vec; - - vec.push_back(1); - vec.push_back(2); - vec.push_back(3); - - EXPECT_TRUE(vec.size() == 3); - EXPECT_TRUE(((INT_PTR)(&vec[0]) % 16) == 0); -} - -TEST_F(CryPrimitives, CUT_DynArray) -{ - LegacyDynArray a; - a.push_back(3); - a.insert(&a[0], 1, 1); - a.insert(&a[1], 1, 2); - a.insert(&a[0], 1, 0); - - for (int i = 0; i < 4; i++) - { - EXPECT_TRUE(a[i] == i); - } - - const int nStrs = 11; - string Strs[nStrs] = { "nought", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" }; - LegacyDynArray s; - for (int i = 0; i < nStrs; i += 2) - { - s.push_back(Strs[i]); - } - for (int i = 1; i < nStrs; i += 2) - { - s.insert(i, Strs[i]); - } - for (int i = 0; i < nStrs; i++) - { - EXPECT_TRUE(s[i] == Strs[i]); - } - - LegacyDynArray s2 = s; - s.erase(5, 2); - EXPECT_TRUE(s.size() == nStrs - 2); - - s.insert(&s[3], &Strs[5], &Strs[8]); - - s2 = s2(3, 4); - EXPECT_TRUE(s2.size() == 4); -} diff --git a/Code/CryEngine/CrySystem/Tests/Test_CrySizer.cpp b/Code/CryEngine/CrySystem/Tests/Test_CrySizer.cpp deleted file mode 100644 index c9aa248eee..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_CrySizer.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* -* 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. -* -*/ - -#include "CrySystem_precompiled.h" - -#include -#include -#include - -#include - -#include "CrySizerImpl.h" - -namespace UnitTest -{ - class CrySizerTest - : public AllocatorsFixture - { - public: - void SetUp() override - { - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - m_sizer = new CrySizerImpl(); - } - - void TearDown() override - { - delete m_sizer; - - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } - protected: - CrySizerImpl* m_sizer; - }; //class StatisticsTest - - /** - * The key data structures fed to ICrySizer in CTerrain::GetMemoryUsage(class ICrySizer* pSizer): - * 1. structs and classes. - * 2. PodArray< of structs / classes> - * 3. PodArray< of pointers> - */ - TEST_F(CrySizerTest, CrySizerTest_AddSomeObjectsUsedInCTerrain_GetExpectedSize) - { - struct TmpStruct - { - AZ::u32 a; - AZ::u32 b; - }; - TmpStruct tmpStructObj; - //Tracking a simple struct. - m_sizer->AddObjectSize(&tmpStructObj); - - //The AddObject method is only available when using the ICrySizer base class. - ICrySizer* sizer = static_cast(m_sizer); - - const int numItemsPerArray = 1024; - - //PodArray of structs - PodArray podArrayOfTmpStruct; - podArrayOfTmpStruct.resize(numItemsPerArray); - sizer->AddObject(podArrayOfTmpStruct); - - //PodArray of pointers - PodArray podArrayOfTmpStructPointers; - podArrayOfTmpStructPointers.resize(numItemsPerArray); - sizer->AddObject(podArrayOfTmpStructPointers); - - //PodArray of Array2d of pointers. - const int array2dAxisSize = 64; - PodArray> podArrayOfArray2d; - podArrayOfArray2d.resize(numItemsPerArray); - for (int i = 0; i < numItemsPerArray; ++i) - { - //Array2d will allocate array2dAxisSize * array2dAxisSize elements. - podArrayOfArray2d[i].Allocate(array2dAxisSize); - } - sizer->AddObject(podArrayOfArray2d); - - //Calculate the total expected size - const size_t expectedSizeOfArray2d = sizeof(Array2d) - + (array2dAxisSize * array2dAxisSize) * sizeof(TmpStruct*); - const size_t expectedTotalSize = sizeof(TmpStruct) - + numItemsPerArray * sizeof(TmpStruct) - + numItemsPerArray * sizeof(TmpStruct*) - + numItemsPerArray * expectedSizeOfArray2d; - - EXPECT_EQ( m_sizer->GetTotalSize(), expectedTotalSize); - } - -}//namespace UnitTest diff --git a/Code/CryEngine/CrySystem/Tests/Test_Localization.cpp b/Code/CryEngine/CrySystem/Tests/Test_Localization.cpp deleted file mode 100644 index ad3972fffe..0000000000 --- a/Code/CryEngine/CrySystem/Tests/Test_Localization.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include -#include "LocalizedStringManager.h" -#include -#include -#include -#include - -#include - -class SystemEventDispatcherMock - : public ISystemEventDispatcher -{ -public: - virtual ~SystemEventDispatcherMock() {} - MOCK_METHOD1(RegisterListener, bool(ISystemEventListener* pListener)); - MOCK_METHOD1(RemoveListener, bool(ISystemEventListener* pListener)); - MOCK_METHOD3(OnSystemEvent, void(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)); - MOCK_METHOD0(Update, void()); -}; - -using namespace testing; -using ::testing::NiceMock; - -using SystemAllocatorScope = AZ::AllocatorScope; - -class SystemFixture - : public ::testing::Test - , public SystemAllocatorScope -{ -public: - SystemFixture() - { - EXPECT_CALL(m_system, GetISystemEventDispatcher()) - .WillRepeatedly(Return(&m_dispatcher)); - - EXPECT_CALL(m_console, GetCVar(_)) - .WillRepeatedly(Return(&m_cvarMock)); - - EXPECT_CALL(m_cryPak, FindFirst(_, _, _)) - .WillRepeatedly(Return(AZ::IO::ArchiveFileIterator{})); - - EXPECT_CALL(m_cryPak, GetLocalizationFolder()) - .WillRepeatedly(Return("french")); - - EXPECT_CALL(m_cvarMock, GetFlags()) - .WillRepeatedly(Return(VF_WASINCONFIG)); - } - - void SetUp() override - { - SystemAllocatorScope::ActivateAllocators(); - - memset(&m_stubEnv, 0, sizeof(SSystemGlobalEnvironment)); - m_stubEnv.pConsole = &m_console; - m_stubEnv.pSystem = &m_system; - m_stubEnv.pCryPak = &m_cryPak; - m_stubEnv.pLog = nullptr; - m_priorEnv = gEnv; - gEnv = &m_stubEnv; - } - - void TearDown() override - { - gEnv = m_priorEnv; - - SystemAllocatorScope::DeactivateAllocators(); - } - - NiceMock m_system; - NiceMock m_dispatcher; - NiceMock m_console; - NiceMock m_cryPak; - NiceMock m_cvarMock; - SSystemGlobalEnvironment m_stubEnv; - SSystemGlobalEnvironment* m_priorEnv = nullptr; -}; - -class UnitTestCLocalizedStringsManager : public CLocalizedStringsManager -{ -public: - UnitTestCLocalizedStringsManager(ISystem* pSystem) : CLocalizedStringsManager(pSystem) - { - } - - bool LocalizeLabel(const char* sLabel, string& outLocalizedString, bool bEnglish = false) override - { - m_capturedLabels.push_back(sLabel); - return CLocalizedStringsManager::LocalizeLabel(sLabel, outLocalizedString, bEnglish); - } - - std::vector m_capturedLabels; - - friend class GTEST_TEST_CLASS_NAME_(SystemFixture, LocalizeStringInternal_WhitespaceCharacters_CorrectlyTokenizes); -}; - -// this test makes sure that whitespace characters such as tab work (not just space) and are considered to be separators. -TEST_F(SystemFixture, LocalizeStringInternal_SpecificWhitespaceCharacters_CorrectlyTokenizes) -{ - UnitTestCLocalizedStringsManager manager(&m_system); - manager.SetLanguage("french"); - - string outString; - manager.LocalizeString_s("@hello\t@world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); - - manager.LocalizeString_s("@hello\n@world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); - - manager.LocalizeString_s("@hello\r@world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); - - manager.LocalizeString_s("@hello @world", outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - manager.m_capturedLabels.clear(); -} - - -// this test makes sure that multiple whitespace characters in a row don't themselves count as tokens or change the output in undesirable ways. -TEST_F(SystemFixture, LocalizeStringInternal_ManyWhitespaceCharacters_CorrectlyTokenizes) -{ - UnitTestCLocalizedStringsManager manager(&m_system); - manager.SetLanguage("french"); - - string outString; - const char* testString = "@hello\n\r\t \t\r\n@world\n\r\t "; - manager.LocalizeString_ch(testString, outString, false); - ASSERT_EQ(manager.m_capturedLabels.size(), 2); - EXPECT_STREQ(manager.m_capturedLabels[0].c_str(), "@hello"); - EXPECT_STREQ(manager.m_capturedLabels[1].c_str(), "@world"); - - // since there are no localizations available it should not have gobbled up whitespace or altered it. - EXPECT_STREQ(outString, testString); -} diff --git a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp b/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp deleted file mode 100644 index 637682065f..0000000000 --- a/Code/CryEngine/CrySystem/Tests/test_CrySystem.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include -#include -#include -#include -#include - -namespace UnitTests -{ - class CSystemUnitTests - : public ::testing::Test - { - public: - void SetUp() override - { - IMemoryManager* cryMemoryManager = nullptr; - CryGetIMemoryManagerInterface((void**)&cryMemoryManager); - AZ_Assert(cryMemoryManager, "Unable to resolve CryMemoryManager"); - m_cryMemoryManager = AZ::Environment::CreateVariable("CryIMemoryManagerInterface", cryMemoryManager); - SSystemInitParams startupParams; - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - m_system = new CSystem(startupParams.pSharedEnvironment); - } - - void TearDown() override - { - delete m_system; - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } - - - CSystem* m_system = nullptr; - AZ::EnvironmentVariable m_cryMemoryManager; - - }; - - TEST_F(CSystemUnitTests, ApplicationLogInstanceUnitTests) - { - const char dummyString[] = "dummy"; - const char testString[] = "test"; - EXPECT_EQ(m_system->GetApplicationLogInstance(dummyString), 0); - EXPECT_EQ(m_system->GetApplicationLogInstance(testString), 0); -#if AZ_TRAIT_OS_USE_WINDOWS_MUTEX - EXPECT_EQ(m_system->GetApplicationLogInstance(dummyString), 1); -#endif - } -} diff --git a/Code/CryEngine/CrySystem/Tests/test_Main.cpp b/Code/CryEngine/CrySystem/Tests/test_Main.cpp deleted file mode 100644 index 5ae78cabbf..0000000000 --- a/Code/CryEngine/CrySystem/Tests/test_Main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" -#include -#include -#include -#include - -class CrySystemTestEnvironment - : public AZ::Test::ITestEnvironment - , public ::UnitTest::TraceBusRedirector -{ -public: - virtual ~CrySystemTestEnvironment() - {} - -protected: - void SetupEnvironment() override - { - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - ::UnitTest::TraceBusRedirector::BusConnect(); - } - - void TeardownEnvironment() override - { - ::UnitTest::TraceBusRedirector::BusDisconnect(); - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - } -}; - -AZ_UNIT_TEST_HOOK(new CrySystemTestEnvironment) diff --git a/Code/CryEngine/CrySystem/Tests/test_MaterialUtils.cpp b/Code/CryEngine/CrySystem/Tests/test_MaterialUtils.cpp deleted file mode 100644 index 99077e41e8..0000000000 --- a/Code/CryEngine/CrySystem/Tests/test_MaterialUtils.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" -#include - -#include -#include -#include "MaterialUtils.h" - -#include - - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestBasics) -{ - char tempBuffer[AZ_MAX_PATH_LEN] = { 0 }; - // call to ensure that it handles nullptr without crashing - MaterialUtils::UnifyMaterialName(nullptr); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(tempBuffer[0] == 0); -} - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestExtensions) -{ - char tempBuffer[AZ_MAX_PATH_LEN]; - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "blahblah.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "blahblah") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "blahblah.mat.mat.abc.test.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "blahblah.mat.mat.abc.test") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "test/.mat.mat/blahblah.mat.mat.abc.test.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "test/.mat.mat/blahblah.mat.mat.abc.test") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, ".mat.mat.blahblah.mat.mat.abc.test.mtl"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, ".mat.mat.blahblah.mat.mat.abc.test") == 0); -} - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestPrefixes) -{ - char tempBuffer[AZ_MAX_PATH_LEN]; - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, ".\\blahblah.mat"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "blahblah") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "./materials/blahblah.mat.mat.abc.test"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, ".\\engine\\materials\\blahblah.mat.mat.abc.test"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "engine/materials/blahblah.mat.mat.abc.test"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); - - azstrcpy(tempBuffer, AZ_MAX_PATH_LEN, "materials/blahblah.mat"); - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah") == 0); -} - -TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestGameName) -{ - char tempBuffer[AZ_MAX_PATH_LEN]; - - auto projectName = AZ::Utils::GetProjectName(); - azsnprintf(tempBuffer, AZ_MAX_PATH_LEN, ".\\%s\\materials\\blahblah.mat.mat.abc.test", projectName.c_str()); - - MaterialUtils::UnifyMaterialName(tempBuffer); - EXPECT_TRUE(strcmp(tempBuffer, "materials/blahblah.mat.mat.abc") == 0); -} diff --git a/Code/CryEngine/CrySystem/ThermalInfoAndroid.cpp b/Code/CryEngine/CrySystem/ThermalInfoAndroid.cpp deleted file mode 100644 index 0c69a728fa..0000000000 --- a/Code/CryEngine/CrySystem/ThermalInfoAndroid.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -* 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. -* -*/ - -#if !defined(AZ_RELEASE_BUILD) -#include "ThermalInfoAndroid.h" -#include -#include - -#include -#include -#include - -ThermalInfoAndroidHandler::ThermalInfoAndroidHandler() -{ - static_assert(AZ_ARRAY_SIZE(m_temperatureFiles) == static_cast(ThermalSensorType::Count), "Thermal count does not match temperature array size"); - ThermalInfoRequestsBus::Handler::BusConnect(); - memset(m_temperatureFiles, 0, sizeof(m_temperatureFiles)); - - const int sensorCount = static_cast(ThermalSensorType::Count); - const char* sensorTypes[sensorCount] = { "cpu", "gpu", "battery" }; - const int maxStringLen = 128; - char tempString[maxStringLen]; - const char* thermalPath = "/sys/class/thermal"; - // List the elements from the thermal folder to get the thermal_zones available on the device - DIR* directory = opendir(thermalPath); - if (directory) - { - struct dirent* item; - const char* thermalPrefix = "thermal_zone"; - // List all items of the directory and find the one that start with thermal_zone (thermal_zone0, thermal_zone1, etc) - while ((item = readdir(directory)) != nullptr) - { - if (strncmp(item->d_name, thermalPrefix, strlen(thermalPrefix)) == 0) - { - // Try to deduce the type of sensor. For this we read the "type" file of the thermal zone. - // This "type" is a string set by the manufacturer, so it can be anything. - AZStd::string path = AZStd::string::format("%s/%s/type", thermalPath, item->d_name); - FILE* sensorTypeFile = fopen(path.c_str(), "r"); - if (sensorTypeFile) - { - if (fscanf(sensorTypeFile, "%s", tempString)) - { - for (int i = 0; i < sensorCount; ++i) - { - if (m_temperatureFiles[i]) - { - continue; - } - - size_t foundPos = AzFramework::StringFunc::Find(tempString, sensorTypes[i]); - if (foundPos != AZStd::string::npos) - { - path = AZStd::string::format("%s/%s/temp", thermalPath, item->d_name); - m_temperatureFiles[i] = fopen(path.c_str(), "r"); - break; - } - } - } - fclose(sensorTypeFile); - } - } - } - closedir(directory); - } - - int cpuSensorIndex = static_cast(ThermalSensorType::CPU); - if (!m_temperatureFiles[cpuSensorIndex]) - { - // If we didn't find the CPU sensor just assume it's the first one. - AZStd::string path = AZStd::string::format("%s/thermal_zone0/temp", thermalPath); - m_temperatureFiles[cpuSensorIndex] = fopen(path.c_str(), "r"); - } -} - -ThermalInfoAndroidHandler::~ThermalInfoAndroidHandler() -{ - ThermalInfoRequestsBus::Handler::BusDisconnect(); - for (int i = 0; i < static_cast(ThermalSensorType::Count); ++i) - { - if (m_temperatureFiles[i]) - { - fclose(m_temperatureFiles[i]); - } - } -} - -float ThermalInfoAndroidHandler::GetSensorTemp(ThermalSensorType sensor) -{ - FILE* tempFile = m_temperatureFiles[static_cast(sensor)]; - if (!tempFile) - { - return 0.f; - } - - fseek(tempFile, 0, SEEK_SET); - float temperature = 0.f; - fscanf(tempFile, "%f", &temperature); - temperature /= 1000.0f; - return temperature; -} - -float ThermalInfoAndroidHandler::GetSensorOverheatingTemp(ThermalSensorType sensor) -{ - const int overheatingTemperatures[static_cast(ThermalSensorType::Count)] = - { - 70, // CPU - 70, // GPU - 40 // Battery - }; - - return overheatingTemperatures[static_cast(sensor)]; -} - -#endif // !defined(AZ_RELEASE_BUILD) - diff --git a/Code/CryEngine/CrySystem/ThermalInfoAndroid.h b/Code/CryEngine/CrySystem/ThermalInfoAndroid.h deleted file mode 100644 index 07d1b86f68..0000000000 --- a/Code/CryEngine/CrySystem/ThermalInfoAndroid.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#if !defined(AZ_RELEASE_BUILD) -#include - -class ThermalInfoAndroidHandler : public ThermalInfoRequestsBus::Handler -{ -public: - ThermalInfoAndroidHandler(); - ~ThermalInfoAndroidHandler() override; - - float GetSensorTemp(ThermalSensorType sensor) override; - float GetSensorOverheatingTemp(ThermalSensorType sensor) override; - -private: - FILE* m_temperatureFiles[static_cast(ThermalSensorType::Count)]; -}; -#endif // !defined(AZ_RELEASE_BUILD) diff --git a/Code/CryEngine/CrySystem/ThreadConfigManager.cpp b/Code/CryEngine/CrySystem/ThreadConfigManager.cpp deleted file mode 100644 index b582aac578..0000000000 --- a/Code/CryEngine/CrySystem/ThreadConfigManager.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ThreadConfigManager.h" -#include "IConsole.h" -#include "System.h" -#include -#include -#include "CryUtils.h" -namespace -{ - const char* sCurThreadConfigFilename = ""; - const uint32 sPlausibleStackSizeLimitKB = (1024 * 100); // 100mb -} - -////////////////////////////////////////////////////////////////////////// -CThreadConfigManager::CThreadConfigManager() -{ - m_defaultConfig.szThreadName = "CryThread_Unnamed"; - m_defaultConfig.stackSizeBytes = 0; - m_defaultConfig.affinityFlag = -1; - m_defaultConfig.priority = THREAD_PRIORITY_NORMAL; - m_defaultConfig.bDisablePriorityBoost = false; - m_defaultConfig.paramActivityFlag = (SThreadConfig::TThreadParamFlag)~0; -} - -////////////////////////////////////////////////////////////////////////// -const SThreadConfig* CThreadConfigManager::GetThreadConfig(const char* szThreadName, ...) -{ - va_list args; - va_start(args, szThreadName); - - // Format thread name - char strThreadName[THREAD_NAME_LENGTH_MAX]; - const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), szThreadName, args); - if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1); - } - - // Get Thread Config - const SThreadConfig* retThreasdConfig = GetThreadConfigImpl(strThreadName); - - va_end(args); - return retThreasdConfig; -} - -////////////////////////////////////////////////////////////////////////// -const SThreadConfig* CThreadConfigManager::GetThreadConfigImpl(const char* szThreadName) -{ - // Get thread config for platform - ThreadConfigMapConstIter threatRet = m_threadConfig.find(CryFixedStringT(szThreadName)); - if (threatRet == m_threadConfig.end()) - { - // Search in wildcard setups - ThreadConfigMapConstIter wildCardIter = m_wildcardThreadConfig.begin(); - ThreadConfigMapConstIter wildCardIterEnd = m_wildcardThreadConfig.end(); - for (; wildCardIter != wildCardIterEnd; ++wildCardIter) - { - if (CryStringUtils::MatchWildcard(szThreadName, wildCardIter->second.szThreadName)) - { - // Store new thread config - SThreadConfig threadConfig = wildCardIter->second; - std::pair res; - res = m_threadConfig.insert(ThreadConfigMapPair(CryFixedStringT(szThreadName), threadConfig)); - - // Store name (ref to key) - SThreadConfig& rMapThreadConfig = res.first->second; - rMapThreadConfig.szThreadName = res.first->first.c_str(); - - // Return new thread config - return &res.first->second; - } - } - - // Failure case, no match found - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": Unable to find config for thread:%s", szThreadName); - return &m_defaultConfig; - } - - // Return thread config - return &threatRet->second; -} - -////////////////////////////////////////////////////////////////////////// -const SThreadConfig* CThreadConfigManager::GetDefaultThreadConfig() const -{ - return &m_defaultConfig; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::LoadConfig(const char* pcPath) -{ - // Adjust filename for OnDisk or in .pak file loading - char szFullPathBuf[AZ::IO::IArchive::MaxPath]; - gEnv->pCryPak->AdjustFileName(pcPath, szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), 0); - - // Open file - XmlNodeRef xmlRoot = GetISystem()->LoadXmlFromFile(szFullPathBuf); - if (!xmlRoot) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": File \"%s\" not found!", pcPath); - return false; - } - - // Load config for active platform - sCurThreadConfigFilename = pcPath; - const char* strPlatformId = IdentifyPlatform(); - CryFixedStringT<32> tmpPlatformStr; - bool retValue = false; - - // Try load common platform settings - tmpPlatformStr.Format("%s_Common", strPlatformId); - LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str()); - -#if defined(CRY_PLATFORM_DESKTOP) - // Handle PC specifically as we do not know the core setup of the executing machine. - // Try and find the next power of 2 core setup. Otherwise fallback to a lower power of 2 core setup spec - - // Try and load next pow of 2 setup for active pc core configuration - const unsigned int numCPUs = ((CSystem*)GetISystem())->GetCPUFeatures()->GetLogicalCPUCount(); - uint32 i = numCPUs; - for (; i > 0; --i) - { - tmpPlatformStr.Format("%s_%i", strPlatformId, i); - retValue = LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str()); - if (retValue) - { - break; - } - } - - if (retValue && i != numCPUs) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": (%s: %u core) Unable to find platform config \"%s\". Next valid config found was %s_%u.", - strPlatformId, numCPUs, tmpPlatformStr.c_str(), strPlatformId, i); - } - -#else - tmpPlatformStr.Format("%s", strPlatformId); - retValue = LoadPlatformConfig(xmlRoot, strPlatformId); -#endif - - // Print out info - if (retValue) - { - CryLogAlways(": Thread profile loaded: \"%s\" (%s) ", tmpPlatformStr.c_str(), pcPath); - } - else - { - // Could not find any matching platform - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": Active platform identifier string \"%s\" not found in config \"%s\".", strPlatformId, sCurThreadConfigFilename); - } - - sCurThreadConfigFilename = ""; - return retValue; -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::ConfigLoaded() const -{ - return !m_threadConfig.empty(); -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::LoadPlatformConfig(const XmlNodeRef& rXmlRoot, const char* sPlatformId) -{ - // Validate node - if (!rXmlRoot->isTag("ThreadConfig")) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": Unable to find root xml node \"ThreadConfig\""); - return false; - } - - // Find active platform - const uint32 numPlatforms = rXmlRoot->getChildCount(); - for (uint32 i = 0; i < numPlatforms; ++i) - { - const XmlNodeRef xmlPlatformNode = rXmlRoot->getChild(i); - - // Is platform node - if (!xmlPlatformNode->isTag("Platform")) - { - continue; - } - - // Is has Name attribute - if (!xmlPlatformNode->haveAttr("Name")) - { - continue; - } - - // Is platform of interest - const char* platformName = xmlPlatformNode->getAttr("Name"); - if (_stricmp(sPlatformId, platformName) == 0) - { - // Load platform - LoadThreadDefaultConfig(xmlPlatformNode); - LoadPlatformThreadConfigs(xmlPlatformNode); - return true; - } - } - - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadPlatformThreadConfigs(const XmlNodeRef& rXmlPlatformRef) -{ - // Get thread configurations for active platform - const uint32 numThreads = rXmlPlatformRef->getChildCount(); - for (uint32 j = 0; j < numThreads; ++j) - { - const XmlNodeRef xmlThreadNode = rXmlPlatformRef->getChild(j); - - if (!xmlThreadNode->isTag("Thread")) - { - continue; - } - - // Ensure thread config has name - if (!xmlThreadNode->haveAttr("Name")) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Thread node without \"name\" attribute encountered."); - continue; - } - - // Load thread config - SThreadConfig loadedThreadConfig = SThreadConfig(m_defaultConfig); - LoadThreadConfig(xmlThreadNode, loadedThreadConfig); - - // Get thread name and check if it contains wildcard characters - const char* szThreadName = xmlThreadNode->getAttr("Name"); - bool bWildCard = strchr(szThreadName, '*') ? true : false; - ThreadConfigMap& threadConfig = bWildCard ? m_wildcardThreadConfig : m_threadConfig; - - // Check for duplicate and override it with new config if found - if (threadConfig.find(szThreadName) != threadConfig.end()) - { - CryLogAlways(": [XML Parsing] Thread with name \"%s\" already loaded. Overriding with new configuration", szThreadName); - threadConfig[szThreadName] = loadedThreadConfig; - continue; - } - - // Store new thread config - std::pair res; - res = threadConfig.insert(ThreadConfigMapPair(CryFixedStringT(szThreadName), loadedThreadConfig)); - - // Store name (ref to key) - SThreadConfig& rMapThreadConfig = res.first->second; - rMapThreadConfig.szThreadName = res.first->first.c_str(); - } -} - -////////////////////////////////////////////////////////////////////////// -bool CThreadConfigManager::LoadThreadDefaultConfig(const XmlNodeRef& rXmlPlatformRef) -{ - // Find default thread config node - const uint32 numNodes = rXmlPlatformRef->getChildCount(); - for (uint32 j = 0; j < numNodes; ++j) - { - const XmlNodeRef xmlNode = rXmlPlatformRef->getChild(j); - - // Load default config - if (xmlNode->isTag("ThreadDefault")) - { - LoadThreadConfig(xmlNode, m_defaultConfig); - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadAffinity(const XmlNodeRef& rXmlThreadRef, uint32& rAffinity, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - const char* szValidCharacters = "-,0123456789"; - uint32 affinity = 0; - - // Validate node - if (!rXmlThreadRef->haveAttr("Affinity")) - { - return; - } - - // Validate token - CryFixedStringT<32> affinityRawStr(rXmlThreadRef->getAttr("Affinity")); - if (affinityRawStr.empty()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Empty attribute \"Affinity\" encountered"); - return; - } - - if (affinityRawStr.compareNoCase("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Affinity; - return; - } - - CryFixedStringT<32>::size_type nPos = affinityRawStr.find_first_not_of(" -,0123456789"); - if (nPos != CryFixedStringT<32>::npos) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, - ": [XML Parsing] Invalid character \"%c\" encountered in \"Affinity\" attribute. Valid characters:\"%s\" Offending token:\"%s\"", affinityRawStr.at(nPos), - szValidCharacters, affinityRawStr.c_str()); - return; - } - - // Tokenize comma separated string - int pos = 0; - CryFixedStringT<32> affnityTokStr = affinityRawStr.Tokenize(",", pos); - while (!affnityTokStr.empty()) - { - affnityTokStr.Trim(); - - long affinityId = strtol(affnityTokStr.c_str(), NULL, 10); - if (affinityId == LONG_MAX || affinityId == LONG_MIN) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unknown value \"%s\" encountered for attribute \"Affinity\"", affnityTokStr.c_str()); - return; - } - - // Allow scheduler to pick thread - if (affinityId == -1) - { - affinity = ~0; - break; - } - - // Set affinity bit - affinity |= BIT(affinityId); - - // Move to next token - affnityTokStr = affinityRawStr.Tokenize(",", pos); - } - - // Set affinity reference - rAffinity = affinity; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadPriority(const XmlNodeRef& rXmlThreadRef, int32& rPriority, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - const char* szValidCharacters = "-,0123456789"; - - // Validate node - if (!rXmlThreadRef->haveAttr("Priority")) - { - return; - } - - // Validate token - CryFixedStringT<32> threadPrioStr(rXmlThreadRef->getAttr("Priority")); - threadPrioStr.Trim(); - if (threadPrioStr.empty()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Empty attribute \"Priority\" encountered"); - return; - } - - if (threadPrioStr.compareNoCase("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Priority; - return; - } - - // Test for character string (no numbers allowed) - if (threadPrioStr.find_first_of(szValidCharacters) == CryFixedStringT<32>::npos) - { - threadPrioStr.MakeLower(); - - // Set priority - if (threadPrioStr.compare("below_normal") == 0) - { - rPriority = THREAD_PRIORITY_BELOW_NORMAL; - } - else if (threadPrioStr.compare("normal") == 0) - { - rPriority = THREAD_PRIORITY_NORMAL; - } - else if (threadPrioStr.compare("above_normal") == 0) - { - rPriority = THREAD_PRIORITY_ABOVE_NORMAL; - } - else if (threadPrioStr.compare("idle") == 0) - { - rPriority = THREAD_PRIORITY_IDLE; - } - else if (threadPrioStr.compare("lowest") == 0) - { - rPriority = THREAD_PRIORITY_LOWEST; - } - else if (threadPrioStr.compare("highest") == 0) - { - rPriority = THREAD_PRIORITY_HIGHEST; - } - else if (threadPrioStr.compare("time_critical") == 0) - { - rPriority = THREAD_PRIORITY_TIME_CRITICAL; - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Platform unsupported value \"%s\" encountered for attribute \"Priority\"", threadPrioStr.c_str()); - return; - } - } - // Test for number string (no alphabetical characters allowed) - else if (threadPrioStr.find_first_not_of(szValidCharacters) == CryFixedStringT<32>::npos) - { - long numValue = strtol(threadPrioStr.c_str(), NULL, 10); - if (numValue == LONG_MAX || numValue == LONG_MIN) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unsupported number type \"%s\" for for attribute \"Priority\"", threadPrioStr.c_str()); - return; - } - - // Set priority - rPriority = numValue; - } - else - { - // String contains characters and numbers - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unsupported type \"%s\" encountered for attribute \"Priority\". Token containers numbers and characters", threadPrioStr.c_str()); - return; - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadDisablePriorityBoost(const XmlNodeRef& rXmlThreadRef, bool& rPriorityBoost, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - // Validate node - if (!rXmlThreadRef->haveAttr("DisablePriorityBoost")) - { - return; - } - - // Extract bool info - CryFixedStringT<16> sAttribToken(rXmlThreadRef->getAttr("DisablePriorityBoost")); - sAttribToken.Trim(); - sAttribToken.MakeLower(); - - if (sAttribToken.compare("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_PriorityBoost; - return; - } - else if (sAttribToken.compare("true") == 0 || sAttribToken.compare("1") == 0) - { - rPriorityBoost = true; - } - else if (sAttribToken.compare("false") == 0 || sAttribToken.compare("0") == 0) - { - rPriorityBoost = false; - } - else - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Unsupported bool type \"%s\" encountered for attribute \"DisablePriorityBoost\"", - rXmlThreadRef->getAttr("DisablePriorityBoost")); - return; - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadStackSize(const XmlNodeRef& rXmlThreadRef, uint32& rStackSize, SThreadConfig::TThreadParamFlag& rParamActivityFlag) -{ - const char* sValidCharacters = "0123456789"; - - if (rXmlThreadRef->haveAttr("StackSizeKB")) - { - // Read stack size - CryFixedStringT<32> stackSize(rXmlThreadRef->getAttr("StackSizeKB")); - - // Validate stack size - if (stackSize.empty()) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Empty attribute \"StackSize\" encountered"); - return; - } - else if (stackSize.compareNoCase("ignore") == 0) - { - // Param is inactive, clear bit - rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_StackSize; - return; - } - else if (stackSize.find_first_not_of(sValidCharacters) == CryFixedStringT<32>::npos) - { - // Convert string to long - long stackSizeVal = strtol(stackSize.c_str(), NULL, 10); - if (stackSizeVal == LONG_MAX || stackSizeVal == LONG_MIN) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] Invalid number for \"StackSize\" encountered. \"%s\"", stackSize.c_str()); - return; - } - else if (stackSizeVal <= 0 || stackSizeVal > sPlausibleStackSizeLimitKB) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, ": [XML Parsing] \"StackSize\" value not plausible \"%" PRId64 "KB\"", (int64)stackSizeVal); - return; - } - - // Set stack size - rStackSize = stackSizeVal * 1024; // Convert to bytes - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::LoadThreadConfig(const XmlNodeRef& rXmlThreadRef, SThreadConfig& rThreadConfig) -{ - LoadAffinity(rXmlThreadRef, rThreadConfig.affinityFlag, rThreadConfig.paramActivityFlag); - LoadPriority(rXmlThreadRef, rThreadConfig.priority, rThreadConfig.paramActivityFlag); - LoadDisablePriorityBoost(rXmlThreadRef, rThreadConfig.bDisablePriorityBoost, rThreadConfig.paramActivityFlag); - LoadStackSize(rXmlThreadRef, rThreadConfig.stackSizeBytes, rThreadConfig.paramActivityFlag); -} - -////////////////////////////////////////////////////////////////////////// -const char* CThreadConfigManager::IdentifyPlatform() -{ -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(ThreadConfigManager_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(ANDROID) - return "android"; -#elif defined(LINUX) - return "linux"; -#elif defined(APPLE) - return "mac"; -#elif defined(WIN32) || defined(WIN64) - return "pc"; -#else -#error "Undefined platform" -#endif -} - -////////////////////////////////////////////////////////////////////////// -void CThreadConfigManager::DumpThreadConfigurationsToLog() -{ -#if !defined(RELEASE) - - // Print header - CryLogAlways("== Thread Startup Config List (\"%s\") ==", IdentifyPlatform()); - - // Print loaded default config - CryLogAlways(" (Default) 1. \"%s\" (StackSize:%uKB | Affinity:%u | Priority:%i | PriorityBoost:\"%s\")", m_defaultConfig.szThreadName, m_defaultConfig.stackSizeBytes / 1024, - m_defaultConfig.affinityFlag, m_defaultConfig.priority, m_defaultConfig.bDisablePriorityBoost ? "disabled" : "enabled"); - - // Print loaded thread configs - int listItemCounter = 1; - ThreadConfigMapConstIter iter = m_threadConfig.begin(); - ThreadConfigMapConstIter iterEnd = m_threadConfig.end(); - for (; iter != iterEnd; ++iter) - { - const SThreadConfig& threadConfig = iter->second; - CryLogAlways("%3d.\"%s\" %s (StackSize:%uKB %s | Affinity:%u %s | Priority:%i %s | PriorityBoost:\"%s\" %s)", ++listItemCounter, - threadConfig.szThreadName, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) ? "" : "(ignored)", - threadConfig.stackSizeBytes / 1024u, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_StackSize) ? "" : "(ignored)", - threadConfig.affinityFlag, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) ? "" : "(ignored)", - threadConfig.priority, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) ? "" : "(ignored)", - !threadConfig.bDisablePriorityBoost ? "enabled" : "disabled", (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) ? "" : "(ignored)"); - } -#endif -} diff --git a/Code/CryEngine/CrySystem/ThreadConfigManager.h b/Code/CryEngine/CrySystem/ThreadConfigManager.h deleted file mode 100644 index ef0c9dca3d..0000000000 --- a/Code/CryEngine/CrySystem/ThreadConfigManager.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include -#include "IThreadConfigManager.h" - -/* -ThreadConfigManager: -Loads a thread configuration from an xml file and stores them. - -== XML File Layout and Rules: === - -= Platform names = -(case insensitive) -"ANDROID" -"PC" -"MAC" -etc. - -= Basic Layout = - - - - - -... - - - -... - - - -= Parser Order for Platform = -1. PlatformName_Common (valid for all potential platform configurations. Can be overridden by concert platform configuration) -2. PlatformName or PlatformName_X (for platforms with unknown CPU count where X is the number of potential cores. The equal or next lower matching configuration for the identified core count at runtime will be taken) - -Note: Overriding of thread configuration by later parsed configuration allowed. - -= and XML attributes = - -!!! -Note: Use "ignore" as value if you do not want the thread system to set the value specifically! - If a value is not defines the value of the parameter will be used. - This is useful when dealing with 3rdParty threads where you are not in control of the parameter setup. -!!! - -Name: - "x" (string) : Name of thread - "x*y" (string) : Name of thread with wildcard character - -Affinity: - "-1" : Put SW thread affinity in the hands of the scheduler - (default) - - "x" : Run thread on specified core - "x, y, ..." : Run thread on specified cores - -Priority: - "idle" : Hint to CryEngine to run thread with pre-set priority - "below_normal" : Hint to CryEngine to run thread with pre-set priority - "normal" : Hint to CryEngine to run thread with pre-set priority - (default) - - "above_normal" : Hint to CryEngine to run thread with pre-set priority - "highest" : Hint to CryEngine to run thread with pre-set priority - "time_critical" : Hint to CryEngine to run thread with pre-set priority - "x" (number) : User defined thread priority number - -StackSizeKB: - "0" : Let platform decide on the stack size - (default) - - "x" : Create thread with "x" KB of stack size - -DisablePriorityBoost: - "true" : Disable priority boosting - (default) - - "false" : Enable priority boosting -*/ - -class CThreadConfigManager - : public IThreadConfigManager -{ -public: - typedef std::map, SThreadConfig> ThreadConfigMap; - typedef std::pair, SThreadConfig> ThreadConfigMapPair; - typedef std::map, SThreadConfig>::iterator ThreadConfigMapIter; - typedef std::map, SThreadConfig>::const_iterator ThreadConfigMapConstIter; - -public: - CThreadConfigManager(); - ~CThreadConfigManager() - { - } - - // Called once during System startup. - // Loads the thread configuration for the executing platform from file. - virtual bool LoadConfig(const char* pcPath) override; - - // Returns true if a config has been loaded - virtual bool ConfigLoaded() const override; - - // Gets the thread configuration for the specified thread on the active platform. - // If no matching config is found a default configuration is returned - // (which does not have the same name as the search string). - virtual const SThreadConfig* GetThreadConfig(const char* sThreadName, ...) override; - virtual const SThreadConfig* GetDefaultThreadConfig() const override; - - virtual void DumpThreadConfigurationsToLog() override; - -private: - const char* IdentifyPlatform(); - - const SThreadConfig* GetThreadConfigImpl(const char* cThreadName); - - bool LoadPlatformConfig(const XmlNodeRef& rXmlRoot, const char* sPlatformId); - - void LoadPlatformThreadConfigs(const XmlNodeRef& rXmlPlatformRef); - bool LoadThreadDefaultConfig(const XmlNodeRef& rXmlPlatformRef); - void LoadThreadConfig(const XmlNodeRef& rXmlThreadRef, SThreadConfig& rThreadConfig); - - void LoadAffinity(const XmlNodeRef& rXmlThreadRef, uint32& rAffinity, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - void LoadPriority(const XmlNodeRef& rXmlThreadRef, int32& rPriority, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - void LoadDisablePriorityBoost(const XmlNodeRef& rXmlThreadRef, bool& rPriorityBoost, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - void LoadStackSize(const XmlNodeRef& rXmlThreadRef, uint32& rStackSize, SThreadConfig::TThreadParamFlag& rParamActivityFlag); - -private: - ThreadConfigMap m_threadConfig; // Note: The map key is referenced by as const char* by the value's storage class. Other containers may not support this behaviour as they will re-allocate memory as they grow/shrink. - ThreadConfigMap m_wildcardThreadConfig; - SThreadConfig m_defaultConfig; -}; diff --git a/Code/CryEngine/CrySystem/ThreadInfo.cpp b/Code/CryEngine/CrySystem/ThreadInfo.cpp deleted file mode 100644 index 14285215b8..0000000000 --- a/Code/CryEngine/CrySystem/ThreadInfo.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ThreadInfo.h" -#include "System.h" - -//////////////////////////////////////////////////////////////////////////// - - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define THREADINFO_CPP_SECTION_1 1 -#define THREADINFO_CPP_SECTION_2 2 -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADINFO_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(ThreadInfo_cpp) -#endif - -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -#if AZ_LEGACY_CRYSYSTEM_TRAIT_THREADINFO_WINDOWS_STYLE -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::GetCurrentThreads(TThreadInfo& threadsOut) -{ - HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - DWORD currProcessId = GetCurrentProcessId(); - if (h != INVALID_HANDLE_VALUE) - { - THREADENTRY32 te; - te.dwSize = sizeof(te); - if (Thread32First(h, &te)) - { - do - { - if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) - { - if (te.th32OwnerProcessID == currProcessId) - { - threadsOut[te.th32ThreadID] = CryThreadGetName(te.th32ThreadID); - } - } - te.dwSize = sizeof(te); - } while (Thread32Next(h, &te)); - } - CloseHandle(h); - } -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds /* = TThreadIds()*/, bool ignoreCurrThread /* = true*/) -{ - TThreadIds threadids = threadIds; - if (threadids.empty()) - { - TThreadInfo threads; - GetCurrentThreads(threads); - DWORD currThreadId = GetCurrentThreadId(); - for (TThreadInfo::iterator it = threads.begin(), end = threads.end(); it != end; ++it) - { - if (!ignoreCurrThread || it->first != currThreadId) - { - threadids.push_back(it->first); - } - } - } - for (TThreadIds::iterator it = threadids.begin(), end = threadids.end(); it != end; ++it) - { - SThreadHandle thread; - thread.Id = *it; - thread.Handle = OpenThread(THREAD_ALL_ACCESS, FALSE, *it); - threadsOut.push_back(thread); - } -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::CloseThreadHandles(const TThreads& threads) -{ - for (TThreads::const_iterator it = threads.begin(), end = threads.end(); it != end; ++it) - { - CloseHandle(it->Handle); - } -} - -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////// -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADINFO_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(ThreadInfo_cpp) -#elif defined(LINUX) || defined(APPLE) -void SThreadInfo::GetCurrentThreads(TThreadInfo& threadsOut) -{ - assert(false); // not implemented! -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds /* = TThreadIds()*/, bool ignoreCurrThread /* = true*/) -{ - assert(false); // not implemented! -} - -//////////////////////////////////////////////////////////////////////////// -void SThreadInfo::CloseThreadHandles(const TThreads& threads) -{ - assert(false); // not implemented! -} - -//////////////////////////////////////////////////////////////////////////// -#endif diff --git a/Code/CryEngine/CrySystem/ThreadInfo.h b/Code/CryEngine/CrySystem/ThreadInfo.h deleted file mode 100644 index 4bcacf71d5..0000000000 --- a/Code/CryEngine/CrySystem/ThreadInfo.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_THREADINFO_H -#define CRYINCLUDE_CRYSYSTEM_THREADINFO_H -#pragma once - - -struct SThreadInfo -{ -public: - struct SThreadHandle - { - HANDLE Handle; - uint32 Id; - }; - - typedef std::vector TThreadIds; - typedef std::vector TThreads; - typedef std::map TThreadInfo; - - // returns thread info - static void GetCurrentThreads(TThreadInfo& threadsOut); - - // fills threadsOut vector with thread handles of given thread ids; if threadIds vector is emtpy it fills all running threads - // if ignoreCurrThread is true it will not return the current thread - static void OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds = TThreadIds(), bool ignoreCurrThread = true); - - // closes thread handles; should be called whenever GetCurrentThreads was called! - static void CloseThreadHandles(const TThreads& threads); -}; - -#endif // CRYINCLUDE_CRYSYSTEM_THREADINFO_H diff --git a/Code/CryEngine/CrySystem/ThreadTask.cpp b/Code/CryEngine/CrySystem/ThreadTask.cpp deleted file mode 100644 index d1ae7304e6..0000000000 --- a/Code/CryEngine/CrySystem/ThreadTask.cpp +++ /dev/null @@ -1,1046 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "ThreadTask.h" -#include "CPUDetect.h" -#include "IConsole.h" -#include "System.h" - -#if defined(AZ_RESTRICTED_PLATFORM) -#undef AZ_RESTRICTED_SECTION -#define THREADTASK_CPP_SECTION_1 1 -#define THREADTASK_CPP_SECTION_2 2 -#endif - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif //WIN32 - -#include "BitFiddling.h" - -#if defined(ANDROID) -#include -#include -#endif -#if defined(LINUX) - -#endif -#if defined(APPLE) -// include for thread_policy_set -#include -#include -#endif - -#include - -////////////////////////////////////////////////////////////////////////// -CThreadTask_Thread::CThreadTask_Thread(CThreadTaskManager* pTaskMgr, const char* sName, - int nIndex, int nProcessor, int nThreadPriority, ThreadPoolHandle poolHandle /* = -1*/) - : tasks(64) -{ - m_nThreadPriority = nThreadPriority; - m_pTaskManager = pTaskMgr; - m_sThreadName = sName; - bStopThread = false; - bRunning = false; - m_hThreadHandle = 0; - m_nThreadIndex = nIndex; - m_nProcessor = nProcessor; - m_poolHandle = poolHandle; -} - -CThreadTask_Thread::~CThreadTask_Thread() -{ - while (!tasks.empty()) - { - tasks.pop()->m_pThread = 0; - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::SingleUpdate() -{ - while (true) - { - m_pProcessingTask = NULL; - - { - if (tasks.empty()) - { - break; - } - // remove from queue - m_pProcessingTask = tasks.pop(); - } - - if (m_pProcessingTask) - { - m_pProcessingTask->m_pTask->OnUpdate(); - } - - if (m_pProcessingTask) // push it back - { - tasks.push(m_pProcessingTask); - } - - if (bStopThread) - { - break; - } - } - - if (m_poolHandle != -1) // if this thread is in the pool, we need to reassign some tasks for it - { - m_pTaskManager->BalanceThreadInPool(this); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::Run() -{ - Init(); - - bRunning = true; - while (!bStopThread) - { - while (tasks.empty() && !bStopThread) - { - m_waitForTasks.Wait(); - } - - if (!bStopThread) - { - SingleUpdate(); - } - } - bRunning = false; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::Cancel() -{ - bStopThread = true; - m_waitForTasks.Set(); - Stop(); - - // for blocking thread notify the blocking task - if (m_nThreadIndex == -1) - { - if (m_pProcessingTask && m_pProcessingTask->m_params.nFlags & THREAD_TASK_BLOCKING) // check if we have a blocking task - { - if (m_pProcessingTask->m_pTask) // cancel it - { - m_pProcessingTask->m_pTask->Stop(); - } - } - } - - WaitForThread(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::Terminate() -{ -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::AddTask(SThreadTaskInfo* pTaskInfo) -{ - pTaskInfo->m_pThread = this; - tasks.push(pTaskInfo); - m_waitForTasks.Set(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::RemoveTask(SThreadTaskInfo* pTaskInfo) -{ - if (!pTaskInfo) - { - return; - } - - if (m_pProcessingTask == pTaskInfo) - { - pTaskInfo->m_pThread = NULL; - m_pProcessingTask = NULL; - return; - } - - // search for task(mirrored search because of locklessness) - bool bFound = false; - Tasks newTasks; - while (!tasks.empty()) - { - SThreadTaskInfo* pTask = tasks.pop(); - if (pTask == pTaskInfo) - { - pTaskInfo->m_pThread = NULL; - bFound = true; - break; - } - if (pTask) - { - newTasks.push(pTask); - } - } - (void)bFound; - // Don't assert if newTasks is empty. There is a thread race condition between - // the thread shutting down and this code being executed (both update/use - // m_pProcessTask with no locks). newTasks will be empty - // and bFound == false when the race condition is won by the task thread and - // not by the thread that is executing this code - CRY_ASSERT(bFound || newTasks.empty()); - - // fill back - while (!newTasks.empty()) - { - tasks.push(newTasks.pop()); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTask_Thread::RemoveAllTasks() -{ - while (!tasks.empty()) - { - tasks.pop()->m_pThread = NULL; - } -} - -void CThreadTask_Thread::Init() -{ -#if AZ_TRAIT_OS_USE_WINDOWS_THREADS - m_hThreadHandle = GetCurrentThread(); -#endif - - // Name this thread. - CryThreadSetName(GetCurrentThreadId(), m_sThreadName); - - // Set affinity - if (m_nProcessor > 0) - { - ChangeProcessor(m_nProcessor); - } -#if defined(WIN32) - ((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions); -#endif -} - -void CThreadTask_Thread::ChangeProcessor(int nProcessor) -{ - // note this function is not thread-safe - m_nProcessor = nProcessor; -#if defined(WIN32) - DWORD_PTR mask1, mask2; - GetProcessAffinityMask(GetCurrentProcess(), &mask1, &mask2); - if (BIT64(m_nProcessor) & mask1) // Check if we have this affinity - { - SetThreadAffinityMask(m_hThreadHandle, BIT64(m_nProcessor)); - } - else // Reserve CPU 1 for main thread. - { - SetThreadAffinityMask(m_hThreadHandle, (mask1 & (~1))); - } - assert(THREAD_PRIORITY_IDLE <= m_nThreadPriority && m_nThreadPriority <= THREAD_PRIORITY_TIME_CRITICAL); - SetThreadPriority(m_hThreadHandle, m_nThreadPriority); -#define AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADTASK_CPP_SECTION_1 -#include AZ_RESTRICTED_FILE(ThreadTask_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#elif defined(ANDROID) - int err, syscallres; - pid_t pid = gettid(); - syscallres = syscall(__NR_sched_setaffinity, pid, sizeof(nProcessor), &nProcessor); - if (syscallres) - { - err = errno; - CryLog("Error in the syscall setaffinity: mask=%d=0x%x sysconf#=%ld err=%d=0x%x", nProcessor, nProcessor, sysconf(_SC_NPROCESSORS_ONLN), err, err); - } -#elif defined(LINUX) - // Check if the processor is valid - assert(nProcessor < sysconf(_SC_NPROCESSORS_ONLN)); - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(nProcessor, &cpuset); - pthread_t current_thread = pthread_self(); - int ret = pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset); - (void) ret; - // check if the operation completed succesfully - assert(ret == 0 && "ChangeProcessor operation failed"); -#elif defined(APPLE) - assert(nProcessor != 0 && "CThreadTask_Thread::ChangeProcessor - If " - "nProcessor is equal to 0, the default afinity will be applied " - "to the thread. Can be fixed by incrementing nProcess by 1."); - thread_affinity_policy_data_t thread_affinity; - thread_affinity.affinity_tag = nProcessor; - thread_policy_set(pthread_mach_thread_np(pthread_self()), THREAD_AFFINITY_POLICY, (thread_policy_t)&thread_affinity, THREAD_AFFINITY_POLICY_COUNT); - //CryWarning(VALIDATOR_MODULE_SYSTEM,VALIDATOR_WARNING, "CThreadTask_Thread::ChangeProcessor: Feature is not supported on Mac OS X."); -#else - assert(0); -#endif -} - -////////////////////////////////////////////////////////////////////////// -CThreadTaskManager::CThreadTaskManager() -{ - m_nMaxThreads = 1; - - SetThreadName(GetCurrentThreadId(), "Main"); - - m_systemThreads.push_back(GetCurrentThreadId()); -} - -////////////////////////////////////////////////////////////////////////// -CThreadTaskManager::~CThreadTaskManager() -{ - CloseThreads(); - - AUTO_MODIFYLOCK(m_threadsPoolsLock); - while (!m_threadsPools.empty()) - { -#if !defined(NDEBUG) - bool res = -#endif - DestroyThreadsPool(m_threadsPools.begin()->m_hHandle); - assert(res); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::StopAllThreads() -{ - if (m_threads.empty()) - { - return; - } - - size_t i; - // Start from 2nd thread, 1st is main thread. - for (i = 1; i < m_threads.size(); i++) - { - CThreadTask_Thread* pThread = m_threads[i]; - pThread->Cancel(); - } - bool bAllStoped = true; - do - { - bAllStoped = true; - CrySleep(10); - for (i = 1; i < m_threads.size(); i++) - { - CThreadTask_Thread* pThread = m_threads[i]; - // Needs ReadWriteBarrier here. - if (pThread->bRunning) - { - bAllStoped = false; - } - } - } - while (!bAllStoped); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::CloseThreads() -{ - if (m_threads.size() > 0) - { - StopAllThreads(); - } - for (size_t i = MAIN_THREAD_INDEX, numThreads = m_threads.size(); i < numThreads; i++) - { - delete m_threads[i]; - } - m_threads.clear(); - //make sure blocking threads are cancelled - for (bool repeat = true; repeat; ) - { - CThreadTask_Thread* thr = NULL; - { - CryAutoCriticalSection lock(m_threadRemove); - - if (!m_blockingThreads.empty()) - { - thr = *m_blockingThreads.rbegin(); - m_blockingThreads.pop_back(); - } - } - - if (thr) - { - thr->Cancel(); - delete thr; - } - else - { - repeat = false; - } - } - - m_blockingThreads.clear(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::InitThreads() -{ - m_nMaxThreads = gEnv->IsDedicated() ? 1 : 4; - CloseThreads(); - - // Create a dummy thread that is used for main thread. - m_threads.resize(1); - m_threads[0] = new CThreadTask_Thread(this, "Main Thread", 0, AFFINITY_MASK_MAINTHREAD, THREAD_PRIORITY_NORMAL); - - CCpuFeatures* pCPU = ((CSystem*)gEnv->pSystem)->GetCPUFeatures(); - - int nThreads = min((int)m_nMaxThreads, (int)pCPU->GetCPUCount()); - - if (nThreads < 1) - { - nThreads = 1; - } - int nAddThreads = nThreads - 1; - - char str[32]; - m_threads.resize(1 + nAddThreads); - for (int i = 0; i < nAddThreads; i++) - { - int nIndex = i + 1; - int nCPU = i + 1; - sprintf_s(str, "TaskThread%d", i); - if (i < m_nMaxThreads) - { - nCPU = ((CSystem*)gEnv->pSystem)->m_sys_TaskThread_CPU[i]->GetIVal(); - } - - // Clamp to random thread between 1 and max, avoid cpu 0 with main thread - if (nCPU >= nThreads) - { - nCPU = (rand() % (nThreads - 1)) + 1; - } - m_threads[nIndex] = new CThreadTask_Thread(this, str, nIndex, nCPU, THREAD_PRIORITY_NORMAL); - m_threads[nIndex]->Start(0, str, THREAD_PRIORITY_NORMAL, SIMPLE_THREAD_STACK_SIZE_KB * 1024); - } - RescheduleTasks(); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::SetMaxThreadCount(int nMaxThreads) -{ - if (nMaxThreads == m_nMaxThreads) - { - return; - } - - m_nMaxThreads = nMaxThreads; - - bool bReallocateThreads = false; - if (m_nMaxThreads < (int)m_threads.size()) - { - bReallocateThreads = true; - } - if (m_nMaxThreads > (int)m_threads.size()) - { - CCpuFeatures* pCPU = ((CSystem*)gEnv->pSystem)->GetCPUFeatures(); - if (m_threads.size() < pCPU->GetCPUCount()) - { - bReallocateThreads = true; - } - } - if (bReallocateThreads) - { - CloseThreads(); - InitThreads(); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options) -{ - if (!pTask) - { - assert(0); - return; - } - SThreadTaskInfo* pTaskInfo = pTask->GetTaskInfo(); - pTaskInfo->m_pTask = pTask; - pTaskInfo->m_params = options; - - if ((options.nFlags & THREAD_TASK_BLOCKING) == 0) - { - ScheduleTask(pTaskInfo); - } - else - { - CryAutoCriticalSection lock(m_threadRemove); - // Blocking task will need it`s own thread. - const int threadPriority = THREAD_PRIORITY_NORMAL; - CThreadTask_Thread* pThread = - new CThreadTask_Thread(this, options.name, -1, options.nPreferedThread, threadPriority); - pThread->Start(0, (char*)options.name, threadPriority, options.nStackSizeKB * 1024); - pThread->AddTask(pTaskInfo); - - m_blockingThreads.push_back(pThread); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::UnregisterTask(IThreadTask* pTask) -{ - assert(pTask); - if (!pTask) - { - return; - } - SThreadTaskInfo* pTaskInfo = pTask->GetTaskInfo(); - assert(pTaskInfo); - - IThreadTask_Thread* pThread = pTaskInfo->m_pThread; - uint32 flags = pTaskInfo->m_params.nFlags; - - // Remove from thread. - if (pThread) - { - pThread->RemoveTask(pTaskInfo); - } - - pTask->Stop(); - - if (flags & THREAD_TASK_BLOCKING) - { - CThreadTask_Thread* thr = NULL; - { - CryAutoCriticalSection lock(m_threadRemove); - Threads::iterator end = m_blockingThreads.end(); - Threads::iterator toErase = std::find(m_blockingThreads.begin(), end, pThread); - - if (toErase != end) // impossible to find anything. no push_back done on m_blockingThreads - { - thr = *toErase; - m_blockingThreads.erase(toErase); - } - } - - if (thr) - { - thr->Cancel(); - delete thr; - } - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::ScheduleTask(SThreadTaskInfo* pTaskInfo) -{ - size_t i; - - if (pTaskInfo->m_pThread) - { - assert(0); - pTaskInfo->m_pThread->RemoveTask(pTaskInfo); - } - - CThreadTask_Thread* pGoodThread = NULL; - - if (pTaskInfo->m_params.nFlags & THREAD_TASK_ASSIGN_TO_POOL) - { - AUTO_READLOCK(m_threadsPoolsLock); - - // find the pool - CThreadsPool* pool = NULL; - size_t nSize = m_threadsPools.size(); - for (i = 0; i < nSize; ++i) - { - if (m_threadsPools[i].m_hHandle == pTaskInfo->m_params.nThreadsGroupId) - { - pool = &m_threadsPools[i]; - } - } - - if (pool) - { - // Find available thread for the task. - for (i = 0; i < (int)pool->m_Threads.size(); ++i) - { - CThreadTask_Thread* pThread = pool->m_Threads[i]; - const bool threadIsFree = pThread->tasks.empty() && pThread->m_pProcessingTask == NULL; - if (threadIsFree || pGoodThread == NULL) - { - pGoodThread = pThread; - if (threadIsFree) - { - break; - } - } - } - } - else - { - gEnv->pLog->LogError("[Error]Task manager: threads pool not found!"); - assert(0); - } - } - else if (pTaskInfo->m_params.nPreferedThread >= 0 && pTaskInfo->m_params.nPreferedThread < (int)m_threads.size()) - { - assert((int)m_threads.size() > pTaskInfo->m_params.nPreferedThread); - // Assign task to desired thread. - pGoodThread = m_threads[pTaskInfo->m_params.nPreferedThread]; - } - else - { - // Find available thread for the task. - for (i = MAIN_THREAD_INDEX + 1; i < (int)m_threads.size(); i++) - { - CThreadTask_Thread* pThread = m_threads[i]; - PREFAST_ASSUME(pThread); - if (pThread->tasks.empty() || pGoodThread == NULL) - { - pGoodThread = pThread; - if (pThread->tasks.empty()) - { - break; - } - } - } - } - if (!pGoodThread && !m_threads.empty()) - { - // Assign to last thread. - pGoodThread = m_threads[m_threads.size() - 1]; - } - - if (pGoodThread) - { - pGoodThread->AddTask(pTaskInfo); - } - else - { - m_unassignedTasks.push(pTaskInfo); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::RescheduleTasks() -{ - // Un-schedule all tasks. - for (int i = 0; i < (int)m_threads.size(); i++) - { - while (!m_threads[i]->tasks.empty()) - { - SThreadTaskInfo* pTask = m_threads[i]->tasks.pop(); - if (!pTask) - { - break; - } - if (pTask->m_params.nFlags & THREAD_TASK_BLOCKING) // Do not schedule blocking tasks. - { - m_threads[i]->tasks.push(pTask); - break; - } - pTask->m_pThread = NULL; - m_unassignedTasks.push(pTask); - } - } - - while (!m_unassignedTasks.empty()) - { - ScheduleTask(m_unassignedTasks.pop()); - } -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::OnUpdate() -{ - AZ_TRACE_METHOD(); - FUNCTION_PROFILER_LEGACYONLY(GetISystem(), PROFILE_SYSTEM); - - // Emulate single update of the main thread. - if (m_threads[0]) - { - m_threads[0]->SingleUpdate(); - } - - // assign unassigned tasks - while (!m_unassignedTasks.empty()) - { - ScheduleTask(m_unassignedTasks.pop()); - } - - // balance all pools - AUTO_READLOCK(m_threadsPoolsLock); - size_t nSize = m_threadsPools.size(); - for (size_t itPool = 0; itPool < nSize; ++itPool) - { - BalanceThreadsPool(m_threadsPools[itPool].m_hHandle); - } -} - -struct THREADNAME_INFO_TASK -{ - DWORD dwType; - LPCSTR szName; - DWORD dwThreadID; - DWORD dwFlags; -}; - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::SetThreadName(threadID dwThreadId, const char* sThreadName) -{ - if (dwThreadId == (THREADID_NULL)) - { - dwThreadId = GetCurrentThreadId(); - } - -#if defined(AZ_PROFILE_TELEMETRY) && AZ_TRAIT_OS_USE_WINDOWS_THREADS - AZStd::thread_desc desc; - desc.m_name = sThreadName; - // we broadcast to the "client" bus and then to the "driller" (profiling) bus - AZStd::ThreadEventBus::Broadcast(&AZStd::ThreadEventBus::Events::OnThreadEnter, AZStd::thread::id(dwThreadId), &desc); - AZStd::ThreadDrillerEventBus::Broadcast(&AZStd::ThreadDrillerEventBus::Events::OnThreadEnter, AZStd::thread::id(dwThreadId), &desc); -#endif - -#if AZ_LEGACY_CRYSYSTEM_TRAIT_THREADTASK_EXCEPTIONS - ////////////////////////////////////////////////////////////////////////// - // Raise exception to set thread name for debugger. - ////////////////////////////////////////////////////////////////////////// - THREADNAME_INFO_TASK threadName; - threadName.dwType = 0x1000; - threadName.szName = sThreadName; - threadName.dwThreadID = dwThreadId; - threadName.dwFlags = 0; - - __try - { - RaiseException(0x406D1388, 0, sizeof(threadName) / sizeof(DWORD), (ULONG_PTR*)&threadName); - } - __except (EXCEPTION_CONTINUE_EXECUTION) - { - } -#endif - -#if defined(AZ_RESTRICTED_PLATFORM) -#define AZ_RESTRICTED_SECTION THREADTASK_CPP_SECTION_2 -#include AZ_RESTRICTED_FILE(ThreadTask_cpp) -#endif - - { - m_threadNameLock.Lock(); - m_threadNames[dwThreadId] = sThreadName; - m_threadNameLock.Unlock(); - } -} - -////////////////////////////////////////////////////////////////////////// -const char* CThreadTaskManager::GetThreadName(threadID dwThreadId) -{ - CryAutoCriticalSection lock(m_threadNameLock); - ThreadNames::const_iterator it = m_threadNames.find(dwThreadId); - if (it != m_threadNames.end()) - { - return it->second.c_str(); - } - - return ""; -} - -////////////////////////////////////////////////////////////////////////// -threadID CThreadTaskManager::GetThreadByName(const char* sThreadName) -{ - CryAutoCriticalSection lock(m_threadNameLock); - for (ThreadNames::const_iterator it = m_threadNames.begin(); it != m_threadNames.end(); ++it) - { - if (it->second.compareNoCase(sThreadName) == 0) - { - return it->first; - } - } - return 0; -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::AddSystemThread(threadID nThreadId) -{ - CryAutoCriticalSection lock(m_systemThreadsLock); - m_systemThreads.push_back(nThreadId); -} - -////////////////////////////////////////////////////////////////////////// -void CThreadTaskManager::RemoveSystemThread(threadID nThreadId) -{ - CryAutoCriticalSection lock(m_systemThreadsLock); - stl::find_and_erase(m_systemThreads, nThreadId); -} - -////////////////////////////////////////////////////////////////////////// -ThreadPoolHandle CThreadTaskManager::CreateThreadsPool(const ThreadPoolDesc& desc) -{ - AUTO_MODIFYLOCK(m_threadsPoolsLock); - - ThreadPoolHandle newId = m_threadsPools.empty() ? 0 : m_threadsPools.rbegin()->m_hHandle + 1; - - if (desc.AffinityMask == INVALID_AFFINITY) - { - assert(0); - return -1; - } - - // create the pool - m_threadsPools.push_back(CThreadsPool()); - CThreadsPool& rPool = m_threadsPools.back(); - - // assign the new handle - rPool.m_hHandle = newId; - - // fill up the desc - rPool.m_pDescription = desc; - - Threads& threads = rPool.m_Threads; - - size_t threadNameSize = desc.sPoolName.size() + 30; - std::vector threadName(threadNameSize); - uint32 iThread = 0; - for (uint32 nIndex = 0; nIndex < sizeof(desc.AffinityMask) * 8; ++nIndex) - { - // check if we have affinity mask bit set for this thread - if (!(desc.AffinityMask & (1 << nIndex))) - { - continue; - } - - const int32 nThreadPriority = (desc.nThreadPriority == -1) ? THREAD_PRIORITY_NORMAL : desc.nThreadPriority; - const int32 nThreadStackSizeKB = (desc.nThreadStackSizeKB == -1) ? SIMPLE_THREAD_STACK_SIZE_KB : desc.nThreadStackSizeKB; - - // create a thread - sprintf_s(&threadName[0], threadNameSize, "%s%d", desc.sPoolName.c_str(), iThread); - CThreadTask_Thread* thread = new CThreadTask_Thread(this, &threadName[0], iThread, nIndex, nThreadPriority, newId); - - // start thread - thread->Start(0, (char*)&threadName[0], nThreadPriority, nThreadStackSizeKB * 1024); - - // add to pool - threads.push_back(thread); - - iThread++; - } - - return newId; -} - -const bool CThreadTaskManager::DestroyThreadsPool(const ThreadPoolHandle& handle) -{ - AUTO_MODIFYLOCK(m_threadsPoolsLock); - - CThreadsPool* pPool = NULL; - size_t nSize = m_threadsPools.size(); - size_t iPool = 0; - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - Threads& threads = pPool->m_Threads; - size_t nThreads = threads.size(); - for (size_t iThread = 0; iThread < nThreads; ++iThread) - { - CThreadTask_Thread* pThread = threads[iThread]; - PREFAST_ASSUME(pThread); - pThread->Cancel(); - assert(!(pThread->bRunning)); - delete pThread; - } - - m_threadsPools.erase(m_threadsPools.begin() + iPool); - return true; - } - return false; -} - -const bool CThreadTaskManager::GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const -{ - AUTO_READLOCK(m_threadsPoolsLock); - - const CThreadsPool* pPool = NULL; - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - if (pDesc) - { - *pDesc = pPool->m_pDescription; - return true; - } - } - - return false; -} - -const bool CThreadTaskManager::SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask) -{ - CThreadsPool* pPool = NULL; - - AUTO_MODIFYLOCK(m_threadsPoolsLock); - - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - return pPool->SetAffinity(AffinityMask); - } - - return false; -} - -void CThreadTaskManager::BalanceThreadsPool(const ThreadPoolHandle& handle) -{ - CThreadsPool* pPool = NULL; - - AUTO_READLOCK(m_threadsPoolsLock); - - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == handle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - // balancing tasks in the pool - for (size_t itThread = 0, nThreads = pPool->m_Threads.size(); itThread < nThreads; ++itThread) - { - CThreadTask_Thread* pThread = pPool->m_Threads[itThread]; - if (pThread->tasks.empty()) // found free thread(without tasks) - { - BalanceThreadInPool(pThread, &pPool->m_Threads); - } - } - } - else - { - assert(0); - } -} - -void CThreadTaskManager::BalanceThreadInPool(CThreadTask_Thread* pFreeThread, Threads* pThreads /* = NULL */) -{ - assert(pFreeThread->m_poolHandle != -1); - - AUTO_READLOCK(m_threadsPoolsLock); - - if (pThreads == NULL) - { - CThreadsPool* pPool = NULL; - size_t iPool = 0, nSize = m_threadsPools.size(); - for (; iPool < nSize; ++iPool) - { - if (m_threadsPools[iPool].m_hHandle == pFreeThread->m_poolHandle) - { - pPool = &m_threadsPools[iPool]; - break; - } - } - - if (pPool) - { - pThreads = &pPool->m_Threads; - } - } - assert(pThreads); - PREFAST_ASSUME(pThreads); - // search for thread with tasks - for (size_t itAnotherThread = 0, nThreads = pThreads->size(); itAnotherThread < nThreads; ++itAnotherThread) - { - CThreadTask_Thread* pAnotherThread = (*pThreads)[itAnotherThread]; - if (pFreeThread == pAnotherThread) - { - continue; - } - if (pAnotherThread->tasks.empty()) - { - continue; - } - - // we found a thread with more than one task - SThreadTaskInfo* pTask = pAnotherThread->tasks.pop(); - if (pTask) - { - assert(pTask->m_pThread == pAnotherThread); - // reassign the last task to another thread - pFreeThread->AddTask(pTask); - break; // process next free thread - } - } -} - -void CThreadTaskManager::MarkThisThreadForDebugging(const char* name, bool bDump) -{ - bDump ? ::MarkThisThreadForDebugging(name) : ::UnmarkThisThreadFromDebugging(); -} - - -const bool CThreadTaskManager::CThreadsPool::SetAffinity(const ThreadPoolAffinityMask AffinityMask) -{ - // check if all threads in the pool are covered by the bits of this mask - if (CountBits(AffinityMask) != m_Threads.size()) - { - // wrong arguments - return false; - } - - // update affinity mask - m_pDescription.AffinityMask = AffinityMask; - - size_t itThread = 0; - for (uint32 nProcessorIndex = 0; nProcessorIndex < sizeof(AffinityMask) * 8; ++nProcessorIndex) - { - assert(itThread < m_Threads.size()); - // check if we have affinity mask bit set for this thread - if (!(AffinityMask & (1 << nProcessorIndex))) - { - continue; - } - - // changin thread's affinity in the pool - m_Threads[itThread]->ChangeProcessor(nProcessorIndex); - ++itThread; - } - return true; -} diff --git a/Code/CryEngine/CrySystem/ThreadTask.h b/Code/CryEngine/CrySystem/ThreadTask.h deleted file mode 100644 index e528fedf5f..0000000000 --- a/Code/CryEngine/CrySystem/ThreadTask.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_THREADTASK_H -#define CRYINCLUDE_CRYSYSTEM_THREADTASK_H -#pragma once - - -#include -#include -#include - -#define MAIN_THREAD_INDEX 0 - -class CThreadTask_Thread; - - -void MarkThisThreadForDebugging(const char* name); -void UnmarkThisThreadFromDebugging(); -void UpdateFPExceptionsMaskForThreads(); - - -class CThreadTaskManager; -/// -struct IThreadTaskRunnable -{ - virtual ~IThreadTaskRunnable(){} - virtual void Run() = 0; - virtual void Cancel() = 0; -}; -////////////////////////////////////////////////////////////////////////// -class CThreadTask_Thread - : public CryThread - , public IThreadTask_Thread -{ -protected: - void Init(); -public: - CThreadTask_Thread(CThreadTaskManager* pTaskMgr, const char* sName, int nThreadIndex, int nProcessor, int nThreadPriority, ThreadPoolHandle poolHandle = -1); - ~CThreadTask_Thread(); - - // see IThreadTaskRunnable, CryThread<> - void Run() override; - void Cancel() override; - - // see CryThread<> - void Terminate() override; - - // IThreadTask_Thread - void AddTask(SThreadTaskInfo* pTaskInfo) override; - void RemoveTask(SThreadTaskInfo* pTaskInfo) override; - void RemoveAllTasks() override; - void SingleUpdate() override; - - void ChangeProcessor(int nProcessor); -public: - CThreadTaskManager* m_pTaskManager; - string m_sThreadName; - int m_nThreadIndex; // -1 means the thread is blocking - int m_nProcessor; - int m_nThreadPriority; - - THREAD_HANDLE m_hThreadHandle; - - // Tasks running on this thread. - typedef CryMT::CLocklessPointerQueue > Tasks; - Tasks tasks; - - // The task is being processing now - SThreadTaskInfo* m_pProcessingTask; - - CryEvent m_waitForTasks; - - // Set to true when thread must stop. - volatile bool bStopThread; - volatile bool bRunning; - - // handle of threads pool which this thread belongs to(if any) - ThreadPoolHandle m_poolHandle; -}; - -////////////////////////////////////////////////////////////////////////// -class CThreadTaskManager - : public IThreadTaskManager -{ -private: - typedef std::vector > Threads; - // note: this struct is auxilary and NOT thread-safe - // it is only for internal use inside the task manager - struct CThreadsPool - { - ThreadPoolHandle m_hHandle; - Threads m_Threads; - ThreadPoolDesc m_pDescription; - const bool SetAffinity(const ThreadPoolAffinityMask AffinityMask); - const bool operator < (const CThreadsPool& p) const { return m_hHandle < p.m_hHandle; } - const bool operator == (const CThreadsPool& p) const { return m_hHandle == p.m_hHandle; } - }; - - typedef std::vector ThreadsPools; - -public: - CThreadTaskManager(); - ~CThreadTaskManager(); - - void InitThreads(); - void CloseThreads(); - void StopAllThreads(); - - ////////////////////////////////////////////////////////////////////////// - // IThreadTaskManager - ////////////////////////////////////////////////////////////////////////// - virtual void RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options); - virtual void UnregisterTask(IThreadTask* pTask); - virtual void SetMaxThreadCount(int nMaxThreads); - virtual void SetThreadName(threadID dwThreadId, const char* sThreadName); - virtual const char* GetThreadName(threadID dwThreadId); - virtual threadID GetThreadByName(const char* sThreadName); - - // Thread pool framework - virtual ThreadPoolHandle CreateThreadsPool(const ThreadPoolDesc& desc); - virtual const bool DestroyThreadsPool(const ThreadPoolHandle& handle); - virtual const bool GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const; - virtual const bool SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask); - - virtual void MarkThisThreadForDebugging(const char* name, bool bDump); - ////////////////////////////////////////////////////////////////////////// - - // This is on update function of the main thread. - void OnUpdate(); - - void AddSystemThread(threadID nThreadId); - void RemoveSystemThread(threadID nThreadId); - - // Balancing tasks in the pool between threads - void BalanceThreadsPool(const ThreadPoolHandle& handle); - void BalanceThreadInPool(CThreadTask_Thread* pFreeThread, Threads* pThreads = NULL); - -private: - void ScheduleTask(SThreadTaskInfo* pTaskInfo); - void RescheduleTasks(); -private: - - // User created threads pools - mutable CryReadModifyLock m_threadsPoolsLock; - ThreadsPools m_threadsPools; - - // Physical threads available to system. - Threads m_threads; - - // Threads with single blocking task attached. - Threads m_blockingThreads; - - typedef CryMT::CLocklessPointerQueue Tasks; - - Tasks m_unassignedTasks; - - mutable CryCriticalSection m_threadNameLock; - mutable CryCriticalSection m_threadRemove; - typedef std::map ThreadNames; - ThreadNames m_threadNames; - - mutable CryCriticalSection m_systemThreadsLock; - std::vector m_systemThreads; - - // Max threads that can be executed at same time. - int m_nMaxThreads; -}; - - -#endif // CRYINCLUDE_CRYSYSTEM_THREADTASK_H diff --git a/Code/CryEngine/CrySystem/Timer.cpp b/Code/CryEngine/CrySystem/Timer.cpp index eb53c1b257..7545b42765 100644 --- a/Code/CryEngine/CrySystem/Timer.cpp +++ b/Code/CryEngine/CrySystem/Timer.cpp @@ -26,9 +26,6 @@ #include "Mmsystem.h" #endif -//this should not be included here -#include // needed for m_pSystem->GetIRenderer()->EF_Query(EFQ_RecurseLevel) - //#define PROFILING 1 #ifdef PROFILING static int64 g_lCurrentTime = 0; @@ -432,7 +429,7 @@ void CTimer::UpdateOnFrameStart() if (m_TimeDebug > 1) { - CryLogAlways("[CTimer]: Frame=%d Cur=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)currentTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); + CryLogAlways("[CTimer]: Cur=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)currentTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); } } @@ -558,7 +555,7 @@ void CTimer::Serialize(TSerialize ser) if (m_TimeDebug) { const int64 now = CryGetTicks(); - CryLogAlways("[CTimer]: Serialize: Frame=%d Last=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)m_lLastTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); + CryLogAlways("[CTimer]: Serialize: Last=%lld Now=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)now, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); } } } @@ -584,7 +581,7 @@ bool CTimer::PauseTimer(ETimer which, bool bPause) m_lGameTimerPausedTime = m_lLastTime + m_lOffsetTime; if (m_TimeDebug) { - CryLogAlways("[CTimer]: Pausing ON: Frame=%d Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); + CryLogAlways("[CTimer]: Pausing ON: Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); } } else @@ -593,7 +590,7 @@ bool CTimer::PauseTimer(ETimer which, bool bPause) m_lGameTimerPausedTime = 0; if (m_TimeDebug) { - CryLogAlways("[CTimer]: Pausing OFF: Frame=%d Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", gEnv->pRenderer->GetFrameID(false), (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); + CryLogAlways("[CTimer]: Pausing OFF: Last=%lld Off=%lld Async=%f CurrTime=%f UI=%f", (long long)m_lLastTime, (long long)m_lOffsetTime, GetAsyncCurTime(), GetCurrTime(ETIMER_GAME), GetCurrTime(ETIMER_UI)); } } diff --git a/Code/CryEngine/CrySystem/Timer.h b/Code/CryEngine/CrySystem/Timer.h index 8778405067..33cfbd6087 100644 --- a/Code/CryEngine/CrySystem/Timer.h +++ b/Code/CryEngine/CrySystem/Timer.h @@ -31,7 +31,7 @@ public: // interface ITimer ---------------------------------------------------------- - // TODO: Review m_time usage in System.cpp / SystemRender.cpp + // TODO: Review m_time usage in System.cpp // if it wants Game Time / UI Time or a new Render Time? virtual void ResetTimer(); diff --git a/Code/CryEngine/CrySystem/UnitTests/CryMathTests.cpp b/Code/CryEngine/CrySystem/UnitTests/CryMathTests.cpp deleted file mode 100644 index 6fc9ae7830..0000000000 --- a/Code/CryEngine/CrySystem/UnitTests/CryMathTests.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/* -* 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. -* -*/ - -#include "CrySystem_precompiled.h" -#include -#include - -namespace UnitTest -{ - class CryMathTestFixture - : public ::testing::Test - {}; - -#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS - TEST_F(CryMathTestFixture, DISABLED_InverserSqrt_HasAtLeast22BitsOfAccuracy) -#else - TEST_F(CryMathTestFixture, InverserSqrt_HasAtLeast22BitsOfAccuracy) -#endif - { - float testFloat(0.336950600); - const float result = isqrt_safe_tpl(testFloat * testFloat); - const float epsilon = 0.00001f; - EXPECT_NEAR(2.96779, result, epsilon); - } - -#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS - TEST_F(CryMathTestFixture, DISABLED_SimdSqrt_HasAtLeast23BitsOfAccuracy) -#else - TEST_F(CryMathTestFixture, SimdSqrt_HasAtLeast23BitsOfAccuracy) -#endif - { - float testFloat(3434.34839439); - const float result = sqrt_tpl(testFloat); - const float epsilon = 0.00001f; - EXPECT_NEAR(58.60331, result, epsilon); - } -} diff --git a/Code/CryEngine/CrySystem/UnitTests/CryPakUnitTests.cpp b/Code/CryEngine/CrySystem/UnitTests/CryPakUnitTests.cpp deleted file mode 100644 index 1935196570..0000000000 --- a/Code/CryEngine/CrySystem/UnitTests/CryPakUnitTests.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* -* 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. -* -*/ -#include "CrySystem_precompiled.h" - -#include -#include - -#include -#include // for max path decl -#include -#include -#include // for function<> in the find files callback. -#include -#include -#include -#include -#include - -namespace CryPakUnitTests -{ - -#if defined(AZ_PLATFORM_WINDOWS) - - // Note: none of the below is really a unit test, its all basic feature tests - // for critical functionality - - class Integ_CryPakUnitTests - : public ::testing::Test - { - protected: - bool IsPackValid(const char* path) - { - AZ::IO::IArchive* pak = gEnv->pCryPak; - if (!pak) - { - return false; - } - - if (!pak->OpenPack(path, AZ::IO::IArchive::FLAGS_PATH_REAL)) - { - return false; - } - - pak->ClosePack(path); - return true; - } - }; - - TEST_F(Integ_CryPakUnitTests, TestCryPakModTime) - { - AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance(); - ASSERT_NE(nullptr, fileIo); - - AZ::IO::IArchive* pak = gEnv->pCryPak; - // repeat the following test multiple times, since timing (seconds) can affect it and it involves time! - for (int iteration = 0; iteration < 10; ++iteration) - { - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds{ 100 }); - - // helper paths and strings - AZStd::string gameFolder = fileIo->GetAlias("@usercache@"); - - AZStd::string testFile = "unittest.bin"; - AZStd::string testFilePath = gameFolder + "\\" + testFile; - AZStd::string testPak = "unittest.pak"; - AZStd::string testPakPath = gameFolder + "\\" + testPak; - AZStd::string zipCmd = "-zip=" + testPakPath; - - // delete test files in case they already exist - fileIo->Remove(testFilePath.c_str()); - pak->ClosePack(testPakPath); - fileIo->Remove(testPakPath.c_str()); - - // create a test file - char data[] = "unittest"; - FILE* f = nullptr; - azfopen(&f, testFilePath.c_str(), "wb"); - EXPECT_TRUE(f != nullptr); // file successfully opened for writing - EXPECT_TRUE(fwrite(data, sizeof(char), sizeof(data), f) == sizeof(data)); // file written to successfully - EXPECT_TRUE(fclose(f) == 0); // file closed successfully - - AZ::IO::HandleType fDisk = pak->FOpen(testFilePath.c_str(), "rb"); - EXPECT_TRUE(fDisk > 0); // opened file on disk successfully - uint64_t modTimeDisk = pak->GetModificationTime(fDisk); // high res mod time extracted from file on disk - EXPECT_TRUE(pak->FClose(fDisk) == 0); // file closed successfully - - // create a low res copy of disk file's mod time - uint64_t absDiff, maxDiff = 20000000ul; - uint16_t dosDate, dosTime; - FILETIME ft; - LARGE_INTEGER lt; - - ft.dwHighDateTime = modTimeDisk >> 32; - ft.dwLowDateTime = modTimeDisk & 0xFFFFFFFF; - EXPECT_TRUE(FileTimeToDosDateTime(&ft, &dosDate, &dosTime) != FALSE); // converted to DOSTIME successfully - ft.dwHighDateTime = 0; - ft.dwLowDateTime = 0; - EXPECT_TRUE(DosDateTimeToFileTime(dosDate, dosTime, &ft) != FALSE); // converted to FILETIME successfully - lt.HighPart = ft.dwHighDateTime; - lt.LowPart = ft.dwLowDateTime; - uint64_t modTimeDiskLowRes = lt.QuadPart; - - absDiff = modTimeDiskLowRes >= modTimeDisk ? modTimeDiskLowRes - modTimeDisk : modTimeDisk - modTimeDiskLowRes; - EXPECT_LE(absDiff, maxDiff); // FILETIME (high res) and DOSTIME (low res) should be at most 2 seconds apart - - gEnv->pResourceCompilerHelper->CallResourceCompiler(testFilePath.c_str(), zipCmd.c_str()); - EXPECT_EQ(AZ::IO::ResultCode::Success, fileIo->Remove(testFilePath.c_str())); // test file on disk deleted successfully - - EXPECT_TRUE(pak->OpenPack(testPakPath)); // opened pak successfully - - AZ::IO::HandleType fPak = pak->FOpen(testFilePath.c_str(), "rb"); - EXPECT_GT(fPak, 0); // file (in pak) opened correctly - uint64_t modTimePak = pak->GetModificationTime(fPak); // low res mod time extracted from file in pak - EXPECT_EQ(0, pak->FClose(fPak)); // file closed successfully - - EXPECT_TRUE(pak->ClosePack(testPakPath)); // closed pak successfully - EXPECT_EQ(AZ::IO::ResultCode::Success, fileIo->Remove(testPakPath.c_str())); // test pak file deleted successfully - - absDiff = modTimePak >= modTimeDisk ? modTimePak - modTimeDisk : modTimeDisk - modTimePak; - // compare mod times. They are allowed to be up to 2 seconds apart but no more - EXPECT_LE(absDiff, maxDiff); // FILETIME (disk) and DOSTIME (pak) should be at most 2 seconds apart - // note: Do not directly compare the disk time and pack time, the resolution drops the last digit off in some cases in pak - // it only has a 2 second resolution. you may compare to make sure that the pak time is WITHIN 2 seconds (as above) but not equal. - - // we depend on the fact that crypak is rounding up, instead of down - EXPECT_GE(modTimePak, modTimeDisk); - } - } - - -#endif -} diff --git a/Code/CryEngine/CrySystem/UnixConsole.cpp b/Code/CryEngine/CrySystem/UnixConsole.cpp deleted file mode 100644 index d0a7bc15ff..0000000000 --- a/Code/CryEngine/CrySystem/UnixConsole.cpp +++ /dev/null @@ -1,2524 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for UNIX systems based on curses ncurses - - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "UnixConsole.h" - -#if defined(USE_DEDICATED_SERVER_CONSOLE) - -#if defined(USE_UNIXCONSOLE) - -#if !defined(WIN32) -#include -#include -#include -#include -#if defined(MAC) -#include -#include -#else -#include -#endif // defined(MAC) -#if defined(LINUX) || defined(MAC) - #include -#endif -#endif -#include - -#define UNIXConsole_MORE_LEFT "<<" -#define UNIXConsole_MORE_RIGHT ">>" -#define UNIXConsole_MORE_COLOR (3) // Colorpair index -#define UNIXConsole_PROMPT "] " -#define UNIXConsole_PROMPT_COLOR (2) // Colorpair index -#define UNIXConsole_WRAP_CHAR '\\' -#define UNIXConsole_WRAP_COLOR (4) -#define UNIXConsole_MIN_WIDTH (10) -#define UNIXConsole_MAX_LINES (1000) -#define UNIXConsole_MAX_HISTORY (100) - -#if defined(LINUX) || defined(MAC) -// Should find a better test for ncurses... -#define NCURSES 1 -#endif - -#if defined(WIN32) -#define snprintf _snprintf -#endif - -// macro which check if we should process console function -// used for disable console on Linux -#define IS_SHOW_CONSOLE if (!m_bShowConsole) {return; } -#define IS_SHOW_CONSOLE_RET(ret) if (!m_bShowConsole) {return ret; } - - -CryCriticalSectionNonRecursive CUNIXConsole::m_cleanupLock; - -class CUNIXConsoleInputThread - : public CrySimpleThread<> -{ - CUNIXConsole& m_UNIXConsole; -#if !defined(WIN32) - int m_IntrPipe[2]; -#else - HANDLE m_IntrEvent; -#endif - bool m_Cancelled; - -public: - CUNIXConsoleInputThread(CUNIXConsole& UNIXConsole) - : m_UNIXConsole(UNIXConsole) - , m_Cancelled(false) - { -#if !defined(WIN32) - pipe(m_IntrPipe); -#else - m_IntrEvent = CreateEvent(NULL, true, false, NULL); -#endif - } - - ~CUNIXConsoleInputThread() - { -#if !defined(WIN32) - close(m_IntrPipe[0]); - close(m_IntrPipe[1]); -#else - CloseHandle(m_IntrEvent); -#endif - } - - virtual void Run(); - virtual void Cancel() { m_Cancelled = true; Interrupt(); } - void Interrupt() - { -#if !defined(WIN32) - write(m_IntrPipe[1], "", 1); -#else - SetEvent(m_IntrEvent); -#endif - } -}; - -class CUNIXConsoleSignalHandler -{ - friend class CUNIXConsole; - - static CUNIXConsole* m_pUNIXConsole; - static void Handler(int signum); -}; - -CUNIXConsole::CUNIXConsole() - : m_HistoryIndex(-1) - , m_PromptResponse(0) - , m_pSystem(NULL) - , m_pConsole(NULL) - , m_pTimer(NULL) - , m_OnUpdateCalled(false) - , m_LastUpdateTime(0.0f) - , m_svMap(NULL) - , m_svGameRules(NULL) - , m_Width(~0) - , m_Height(~0) - , m_HeaderHeight(1) - , m_StatusHeight(1) - , m_CmdHeight(2) - , m_Color(DEFAULT_COLOR) - , m_DefaultColorPair(-1) - , m_EnableColor(true) - , m_WindowResized(false) - , m_OnShutdownCalled(false) - , m_Initialized(false) - , m_RequireDedicatedServer(false) - , m_ScrollUp(0) - , m_InputThread(NULL) - , m_CursorPosition(0) - , m_ScrollPosition(0) - , m_fsMode(false) - , m_bShowConsole(true) -{ -} - -CUNIXConsole::~CUNIXConsole() -{ - Cleanup(); - m_Lock.Lock(); -} - -void CUNIXConsole::SetRequireDedicatedServer(bool value) -{ - assert(!m_Initialized); - m_RequireDedicatedServer = value; -} - -#if defined(WIN32) || defined(WIN64) -void ResizeConBufAndWindow(HANDLE hConsole, SHORT xSize, SHORT ySize) -{ - CONSOLE_SCREEN_BUFFER_INFO csbi; /* hold current console buffer info */ - BOOL bSuccess; - SMALL_RECT srWindowRect; /* hold the new console size */ - COORD coordScreen; - - bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi); - /* get the largest size we can size the console window to */ - coordScreen = GetLargestConsoleWindowSize(hConsole); - /* define the new console window size and scroll position */ - srWindowRect.Right = (SHORT) (min(xSize, coordScreen.X) - 1); - srWindowRect.Bottom = (SHORT) (min(ySize, coordScreen.Y) - 1); - srWindowRect.Left = srWindowRect.Top = (SHORT) 0; - /* define the new console buffer size */ - coordScreen.X = xSize; - coordScreen.Y = ySize; - /* if the current buffer is larger than what we want, resize the */ - /* console window first, then the buffer */ - if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y > (DWORD) xSize * ySize) - { - bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); - bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); - bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); - bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); - } - /* if the current buffer is smaller than what we want, resize the */ - /* buffer first, then the console window */ - if ((DWORD) csbi.dwSize.X * csbi.dwSize.Y < (DWORD) xSize * ySize) - { - bSuccess = SetConsoleScreenBufferSize(hConsole, coordScreen); - bSuccess = SetConsoleWindowInfo(hConsole, TRUE, &srWindowRect); - } - /* if the current buffer *is* the size we want, don't do anything! */ - return; -} - -BOOL WINAPI CtrlHandler(DWORD evt) -{ - switch (evt) - { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - return TRUE; - case CTRL_CLOSE_EVENT: - gEnv->pSystem->Quit(); - return TRUE; - } - return FALSE; -} -#endif - -void CUNIXConsole::Init(const char* headerString) -{ - assert(!m_Initialized); - - if (headerString != NULL) - { - m_HeaderString = headerString; - } - -#if defined(WIN32) || defined(WIN64) - // Allocate a console for the process. We don't care if this is successful - // or not, because failure indicates that the process already has a - // console, which is fine. - AllocConsole(); - HANDLE hConsOut = GetStdHandle(STD_OUTPUT_HANDLE); - ResizeConBufAndWindow(hConsOut, 120, 60); - SetConsoleCtrlHandler(CtrlHandler, TRUE); -#endif - - // Initialize curses. - initscr(); - cbreak(); - noecho(); - nonl(); - intrflush(stdscr, FALSE); - keypad(stdscr, TRUE); - scrollok(stdscr, TRUE); - idcok(stdscr, TRUE); - idlok(stdscr, TRUE); - nodelay(stdscr, TRUE); - - // Enable color output. - if (m_EnableColor) - { - if (start_color() != OK) - { - m_EnableColor = false; - } - } - - if (m_EnableColor) - { -#if defined(NCURSES) - // Setup the color table. - short colorPair = 0; - attr_t attr; - attr_get(&attr, &colorPair, NULL); - m_DefaultColorPair = colorPair; - m_ColorPair[0] = m_DefaultColorPair; - m_ColorPair[1] = m_DefaultColorPair; - short color_fg = 0, color_bg = 0; - pair_content(m_DefaultColorPair, &color_fg, &color_bg); - short pair = 0; - init_pair(++pair, COLOR_BLUE, color_bg); - m_ColorPair[2] = pair; - init_pair(++pair, COLOR_GREEN, color_bg); - m_ColorPair[3] = pair; - init_pair(++pair, COLOR_RED, color_bg); - m_ColorPair[4] = pair; - init_pair(++pair, COLOR_CYAN, color_bg); - m_ColorPair[5] = pair; - init_pair(++pair, COLOR_YELLOW, COLOR_BLACK); - m_ColorPair[6] = pair; - init_pair(++pair, COLOR_MAGENTA, color_bg); - m_ColorPair[7] = pair; - init_pair(++pair, COLOR_RED, color_bg); - m_ColorPair[8] = pair; - init_pair(++pair, COLOR_BLACK, COLOR_WHITE); - m_ColorPair[9] = pair; -#else - // Color output supported only for ncurses. - m_EnableColor = false; - m_DefaultColorPair = 0; -#endif - } - else - { - m_DefaultColorPair = 0; - } - - // Set the screen size and draw the initial screen. - SetSize(COLS, LINES); - - m_syslogStats.Init(); - - m_Initialized = true; -} - -void CUNIXConsole::Cleanup() -{ - m_cleanupLock.Lock(); - if (m_Initialized) - { - // Kill the input thread. - if (m_InputThread != NULL) - { - m_InputThread->Cancel(); - m_InputThread->WaitForThread(); - delete m_InputThread; - m_InputThread = NULL; - } - - // Curses cleanup. - clear(); - endwin(); - - m_Initialized = false; - } - m_cleanupLock.Unlock(); -} - -void CUNIXConsole::SetSize(unsigned width, unsigned height) -{ - bool repaint = false; - - assert(IsLocked()); - if (width != m_Width) - { - m_Width = width; - FixCursorPosition(); - repaint = true; - } - if (height != m_Height) - { - m_Height = height; - repaint = true; - } - if (repaint) - { - Repaint(); - } -} - -bool CUNIXConsole::IsTooSmall() -{ - assert(IsLocked()); - if (m_Height < m_HeaderHeight + m_StatusHeight + m_CmdHeight + 1) - { - return true; - } - if (m_Width < UNIXConsole_MIN_WIDTH) - { - return true; - } - return false; -} - -void CUNIXConsole::CheckResize() -{ - assert(IsLocked()); -#if defined(NCURSES) - int lines, cols; - - IS_SHOW_CONSOLE - - if (m_WindowResized) - { - m_WindowResized = false; - // Get the new window size from the terminal driver. - winsize ws; - memset(&ws, 0, sizeof ws); - ioctl(1, TIOCGWINSZ, &ws); - lines = ws.ws_row; - cols = ws.ws_col; - if (m_Width != lines || m_Height != cols) - { - resizeterm(lines, cols); - SetSize(cols, lines); - Repaint(); - } - } -#endif -} - -void CUNIXConsole::NewLine() -{ - char lineBuf[3] = "\1X"; - bool doScroll = !m_LineBuffer.empty(); - - assert(IsLocked()); - lineBuf[1] = m_Color + '0'; - - if (m_LineBuffer.size() == UNIXConsole_MAX_LINES) - { - m_LineBuffer.pop_front(); - } - m_LineBuffer.push_back(lineBuf); - - if (doScroll) - { - ScrollLog(); - } - else - { - unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - move(row, 0); - } - if (m_ScrollUp > 0) - { - const string& lastDisplayLine - = m_LineBuffer[m_LineBuffer.size() - m_ScrollUp - 1]; - DrawLogLine(lastDisplayLine); - } -} - -void CUNIXConsole::ContinueLine() -{ - IS_SHOW_CONSOLE - - if (m_LineBuffer.empty()) - { - NewLine(); - return; - } - const string& lastLine = *m_LineBuffer.rbegin(); - unsigned column = DrawLogLine(lastLine, true /* noOutput */); - SetColorRaw(m_Color); - const unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - move(row, column); -} - -void CUNIXConsole::SetColor(int color) -{ - assert(IsLocked()); - m_Color = color; - SetColorRaw(color); - if (m_LineBuffer.empty()) - { - m_LineBuffer.push_back(""); - } - const TLineBuffer::const_reverse_iterator it = m_LineBuffer.rbegin(); - string& lastLine = const_cast(*it); - lastLine.push_back(1); - lastLine.push_back('0' + color); -} - -void CUNIXConsole::SetColorRaw(int color) -{ - attr_t colorAttr = 0; - - assert(IsLocked()); - if (color == DEFAULT_COLOR) - { - color = 0; - } - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(m_ColorPair[color]); - } - switch (color) - { - case 0: - attrset(A_NORMAL | colorAttr); - break; - case 1: - attrset(A_REVERSE | colorAttr); - break; - case 2: - case 3: - attrset(A_NORMAL | colorAttr); - break; - case 4: - attrset(A_BOLD | colorAttr); - break; - case 5: - attrset(A_NORMAL | colorAttr); - break; - case 6: - attrset(A_BOLD | colorAttr); - break; - case 7: - case 8: - case 9: - attrset(A_NORMAL | colorAttr); - break; - default: - abort(); - } -} - -void CUNIXConsole::Put(int c) -{ - assert(IsLocked()); - - // Get the last buffer line. - if (m_LineBuffer.empty()) - { - NewLine(); - } - const TLineBuffer::const_reverse_iterator it = m_LineBuffer.rbegin(); - string& lastLine = const_cast(*it); - assert(c >= 0x20); - - // Wrap the line if required. - unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - unsigned column = 0; - GetLineHeight(lastLine, &column); - assert(column <= m_Width); - lastLine.push_back(char(c)); - - if (m_ScrollUp == 0) - { - // Output the line wrap character. - if (column == m_Width - 1) - { - move(row, m_Width - 1); - attr_t colorAttr = 0; - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_WRAP_COLOR); - } - attrset(A_NORMAL | colorAttr); - addch(UNIXConsole_WRAP_CHAR); - ScrollLog(); - move(row, 0); - } - - // Output the character. - SetColorRaw(m_Color); - addch(c); - } -} - -void CUNIXConsole::Put(const char* s) -{ - assert(IsLocked()); - while (*s) - { - if (*s == '\n') - { - NewLine(); - } - else - { - Put(*s); - } - ++s; - } -} - -unsigned CUNIXConsole::GetLineLength(const string& line) -{ - unsigned length = 0; - - for (string::const_iterator it = line.begin(), itEnd = line.end(); - it != itEnd; - ++it) - { - char c = *it; - if (c == 1) - { - ++it; - assert(it != itEnd); - continue; - } - ++length; - } - return length; -} - -char CUNIXConsole::GetLastCharacter(const string& line, int* color) -{ - char c0 = 0, c1 = 0; - char lastChar = 0; - - if (!line.empty()) - { - for (int i = line.size() - 1; i >= 0; i--) - { - c1 = c0; - c0 = line[i]; - if (c0 == 1) - { - assert(lastChar); - if (color) - { - *color = c1 - '0'; - } - return lastChar; - } - else if (c0 && c1 != 1 && !lastChar) - { - lastChar = c0; - } - } - } - - *color = DEFAULT_COLOR; - if (lastChar) - { - return lastChar; - } - assert(c0 && c0 != 1); - return c0; -} - -unsigned CUNIXConsole::GetLineHeight(const string& line, unsigned* column) -{ - unsigned lineLength = GetLineLength(line); - unsigned height = 1; - - assert(IsLocked()); - while (lineLength > m_Width) - { - lineLength -= m_Width - 1; - ++height; - } - if (column != NULL) - { - *column = lineLength; - } - return height; -} - -void CUNIXConsole::ScrollLog() -{ - if (m_fsMode) - { - return; - } - - // Scroll the log window. We'll do that by defining a software scrolling - // region. The constructor has set scrollok() and idlok(), so the output - // routing will use the hardware scrolling region (if available). - unsigned top = m_HeaderHeight; - unsigned bottom = m_Height - m_CmdHeight - m_StatusHeight; - - assert(IsLocked()); - // Some curses implementations (pdcurses) require the current position to - // be within the defined scrolling region. - move(top, 0); - if (setscrreg(top, bottom) == OK) - { - move(bottom, 0); - addch('\n'); - setscrreg(0, m_Height - 1); - DrawStatus(1); - } - else - { - // Scrolling regions not supported. We'll scroll the entire window and - // the repaint everything except for the log window. - scroll(stdscr); - move(bottom - 1, 0); - attrset(A_NORMAL); - clrtobot(); - DrawHeader(); - DrawStatus(); - DrawCmd(); - } - move(bottom - 1, 0); -} - -bool CUNIXConsole::FixCursorPosition() -{ - IS_SHOW_CONSOLE_RET(false) - - bool repaint = false; - - assert(IsLocked()); - - // Clip the cursor position. - if (m_CursorPosition > (int)m_InputLine.size()) - { - m_CursorPosition = m_InputLine.size(); - } - - // Trivial scroll position fixes. - if (m_CursorPosition < (int)m_Width / 2 && m_ScrollPosition > 0) - { - m_ScrollPosition = 0; - repaint = true; - } - else if (m_CursorPosition < m_ScrollPosition) - { - m_ScrollPosition = m_CursorPosition - m_Width / 4; - repaint = true; - } - - assert(m_ScrollPosition <= m_CursorPosition); - // The method may be called after the cursor has been moved to the - // right, so we may have to scroll the input line. - int displayLenth = m_Width * m_CmdHeight; - displayLenth -= strlen(UNIXConsole_PROMPT); - // If the cursor is at the end of the input line, then we only must leave - // one space for the cursor itself, otherwise we must leave space for the - // right scroll indicator. - if (m_CursorPosition == m_InputLine.size()) - { - displayLenth -= 1; - } - else - { - displayLenth -= strlen(UNIXConsole_MORE_RIGHT); - } - if (m_ScrollPosition < m_CursorPosition - displayLenth) - { - m_ScrollPosition = m_CursorPosition - displayLenth; - repaint = true; - } - - return repaint; -} - -void CUNIXConsole::OnEdit() -{ - assert(IsLocked()); - m_SavedInputLine.clear(); - m_HistoryIndex = -1; - if (m_pConsole != NULL) - { - m_pConsole->ResetAutoCompletion(); - } -} - -void CUNIXConsole::KeyEnter() -{ - bool redrawAll = false; - bool pushCommand = false; - - assert(IsLocked()); - - // Scroll the log window to the bottom. - if (m_ScrollUp > 0) - { - m_ScrollUp = 0; - redrawAll = true; - } - - // Process the input line. - while (!m_InputLine.empty() && m_InputLine[0] == '\\') - { - m_InputLine.erase(0, 1); - } - if (!m_InputLine.empty()) - { - pushCommand = true; - -#if defined(UC_ENABLE_MAGIC_COMMANDS) - // Enable some magic commands intercepted by the console. All magic - // commands start with an '@' character. - { - const char* const command = m_InputLine.c_str(); - if (!azstricmp(command, "@quit")) - { - // We're called from the input thread, hence we can't join it. We - // have to prevent Cleanup() (called via atexit()) from trying to - // join. - CUNIXConsoleInputThread* inputThread = m_InputThread; - m_InputThread = NULL; - Unlock(); - if (m_pSystem != NULL) - { - m_pSystem->Quit(); - inputThread->Exit(); - } - exit(0); - // Not reached. - abort(); - } - // Add other magic commands here. - } -#endif - } - - if (pushCommand) - { - CSystem* pSystem = static_cast(gEnv->pSystem); -#if defined(CVARS_WHITELIST) - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); - bool execute = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(m_InputLine, false) : true; - if (execute) -#endif // defined(CVARS_WHITELIST) - { - m_CommandQueue.push_back(m_InputLine); - } - } - - if (!m_InputLine.empty()) - { - m_CommandHistory.push_back(m_InputLine); - while (m_CommandHistory.size() > UNIXConsole_MAX_HISTORY) - { - m_CommandHistory.pop_front(); - } - m_HistoryIndex = -1; - m_InputLine.clear(); - m_SavedInputLine.clear(); - m_CursorPosition = 0; - m_ScrollPosition = 0; - if (!redrawAll) - { - DrawCmd(); - refresh(); - } - } - - if (redrawAll) - { - Repaint(); - } -} -void CUNIXConsole::KeyUp() -{ - const int historySize = m_CommandHistory.size(); - - assert(IsLocked()); - if (m_HistoryIndex < historySize - 1) - { - if (m_HistoryIndex == -1) - { - m_SavedInputLine = m_InputLine; - } - m_HistoryIndex += 1; - m_InputLine = m_CommandHistory[historySize - m_HistoryIndex - 1]; - m_CursorPosition = m_InputLine.size(); - FixCursorPosition(); - DrawCmd(); - refresh(); - } -} - -void CUNIXConsole::KeyDown() -{ - const int historySize = m_CommandHistory.size(); - - assert(IsLocked()); - if (m_HistoryIndex > -1) - { - m_HistoryIndex -= 1; - if (m_HistoryIndex == -1) - { - m_InputLine = m_SavedInputLine; - m_SavedInputLine.clear(); - } - else - { - m_InputLine = m_CommandHistory[historySize - m_HistoryIndex - 1]; - } - m_CursorPosition = m_InputLine.size(); - FixCursorPosition(); - DrawCmd(); - refresh(); - } -} - -void CUNIXConsole::KeyLeft() -{ - assert(IsLocked()); - if (m_CursorPosition > 0) - { - m_CursorPosition -= 1; - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyRight() -{ - assert(IsLocked()); - if (m_CursorPosition < (int)m_InputLine.size()) - { - m_CursorPosition += 1; - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyHome(bool ctrl) -{ - assert(IsLocked()); - if (ctrl) - { - const int logHeight = GetLogHeight(); - int maxUp = m_LineBuffer.size() - logHeight; - if (m_ScrollUp != maxUp) - { - m_ScrollUp = maxUp; - Repaint(); - } - } - else if (m_CursorPosition != 0) - { - m_CursorPosition = 0; - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyEnd(bool ctrl) -{ - assert(IsLocked()); - if (ctrl) - { - const int logHeight = GetLogHeight(); - int maxUp = m_LineBuffer.size() - logHeight; - if (m_ScrollUp != 0) - { - m_ScrollUp = 0; - Repaint(); - } - } - else if (m_CursorPosition < (int)m_InputLine.size()) - { - m_CursorPosition = m_InputLine.size(); - DrawCmd(!FixCursorPosition()); - } -} - -void CUNIXConsole::KeyBackspace() -{ - assert(IsLocked()); - if (m_CursorPosition > 0) - { - m_InputLine.erase(m_CursorPosition - 1, 1); - m_CursorPosition -= 1; - FixCursorPosition(); - OnEdit(); - DrawCmd(); - } -} - -void CUNIXConsole::KeyDelete() -{ - assert(IsLocked()); - if (m_CursorPosition < (int)m_InputLine.size()) - { - m_InputLine.erase(m_CursorPosition, 1); - FixCursorPosition(); - OnEdit(); - DrawCmd(); - } -} - -void CUNIXConsole::KeyDeleteWord() -{ - assert(IsLocked()); - if (m_CursorPosition > 0) - { - const char* const inputLine = m_InputLine.c_str(); - const char* p = inputLine + m_CursorPosition - 1; - - while (p > inputLine && *p == ' ') - { - --p; - } - while (p > inputLine && *p != ' ') - { - --p; - } - m_InputLine.erase(p - inputLine, m_CursorPosition); - m_CursorPosition = (uint32)(p - inputLine); - FixCursorPosition(); - OnEdit(); - DrawCmd(); - - /* Old std::string based code, kept for reference. - size_t wordIndex; - wordIndex = m_InputLine.find_last_of(" ", m_CursorPosition - 1); - if (wordIndex != string::npos) - { - wordIndex = m_InputLine.find_last_not_of(" ", wordIndex); - if (wordIndex != string::npos) - wordIndex += 1; - } - if (wordIndex == string::npos) - { - m_InputLine.erase(0, m_CursorPosition); - m_CursorPosition = 0; - } - else - { - m_InputLine.erase(wordIndex, m_CursorPosition - wordIndex); - m_CursorPosition = wordIndex; - } - FixCursorPosition(); - OnEdit(); - DrawCmd(); - */ - } -} - -void CUNIXConsole::KeyKill() -{ - assert(IsLocked()); - if (m_CursorPosition < (int)m_InputLine.size()) - { - m_InputLine.resize(m_CursorPosition); - FixCursorPosition(); - OnEdit(); - DrawCmd(); - } -} - -void CUNIXConsole::KeyRepaint() -{ - assert(IsLocked()); - Repaint(); -} - -void CUNIXConsole::KeyTab() -{ - const char* result; - - assert(IsLocked()); - if (m_OnShutdownCalled) - { - return; - } - string Tmp(m_InputLine); - Unlock(); - result = m_pConsole->ProcessCompletion(Tmp.c_str()); - Lock(); - if (result != NULL) - { - if (result[0] == '\\') - { - ++result; - } - m_InputLine = result; - m_CursorPosition = m_InputLine.size(); - FixCursorPosition(); - m_SavedInputLine.clear(); - m_HistoryIndex = -1; - DrawCmd(); - refresh(); - } -} - -void CUNIXConsole::KeyPgUp(bool ctrl) -{ - const int logHeight = GetLogHeight(); - // int logStep = logHeight - 2; - int logStep = ctrl ? 10 : 1; - int maxUp = m_LineBuffer.size() - logHeight; - int prevScrollUp = m_ScrollUp; - - assert(IsLocked()); - if (logStep < 1) - { - logStep = 1; - } - if (maxUp < 0) - { - maxUp = 0; - } - m_ScrollUp += logStep; - if (m_ScrollUp > maxUp) - { - m_ScrollUp = maxUp; - } - if (m_ScrollUp != prevScrollUp) - { - Repaint(); - } -} - -void CUNIXConsole::KeyPgDown(bool ctrl) -{ - const int logHeight = GetLogHeight(); - // int logStep = logHeight - 2; - int logStep = ctrl ? 10 : 1; - int prevScrollUp = m_ScrollUp; - - assert(IsLocked()); - if (logStep < 1) - { - logStep = 1; - } - if (m_ScrollUp > 0) - { - m_ScrollUp -= logStep; - } - if (m_ScrollUp < 0) - { - m_ScrollUp = 0; - } - if (m_ScrollUp != prevScrollUp) - { - Repaint(); - } -} - -void CUNIXConsole::Key(int c) -{ - assert(IsLocked()); - assert(c >= 0x20 && c <= 0xff); - assert(m_CursorPosition <= (int)m_InputLine.size()); - m_InputLine.insert(m_CursorPosition, 1, (char)c); - m_CursorPosition += 1; - FixCursorPosition(); - OnEdit(); - DrawCmd(); - refresh(); -} - -void CUNIXConsole::Repaint() -{ - IS_SHOW_CONSOLE - - assert(IsLocked()); - clear(); - DrawHeader(); - if (m_fsMode) - { - DrawFullscreen(); - } - else - { - DrawLog(); - } - DrawStatus(); - DrawCmd(); - refresh(); -} - -void CUNIXConsole::Flush() -{ - IS_SHOW_CONSOLE - - assert(IsLocked()); - refresh(); -} - -void CUNIXConsole::InputIdle() -{ - IS_SHOW_CONSOLE - - if (m_pTimer == NULL) - { - return; - } - - Lock(); - - CTimeValue now = m_pTimer->GetAsyncTime(); - float timePassed = (now - m_LastUpdateTime).GetSeconds(); - - // If more than 0.2 sec have passed since the last OnUpdate() call, then - // we'll start painting dots to the status line. - if (timePassed > 0.2f) - { - int nDots = (int)(timePassed + 0.5) / 3; - if (nDots > (int) m_Width - 2) - { - nDots = (int)m_Width - 2; - } - if (m_ProgressStatus.length() != nDots) - { - m_ProgressStatus.clear(); - m_ProgressStatus.append(nDots, '.'); - DrawStatus(); - DrawCmd(true); - refresh(); - } - } - - Unlock(); -} - -// get at least n spaces -static char* GetSpaces(int n) -{ - static char* spaceBuffer = 0; - static int spaceBufferSz = 0; - - if (n > spaceBufferSz) - { - spaceBufferSz = MAX(spaceBufferSz * 2, n); - delete[] spaceBuffer; - spaceBuffer = new char[spaceBufferSz]; - memset(spaceBuffer, ' ', spaceBufferSz); - } - - return spaceBuffer; -} - -void CUNIXConsole::DrawHeader() -{ - IS_SHOW_CONSOLE - - const char* const headerString = m_HeaderString.c_str(); - int headerLength = m_HeaderString.size(); - int padLeft = 0, padRight = 0; - const char* term = termname(); - - assert(IsLocked()); - - if (m_HeaderHeight == 0) - { - return; - } - - if (headerLength >= (int)m_Width) - { - padLeft = 0; - padRight = 0; - headerLength = m_Width; - } - else - { - padLeft = (m_Width - headerLength) / 2; - padRight = m_Width - headerLength - padLeft; - } - move(m_HeaderHeight - 1, 0); -#if defined(LINUX) - // For the Linux console ncurses reports the A_UNDERLINE is supported, even - // thought it is not. We'll do an explicit test for the terminal type - // "linux" (i.e. Linux console). - if ((termattrs() & A_UNDERLINE) && strcasecmp(term, "linux")) - { - attrset(A_UNDERLINE); - } - else -#endif - { - if (m_EnableColor) - { - attrset(A_BOLD | COLOR_PAIR(m_ColorPair[2] /* blue */)); - } - else - { - attrset(A_REVERSE); - } - } - scrollok(stdscr, FALSE); - addnstr(GetSpaces(padLeft), padLeft); - addnstr(headerString, headerLength); - addnstr(GetSpaces(padRight), padRight); - scrollok(stdscr, TRUE); - attrset(A_NORMAL); -} - -// Output a single log line. -// If the noOutput flag is set to 'true', then no output is written to the -// screen and no cursor movements are performed. -// The method returns the current output column (i.e. the output column for -// the next charater to be written to the log window). -// Note: Even it the noOutput flag is set, the method will update the m_Color -// field of the UNIX console. -unsigned CUNIXConsole::DrawLogLine(const string& line, bool noOutput) -{ - IS_SHOW_CONSOLE_RET(0) - - const unsigned row = m_Height - m_CmdHeight - m_StatusHeight - 1; - unsigned column = 0; - - if (!noOutput) - { - assert(IsLocked()); - move(row, column); - attrset(A_NORMAL); - } - for (string::const_iterator it = line.begin(), itEnd = line.end(); it != itEnd; ) - { - char c = *it++; - if (column == m_Width - 1) - { - if (!noOutput) - { - attr_t colorAttr = 0; - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_WRAP_COLOR); - } - attrset(A_NORMAL | colorAttr); - addch(UNIXConsole_WRAP_CHAR); - ScrollLog(); - move(row, 0); - SetColorRaw(m_Color); - } - column = 0; - } - if (c == 1) - { - assert(it != itEnd); - int color = *it - '0'; - m_Color = color; - ++it; - if (!noOutput) - { - SetColorRaw(color); - } - continue; - } - if (!noOutput) - { - addch(c); - } - ++column; - } - return column; -} - -// The scrollUp parameter indicates how many log lines to scroll up from the -// bottom. -void CUNIXConsole::DrawLog() -{ - IS_SHOW_CONSOLE - - unsigned scrollUp = m_ScrollUp; - - assert(IsLocked()); - - if (IsTooSmall()) - { - return; - } - if (m_LineBuffer.empty()) - { - return; - } - - // DrawLog is called only on refresh and on window resize, so performance is - // not an issue. We'll simply repaint by re-sending the log lines from the - // scroll buffer. - int nLines = m_LineBuffer.size(); - int lastLine = nLines - 1 - (int)scrollUp; - int firstLine = lastLine - GetLogHeight(); - - if (firstLine < 0) - { - firstLine = 0; - } - for (int i = firstLine; i <= lastLine; ++i) - { - const string& line = m_LineBuffer[i]; - if (i > firstLine) - { - ScrollLog(); - } - DrawLogLine(line); - } -} - -void CUNIXConsole::DrawStatus(int maxLines) -{ - IS_SHOW_CONSOLE - - unsigned row = m_Height - m_CmdHeight - m_StatusHeight; - const char* statusLeft = NULL; - const char* statusRight = NULL; - char bufferLeft[256]; - char bufferRight[256]; - - assert(IsLocked()); - - if (IsTooSmall() || maxLines == 0 || m_StatusHeight == 0) - { - return; - } - else if (maxLines == -1) - { - maxLines = m_StatusHeight; - } - - // If we're scrolled, then the right size shows a scroll indicator. - if (m_ScrollUp > 0) - { - const int logHeight = GetLogHeight(); - int logBottomLine = (int)m_LineBuffer.size() - m_ScrollUp; - assert(logBottomLine >= 0); - float percent = 100.f * (float)logBottomLine / m_LineBuffer.size(); - if (m_ScrollUp == m_LineBuffer.size() - logHeight) - { - cry_strcpy(bufferRight, "| SCROLL:TOP "); - } - else - { - snprintf( - bufferRight, - sizeof bufferRight, - "| SCROLL:%.1f%% ", - percent); - bufferRight[sizeof(bufferRight) - 1] = 0; - } - statusRight = bufferRight; - } - - if (!m_Prompt.empty()) - { - // No status display when a user prompt is active. - } - else if (!m_ProgressStatus.empty()) - { - snprintf(bufferLeft, sizeof bufferLeft, " %s", m_ProgressStatus.c_str()); - bufferLeft[sizeof bufferLeft - 1] = 0; - statusLeft = bufferLeft; - } - else if (m_OnUpdateCalled) - { - // Standard status display. - // Map name and game rules on the left. - // Current update rate and player count on the right. - const char* mapName = m_svMap->GetString(); - const char* gameRules = m_svGameRules->GetString(); - snprintf(bufferLeft, sizeof bufferLeft, - " map:%s rules:%s", - mapName, - gameRules); - bufferLeft[sizeof bufferLeft - 1] = 0; - statusLeft = bufferLeft; - float updateRate = 0.f; - static float displayUpdateRate = 0.f; - if (m_pTimer != NULL) - { - updateRate = m_pTimer->GetFrameRate(); -#if 0 - // Avoid jumping numbers in the update rate display. Per update the - // displayed update rate changes by at most maxDeltaRate. - const static float maxDeltaRate = 10.0f; - if (updateRate - displayUpdateRate > maxDeltaRate) - { - displayUpdateRate += maxDeltaRate; - } - else if (updateRate - displayUpdateRate < -maxDeltaRate) - { - displayUpdateRate -= maxDeltaRate; - } - else - { - displayUpdateRate = updateRate; - } -#else - // Display the update rate as reported by the timer. - displayUpdateRate = updateRate; -#endif - } - else - { - displayUpdateRate = 0.f; - } - if (statusRight == NULL) - { - char* pBufferRight = bufferRight; - char* const pBufferRightEnd = bufferRight + sizeof bufferRight; - azstrcpy(pBufferRight, AZ_ARRAY_SIZE(bufferRight), "| "); - pBufferRight += strlen(pBufferRight); - int numPlayers = 0; - - if (pBufferRight < pBufferRightEnd) - { - if (m_pConsole != NULL) - { - pBufferRight += snprintf( - pBufferRight, - pBufferRightEnd - pBufferRight, - "upd:%.1fms(%.2f..%.2f) " \ - "rate:%.1f/s", - m_updStats.avgUpdateTime, m_updStats.minUpdateTime, m_updStats.maxUpdateTime, - displayUpdateRate); - } - else - { - cry_strcpy(pBufferRight, pBufferRightEnd - pBufferRight, "BUSY "); - } - } - bufferRight[sizeof bufferRight - 1] = 0; - statusRight = bufferRight; - } - } - else - { - // No status display (blank). This branch is taken on the very first draw - // operation of the UNIX console. - } - if (statusLeft == NULL) - { - statusLeft = ""; - } - if (statusRight == NULL) - { - statusRight = ""; - } - - int leftWidth = strlen(statusLeft); - int rightWidth = strlen(statusRight); - int pad = 0; - - if (leftWidth + rightWidth > (int)m_Width) - { - pad = 0; - if (rightWidth > (int)m_Width) - { - leftWidth = 0; - rightWidth = m_Width; - } - else - { - leftWidth = m_Width - rightWidth; - } - } - else - { - pad = m_Width - leftWidth - rightWidth; - } - - move(row, 0); - attrset(A_REVERSE | A_BOLD); - scrollok(stdscr, FALSE); - for (int i = 0; i < leftWidth; ++i) - { - addch(statusLeft[i]); - } - for (int i = 0; i < pad; ++i) - { - addch(' '); - } - for (int i = 0; i < rightWidth; ++i) - { - addch(statusRight[i]); - } - scrollok(stdscr, TRUE); - attrset(A_NORMAL); -} - -void CUNIXConsole::DrawFullscreen() -{ - IS_SHOW_CONSOLE - - scrollok(stdscr, FALSE); - - int maxy = 1; - for (DynArray::iterator iter = m_drawCmds.begin(); iter != m_drawCmds.end(); ++iter) - { - maxy = max(maxy, iter->y); - } - - int scrolly = min(maxy - 1, m_ScrollUp); - - for (DynArray::iterator iter = m_drawCmds.begin(); iter != m_drawCmds.end(); ++iter) - { - switch (iter->op) - { - case eCDO_PutText: - { - int y = iter->y - scrolly; - if (y < 0 || y > (int)m_Height - 4) - { - break; - } - if (iter->x < 0 || iter->x > (int)m_Width) - { - break; - } - int len = strlen(iter->text); - if (iter->x + len > (int)m_Width) - { - len = m_Width - iter->x; - } - move(y + 1, iter->x); - for (int i = 0; i < len; i++) - { - addch(iter->text[i]); - } - } - } - } - scrollok(stdscr, TRUE); -} - -void CUNIXConsole::DrawCmd(bool cursorOnly) -{ - IS_SHOW_CONSOLE - - unsigned row = m_Height - m_CmdHeight; - unsigned column = 0; - attr_t colorAttr = 0; - const unsigned promptWidth = strlen(UNIXConsole_PROMPT); - const unsigned moreLeftWidth = strlen(UNIXConsole_MORE_LEFT); - const unsigned moreRightWidth = strlen(UNIXConsole_MORE_RIGHT); - - assert(IsLocked()); - - // If the window is too small, then don't draw anything. - if (IsTooSmall() - || m_CmdHeight == 0 - || m_Width < promptWidth + moreLeftWidth + moreRightWidth) - { - return; - } - - if (!m_Prompt.empty()) - { - DrawCmdPrompt(); - return; - } - - if (!cursorOnly) - { - scrollok(stdscr, FALSE); - - // Draw the command prompt. - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_PROMPT_COLOR); - } - attrset(A_BOLD | colorAttr); - move(row, 0); - for (const char* p = UNIXConsole_PROMPT; *p; ++p) - { - addch(*p); - ++column; - } - - // Draw the left scroll indicator (if scrolled). - if (m_ScrollPosition > 0) - { - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_MORE_COLOR); - } - attrset(A_NORMAL | colorAttr); - for (const char* p = UNIXConsole_MORE_LEFT; *p; ++p) - { - addch(*p); - ++column; - } - } - - // Draw the input line. We'll draw to the end of the command window - // (leaving the last cell blank) and the overdraw the more indicator (if - // required). - string::const_iterator it = m_InputLine.begin(); - string::const_iterator itEnd = m_InputLine.end(); - if (m_ScrollPosition > 0) - { - for (int i = m_ScrollPosition + strlen(UNIXConsole_MORE_LEFT); - i > 0; - --i, ++it) - { - ; - } - } - attrset(A_NORMAL); - bool lineTruncated = false; - for (; it != itEnd; ++it) - { - char c = *it; - if (row == m_Height - 1 && column == m_Width - 1) - { - lineTruncated = true; - break; - } - if (column == m_Width) - { - row += 1; - column = 0; - assert(row < m_Height); - move(row, column); - } - addch(c); - ++column; - } - - // Draw the right scroll indicator (if required). - if (lineTruncated) - { - move(m_Height - 1, m_Width - moreRightWidth); - if (m_EnableColor) - { - colorAttr = COLOR_PAIR(UNIXConsole_MORE_COLOR); - } - attrset(A_NORMAL | colorAttr); - for (const char* p = UNIXConsole_MORE_RIGHT; *p; ++p) - { - addch(*p); - ++column; - } - } - else - { - attrset(A_NORMAL); - clrtobot(); - move(m_Height - 1, m_Width - 1); - addch(' '); - } - - scrollok(stdscr, TRUE); - } - - // Update the cursor position. - column = m_CursorPosition - m_ScrollPosition + promptWidth; - row = m_Height - m_CmdHeight; - if (column >= m_Width) - { - row += column / m_Width; - column %= m_Width; - } - move(row, column); - refresh(); -} - -void CUNIXConsole::DrawCmdPrompt() -{ - IS_SHOW_CONSOLE - - unsigned row = m_Height - m_CmdHeight; - unsigned column = 0; - - string::const_iterator it = m_Prompt.begin(); - string::const_iterator itEnd = m_Prompt.end(); - attrset(A_BOLD); - clrtobot(); - scrollok(stdscr, FALSE); - move(row, column); - for (; it != itEnd; ++it) - { - char c = *it; - if (row == m_Height - 1 && column == m_Width - 1) - { - break; - } - if (column == m_Width) - { - row += 1; - column = 0; - move(row, column); - } - addch(c); - ++column; - } - scrollok(stdscr, TRUE); - move(row, column); - refresh(); -} - -char CUNIXConsole::Prompt(const char* promptString, const char* responseChars) -{ - char response = 0; - - Lock(); - - while (m_PromptResponse != 0) - { - m_PromptCond.Wait(m_Lock); - } -#ifndef _NDEBUG - // This method is called from __assert_fail, so we better don't put any - // asserts in here... - if (!m_Prompt.empty() || !*promptString || !*responseChars) - { - abort(); - } - if (strlen(responseChars) + 1 > sizeof m_PromptResponseChars) - { - abort(); - } -#endif - m_Prompt = promptString; - cry_strcpy(m_PromptResponseChars, responseChars); - DrawCmd(); - while (m_PromptResponse == 0) - { - m_PromptCond.Wait(m_Lock); - } - response = m_PromptResponse; - m_PromptResponse = 0; - m_Prompt.clear(); - m_PromptResponseChars[0] = 0; - m_PromptCond.Notify(); - DrawCmd(); - - Unlock(); - - return response; -} - -bool CUNIXConsole::IsInputThread() -{ - CrySimpleThread<>* callerThread = CrySimpleThread<>::Self(); - - return callerThread == m_InputThread; -} - -void CUNIXConsole::PrintF(const char* format, ...) -{ - char lineBuffer[1024]; - va_list ap; - - va_start(ap, format); - vsnprintf(lineBuffer, sizeof lineBuffer, format, ap); - lineBuffer[sizeof lineBuffer - 1] = 0; - Print(lineBuffer); - va_end(ap); -} - -void CUNIXConsole::Print(const char* line) -{ - IS_SHOW_CONSOLE - - static string lastLine; - static bool firstCall = true; - const size_t lineLength = strlen(line); - size_t lineOffset = 0; - - Lock(); - - // Check if the last line is a true prefix of the specified text argument. - // It it is a prefix, then the output is added to the last line sent to the - // sink. - if (!firstCall - && lineLength > lastLine.size() - && !strncmp(line, lastLine.c_str(), lastLine.size())) - { - // Line continued. - lineOffset = lastLine.size(); - ContinueLine(); // Will set the correct color. - } - else - { - NewLine(); - SetColor(); - } - lastLine = line; - firstCall = false; - - for (size_t i = lineOffset; i < lineLength; ++i) - { - char c = line[i]; - switch (c) - { - case '\\': - if (i < lineLength - 1 && line[i + 1] == 'n') - { - // Sequence "\\n", treat as "\n". - NewLine(); - ++i; - continue; - } - break; - case '\n': - NewLine(); - continue; - case '\r': - ClearLine(); - continue; - case '\t': - // We'll do it like the graphical console, just add 4 spaces and don't - // care about TAB stops. - for (unsigned j = 0; j < 4; ++j) - { - Put(' '); - } - continue; - case '$': - if (i < lineLength - 1) - { - ++i; - char colorChar = line[i]; - if (isdigit(colorChar)) - { - SetColor(colorChar - '0'); - continue; - } - if (colorChar == 'o' || colorChar == 'O') - { - // Ignore. - continue; - } - } - break; - default: - break; - } - if (c < 0x20) - { - // Unrecognized control character. Ignore. - continue; - } - Put((unsigned char)c); - } - DrawCmd(true); - // Flush(); - - Unlock(); -} - -bool CUNIXConsole::OnError(const char* errorString) -{ - if (!m_Initialized) - { - return true; - } - - return true; -} - -void CUNIXConsole::OnInitProgress(const char* sProgressMsg) -{ - if (!m_Initialized) - { - return; - } - - Lock(); - m_ProgressStatus = sProgressMsg; - DrawStatus(); - DrawCmd(true); - Flush(); - Unlock(); -} - -void CUNIXConsole::OnInit(ISystem* pSystem) -{ - if (m_RequireDedicatedServer && !gEnv->IsDedicated()) - { - return; - } - - Lock(); - - if (!m_Initialized) - { - Init(); - } - - assert(m_pSystem == NULL); - m_pSystem = pSystem; - assert(m_pConsole == NULL); - m_pConsole = pSystem->GetIConsole(); - - // Add the output print sink to the system console. - if (m_pConsole != 0) - { - m_pConsole->AddOutputPrintSink(this); - } - - // Start the input thread. - m_InputThread = new CUNIXConsoleInputThread(*this); - m_InputThread->Start(); - - Unlock(); - -#if defined(NCURSES) - // Setup the signal handler. - struct sigaction action; - memset(&action, 0, sizeof action); - action.sa_handler = CUNIXConsoleSignalHandler::Handler; - sigfillset(&action.sa_mask); - CUNIXConsoleSignalHandler::m_pUNIXConsole = this; - sigaction(SIGWINCH, &action, NULL); - sigset_t mask; - memset(&mask, 0, sizeof mask); - sigemptyset(&mask); - sigaddset(&mask, SIGWINCH); - sigprocmask(SIG_UNBLOCK, &mask, NULL); -#endif -} - -void CUNIXConsole::OnShutdown() -{ - if (!m_Initialized) - { - return; - } - - Lock(); - assert(!m_OnShutdownCalled); - m_pConsole->RemoveOutputPrintSink(this); - m_OnShutdownCalled = true; - Unlock(); - - Cleanup(); -} - -void CUNIXConsole::OnUpdate() -{ - FUNCTION_PROFILER(gEnv->pSystem, PROFILE_SYSTEM); - - IS_SHOW_CONSOLE - - if (!m_Initialized) - { - return; - } - - bool updateStatus = false; - static CTimeValue lastStatusUpdate = 0.f; - - if (m_OnShutdownCalled) - { - return; - } - - Lock(); - - if (!m_OnUpdateCalled) - { - m_OnUpdateCalled = true; - assert(m_svMap == NULL); - assert(m_svGameRules == NULL); - m_svMap = m_pConsole->GetCVar("sv_map"); - m_svGameRules = m_pConsole->GetCVar("sv_gamerules"); - assert(m_pTimer == NULL); - m_pTimer = m_pSystem->GetITimer(); - } - - if (!m_ProgressStatus.empty()) - { - m_ProgressStatus.clear(); - updateStatus = true; - } - CTimeValue now = m_pTimer->GetAsyncTime(); - if ((now - lastStatusUpdate).GetSeconds() > 0.1f) - { - updateStatus = true; - } - m_LastUpdateTime = now; - - if (updateStatus) - { - DrawStatus(); - DrawCmd(true); - Flush(); - lastStatusUpdate = now; - } - - while (!m_CommandQueue.empty()) - { - const string& command = m_CommandQueue[0]; - Unlock(); - if (m_pConsole) - { - m_pConsole->ExecuteString(command.c_str()); - - // doing the check again in case m_pConsole was nulled while executing the command - if (m_pConsole) - { - m_pConsole->AddCommandToHistory(command.c_str()); - } - } - Lock(); - m_CommandQueue.pop_front(); - } - - m_pSystem->GetUpdateStats(m_updStats); - - bool fsMode = !m_drawCmds.empty(); - if (fsMode || fsMode != m_fsMode) - { - m_fsMode = fsMode; - Repaint(); - } - - Unlock(); -} - -void CUNIXConsole::GetMemoryUsage(ICrySizer* pSizer) -{ - size_t size = sizeof *this; - - Lock(); - - // We're using string (for various reasons), so our best guess of the - // size is the .size(). - size += m_HeaderString.size(); - size += m_LineBuffer.size() * sizeof(string); - for (TLineBuffer::const_iterator it = m_LineBuffer.begin(), - itEnd = m_LineBuffer.end(); - it != itEnd; - ++it) - { - size += it->size(); - } - size += m_CommandQueue.size() * sizeof(string); - for (TCommandQueue::const_iterator it = m_CommandQueue.begin(), - itEnd = m_CommandQueue.end(); - it != itEnd; - ++it) - { - size += it->size(); - } - size += m_CommandHistory.size() * sizeof(string); - for (TCommandHistory::const_iterator it = m_CommandHistory.begin(), - itEnd = m_CommandHistory.end(); - it != itEnd; - ++it) - { - size += it->size(); - } - if (m_InputThread != NULL) - { - size += sizeof *m_InputThread; - } - size += m_InputLine.size(); - size += m_SavedInputLine.size(); - size += m_ProgressStatus.size(); - - Unlock(); - - pSizer->AddObject(this, size); -} - -Vec2_tpl CUNIXConsole::BeginDraw() -{ - m_newCmds.resize(0); - return Vec2_tpl(80, 25 - 3); -} - -void CUNIXConsole::PutText(int x, int y, const char* msg) -{ - IS_SHOW_CONSOLE - - SConDrawCmd cmd; - cmd.op = eCDO_PutText; - cmd.x = x; - cmd.y = y; - cry_strcpy(cmd.text, msg); - m_newCmds.push_back(cmd); -} - -void CUNIXConsole::EndDraw() -{ - IS_SHOW_CONSOLE - - Lock(); - m_drawCmds.swap(m_newCmds); - Unlock(); -} - -void CUNIXConsoleInputThread::Run() -{ -#if !defined(WIN32) - fd_set rdfds; -#endif - bool interrupted = false; - - // The input thread selects stdin (0) and the interrupt pipe. The select() - // call has a timeout (typically 0.5 sec) and will call the InputIdle() - // method whenever the timer expires. - while (true) - { - interrupted = false; -#if !defined(WIN32) - FD_ZERO(&rdfds); - FD_SET(m_IntrPipe[0], &rdfds); - FD_SET(0, &rdfds); - timeval tv; - memset(&tv, 0, sizeof tv); - tv.tv_sec = 0; - tv.tv_usec = 100000; // 0.1 sec. - if (select(m_IntrPipe[0] + 1, &rdfds, NULL, NULL, &tv) != -1) - { - if (FD_ISSET(m_IntrPipe[0], &rdfds)) - { - char buf; - read(m_IntrPipe[0], &buf, 1); - interrupted = true; - } - else if (!FD_ISSET(0, &rdfds)) - { - // Both m_IntrPipe[0] and 0 are not ready, so this must be a timeout. - m_UNIXConsole.InputIdle(); - continue; - } - } - else - { - // Got interrupted by a signal. - assert(errno == EINTR); - interrupted = true; - } -#else - HANDLE handles[2]; - handles[0] = m_IntrEvent; - handles[1] = GetStdHandle(STD_INPUT_HANDLE); - DWORD result = WaitForMultipleObjects(2, handles, false, 10 /* 0.1 sec */); - switch (result) - { - case WAIT_OBJECT_0: - interrupted = true; - ResetEvent(m_IntrEvent); - break; - case WAIT_OBJECT_0 + 1: - break; - case WAIT_TIMEOUT: - m_UNIXConsole.InputIdle(); - continue; - case WAIT_FAILED: - assert(!"WaitForMultipleObjects() failed"); - } -#endif - if (interrupted) - { - if (m_Cancelled) - { - break; - } - m_UNIXConsole.Lock(); - m_UNIXConsole.CheckResize(); - m_UNIXConsole.Unlock(); - continue; - } - int c = getch(); - m_UNIXConsole.Lock(); - - // Handle prompt responses. - if (!m_UNIXConsole.m_Prompt.empty()) - { - bool acceptAll = false; - char response = 0; - if (strchr(m_UNIXConsole.m_PromptResponseChars, '@')) - { - acceptAll = true; - } - if (c == KEY_ENTER || c == '\r') - { - c = '\n'; - } - if (c == KEY_BACKSPACE || c == 0x7f) - { - c = '\010'; - } - if (c <= 0xff && strchr(m_UNIXConsole.m_PromptResponseChars, (char)c)) - { - response = (char)c; - } - else if (acceptAll && (isprint(c) || c == '\n')) - { - response = (char)c; - } - else - { - beep(); - m_UNIXConsole.Unlock(); - continue; - } - m_UNIXConsole.m_PromptResponse = response; - m_UNIXConsole.m_PromptCond.Notify(); - m_UNIXConsole.Unlock(); - continue; - } - - // if console is hided then pass only F10 key - if (!m_UNIXConsole.m_bShowConsole) - { - if (KEY_F(10) == c) - { - m_UNIXConsole.KeyF(10); - } - m_UNIXConsole.Unlock(); - continue; - } - - switch (c) - { - case ERR: - break; - case KEY_RESIZE: - // Window size changed. This key is received only if the ncurses - // library is configured to handle SIGWINCH and if no other SIGWINCH - // handler has been installed. - m_UNIXConsole.SetSize(COLS, LINES); - m_UNIXConsole.Repaint(); - break; - case KEY_ENTER: - case PADENTER: - case '\r': - case '\n': - m_UNIXConsole.KeyEnter(); - break; - case KEY_UP: - case '\020': // CTRL-P - m_UNIXConsole.KeyUp(); - break; - case KEY_DOWN: - case '\016': // CTRL-N - m_UNIXConsole.KeyDown(); - break; - case KEY_LEFT: - m_UNIXConsole.KeyLeft(); - break; - case KEY_RIGHT: - m_UNIXConsole.KeyRight(); - break; - case KEY_HOME: - case '\001': // CTRL-A - m_UNIXConsole.KeyHome(false); - break; - case CTL_HOME: - m_UNIXConsole.KeyHome(true); - break; - case KEY_END: - case '\005': // CTRL-E - m_UNIXConsole.KeyEnd(false); - break; - case CTL_END: - m_UNIXConsole.KeyEnd(true); - break; - case KEY_BACKSPACE: -#if defined(MAC) - // Mac OS X returns delete key instead of backspace - case 0x7f: -#else - case '\010': // CTRL-H -#endif - m_UNIXConsole.KeyBackspace(); - break; - case KEY_DC: - case KEY_SDC: - case '\004': // CTRL-D - m_UNIXConsole.KeyDelete(); - break; - case '\027': // CTRL-W - m_UNIXConsole.KeyDeleteWord(); - break; - case '\013': // CTRL-K - m_UNIXConsole.KeyKill(); - break; - case '\014': // CTRL-L - m_UNIXConsole.KeyRepaint(); - break; - case '\t': // TAB - m_UNIXConsole.KeyTab(); - break; - case KEY_NPAGE: - case '\006': // CTRL-F - m_UNIXConsole.KeyPgDown(false); - break; - case CTL_PGDN: - m_UNIXConsole.KeyPgDown(true); - break; - case KEY_PPAGE: - case '\002': // CTRL-B - m_UNIXConsole.KeyPgUp(false); - break; - case CTL_PGUP: - m_UNIXConsole.KeyPgUp(true); - break; - case KEY_F(10): - m_UNIXConsole.KeyF(10); - break; - case KEY_F(11): - m_UNIXConsole.KeyF(11); - break; - default: - if (c >= 0x20 && c <= 0xff) - { - m_UNIXConsole.Key(c); - } - break; - } - m_UNIXConsole.Unlock(); - } -} - -void CUNIXConsole::KeyF(int id) -{ -#ifdef LINUX - if (11 == id) - { - def_prog_mode(); - endwin(); - m_bShowConsole = false; - system("/bin/bash"); - reset_prog_mode(); - refresh(); - m_bShowConsole = true; - } - else if (10 == id) - { - if (m_bShowConsole) - { - def_prog_mode(); - endwin(); - m_bShowConsole = false; - } - else - { - reset_prog_mode(); - refresh(); - m_bShowConsole = true; - } - } -#endif -} - -CUNIXConsole* CUNIXConsoleSignalHandler::m_pUNIXConsole = NULL; - -void CUNIXConsoleSignalHandler::Handler(int signum) -{ -#if defined(NCURSES) - switch (signum) - { - case SIGWINCH: - m_pUNIXConsole->m_WindowResized = true; - m_pUNIXConsole->m_InputThread->Interrupt(); - break; - default: - break; - } -#endif -} - -#endif // USE_UNIXCONSOLE - -/////////////////////////////////////////////////////////////////////////////////////// -// -// simple light-weight console implementation -// -/////////////////////////////////////////////////////////////////////////////////////// -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(UnixConsole_cpp) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -CNULLConsole::CNULLConsole(bool isDaemonMode) - : m_isDaemon(isDaemonMode) -{ -} - -void CNULLConsole::Print(const char* inszText) -{ - if (m_isDaemon) - { - return; - } - -#if defined(WIN32) || defined(WIN64) - DWORD written; - char buf[1024]; - sprintf_s(buf, "%s\n", inszText); - WriteConsole(m_hOut, buf, strlen(buf), &written, NULL); -#elif defined(LINUX) || defined(MAC) - printf("%s\n", inszText); -#endif -} - -void CNULLConsole::OnInit(ISystem* pSystem) -{ - m_syslogStats.Init(); - - if (m_isDaemon) - { - return; - } - - IConsole* pConsole = pSystem->GetIConsole(); - pConsole->AddOutputPrintSink(this); - -#if defined(WIN32) || defined(WIN64) - AllocConsole(); - m_hOut = GetStdHandle(STD_OUTPUT_HANDLE); -#endif -} - -void CNULLConsole::OnUpdate() -{ -} - -void CNULLConsole::PutText([[maybe_unused]] int x, [[maybe_unused]] int y, [[maybe_unused]] const char* msg) -{ -} -#endif - -/////////////////////////////////////////////////////////////////////////////////////// -// -// Logging server internal statistics into syslog service -// -/////////////////////////////////////////////////////////////////////////////////////// -CSyslogStats::CSyslogStats() - : m_syslog_stats(0) - , m_syslog_period(SYSLOG_DEFAULT_PERIOD) -{ -} - -CSyslogStats::~CSyslogStats() -{ -#if (defined(LINUX) && !defined(ANDROID)) || defined(MAC) -#if defined(NCURSES) - closelog(); -#endif - if (gEnv->pConsole) - { - gEnv->pConsole->UnregisterVariable("syslog_stats"); - gEnv->pConsole->UnregisterVariable("syslog_period"); - } -#endif -} - -void CSyslogStats::Init() -{ -#if (defined(LINUX) && !defined(ANDROID)) || defined(MAC) -#if defined(NCURSES) -# if defined(LINUX) - openlog("LinuxLauncher", LOG_PID, LOG_USER); -# elif defined(MAC) - openlog("MacLauncher", LOG_PID, LOG_USER); -# endif -#endif // NCURSES - - if (gEnv->pConsole) - { - REGISTER_CVAR2("syslog_stats", &m_syslog_stats, 0, 0, "Start/Stop logging server info into syslog"); - REGISTER_CVAR2("syslog_period", &m_syslog_period, SYSLOG_DEFAULT_PERIOD, 0, "Syslog logging timeout period"); - } -#endif -} - -void CSyslogStats::Update([[maybe_unused]] float srvRate, [[maybe_unused]] int numPlayers) -{ -} - -#endif // defined(USE_DEDICATED_SERVER_CONSOLE) - -// vim:ts=2 - diff --git a/Code/CryEngine/CrySystem/UnixConsole.h b/Code/CryEngine/CrySystem/UnixConsole.h deleted file mode 100644 index 12b2852e69..0000000000 --- a/Code/CryEngine/CrySystem/UnixConsole.h +++ /dev/null @@ -1,573 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Console implementation for UNIX systems, based on curses ncurses. - - -#pragma once - - -#include -#include - -#if defined(USE_DEDICATED_SERVER_CONSOLE) - -class CSyslogStats -{ -public: - CSyslogStats(); - ~CSyslogStats(); - - void Init(); - void Update(float srvRate, int numPlayers); - -private: - int m_syslog_stats; - int m_syslog_period; - CTimeValue m_syslogStartTime; - CTimeValue m_syslogCurrTime; - static const int SYSLOG_DEFAULT_PERIOD = 3000; // default timeout (sec) -}; - -#if defined(USE_UNIXCONSOLE) - -#if defined(WIN32) -// Avoid naming conflict with wincon.h. -#undef MOUSE_MOVED -#endif - -#include -#include - -// Avoid naming conflicts with pdcurses. -// Use werase(stdscr) instead of erase(). -#undef erase -// Use wclear(stdscr) instead of clear(). -#undef clear -// (MATT) Could not compile CONTAINER_VALUE etc templates for Vector{Map,Set} in ISerialise apparently because of the -// clear and erase macros. Changed order to undefine them straight after pdcurses. {2009/04/09} - -#include - - -// Define if you wish to enable the player count feature. -// Note: The player count feature can not be used when building -// Windows-style DLLs! -#if defined(LINUX) || defined(MAC) -#define UC_ENABLE_PLAYER_COUNT 1 -#else -#undef UC_ENABLE_PLAYER_COUNT -#endif - -// Define if you wish to enable magic console commands. -// These are commands starting with an '@' character, which are intercepted by -// the CUNIXConsole class and not passed to the system. -//#undef UC_ENABLE_MAGIC_COMMANDS -#define UC_ENABLE_MAGIC_COMMANDS 1 - -class CUNIXConsoleInputThread; -class CUNIXConsoleSignalHandler; - - -class CUNIXConsole - : public ISystemUserCallback - , public IOutputPrintSink - , public ITextModeConsole -{ - friend class CUNIXConsoleInputThread; - friend class CUNIXConsoleSignalHandler; - - static const int DEFAULT_COLOR = -1; - - typedef CryMutex ConsoleLock; - ConsoleLock m_Lock; - static CryCriticalSectionNonRecursive m_cleanupLock; - - enum EConDrawOp - { - eCDO_PutText, - }; - struct SConDrawCmd - { - EConDrawOp op; - int x, y; - char text[256]; - }; - DynArray m_drawCmds; - DynArray m_newCmds; - bool m_fsMode; - - CSyslogStats m_syslogStats; - bool m_bShowConsole; // hide or show console - - SSystemUpdateStats m_updStats; - - bool IsLocked() { return m_Lock.IsLocked(); } - - // The header string. - // - // Should be set by the launcher through SetHeader(). - string m_HeaderString; - - // The line buffer. - // - // We'll use the escape sequence "\1" followed by a digit to encode color - // changes. - typedef std::deque TLineBuffer; - TLineBuffer m_LineBuffer; - - // The command queue. - // - // Commands typed on the console are added to this command queue. It is - // processed by the OnUpdate() callback. - typedef std::deque TCommandQueue; - TCommandQueue m_CommandQueue; - - // The command history. - // - // The UNIX console is decoupled from the system console object through a - // command queue, so we can't use the history buffer from the system - // console. This is our own command history. - // - // The history index indicates the reverse index (counting from the end) - // into our command history. The special value -1 indicates that we're not - // currently showing a command from the history. - typedef std::deque TCommandHistory; - TCommandHistory m_CommandHistory; - int m_HistoryIndex; - - // Interactive prompt. - // - // If this is not empty, then this prompt is shown in the command area. The - // input thread will wait for one if the response characters. The response is - // stored to m_PromptResponse and m_PromptCond is notified. - string m_Prompt; - char m_PromptResponseChars[16]; // Null-terminated. - char m_PromptResponse; - CryConditionVariable m_PromptCond; - - ISystem* m_pSystem; - IConsole* m_pConsole; - ITimer* m_pTimer; // Initialized on the first call to OnUpdate(). - - // Flag indicating if OnUpdate() has been called. - // - // The initialization of the console variable pointers for 'sv_map' and - // 'sv_gamerules' is deferred until the first iteration of the update loop, - // because OnInit() is called too early for that. - bool m_OnUpdateCalled; - CTimeValue m_LastUpdateTime; - - ICVar* m_svMap; - ICVar* m_svGameRules; - - // Terminal window layout. - // - // The terminal window is split into 4 logical windows. Top to bottom, - // these windows are: - // - Header window. May be empty (height 0). - // - Log window. This is the area in the middle of the terminal showing the - // log messages. - // - Status window. This is a window below the log window showing things - // like current FPS or other status information. - // - Command window. This is a few lines (typically 1 or 2) at the - // bottom of the terminal window. The command prompt and command line - // editor is shown in the command window. - // - // The layout is implementated as a single curses window - the standard - // screen (stdscr). - - // The width and height of the terminal window. - unsigned m_Width, m_Height; - - // The height of the header window. - // The header window is displayed at the top of the terminal window. - // Typically 0 (no header) or 1 (single header line). - unsigned m_HeaderHeight; - - // The height of the status window. - // This is typically a single line between the log window and the command - // window, displayed in inverse video. - unsigned m_StatusHeight; - - // The height of the command window. - // This is typically a single line at the bottom of the screen. - unsigned m_CmdHeight; - - // The current text color. - int m_Color; - - // The default text color pair (read from curses when the app starts). - int m_DefaultColorPair; - - // Flag indicating if color output is enabled. - bool m_EnableColor; - - // Flag indicating that the window has been resized. - // Set by the SIGWINCH signal handler. - bool m_WindowResized; - - // Flag indicating that OnShutdown() has been called. - bool m_OnShutdownCalled; - - // Flag indicating if the console has been initialized (i.e. Init() has been - // called). - bool m_Initialized; - - // Flag indicating if the implied console initialization (performed by the - // OnInit() callback) requires a dedicated server. - // This flag is set through the public SetRequireDedicatedServer() method. - bool m_RequireDedicatedServer; - - // The number of (logical) lines scrolled up. - // 0 indicates that we're at the bottom of the log. - int m_ScrollUp; - - // Array of color pair handles. - // 0: default terminal color - // 1: default terminal color, reverse video - // 2: blue - // 3: green - // 4: red, bold font - // 5: cyan - // 6: yellow on black, bold font - // 7: magenta - // 8: red, normal text - // 9: black on white - short m_ColorPair[10]; - - // The keyboard input thread. - CUNIXConsoleInputThread* m_InputThread; - - // The current input line, cursor position, and horizontal scroll position. - string m_InputLine; - string m_SavedInputLine; - int m_CursorPosition; - int m_ScrollPosition; - - // The current progress status string. - // - // Set by the OnInitProgress() method and cleared by OnUpdate(). If this is - // not empty, then this is shown in the status line. - string m_ProgressStatus; - - // Set the size of the terminal window. - // - // This method is called when the UNIX console is created and whenever the - // size of the terminal window changes (i.e. SIGWINCH received). - // - // We're relying on the ncurses handler for SIGWINCH, so we'll call this - // method when getch() returns KEY_RESIZE. - void SetSize(unsigned width, unsigned height); - - // Check if the terminal window is too small for drawing. - bool IsTooSmall(); - - // Check if the window size has changed. - void CheckResize(); - - // Get the height of the log window. - unsigned GetLogHeight() - { - return m_Height - m_HeaderHeight - m_StatusHeight - m_CmdHeight; - } - - // Scroll the log window and start a new log line. - // - // Move the cursor position to the beginning of the new log line. - void NewLine(); - - // Continue the last log line. - // - // Move the cursor position to the first character following the last - // character logged and update the current color. - void ContinueLine(); - - // Clear the current output line. - // - // Move the cursor to the beginning of the current output line. - // - // Note: This is a bit fuzzy to implement because long wrapped lines are not - // easy to deal with. Instead I'll simply call NewLine() and maybe - // implement this later. - void ClearLine() { NewLine(); } - - // Set the output color. - // - // The color is one of the 10 color codes (0-9) used by the graphical - // console. If color output is enabled, then the corresponding terminal - // color is set. If color output is not enabled, then only the text - // attributes are changed. - // - // In addition to setting the color (if enabled), the method will set the - // following terminal attributes: - // 0, 1: Normal text (black, white) - // 4, 6: Bold text (red, yellow, typically indicates an error or warning) - // other: Underlined text - void SetColor(int color = DEFAULT_COLOR); - void SetColorRaw(int color); - - // Write a single character or a sequence of characters to the console, - // using the currently specified color. The specified character must be a - // printable character. - // - // Note: - // - The Put(const char *) method will interpret '\n' as a line separator an - // call NewLine() when encountered. All other characters must be - // printable characters. - // - Both Put() methods will _not_ update the cursor position before writing - // the character to the screen. It is up to the caller to update the - // cursor position (either by calling NewLine() or ContinueLine()). - void Put(int c); - void Put(const char* s); - - // Get the length of the line (number of displayed characters), not counting - // color change escapes. - static unsigned GetLineLength(const string& line); - - // Get the last printable character from the specified line. It is an error - // if the specified line contains no printable characters. If color is not - // NULL, then the selected color for the last character is stored to *color. - static char GetLastCharacter(const string& line, int* color); - - // Get the height of a line of text. - // - // The method returns the number of terminal lines to display the specified - // line (wrapped). If column is not NULL, then *column is set to the column - // indicating the end of the last wrapped terminal line. - unsigned GetLineHeight(const string& line, unsigned* column = NULL); - - // Scroll the log window one line. - void ScrollLog(); - - // Flush/repaint the screen. - void Flush(); - - // Called by the input thread when idle. - void InputIdle(); - - // Lock/unlock the UNIX console. - void Lock() { m_Lock.Lock(); } - void Unlock() { m_Lock.Unlock(); } - - // Fix the cursor position and scroll position after updating the command - // input line. Returns true if the command window must be repainted. - bool FixCursorPosition(); - - // Called when the command line has been edited. - void OnEdit(); - - // Keyboard input. - void KeyEnter(); - void KeyUp(); - void KeyDown(); - void KeyLeft(); - void KeyRight(); - void KeyHome(bool ctrl); - void KeyEnd(bool ctrl); - void KeyBackspace(); - void KeyDelete(); - void KeyDeleteWord(); - void KeyKill(); - void KeyRepaint(); - void KeyTab(); - void KeyPgUp(bool ctrl); - void KeyPgDown(bool ctrl); - void KeyF(int id); - void Key(int c); - - // Drawing. - void Repaint(); - void DrawHeader(); - unsigned DrawLogLine(const string&, bool noOutput = false); - void DrawLog(); - void DrawFullscreen(); - void DrawStatus(int maxLines = -1); - void DrawCmd(bool cursorOnly = false); - void DrawCmdPrompt(); - - CUNIXConsole(const CUNIXConsole&); - void operator = (const CUNIXConsole&); - -public: - CUNIXConsole(); - ~CUNIXConsole(); - - // Set or clear the RequireDedicatedServer flag. - // The implied initialization call performed by the - // ISystemUserCallback::OnInit() depends on this flag. - // Note: This method _must_ be called before Init() or OnInit() is called. - void SetRequireDedicatedServer(bool); - - // Initialize the console for use. - // - // This method must be called before any other method of the console is - // called. - // It is perfectly valid to instanciate a console and not use it (i.e. skip - // the Init() call). - // - // Note: If the ISystemUserCallback interface is used, then the call to - // Init() is optional. OnInit() will call Init() if it has not been called - // already. - void Init(const char* headerString = NULL); - - // Check if the console is initialized. - bool IsInitialized() { return m_Initialized; } - - // Cleanup function. - // This method is called by the destructor. - // If the instance has not been initialized (via Init() and/or OnInit()), - // then this method has no effect. - void Cleanup(); - - // Set the header string. - // Note: - // - Setting the header string does _not_ trigger a redraw. - // - This method may be called before Init() has been called. - void SetHeader(const char* headerString) - { - Lock(); - m_HeaderString = headerString; - Unlock(); - } - - // Issue a query-response prompt. - // - // promptString is the string to be shown as the query prompt. - // responseChars is a null-terminated string of valid response characters. - // Add '@' to the response characters if the user may type any character. - // - // The method blocks the caller until the user has typed a response. The - // return value is the response character typed by the user. - DLL_EXPORT char Prompt(const char* promptString, const char* responseChars); - - // Check if the calling thread is the input thread. - // - // This may be used to make sure that you're not calling Prompt() from the - // input thread - which will deadlock. - DLL_EXPORT bool IsInputThread(); - - // Print formatted. Calls Print(). - DLL_EXPORT void PrintF(const char* format, ...) PRINTF_PARAMS(2, 3); - - // Interface IOutputPrintSink ///////////////////////////////////////////// - DLL_EXPORT virtual void Print(const char* line); - - // Interface ISystemUserCallback ////////////////////////////////////////// - virtual bool OnError(const char* errorString); - virtual bool OnSaveDocument() { return false; } - virtual bool OnBackupDocument() { return false; } - virtual void OnProcessSwitch() { } - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem*); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - - // Interface ITextModeConsole ///////////////////////////////////////////// - virtual Vec2_tpl BeginDraw(); - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw(); -}; - -#endif // USE_UNIXCONSOLE - -#if defined(AZ_RESTRICTED_PLATFORM) -#include AZ_RESTRICTED_FILE(UnixConsole_h) -#endif -#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) -#undef AZ_RESTRICTED_SECTION_IMPLEMENTED -#else -// simple light-weight console -class CNULLConsole - : public IOutputPrintSink - , public ISystemUserCallback - , public ITextModeConsole -{ -public: - CNULLConsole(bool isDaemonMode); - - /////////////////////////////////////////////////////////////////////////////////////// - // IOutputPrintSink - /////////////////////////////////////////////////////////////////////////////////////// - virtual void Print(const char* inszText); - - /////////////////////////////////////////////////////////////////////////////////////// - // ISystemUserCallback - /////////////////////////////////////////////////////////////////////////////////////// - /** this method is called at the earliest point the ISystem pointer can be used - the log might not be yet there - */ - virtual void OnSystemConnect([[maybe_unused]] ISystem* pSystem) {}; - /** Signals to User that engine error occured. - @return true to Halt execution or false to ignore this error. - */ - virtual bool OnError([[maybe_unused]] const char* szErrorString) { return false; }; - /** If working in Editor environment notify user that engine want to Save current document. - This happens if critical error have occured and engine gives a user way to save data and not lose it - due to crash. - */ - virtual bool OnSaveDocument() { return false; } - - /** If working in Editor environment and a critical error occurs notify the user to backup - the current document to prevent data loss due to crash. - */ - virtual bool OnBackupDocument() { return false; } - - /** Notify user that system wants to switch out of current process. - (For ex. Called when pressing ESC in game mode to go to Menu). - */ - virtual void OnProcessSwitch() {}; - - // Notify user, usually editor about initialization progress in system. - virtual void OnInitProgress([[maybe_unused]] const char* sProgressMsg) {}; - - // Initialization callback. This is called early in CSystem::Init(), before - // any of the other callback methods is called. - virtual void OnInit(ISystem*); - - // Shutdown callback. - virtual void OnShutdown() {}; - - // Notify user of an update iteration. Called in the update loop. - virtual void OnUpdate(); - - // to collect the memory information in the user program/application - virtual void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) {}; - - /////////////////////////////////////////////////////////////////////////////////////// - // ITextModeConsole - /////////////////////////////////////////////////////////////////////////////////////// - virtual Vec2_tpl BeginDraw() { return Vec2_tpl(0, 0); }; - virtual void PutText(int x, int y, const char* msg); - virtual void EndDraw() {}; - - void SetRequireDedicatedServer(bool) - { - // Does nothing - } - void SetHeader(const char*) - { - //Does nothing - } -private: -#if defined(WIN32) || defined(WIN64) - HANDLE m_hOut; -#endif - bool m_isDaemon; - CSyslogStats m_syslogStats; -}; - -#endif - -#endif // defined(USE_DEDICATED_SERVER_CONSOLE) diff --git a/Code/CryEngine/CrySystem/Validator.h b/Code/CryEngine/CrySystem/Validator.h deleted file mode 100644 index 409377ee28..0000000000 --- a/Code/CryEngine/CrySystem/Validator.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_VALIDATOR_H -#define CRYINCLUDE_CRYSYSTEM_VALIDATOR_H - -#pragma once - -////////////////////////////////////////////////////////////////////////// -// Default validator implementation. -////////////////////////////////////////////////////////////////////////// -struct SDefaultValidator - : public IValidator -{ - CSystem* m_pSystem; - SDefaultValidator(CSystem* system) - : m_pSystem(system) {}; - virtual void Report(SValidatorRecord& record) - { - if (record.text) - { - static bool bNoMsgBoxOnWarnings = false; - if ((record.text[0] == '!') || (m_pSystem->m_sysWarnings && m_pSystem->m_sysWarnings->GetIVal() != 0)) - { - if (g_cvars.sys_no_crash_dialog) - { - return; - } - - if (bNoMsgBoxOnWarnings) - { - return; - } - -#ifdef WIN32 - ICVar* pFullscreen = (gEnv && gEnv->pConsole) ? gEnv->pConsole->GetCVar("r_Fullscreen") : 0; - if (pFullscreen && pFullscreen->GetIVal() != 0 && gEnv->pRenderer && gEnv->pRenderer->GetHWND()) - { - ::ShowWindow((HWND)gEnv->pRenderer->GetHWND(), SW_MINIMIZE); - } - string strMessage = record.text; - strMessage += "\n---------------------------------------------\nAbort - terminate application\nRetry - continue running the application\nIgnore - don't show this message box any more"; - switch (::MessageBox(NULL, strMessage.c_str(), "CryEngine Warning", MB_ABORTRETRYIGNORE | MB_DEFBUTTON2 | MB_ICONWARNING | MB_SYSTEMMODAL)) - { - case IDABORT: - m_pSystem->GetIConsole()->Exit ("User abort requested during showing the warning box with the following message: %s", record.text); - break; - case IDRETRY: - break; - case IDIGNORE: - bNoMsgBoxOnWarnings = true; - m_pSystem->m_sysWarnings->Set(0); - break; - } -#endif - } - } - } -}; - -#endif // CRYINCLUDE_CRYSYSTEM_VALIDATOR_H diff --git a/Code/CryEngine/CrySystem/ViewSystem/DebugCamera.cpp b/Code/CryEngine/CrySystem/ViewSystem/DebugCamera.cpp index ace30d5df7..f38dda32c7 100644 --- a/Code/CryEngine/CrySystem/ViewSystem/DebugCamera.cpp +++ b/Code/CryEngine/CrySystem/ViewSystem/DebugCamera.cpp @@ -137,15 +137,6 @@ void DebugCamera::PostUpdate() CCamera& camera = gEnv->pSystem->GetViewCamera(); camera.SetMatrix(Matrix34(m_view, m_position)); - - const float FONT_COLOR[4] = { 1.0f, 0.0f, 0.0f, 1.0f }; - gEnv->pRenderer->Draw2dLabel(0.0f, 700.0f, 1.3f, FONT_COLOR, false, - "Debug Camera: pos [ %.3f, %.3f, %.3f ] p/y [ %.1f, %.1f ] dir [ %.3f, %.3f, %.3f ] scl %.2f inv %d", - m_position.x, m_position.y, m_position.z, - m_cameraPitch, m_cameraYaw, - m_view.GetColumn1().x, m_view.GetColumn1().y, m_view.GetColumn1().z, - m_moveScale, - m_isYInverted); } /////////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/ViewSystem/View.cpp b/Code/CryEngine/CrySystem/ViewSystem/View.cpp index f8b84bea19..0ab2d6169b 100644 --- a/Code/CryEngine/CrySystem/ViewSystem/View.cpp +++ b/Code/CryEngine/CrySystem/ViewSystem/View.cpp @@ -101,25 +101,6 @@ void CView::Update(float frameTime, bool isActive) const float farPlane = (m_viewParams.farplane > 0.f) ? m_viewParams.farplane : DEFAULT_FAR; float fov = (m_viewParams.fov < 0.001f) ? DEFAULT_FOV : m_viewParams.fov; - // [VR] specific - // Modify FOV based on the HMD device configuration - bool isRenderingToHMD = gEnv->pRenderer ? gEnv->pRenderer->GetIStereoRenderer()->IsRenderingToHMD() : false; - if (isRenderingToHMD) - { - const AZ::VR::HMDDeviceInfo* deviceInfo = nullptr; - EBUS_EVENT_RESULT(deviceInfo, AZ::VR::HMDDeviceRequestBus, GetDeviceInfo); - if (deviceInfo) - { - //Add 12 degrees to the FOV here used for culling. - //It won't be used for rendering, just to make sure we don't cull - //anything out incorrectly. - //This value was decided based on experimentation with the HTC Vive - //and works perfectly fine for the Oculus Rift - const float fovCorrection = 12.0f; - fov = deviceInfo->fovV + DEG2RAD(fovCorrection); - } - } - m_camera.SetFrustum(pSysCam->GetViewSurfaceX(), pSysCam->GetViewSurfaceZ(), fov, nearPlane, farPlane, pSysCam->GetPixelAspectRatio()); //apply shake & set the view matrix @@ -140,20 +121,6 @@ void CView::Update(float frameTime, bool isActive) Vec3 pos = m_viewParams.position; Vec3 p = Vec3(ZERO); - if (isRenderingToHMD) - { - //This HMD tracking state is used JUST for use in the visibility system. - //RT_SetStereoCamera in D3DRendPipeline will override this info before rendering with the absolute - //latest tracking info. - const AZ::VR::TrackingState* trackingState = nullptr; - EBUS_EVENT_RESULT(trackingState, AZ::VR::HMDDeviceRequestBus, GetTrackingState); - if (trackingState && trackingState->CheckStatusFlags(AZ::VR::HMDStatus_IsUsable)) - { - p = q * AZVec3ToLYVec3(trackingState->pose.position); - q = q * AZQuaternionToLYQuaternion(trackingState->pose.orientation); - } - } - Matrix34 viewMtx(q); viewMtx.SetTranslation(pos + p); m_camera.SetMatrix(viewMtx); diff --git a/Code/CryEngine/CrySystem/ViewSystem/ViewSystem.cpp b/Code/CryEngine/CrySystem/ViewSystem/ViewSystem.cpp index 13f7f5b82d..c0f681511b 100644 --- a/Code/CryEngine/CrySystem/ViewSystem/ViewSystem.cpp +++ b/Code/CryEngine/CrySystem/ViewSystem/ViewSystem.cpp @@ -640,30 +640,6 @@ void CViewSystem::ClearAllViews() //////////////////////////////////////////////////////////////////// void CViewSystem::DebugDraw() { - IRenderer* pRenderer = gEnv->pRenderer; - if (pRenderer) - { - float xpos = 20; - float ypos = 15; - float fColor[4] = {1.0f, 1.0f, 1.0f, 0.7f}; - float fColorRed[4] = {1.0f, 0.0f, 0.0f, 0.7f}; - float fColorGreen[4] = {0.0f, 1.0f, 0.0f, 0.7f}; - - pRenderer->Draw2dLabel(xpos, 5, 1.35f, fColor, false, "ViewSystem Stats: %" PRISIZE_T " Views ", m_views.size()); - - IView* pActiveView = GetActiveView(); - for (TViewMap::iterator it = m_views.begin(); it != m_views.end(); ++it) - { - IView* pView = it->second; - const CCamera& cam = pView->GetCamera(); - bool isActive = (pView == pActiveView); - Vec3 pos = cam.GetPosition(); - Ang3 ang = cam.GetAngles(); - pRenderer->Draw2dLabel(xpos, ypos, 1.35f, isActive ? fColorGreen : fColorRed, false, "View Camera: %p . View Id: %d, pos (%f, %f, %f), ang (%f, %f, %f)", &cam, it->first, pos.x, pos.y, pos.z, ang.x, ang.y, ang.z); - - ypos += 11; - } - } } ////////////////////////////////////////////////////////////////////////// diff --git a/Code/CryEngine/CrySystem/VisRegTest.cpp b/Code/CryEngine/CrySystem/VisRegTest.cpp deleted file mode 100644 index 206d8f349a..0000000000 --- a/Code/CryEngine/CrySystem/VisRegTest.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Visual Regression Test - - -#include "CrySystem_precompiled.h" -#include "VisRegTest.h" - -#include "ISystem.h" -#include "IRenderer.h" -#include "IConsole.h" -#include "ITimer.h" -#include "IStreamEngine.h" -#include - -#include - -const float CVisRegTest::MaxStreamingWait = 30.0f; - -CVisRegTest::CVisRegTest() - : m_nextCmd(0) - , m_waitFrames(0) -{ - CryLog("Enabled visual regression tests"); -} - - -void CVisRegTest::Init(IConsoleCmdArgs* pParams) -{ - assert(pParams); - - stack_string configFile("visregtest.xml"); - - // Reset - m_cmdBuf.clear(); - m_dataSamples.clear(); - m_nextCmd = 0; - m_cmdFreq = 0; - m_waitFrames = 0; - m_streamingTimeout = 0.0f; - m_testName = "test"; - m_quitAfterTests = false; - - // Parse arguments - if (pParams->GetArgCount() >= 2) - { - m_testName = pParams->GetArg(1); - } - if (pParams->GetArgCount() >= 3) - { - configFile = pParams->GetArg(2); - } - if (pParams->GetArgCount() >= 4) - { - if (_stricmp(pParams->GetArg(3), "quit") == 0) - { - m_quitAfterTests = true; - } - } - - // Fill cmd buffer - if (!LoadConfig(configFile.c_str())) - { - CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "VisRegTest: Failed to load config file '%s' from game folder", configFile.c_str()); - return; - } - - gEnv->pTimer->SetTimeScale(0); - GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_RANDOM_SEED, 0, 0); - srand(0); - - gEnv->pRenderer->EnableGPUTimers2(true); -} - - -void CVisRegTest::AfterRender() -{ - ExecCommands(); -} - - -bool CVisRegTest::LoadConfig(const char* configFile) -{ - XmlNodeRef rootNode = GetISystem()->LoadXmlFromFile(configFile); - if (!rootNode || !rootNode->isTag("VisRegTest")) - { - return false; - } - - m_cmdBuf.push_back(SCmd(eCMDStart, "")); - - for (int i = 0; i < rootNode->getChildCount(); ++i) - { - XmlNodeRef node = rootNode->getChild(i); - - if (node->isTag("Config")) - { - SCmd cmd; - for (int j = 0; j < node->getChildCount(); ++j) - { - XmlNodeRef node2 = node->getChild(j); - - if (node2->isTag("ConsoleCmd")) - { - m_cmdBuf.push_back(SCmd(eCMDConsoleCmd, node2->getAttr("cmd"))); - } - } - } - else if (node->isTag("Map")) - { - const char* mapName = node->getAttr("name"); - int imageIndex = 0; - - m_cmdBuf.push_back(SCmd(eCMDLoadMap, mapName)); - m_cmdBuf.push_back(SCmd(eCMDOnMapLoaded, "")); - - for (int j = 0; j < node->getChildCount(); ++j) - { - XmlNodeRef node2 = node->getChild(j); - - if (node2->isTag("ConsoleCmd")) - { - m_cmdBuf.push_back(SCmd(eCMDConsoleCmd, node2->getAttr("cmd"))); - } - else if (node2->isTag("Sample")) - { - m_cmdBuf.push_back(SCmd(eCMDGoto, node2->getAttr("location"))); - m_cmdBuf.push_back(SCmd(eCMDWaitStreaming, "")); - - char strbuf[256]; -#ifdef WIN32 - sprintf_s(strbuf, "%s_%i.bmp", mapName, imageIndex++); -#else - sprintf_s(strbuf, "%s_%i.tga", mapName, imageIndex++); -#endif - m_cmdBuf.push_back(SCmd(eCMDCaptureSample, strbuf, SampleCount)); - } - } - } - } - - m_cmdBuf.push_back(SCmd(eCMDFinish, "")); - - return true; -} - - -void CVisRegTest::ExecCommands() -{ - if (m_nextCmd >= m_cmdBuf.size()) - { - return; - } - - float col[] = {0, 1, 0, 1}; - gEnv->pRenderer->Draw2dLabel(10, 10, 2, col, false, "Visual Regression Test"); - - if (m_waitFrames > 0) - { - --m_waitFrames; - return; - } - else if (m_waitFrames < 0) // Wait for streaming - { - SStreamEngineOpenStats stats; - gEnv->pSystem->GetStreamEngine()->GetStreamingOpenStatistics(stats); - if (stats.nOpenRequestCount > 0 && m_streamingTimeout > 0) - { - gEnv->pConsole->ExecuteString("t_FixedStep 0"); - m_streamingTimeout -= gEnv->pTimer->GetRealFrameTime(); - m_waitFrames = -16; - } - else if (++m_waitFrames == 0) - { - gEnv->pConsole->ExecuteString("t_FixedStep 0.033333"); - m_waitFrames = 64; // Wait some more frames for tone-mapper to adapt - } - - return; - } - - stack_string tmp; - - while (m_nextCmd < m_cmdBuf.size()) - { - SCmd& cmd = m_cmdBuf[m_nextCmd]; - - if (m_cmdFreq == 0) - { - m_cmdFreq = cmd.freq; - } - - switch (cmd.cmd) - { - case eCMDStart: - break; - case eCMDFinish: - Finish(); - break; - case eCMDOnMapLoaded: - gEnv->pTimer->SetTimer(ITimer::ETIMER_GAME, 0); - gEnv->pTimer->SetTimer(ITimer::ETIMER_UI, 0); - gEnv->pConsole->ExecuteString("t_FixedStep 0.033333"); - GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_RANDOM_SEED, 0, 0); - srand(0); - break; - case eCMDConsoleCmd: - gEnv->pConsole->ExecuteString(cmd.args.c_str()); - break; - case eCMDLoadMap: - LoadMap(cmd.args.c_str()); - break; - case eCMDWaitStreaming: - m_waitFrames = -1; - m_streamingTimeout = MaxStreamingWait; - break; - case eCMDWaitFrames: - m_waitFrames = (uint32)atoi(cmd.args.c_str()); - break; - case eCMDGoto: - tmp = "playerGoto "; - tmp.append(cmd.args.c_str()); - gEnv->pConsole->ExecuteString(tmp.c_str()); - m_waitFrames = 1; - break; - case eCMDCaptureSample: - CaptureSample(cmd); - break; - } - - if (m_cmdFreq-- == 1) - { - ++m_nextCmd; - } - - if (m_waitFrames != 0) - { - break; - } - } -} - - -void CVisRegTest::LoadMap(const char* mapName) -{ - string mapCmd("map "); - mapCmd.append(mapName); - gEnv->pConsole->ExecuteString(mapCmd.c_str()); - - gEnv->pTimer->SetTimer(ITimer::ETIMER_GAME, 0); - gEnv->pTimer->SetTimer(ITimer::ETIMER_UI, 0); - gEnv->pConsole->ExecuteString("t_FixedStep 0"); - GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_RANDOM_SEED, 0, 0); - srand(0); -} - - -void CVisRegTest::CaptureSample(const SCmd& cmd) -{ - if (m_cmdFreq == SampleCount) // First sample - { - m_dataSamples.push_back(SSample()); - gEnv->pConsole->ExecuteString("t_FixedStep 0"); - } - - SSample& sample = m_dataSamples.back(); - - // Collect stats - sample.imageName = cmd.args.c_str(); - sample.frameTime += gEnv->pTimer->GetRealFrameTime() * 1000.f; - sample.drawCalls += gEnv->pRenderer->GetCurrentNumberOfDrawCalls(); - - const RPProfilerStats* pRPPStats = gEnv->pRenderer->GetRPPStatsArray(); - - if (pRPPStats) - { - sample.gpuTimes[0] += pRPPStats[eRPPSTATS_OverallFrame].gpuTime; - - sample.gpuTimes[1] += pRPPStats[eRPPSTATS_SceneOverall].gpuTime; - sample.gpuTimes[2] += pRPPStats[eRPPSTATS_ShadowsOverall].gpuTime; - sample.gpuTimes[3] += pRPPStats[eRPPSTATS_LightingOverall].gpuTime; - sample.gpuTimes[4] += pRPPStats[eRPPSTATS_VfxOverall].gpuTime; - } - - if (m_cmdFreq == 1) // Final sample - { - // Screenshot - stack_string filename("@usercache@/TestResults/VisReg/"); // the default unaliased assets folder is read-only! - filename += m_testName + "/" + cmd.args.c_str(); - gEnv->pRenderer->ScreenShot(filename); - - // Average results - sample.frameTime /= (float)SampleCount; - sample.drawCalls /= SampleCount; - for (uint32 i = 0; i < MaxNumGPUTimes; ++i) - { - sample.gpuTimes[i] /= (float)SampleCount; - } - - gEnv->pConsole->ExecuteString("t_FixedStep 0.033333"); - } -} - - -void CVisRegTest::Finish() -{ - WriteResults(); - - gEnv->pConsole->ExecuteString("t_FixedStep 0"); - gEnv->pTimer->SetTimeScale(1); - - gEnv->pRenderer->EnableGPUTimers2(false); - - CryLog("VisRegTest: Finished tests"); - - if (m_quitAfterTests) - { - gEnv->pConsole->ExecuteString("quit"); - return; - } -} - - -bool CVisRegTest::WriteResults() -{ - stack_string filename("@usercache@/TestResults/VisReg/"); - filename += m_testName + "/visreg_results.xml"; - - AZ::IO::HandleType fileHandle = fxopen(filename.c_str(), "wb"); - if (fileHandle == AZ::IO::InvalidHandle) - { - return false; - } - - AZ::IO::Print(fileHandle, "\n"); - AZ::IO::Print(fileHandle, "\t\n"); - - for (int i = 0; i < (int)m_dataSamples.size(); ++i) - { - SSample sample = m_dataSamples[i]; - - AZ::IO::Print(fileHandle, "\t\t\n", i, sample.imageName); - - AZ::IO::Print(fileHandle, "\t\t\t\n"); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.frameTime); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.drawCalls); - AZ::IO::Print(fileHandle, "\t\t\t\n"); - - AZ::IO::Print(fileHandle, "\t\t\t\n"); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[0]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[1]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[2]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[3]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[4]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[5]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[6]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[7]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[8]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[9]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[10]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[11]); - AZ::IO::Print(fileHandle, "\t\t\t\t\n", sample.gpuTimes[12]); - AZ::IO::Print(fileHandle, "\t\t\t\n"); - - AZ::IO::Print(fileHandle, "\t\t\n"); - } - - AZ::IO::Print(fileHandle, "\t\n"); - AZ::IO::Print(fileHandle, ""); - gEnv->pFileIO->Close(fileHandle); - - return true; -} diff --git a/Code/CryEngine/CrySystem/VisRegTest.h b/Code/CryEngine/CrySystem/VisRegTest.h deleted file mode 100644 index 19653940a4..0000000000 --- a/Code/CryEngine/CrySystem/VisRegTest.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : Visual Regression Test - - -#ifndef CRYINCLUDE_CRYSYSTEM_VISREGTEST_H -#define CRYINCLUDE_CRYSYSTEM_VISREGTEST_H -#pragma once - - -struct IConsoleCmdArgs; - -class CVisRegTest -{ -public: - static const uint32 SampleCount = 16; - static const uint32 MaxNumGPUTimes = 13; - static const float MaxStreamingWait; - -protected: - - enum ECmd - { - eCMDStart, - eCMDFinish, - eCMDOnMapLoaded, - eCMDConsoleCmd, - eCMDLoadMap, - eCMDWaitStreaming, - eCMDWaitFrames, - eCMDGoto, - eCMDCaptureSample - }; - - struct SCmd - { - ECmd cmd; - uint32 freq; - string args; - - SCmd() {} - SCmd(ECmd _cmd, const string& _args, uint32 _freq = 1) - { this->cmd = _cmd; this->args = _args; this->freq = _freq; } - }; - - struct SSample - { - const char* imageName; - float frameTime; - uint32 drawCalls; - float gpuTimes[MaxNumGPUTimes]; - - SSample() - : imageName(NULL) - , frameTime(0.f) - , drawCalls(0) - { - for (uint32 i = 0; i < MaxNumGPUTimes; ++i) - { - gpuTimes[i] = 0; - } - } - }; - -protected: - string m_testName; - std::vector< SCmd > m_cmdBuf; - std::vector< SSample > m_dataSamples; - uint32 m_nextCmd; - uint32 m_cmdFreq; - int m_waitFrames; - float m_streamingTimeout; - int m_curSample; - bool m_quitAfterTests; - -public: - - CVisRegTest(); - - void Init(IConsoleCmdArgs* pParams); - void AfterRender(); - -protected: - - bool LoadConfig(const char* configFile); - void ExecCommands(); - void LoadMap(const char* mapName); - void CaptureSample(const SCmd& cmd); - void Finish(); - bool WriteResults(); -}; - -#endif // CRYINCLUDE_CRYSYSTEM_VISREGTEST_H diff --git a/Code/CryEngine/CrySystem/WindowsConsole.cpp b/Code/CryEngine/CrySystem/WindowsConsole.cpp deleted file mode 100644 index c83606890e..0000000000 --- a/Code/CryEngine/CrySystem/WindowsConsole.cpp +++ /dev/null @@ -1,1153 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : CWindowsConsole member definitions - - -#include "CrySystem_precompiled.h" -#include "System.h" -#include "WindowsConsole.h" - -#ifdef USE_WINDOWSCONSOLE - -#define WINDOWS_CONSOLE_WIDTH 128 -#define WINDOWS_CONSOLE_HEIGHT 50 -#define WINDOWS_CONSOLE_LOG_BUFFER_LINES 1024 -#define WINDOWS_CONSOLE_LOG_SCROLL_LINES 10 -#define WINDOWS_CONSOLE_TAB_SIZE 4 -#define WINDOWS_CONSOLE_CRYENGINE_BLACK 0x0 -#define WINDOWS_CONSOLE_CRYENGINE_WHITE 0x1 -#define WINDOWS_CONSOLE_CRYENGINE_BLUE 0x2 -#define WINDOWS_CONSOLE_CRYENGINE_GREEN 0x3 -#define WINDOWS_CONSOLE_CRYENGINE_RED 0x4 -#define WINDOWS_CONSOLE_CRYENGINE_CYAN 0x5 -#define WINDOWS_CONSOLE_CRYENGINE_YELLOW 0x6 -#define WINDOWS_CONSOLE_CRYENGINE_MAGENTA 0x7 -#define WINDOWS_CONSOLE_CRYENGINE_ORANGE 0x8 -#define WINDOWS_CONSOLE_CRYENGINE_GREY 0x9 -#define WINDOWS_CONSOLE_NATIVE_BLACK 0x0 -#define WINDOWS_CONSOLE_NATIVE_BROWN 0x6 -#define WINDOWS_CONSOLE_NATIVE_LIGHTGREY 0x7 -#define WINDOWS_CONSOLE_NATIVE_LIGHTBLUE 0x9 -#define WINDOWS_CONSOLE_NATIVE_LIGHTGREEN 0xA -#define WINDOWS_CONSOLE_NATIVE_LIGHTCYAN 0xB -#define WINDOWS_CONSOLE_NATIVE_LIGHTRED 0xC -#define WINDOWS_CONSOLE_NATIVE_LIGHTMAGENTA 0xD -#define WINDOWS_CONSOLE_NATIVE_YELLOW 0xE -#define WINDOWS_CONSOLE_NATIVE_WHITE 0xF -#define WINDOWS_CONSOLE_COLOR_MASK 0xF -#define WINDOWS_CONSOLE_BGCOLOR_SHIFT 4 - -const uint8 CWindowsConsole::s_colorTable[ WINDOWS_CONSOLE_NUM_CRYENGINE_COLORS ] = -{ - WINDOWS_CONSOLE_NATIVE_BLACK, - WINDOWS_CONSOLE_NATIVE_WHITE, - WINDOWS_CONSOLE_NATIVE_LIGHTBLUE, - WINDOWS_CONSOLE_NATIVE_LIGHTGREEN, - WINDOWS_CONSOLE_NATIVE_LIGHTRED, - WINDOWS_CONSOLE_NATIVE_LIGHTCYAN, - WINDOWS_CONSOLE_NATIVE_YELLOW, - WINDOWS_CONSOLE_NATIVE_LIGHTMAGENTA, - WINDOWS_CONSOLE_NATIVE_BROWN, - WINDOWS_CONSOLE_NATIVE_LIGHTGREY -}; - -CWindowsConsole::CWindowsConsole() - : m_lock() - , m_consoleScreenBufferSize() - , m_consoleWindow() - , m_inputBufferHandle(INVALID_HANDLE_VALUE) - , m_screenBufferHandle(INVALID_HANDLE_VALUE) - , m_logBuffer(0, 0, WINDOWS_CONSOLE_WIDTH, WINDOWS_CONSOLE_HEIGHT - 2, WINDOWS_CONSOLE_LOG_BUFFER_LINES, L' ', WINDOWS_CONSOLE_CRYENGINE_GREY, WINDOWS_CONSOLE_CRYENGINE_BLACK) - , m_fullScreenBuffer(0, 0, WINDOWS_CONSOLE_WIDTH, WINDOWS_CONSOLE_HEIGHT - 2, WINDOWS_CONSOLE_HEIGHT - 2, L' ', WINDOWS_CONSOLE_CRYENGINE_GREY, WINDOWS_CONSOLE_CRYENGINE_BLACK) - , m_statusBuffer(0, WINDOWS_CONSOLE_HEIGHT - 2, WINDOWS_CONSOLE_WIDTH, 1, 1, L' ', WINDOWS_CONSOLE_CRYENGINE_BLACK, WINDOWS_CONSOLE_CRYENGINE_GREY) - , m_commandBuffer(0, WINDOWS_CONSOLE_HEIGHT - 1, WINDOWS_CONSOLE_WIDTH, 1, 1, L' ', WINDOWS_CONSOLE_CRYENGINE_WHITE, WINDOWS_CONSOLE_CRYENGINE_BLACK) - , m_dirtyCellBuffers(0) - , m_commandQueue() - , m_commandPrompt("] ") - , m_commandPromptLength(m_commandPrompt.length()) - , m_command() - , m_commandCursor(0) - , m_logLine() - , m_progressString() - , m_header() - , m_updStats() - , m_pInputThread(NULL) - , m_pSystem(NULL) - , m_pConsole(NULL) - , m_pTimer(NULL) - , m_pCVarSvMap(NULL) - , m_pCVarSvMission(NULL) - , m_pCVarSvGameRules(NULL) - , m_lastStatusUpdate() - , m_lastUpdateTime() - , m_initialized(false) - , m_OnUpdateCalled(false) - , m_requireDedicatedServer(false) -{ -} - -CWindowsConsole::~CWindowsConsole() -{ - CleanUp(); -} - -Vec2_tpl< int > CWindowsConsole::BeginDraw() -{ - m_newCmds.resize(0); - return Vec2_tpl< int >(WINDOWS_CONSOLE_WIDTH, WINDOWS_CONSOLE_HEIGHT - 2); -} - -void CWindowsConsole::PutText(int x, int y, const char* pMsg) -{ - SConDrawCmd cmd; - - cmd.x = x; - cmd.y = y; - cry_strcpy(cmd.text, pMsg); - m_newCmds.push_back(cmd); -} - -void CWindowsConsole::EndDraw() -{ - Lock(); - m_drawCmds.swap(m_newCmds); - Unlock(); -} - -void CWindowsConsole::SetTitle(const char* title) -{ - m_title = title; - - if (m_title.empty()) - { - SetConsoleTitle(m_header.c_str()); - } - else - { - stack_string fullHeader = m_title + " - " + m_header; - SetConsoleTitle(fullHeader); - } -} - -void CWindowsConsole::Print(const char* pInszText) -{ - Lock(); - - bool isContinue = true; - const char* pInszTextPtr = pInszText; - const char* pLogLinePtr = m_logLine.c_str(); - - while (*pLogLinePtr && isContinue) - { - if (*pInszTextPtr != *pLogLinePtr) - { - isContinue = false; - } - - ++pInszTextPtr; - ++pLogLinePtr; - } - - // Do not treat lines as equal if the new line starts the same as the previous line - isContinue = isContinue && (*pInszTextPtr == 0 || m_logLine.empty()); - - if (!isContinue) - { - pInszTextPtr = pInszText; - m_logBuffer.NewLine(); - m_logLine.clear(); - } - - m_logLine.append(pInszTextPtr); - m_logBuffer.Print(pInszTextPtr); - m_dirtyCellBuffers |= eCBB_Log; - - Unlock(); -} - -bool CWindowsConsole::OnError([[maybe_unused]] const char* szErrorString) -{ - return true; -} - -bool CWindowsConsole::OnSaveDocument() -{ - return false; -} - -bool CWindowsConsole::OnBackupDocument() -{ - return false; -} - -void CWindowsConsole::OnProcessSwitch() -{ -} - -void CWindowsConsole::OnInitProgress(const char* sProgressMsg) -{ - if (m_initialized) - { - Lock(); - m_progressString = sProgressMsg; - DrawStatus(); - Unlock(); - } -} - -// the CtrlHandler will be called from a separate thread that only handles -// Ctrl messages. When the CLOSE event is sent, this function can just wait -// forever, as FreeConsole() will kill the thread. If this function returns -// immediately, windows will call TerminateProcess() and nothing will be cleaned up. -static BOOL WINAPI CtrlHandler(DWORD ctrlEvent) -{ - switch (ctrlEvent) - { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - return TRUE; - case CTRL_CLOSE_EVENT: - if ( (gEnv != nullptr) && (gEnv->pSystem != nullptr) && (gEnv->pSystem->GetIConsole() != nullptr) ) - { - gEnv->pSystem->GetIConsole()->ExecuteString("quit", true, true); - Sleep(INFINITE); - return TRUE; - } - default: - break; - } - return FALSE; -} - -void CWindowsConsole::OnInit(ISystem* pSystem) -{ - if (m_requireDedicatedServer && !gEnv->IsDedicated()) - { - return; - } - - Lock(); - - if (!m_initialized) - { - assert(m_pSystem == NULL); - assert(m_pConsole == NULL); - - m_pSystem = pSystem; - m_pConsole = pSystem->GetIConsole(); - - AllocConsole(); - m_inputBufferHandle = GetStdHandle(STD_INPUT_HANDLE); - m_screenBufferHandle = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleMode(m_inputBufferHandle, ENABLE_WINDOW_INPUT); - m_consoleScreenBufferSize.X = WINDOWS_CONSOLE_WIDTH; - m_consoleScreenBufferSize.Y = WINDOWS_CONSOLE_HEIGHT; - m_consoleWindow.Left = 0; - m_consoleWindow.Top = 0; - m_consoleWindow.Right = WINDOWS_CONSOLE_WIDTH - 1; - m_consoleWindow.Bottom = WINDOWS_CONSOLE_HEIGHT - 1; - SetConsoleScreenBufferSize(m_screenBufferHandle, m_consoleScreenBufferSize); - SetConsoleWindowInfo(m_screenBufferHandle, TRUE, &m_consoleWindow); - SetConsoleTitle(m_header.c_str()); - - if (m_pConsole) - { - m_pConsole->AddOutputPrintSink(this); - } - - DrawCommand(); - - m_pInputThread = new CWindowsConsoleInputThread(*this); - m_pInputThread->Start(); - -#if !defined(NDEBUG) - BOOL handlerInstalled = -#endif - SetConsoleCtrlHandler(CtrlHandler, TRUE); - CRY_ASSERT(handlerInstalled); - - m_initialized = true; - } - - Unlock(); -} - -void CWindowsConsole::OnShutdown() -{ - CleanUp(); -} - -void CWindowsConsole::OnUpdate() -{ - if (m_initialized) - { - Lock(); - - bool updateStatus = false; - - if (!m_OnUpdateCalled) - { - assert(m_pCVarSvMap == NULL); - assert(m_pCVarSvGameRules == NULL); - assert(m_pTimer == NULL); - - m_pCVarSvMap = m_pConsole->GetCVar("sv_map"); - m_pCVarSvGameRules = m_pConsole->GetCVar("sv_gamerules"); - m_pTimer = m_pSystem->GetITimer(); - m_OnUpdateCalled = true; - - assert(m_pCVarSvMission == NULL); - m_pCVarSvMission = m_pConsole->GetCVar("sv_mission"); - } - - if (!m_progressString.empty()) - { - m_progressString.clear(); - updateStatus = true; - } - - CTimeValue now = m_pTimer->GetAsyncTime(); - - if ((now - m_lastStatusUpdate).GetSeconds() > 0.1F) - { - updateStatus = true; - } - - m_lastUpdateTime = now; - - m_pSystem->GetUpdateStats(m_updStats); - - if (updateStatus) - { - DrawStatus(); - m_lastStatusUpdate = now; - } - - while (m_commandQueue.size()) - { - const string& command = m_commandQueue[0]; - Unlock(); - // 'm_pConsole' will be set to NULL when executing 'quit' command - // Cache pointer in local variable to prevent crash when adding the last command to the history - IConsole* pConsole = m_pConsole; - pConsole->ExecuteString(command.c_str()); - pConsole->AddCommandToHistory(command.c_str()); - Lock(); - m_commandQueue.pop_front(); - } - - if (!m_drawCmds.empty()) - { - DrawFull(); - } - - Repaint(); - - Unlock(); - } -} - -void CWindowsConsole::OnConsoleInputEvent(INPUT_RECORD inputRecord) -{ - switch (inputRecord.EventType) - { - case KEY_EVENT: - OnKey(inputRecord.Event.KeyEvent); - break; - case WINDOW_BUFFER_SIZE_EVENT: - OnResize(inputRecord.Event.WindowBufferSizeEvent.dwSize); - break; - } -} - -void CWindowsConsole::OnKey(const KEY_EVENT_RECORD& event) -{ - if (event.bKeyDown) - { - for (uint32 i = 0; i < event.wRepeatCount; ++i) - { - switch (event.wVirtualKeyCode) - { - case VK_BACK: - OnBackspace(); - break; - case VK_TAB: - OnTab(); - break; - case VK_RETURN: - OnReturn(); - break; - case VK_PRIOR: - OnPgUp(); - break; - case VK_NEXT: - OnPgDn(); - break; - case VK_LEFT: - OnLeft(); - break; - case VK_UP: - OnUp(); - break; - case VK_RIGHT: - OnRight(); - break; - case VK_DOWN: - OnDown(); - break; - case VK_DELETE: - OnDelete(); - break; - default: - OnChar(event.uChar.AsciiChar); - break; - } - } - } -} - -void CWindowsConsole::OnResize(const COORD& size) -{ - if ((size.X != m_consoleScreenBufferSize.X) || (size.Y != m_consoleScreenBufferSize.Y)) - { - SetConsoleScreenBufferSize(m_screenBufferHandle, m_consoleScreenBufferSize); - SetConsoleWindowInfo(m_screenBufferHandle, TRUE, &m_consoleWindow); - } -} - -void CWindowsConsole::OnBackspace() -{ - if (m_commandCursor > 0) - { - m_command.erase(--m_commandCursor, 1); - m_pConsole->ResetAutoCompletion(); - DrawCommand(); - } -} - -void CWindowsConsole::OnTab() -{ - const char* pCompletion; - - pCompletion = m_pConsole->ProcessCompletion(m_command.c_str()); - - if (pCompletion) - { - m_command = pCompletion; - m_commandCursor = m_command.length(); - DrawCommand(); - } -} - -void CWindowsConsole::OnReturn() -{ - m_commandQueue.push_back(m_command); - m_command.clear(); - m_pConsole->ResetAutoCompletion(); - m_commandCursor = 0; - DrawCommand(); -} - -void CWindowsConsole::OnPgUp() -{ - if (m_logBuffer.Scroll(-WINDOWS_CONSOLE_LOG_SCROLL_LINES)) - { - m_dirtyCellBuffers |= eCBB_Log; - } -} - -void CWindowsConsole::OnPgDn() -{ - if (m_logBuffer.Scroll(WINDOWS_CONSOLE_LOG_SCROLL_LINES)) - { - m_dirtyCellBuffers |= eCBB_Log; - } -} - -void CWindowsConsole::OnLeft() -{ - if (m_commandCursor > 0) - { - --m_commandCursor; - m_commandBuffer.SetCursor(m_screenBufferHandle, m_commandCursor + m_commandPromptLength); - } -} - -void CWindowsConsole::OnUp() -{ - OnHistory(m_pConsole->GetHistoryElement(true)); -} - -void CWindowsConsole::OnRight() -{ - if (m_commandCursor < m_command.length()) - { - ++m_commandCursor; - m_commandBuffer.SetCursor(m_screenBufferHandle, m_commandCursor + m_commandPromptLength); - } -} - -void CWindowsConsole::OnDown() -{ - OnHistory(m_pConsole->GetHistoryElement(false)); -} - -void CWindowsConsole::OnDelete() -{ - if (m_commandCursor < m_command.length()) - { - m_command.erase(m_commandCursor, 1); - m_pConsole->ResetAutoCompletion(); - DrawCommand(); - } -} - -void CWindowsConsole::OnChar(CHAR ch) -{ - if ((ch >= ' ') && (ch <= '~')) - { - m_command.insert(m_commandCursor++, ch); - m_pConsole->ResetAutoCompletion(); - DrawCommand(); - } -} - -void CWindowsConsole::OnHistory(const char* pHistoryElement) -{ - if (pHistoryElement) - { - m_command = pHistoryElement; - } - else - { - m_command.clear(); - } - - m_commandCursor = m_command.length(); - DrawCommand(); -} - -void CWindowsConsole::DrawCommand() -{ - m_commandBuffer.Clear(); - m_commandBuffer.PutText(0, 0, m_commandPrompt.c_str()); - m_commandBuffer.PutText(m_commandPromptLength, 0, m_command); - m_commandBuffer.SetCursor(m_screenBufferHandle, m_commandCursor + m_commandPromptLength); - m_dirtyCellBuffers |= eCBB_Command; -} - -void CWindowsConsole::GetMemoryUsage(ICrySizer* pSizer) -{ - pSizer->Add(this); - pSizer->Add(m_command); - pSizer->Add(m_logLine); - pSizer->Add(m_pInputThread); - m_logBuffer.GetMemoryUsage(pSizer); - m_fullScreenBuffer.GetMemoryUsage(pSizer); - m_statusBuffer.GetMemoryUsage(pSizer); - m_commandBuffer.GetMemoryUsage(pSizer); -} - -void CWindowsConsole::SetRequireDedicatedServer(bool value) -{ - m_requireDedicatedServer = value; -} - -void CWindowsConsole::SetHeader(const char* pHeader) -{ - m_header = pHeader; - SetConsoleTitle(pHeader); -} - -void CWindowsConsole::InputIdle() -{ - if (m_pTimer) - { - CTimeValue now = m_pTimer->GetAsyncTime(); - float timePassed = (now - m_lastUpdateTime).GetSeconds(); - - if (timePassed > 0.2F) - { - int nDots = ( int )(timePassed + 0.5) / 3; - int nDotsMax = m_statusBuffer.Width() - 2; - - if (nDots > nDotsMax) - { - nDots = nDotsMax; - } - - if (m_progressString.length() != nDots) - { - m_progressString.clear(); - m_progressString.append(nDots, '.'); - DrawStatus(); - } - } - } - - Repaint(); -} - -void CWindowsConsole::Lock() -{ - m_lock.Lock(); -} - -void CWindowsConsole::Unlock() -{ - m_lock.Unlock(); -} - -bool CWindowsConsole::TryLock() -{ - return m_lock.TryLock(); -} - -void CWindowsConsole::Repaint() -{ - if (m_dirtyCellBuffers) - { - if (m_dirtyCellBuffers & eCBB_Full) - { - m_fullScreenBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Full; - } - else if (m_dirtyCellBuffers & eCBB_Log) - { - m_logBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Log; - } - - if (m_dirtyCellBuffers & eCBB_Status) - { - m_statusBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Status; - } - - if (m_dirtyCellBuffers & eCBB_Command) - { - m_commandBuffer.Blit(m_screenBufferHandle); - m_dirtyCellBuffers &= ~eCBB_Command; - } - } -} - -void CWindowsConsole::DrawStatus() -{ - const char* pStatusLeft = NULL; - const char* pStatusRight = NULL; - char bufferLeft[ 256 ]; - char bufferRight[ 256 ]; - - // If we're scrolled, then the right size shows a scroll indicator. - if (m_logBuffer.IsScrolledUp()) - { - m_logBuffer.FmtScrollStatus(sizeof bufferRight, bufferRight); - bufferRight[ sizeof bufferRight - 1 ] = 0; - pStatusRight = bufferRight; - } - - if (!m_progressString.empty()) - { - azsnprintf(bufferLeft, sizeof bufferLeft, " %s", m_progressString.c_str()); - bufferLeft [sizeof bufferLeft - 1 ] = 0; - pStatusLeft = bufferLeft; - } - else if (m_OnUpdateCalled) - { - // Standard status display. - // Map name and game rules on the left. - // Current update rate and player count on the right. - - const char* pMapName = m_pCVarSvMap->GetString(); - - const char* pMissionName = m_pCVarSvMission ? m_pCVarSvMission->GetString() : ""; - azsnprintf(bufferLeft, sizeof bufferLeft, " mission: %s map:%s", pMissionName, pMapName); - - bufferLeft[ sizeof bufferLeft - 1 ] = 0; - pStatusLeft = bufferLeft; - - if (!pStatusRight) - { - float updateRate = 0.f; - - if (m_pTimer != NULL) - { - updateRate = m_pTimer->GetFrameRate(); - } - else - { - updateRate = 0.f; - } - - char* pBufferRight = bufferRight; - char* const pBufferRightEnd = bufferRight + sizeof bufferRight; - - azstrcpy(pBufferRight, AZ_ARRAY_SIZE(bufferRight), "| "); - pBufferRight += strlen(pBufferRight); - - if (pBufferRight < pBufferRightEnd) - { - if (m_pConsole != NULL) - { - pBufferRight += azsnprintf( - pBufferRight, - pBufferRightEnd - pBufferRight, - "upd:%.1fms(%.2f..%.2f) " \ - "rate:%.1f/s", - m_updStats.avgUpdateTime, m_updStats.minUpdateTime, m_updStats.maxUpdateTime, - updateRate); - } - else - { - cry_strcpy(pBufferRight, pBufferRightEnd - pBufferRight, "BUSY "); - } - } - - bufferRight[ sizeof bufferRight - 1 ] = 0; - pStatusRight = bufferRight; - } - } - - if (pStatusLeft == NULL) - { - pStatusLeft = ""; - } - - if (pStatusRight == NULL) - { - pStatusRight = ""; - } - - int rightWidth = strlen(pStatusRight); - - m_statusBuffer.Clear(); - m_statusBuffer.PutText(0, 0, pStatusLeft); - m_statusBuffer.PutText(-rightWidth, 0, pStatusRight); - m_dirtyCellBuffers |= eCBB_Status; -} - -void CWindowsConsole::CleanUp() -{ - Lock(); - - if (m_initialized) - { - if (m_pInputThread) - { - m_pInputThread->Cancel(); - - // The input thread may continue to lock before it gets our cancel event, so - // we need to release the lock until we confirm that it has canceled its operations. - Unlock(); - m_pInputThread->WaitForThread(); - Lock(); - - delete m_pInputThread; - m_pInputThread = NULL; - } - - if (m_pConsole) - { - m_pConsole->RemoveOutputPrintSink(this); - } - - m_pSystem = NULL; - m_pConsole = NULL; - m_pTimer = NULL; - m_pCVarSvMap = NULL; - m_pCVarSvGameRules = NULL; - m_inputBufferHandle = INVALID_HANDLE_VALUE; - m_screenBufferHandle = INVALID_HANDLE_VALUE; - m_initialized = false; - } - - Unlock(); -} - -void CWindowsConsole::DrawFull() -{ - for (DynArray< SConDrawCmd >::iterator iter = m_drawCmds.begin(); iter != m_drawCmds.end(); ++iter) - { - m_fullScreenBuffer.PutText(iter->x, iter->y, iter->text); - } - - m_dirtyCellBuffers |= eCBB_Full; -} - -CWindowsConsole::CCellBuffer::CCellBuffer(SHORT x, short y, SHORT w, SHORT h, SHORT lines, WCHAR emptyChar, uint8 defaultFgColor, uint8 defaultBgColor) -{ - m_emptyCell.Char.UnicodeChar = emptyChar; - m_emptyCell.Attributes = s_colorTable[ defaultFgColor ] | (s_colorTable[ defaultBgColor ] << WINDOWS_CONSOLE_BGCOLOR_SHIFT); - m_attr = m_emptyCell.Attributes; - m_size.X = w; - m_size.Y = lines; - m_screenArea.Left = x; - m_screenArea.Top = y; - m_screenArea.Right = x + w - 1; - m_screenArea.Bottom = y + h - 1; - m_position.head = 0; - m_position.lines = 1; - m_position.wrap = 0; - m_position.offset = 0; - m_position.scroll = 0; - m_escape = false; - m_color = false; - m_buffer.resize(w * lines, m_emptyCell); -} - -CWindowsConsole::CCellBuffer::~CCellBuffer() -{ -} - -void CWindowsConsole::CCellBuffer::PutText(int x, int y, const char* pMsg) -{ - SPosition position; - - position.head = m_position.head; - position.offset = x; - position.lines = y; - position.scroll = 0; - position.wrap = 0; - - if (position.offset < 0) - { - position.offset += m_screenArea.Right - 1; - } - - if (position.lines < 0) - { - position.lines += m_screenArea.Bottom - 1; - } - - Print(pMsg, position); -} - -void CWindowsConsole::CCellBuffer::Print(const char* pInszText) -{ - Print(pInszText, m_position); -} - -void CWindowsConsole::CCellBuffer::ClearCells(TBuffer::iterator pDst, TBuffer::iterator pDstEnd) -{ - std::fill(pDst, pDstEnd, m_emptyCell); -} - -bool CWindowsConsole::CCellBuffer::Scroll(SHORT numLines) -{ - bool result = false; - SHORT newScroll = m_position.scroll + numLines; - SHORT maxScroll = m_position.lines - 1 - (m_screenArea.Bottom - m_screenArea.Top); - - if (newScroll > maxScroll) - { - newScroll = maxScroll; - } - - if (newScroll < 0) - { - newScroll = 0; - } - - if (newScroll != m_position.scroll) - { - m_position.scroll = newScroll; - result = true; - } - - return result; -} - -void CWindowsConsole::CCellBuffer::SetCursor(HANDLE hScreenBuffer, SHORT offset) -{ - COORD position; - - position.X = m_screenArea.Left + offset; - position.Y = m_screenArea.Top; - SetConsoleCursorPosition(hScreenBuffer, position); -} - -void CWindowsConsole::CCellBuffer::AddCharacter(WCHAR ch, SPosition& position) -{ - if (position.offset == m_size.X) - { - WrapLine(position); - } - - int32 index = (((position.head + position.lines + m_size.Y - 1) % m_size.Y) * m_size.X) + position.offset; - - CHAR_INFO& info = m_buffer[ index ]; - - info.Attributes = m_attr; - info.Char.UnicodeChar = ch; - ++position.offset; -} - -void CWindowsConsole::CCellBuffer::WrapLine(SPosition& position) -{ - ++position.wrap; - AdvanceLine(position); -} - -void CWindowsConsole::CCellBuffer::NewLine() -{ - NewLine(m_position); -} - -void CWindowsConsole::CCellBuffer::NewLine(SPosition& position) -{ - m_attr = m_emptyCell.Attributes; - position.wrap = 0; - AdvanceLine(position); -} - -void CWindowsConsole::CCellBuffer::ClearLine(SPosition& position) -{ - ClearCells(m_buffer.begin() + ((position.head + position.lines - position.wrap) % m_size.Y) * m_size.X, m_buffer.begin() + ((position.head + position.lines + 1) % m_size.Y) * m_size.X); - position.lines -= position.wrap; - position.wrap = 0; - position.offset = 0; -} - -void CWindowsConsole::CCellBuffer::Tab(SPosition& position) -{ - do - { - AddCharacter(' ', position); - } while (position.offset % WINDOWS_CONSOLE_TAB_SIZE); -} - -void CWindowsConsole::CCellBuffer::Blit(HANDLE hScreenBuffer) -{ - COORD src; - SMALL_RECT dst; - - src.X = 0; - src.Y = (m_position.head + m_position.scroll) % m_size.Y; - dst = m_screenArea; - WriteConsoleOutput(hScreenBuffer, &*m_buffer.begin(), m_size, src, &dst); - - if ((m_size.Y - src.Y) < (m_screenArea.Bottom - m_screenArea.Top + 1)) - { - src.Y = 0; - dst.Top = dst.Bottom + 1; - dst.Bottom = m_screenArea.Bottom; - WriteConsoleOutput(hScreenBuffer, &*m_buffer.begin(), m_size, src, &dst); - } -} - -void CWindowsConsole::CCellBuffer::AdvanceLine(SPosition& position) -{ - position.offset = 0; - - if (position.lines == m_size.Y) - { - position.head = (position.head + 1) % m_size.Y; - } - else - { - ++position.lines; - - if (position.lines > m_screenArea.Bottom - m_screenArea.Top + 1) - { - ++position.scroll; - } - } - - TBuffer::iterator start = m_buffer.begin() + ((position.head + position.lines + m_size.Y - 1) % m_size.Y) * m_size.X; - TBuffer::iterator end = start + m_size.X; - - ClearCells(start, end); -} - -void CWindowsConsole::CCellBuffer::SetFgColor(WORD color) -{ - m_attr = (m_attr & ~WINDOWS_CONSOLE_COLOR_MASK) | s_colorTable[ color ]; -} - -void CWindowsConsole::CCellBuffer::Print(const char* pInszText, SPosition& position) -{ - while (*pInszText) - { - switch (*pInszText) - { - case '$': - if (!m_escape) - { - m_color = true; - break; - } - case '\\': - m_escape = !m_escape; - if (m_escape) - { - break; - } - case 'n': - if (m_escape) - { - case '\n': - NewLine(position); - m_escape = false; - break; - } - case 'r': - if (m_escape) - { - case '\r': - ClearLine(position); - m_escape = false; - break; - } - case 't': - if (m_escape) - { - case '\t': - Tab(position); - m_escape = false; - break; - } - default: - if (m_color) - { - if (isdigit(*pInszText)) - { - SetFgColor(*pInszText - '0'); - } - - m_color = false; - } - else - { - if (m_escape && (*pInszText != '\\')) - { - AddCharacter('\\', position); - } - AddCharacter(*pInszText, position); - } - m_escape = false; - break; - } - - ++pInszText; - } -} - -void CWindowsConsole::CCellBuffer::GetMemoryUsage(ICrySizer* pSizer) -{ - pSizer->Add(m_buffer); -} - -bool CWindowsConsole::CCellBuffer::IsScrolledUp() -{ - return (m_position.lines - m_position.scroll) > (m_screenArea.Bottom - m_screenArea.Top + 1); -} - -void CWindowsConsole::CCellBuffer::FmtScrollStatus(uint32 size, char* pBuffer) -{ - if (m_position.scroll) - { - azsnprintf(pBuffer, size, "| SCROLL: %.1f%%", 100.0F * static_cast< float >(m_position.scroll) / static_cast< float >(m_position.lines - (m_screenArea.Bottom - m_screenArea.Top + 1))); - } - else - { - cry_strcpy(pBuffer, size, "| SCROLL:TOP "); - } -} - -void CWindowsConsole::CCellBuffer::Clear() -{ - ClearCells(m_buffer.begin(), m_buffer.end()); -} - -SHORT CWindowsConsole::CCellBuffer::Width() -{ - return m_screenArea.Right - m_screenArea.Left + 1; -} - - -CWindowsConsoleInputThread::CWindowsConsoleInputThread(CWindowsConsole& console) - : m_WindowsConsole(console) -{ - m_handles[ eWH_Event ] = CreateEvent(NULL, TRUE, FALSE, NULL); - m_handles[ eWH_Console ] = m_WindowsConsole.m_inputBufferHandle; -} - -CWindowsConsoleInputThread::~CWindowsConsoleInputThread() -{ - CloseHandle(m_handles[ eWH_Event ]); -} - -void CWindowsConsoleInputThread::Run() -{ - bool cancelled = false; - - do - { - DWORD inputRecordCount = 0; - DWORD waitResult; - - waitResult = WaitForMultipleObjects(eWH_NumWaitHandles, m_handles, FALSE, 100); - - switch (waitResult) - { - case WAIT_OBJECT_0 + eWH_Event: - - cancelled = true; - break; - - case WAIT_OBJECT_0 + eWH_Console: - - ReadConsoleInput(m_WindowsConsole.m_inputBufferHandle, m_inputRecords, WINDOWS_CONSOLE_MAX_INPUT_RECORDS, &inputRecordCount); - - // FALL THROUGH - - case WAIT_TIMEOUT: - - if (inputRecordCount || (m_WindowsConsole.m_dirtyCellBuffers && !m_WindowsConsole.m_OnUpdateCalled)) - { - m_WindowsConsole.Lock(); - - if (inputRecordCount) - { - PINPUT_RECORD pInputRecordEnd = m_inputRecords + inputRecordCount; - - for (PINPUT_RECORD pInputRecord = m_inputRecords; pInputRecord < pInputRecordEnd; ++pInputRecord) - { - m_WindowsConsole.OnConsoleInputEvent(*pInputRecord); - } - - m_WindowsConsole.DrawCommand(); - } - else - { - m_WindowsConsole.InputIdle(); - } - - m_WindowsConsole.Unlock(); - } - - break; - } - } while (!cancelled); -} - -void CWindowsConsoleInputThread::Cancel() -{ - SetEvent(m_handles[ eWH_Event ]); -} - -#endif // def USE_WINDOWSCONSOLE diff --git a/Code/CryEngine/CrySystem/WindowsConsole.h b/Code/CryEngine/CrySystem/WindowsConsole.h deleted file mode 100644 index cfecd06db2..0000000000 --- a/Code/CryEngine/CrySystem/WindowsConsole.h +++ /dev/null @@ -1,245 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : CWindowsConsole class definition - - -#ifndef CRYINCLUDE_CRYSYSTEM_WINDOWSCONSOLE_H -#define CRYINCLUDE_CRYSYSTEM_WINDOWSCONSOLE_H -#pragma once - - -#include -#include - -#if defined(USE_WINDOWSCONSOLE) - -class CWindowsConsole; -class CWindowsConsoleInputThread; - -#define WINDOWS_CONSOLE_MAX_INPUT_RECORDS 256 -#define WINDOWS_CONSOLE_NUM_CRYENGINE_COLORS 10 - -class CWindowsConsoleInputThread - : public CrySimpleThread<> -{ -public: - CWindowsConsoleInputThread(CWindowsConsole& console); - - ~CWindowsConsoleInputThread(); - - virtual void Run(); - virtual void Cancel(); - void Interrupt() - { - } - -private: - - enum EWaitHandle - { - eWH_Event, - eWH_Console, - eWH_NumWaitHandles - }; - - CWindowsConsole& m_WindowsConsole; - HANDLE m_handles[ eWH_NumWaitHandles ]; - INPUT_RECORD m_inputRecords[ WINDOWS_CONSOLE_MAX_INPUT_RECORDS ]; -}; - -class CWindowsConsole - : public ITextModeConsole - , public IOutputPrintSink - , public ISystemUserCallback -{ -public: - - CWindowsConsole(); - virtual ~CWindowsConsole(); - - // ITextModeConsole - virtual Vec2_tpl< int > BeginDraw(); - virtual void PutText(int x, int y, const char* pMsg); - virtual void EndDraw(); - virtual void SetTitle(const char* title); - - // ~ITextModeConsole - - // IOutputPrintSink - virtual void Print(const char* pInszText); - // ~IOutputPrintSink - - // ISystemUserCallback - virtual bool OnError(const char* szErrorString); - virtual bool OnSaveDocument(); - virtual bool OnBackupDocument(); - virtual void OnProcessSwitch(); - virtual void OnInitProgress(const char* sProgressMsg); - virtual void OnInit(ISystem* pSystem); - virtual void OnShutdown(); - virtual void OnUpdate(); - virtual void GetMemoryUsage(ICrySizer* pSizer); - // ~ISystemUserCallback - - void SetRequireDedicatedServer(bool value); - void SetHeader(const char* pHeader); - void InputIdle(); - -private: - - struct SConDrawCmd - { - int x; - int y; - char text[ 256 ]; - }; - - DynArray m_drawCmds; - DynArray m_newCmds; - - enum ECellBuffer - { - eCB_Log, - eCB_Full, - eCB_Status, - eCB_Command, - eCB_NumCellBuffers - }; - - enum ECellBufferBit - { - eCBB_Log = BIT(eCB_Log), - eCBB_Full = BIT(eCB_Full), - eCBB_Status = BIT(eCB_Status), - eCBB_Command = BIT(eCB_Command) - }; - - class CCellBuffer - { - public: - - CCellBuffer(SHORT x, short y, SHORT w, SHORT h, SHORT lines, WCHAR emptyChar, uint8 defaultFgColor, uint8 defaultBgColor); - ~CCellBuffer(); - - void PutText(int x, int y, const char* pMsg); - void Print(const char* pInszText); - void NewLine(); - void SetCursor(HANDLE hScreenBuffer, SHORT offset); - void SetFgColor(WORD color); - void Blit(HANDLE hScreenBuffer); - bool Scroll(SHORT numLines); - bool IsScrolledUp(); - void FmtScrollStatus(uint32 size, char* pBuffer); - void GetMemoryUsage(ICrySizer* pSizer); - void Clear(); - SHORT Width(); - - private: - - struct SPosition - { - SHORT head; - SHORT lines; - SHORT wrap; - SHORT offset; - SHORT scroll; - }; - - typedef std::vector< CHAR_INFO > TBuffer; - - void Print(const char* pInszText, SPosition& position); - void AddCharacter(WCHAR ch, SPosition& position); - void NewLine(SPosition& position); - void ClearLine(SPosition& position); - void Tab(SPosition& position); - void WrapLine(SPosition& position); - void AdvanceLine(SPosition& position); - void ClearCells(TBuffer::iterator pDst, TBuffer::iterator pDstEnd); - - TBuffer m_buffer; - CHAR_INFO m_emptyCell; - WORD m_attr; - COORD m_size; - SMALL_RECT m_screenArea; - SPosition m_position; - bool m_escape; - bool m_color; - }; - - void Lock(); - void Unlock(); - bool TryLock(); - void OnConsoleInputEvent(INPUT_RECORD inputRecord); - void OnKey(const KEY_EVENT_RECORD& event); - void OnResize(const COORD& size); - void OnBackspace(); - void OnTab(); - void OnReturn(); - void OnPgUp(); - void OnPgDn(); - void OnLeft(); - void OnUp(); - void OnRight(); - void OnDown(); - void OnDelete(); - void OnHistory(const char* pHistoryElement); - void OnChar(CHAR ch); - void DrawFull(); - void DrawStatus(); - void DrawCommand(); - void Repaint(); - void CleanUp(); - - CryCriticalSection m_lock; - COORD m_consoleScreenBufferSize; - SMALL_RECT m_consoleWindow; - HANDLE m_inputBufferHandle; - HANDLE m_screenBufferHandle; - CCellBuffer m_logBuffer; - CCellBuffer m_fullScreenBuffer; - CCellBuffer m_statusBuffer; - CCellBuffer m_commandBuffer; - uint32 m_dirtyCellBuffers; - std::deque< CryStringT< char > > m_commandQueue; - CryStringT< char > m_commandPrompt; - uint32 m_commandPromptLength; - CryStringT< char > m_command; - uint32 m_commandCursor; - CryStringT< char > m_logLine; - CryStringT< char > m_progressString; - CryStringT< char > m_header; - SSystemUpdateStats m_updStats; - CWindowsConsoleInputThread* m_pInputThread; - ISystem* m_pSystem; - IConsole* m_pConsole; - ITimer* m_pTimer; - ICVar* m_pCVarSvMap; - ICVar* m_pCVarSvMission; - CryStringT< char > m_title; - - ICVar* m_pCVarSvGameRules; - CTimeValue m_lastStatusUpdate; - CTimeValue m_lastUpdateTime; - bool m_initialized; - bool m_OnUpdateCalled; - bool m_requireDedicatedServer; - - static const uint8 s_colorTable[ WINDOWS_CONSOLE_NUM_CRYENGINE_COLORS ]; - - friend class CWindowsConsoleInputThread; -}; - -#endif // USE_WINDOWSCONSOLE - -#endif // CRYINCLUDE_CRYSYSTEM_WINDOWSCONSOLE_H diff --git a/Code/CryEngine/CrySystem/WindowsErrorReporting.cpp b/Code/CryEngine/CrySystem/WindowsErrorReporting.cpp index bd6f0c3ee2..feaffd42aa 100644 --- a/Code/CryEngine/CrySystem/WindowsErrorReporting.cpp +++ b/Code/CryEngine/CrySystem/WindowsErrorReporting.cpp @@ -98,18 +98,6 @@ LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExcept return EXCEPTION_CONTINUE_SEARCH; } -/* -struct AutoSetCryEngineExceptionFilter -{ - AutoSetCryEngineExceptionFilter() - { - WCHAR * psz = GetFullPathToFaultrepDll(); - SetUnhandledExceptionFilter(CryEngineExceptionFilterWER); - } -}; -AutoSetCryEngineExceptionFilter g_AutoSetCryEngineExceptionFilter; -*/ - ////////////////////////////////////////////////////////////////////////// LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers) { @@ -146,6 +134,4 @@ LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPo return lRet; } - #endif // WIN32 - diff --git a/Code/CryEngine/CrySystem/XConsole.cpp b/Code/CryEngine/CrySystem/XConsole.cpp index f4271d6dc4..32fe67dcc0 100644 --- a/Code/CryEngine/CrySystem/XConsole.cpp +++ b/Code/CryEngine/CrySystem/XConsole.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "ConsoleHelpGen.h" // CConsoleHelpGen @@ -141,147 +140,6 @@ void Command_SetWaitFrames(IConsoleCmdArgs* pCmd) } } -/* - - CNotificationNetworkConsole - -*/ - -#include -class CNotificationNetworkConsole - : public INotificationNetworkListener -{ -private: - static const uint32 LENGTH_MAX = 256; - static CNotificationNetworkConsole* s_pInstance; - -public: - static bool Initialize() - { - if (s_pInstance) - { - return true; - } - - INotificationNetwork* pNotificationNetwork = gEnv->pSystem->GetINotificationNetwork(); - if (!pNotificationNetwork) - { - return false; - } - - s_pInstance = new CNotificationNetworkConsole(); - pNotificationNetwork->ListenerBind("Command", s_pInstance); - return true; - } - - static void Shutdown() - { - if (!s_pInstance) - { - return; - } - - delete s_pInstance; - s_pInstance = NULL; - } - - static void Update() - { - if (s_pInstance) - { - s_pInstance->ProcessCommand(); - } - } - -private: - CNotificationNetworkConsole() - { - m_pConsole = NULL; - - m_commandBuffer[0][0] = '\0'; - m_commandBuffer[1][0] = '\0'; - m_commandBufferIndex = 0; - m_commandCriticalSection = ::CryCreateCriticalSection(); - } - - ~CNotificationNetworkConsole() - { - if (m_commandCriticalSection) - { - ::CryDeleteCriticalSection(m_commandCriticalSection); - } - } - -private: - void ProcessCommand() - { - if (!ValidateConsole()) - { - return; - } - - char* command = NULL; - ::CryEnterCriticalSection(m_commandCriticalSection); - if (*m_commandBuffer[m_commandBufferIndex]) - { - command = m_commandBuffer[m_commandBufferIndex]; - } - ++m_commandBufferIndex &= 1; - ::CryLeaveCriticalSection(m_commandCriticalSection); - - if (command) - { - m_pConsole->ExecuteString(command); - *command = '\0'; - } - } - - bool ValidateConsole() - { - if (m_pConsole) - { - return true; - } - - if (!gEnv->pConsole) - { - return false; - } - - m_pConsole = gEnv->pConsole; - return true; - } - - // INotificationNetworkListener -public: - void OnNotificationNetworkReceive(const void* pBuffer, size_t length) - { - if (!ValidateConsole()) - { - return; - } - - if (length > LENGTH_MAX) - { - length = LENGTH_MAX; - } - - ::CryEnterCriticalSection(m_commandCriticalSection); - ::memcpy(m_commandBuffer[m_commandBufferIndex], pBuffer, length); - m_commandBuffer[m_commandBufferIndex][LENGTH_MAX - 1] = '\0'; - ::CryLeaveCriticalSection(m_commandCriticalSection); - } - -private: - IConsole* m_pConsole; - - char m_commandBuffer[2][LENGTH_MAX]; - size_t m_commandBufferIndex; - void* m_commandCriticalSection; -}; - -CNotificationNetworkConsole* CNotificationNetworkConsole::s_pInstance = NULL; - void ConsoleShow(IConsoleCmdArgs*) { gEnv->pConsole->ShowConsole(true); @@ -328,7 +186,6 @@ CXConsole::CXConsole() m_fRepeatTimer = 0; m_pSysDeactivateConsole = 0; m_pFont = NULL; - m_pRenderer = NULL; m_pImage = NULL; m_nCursorPos = 0; m_nScrollPos = 0; @@ -361,8 +218,6 @@ CXConsole::CXConsole() m_waitSeconds = 0.0f; m_blockCounter = 0; - CNotificationNetworkConsole::Initialize(); - AzFramework::ConsoleRequestBus::Handler::BusConnect(); AzFramework::CommandRegistrationBus::Handler::BusConnect(); @@ -381,8 +236,6 @@ CXConsole::~CXConsole() gEnv->pSystem->GetIRemoteConsole()->UnregisterListener(this); } - CNotificationNetworkConsole::Shutdown(); - if (!m_mapVariables.empty()) { while (!m_mapVariables.empty()) @@ -397,18 +250,6 @@ CXConsole::~CXConsole() ////////////////////////////////////////////////////////////////////////// void CXConsole::FreeRenderResources() { - if (m_pRenderer) - { - if (m_nLoadingBackTexID) - { - m_pRenderer->RemoveTexture(m_nLoadingBackTexID); - m_nLoadingBackTexID = -1; - } - if (m_pImage) - { - m_pImage->Release(); - } - } } ////////////////////////////////////////////////////////////////////////// @@ -485,7 +326,6 @@ void CXConsole::Init(ISystem* pSystem) { m_pFont = pSystem->GetICryFont()->GetFont("default"); } - m_pRenderer = pSystem->GetIRenderer(); m_pTimer = pSystem->GetITimer(); AzFramework::InputChannelEventListener::Connect(); @@ -534,10 +374,7 @@ void CXConsole::Init(ISystem* pSystem) // ---------------------------------------------------------- - if (!m_pRenderer || gEnv->IsInToolMode()) - { - m_nLoadingBackTexID = -1; - } + m_nLoadingBackTexID = -1; if (gEnv->IsDedicated()) { @@ -1176,7 +1013,6 @@ void CXConsole::Clear() ////////////////////////////////////////////////////////////////////////// void CXConsole::Update() { - // Repeat GetIRenderer (For Editor). if (!m_pSystem) { return; @@ -1192,8 +1028,6 @@ void CXConsole::Update() // Execute the deferred commands ExecuteDeferredCommands(); - m_pRenderer = m_pSystem->GetIRenderer(); - if (!m_bConsoleActive) { m_nRepeatEventId = s_nullRepeatEventId; @@ -1226,8 +1060,6 @@ void CXConsole::Update() } } } - - CNotificationNetworkConsole::Update(); } //enable this for now, we need it for profiling etc @@ -1588,206 +1420,10 @@ const char* CXConsole::GetHistoryElement(const bool bUpOrDown) ////////////////////////////////////////////////////////////////////////// void CXConsole::Draw() { - //ShowConsole(true); - if (!m_pSystem || !m_nTempScrollMax) - { - return; - } - - if (!m_pRenderer) - { - // For Editor. - m_pRenderer = m_pSystem->GetIRenderer(); - } - - if (!m_pRenderer) - { - return; - } - - if (!m_pFont) - { - // For Editor. - ICryFont* pICryFont = m_pSystem->GetICryFont(); - - if (pICryFont) - { - m_pFont = m_pSystem->GetICryFont()->GetFont("default"); - } - } - - ScrollConsole(); - - if (!m_bConsoleActive && con_display_last_messages == 0) - { - return; - } - - if (m_pRenderer->GetIRenderAuxGeom()) - { - m_pRenderer->GetIRenderAuxGeom()->Flush(); - } - - m_pRenderer->EF_RenderTextMessages(); - - m_pRenderer->PushProfileMarker("DISPLAY_CONSOLE"); - - if (m_nScrollPos <= 0) - { - DrawBuffer(70, "console"); - } - else - { - // cursor blinking - { - m_fCursorBlinkTimer += gEnv->pTimer->GetRealFrameTime(); // works even when time is manipulated - // m_fCursorBlinkTimer += gEnv->pTimer->GetFrameTime(ITimer::ETIMER_UI); // can be used once ETIMER_UI works even with t_FixedTime - - const float fCursorBlinkDelay = 0.5f; // in sec (similar to Windows default but might differ from actual setting) - - if (m_fCursorBlinkTimer > fCursorBlinkDelay) - { - m_bDrawCursor = !m_bDrawCursor; - m_fCursorBlinkTimer = 0.0f; - } - } - - CScopedWireFrameMode scopedWireFrame(m_pRenderer, R_SOLID_MODE); - - if (!m_nProgressRange) - { - int whiteTexId = gEnv->pRenderer ? gEnv->pRenderer->GetWhiteTextureId() : -1; - - if (m_bStaticBackground) - { - m_pRenderer->SetState(GS_NODEPTHTEST); - m_pRenderer->Draw2dImage(0, 0, 800, 600, m_pImage ? m_pImage->GetTextureID() : whiteTexId, 0.0f, 1.0f, 1.0f, 0.0f); - } - else - { - TransformationMatrices backupSceneMatrices; - m_pRenderer->Set2DMode(m_pRenderer->GetWidth(), m_pRenderer->GetHeight(), backupSceneMatrices); - - float fReferenceSize = 600.0f; - - float fSizeX = (float)m_pRenderer->GetWidth(); - float fSizeY = m_nTempScrollMax * m_pRenderer->GetHeight() / fReferenceSize; - - m_pRenderer->SetState(GS_NODEPTHTEST | GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA); - m_pRenderer->DrawImage(0, 0, fSizeX, fSizeY, whiteTexId, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.7f); - m_pRenderer->DrawImage(0, fSizeY, fSizeX, 2.0f * m_pRenderer->GetHeight() / fReferenceSize, whiteTexId, 0, 0, 0, 0, 0.0f, 0.0f, 0.0f, 1.0f); - - m_pRenderer->Unset2DMode(backupSceneMatrices); - } - } - - // draw progress bar - if (m_nProgressRange) - { - m_pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST); - m_pRenderer->Draw2dImage(0.0, 0.0, 800.0f, 600.0f, m_nLoadingBackTexID, 0.0f, 1.0f, 1.0f, 0.0f); - } - - DrawBuffer(m_nScrollPos, "console"); - } - - m_pRenderer->PopProfileMarker("DISPLAY_CONSOLE"); } -void CXConsole::DrawBuffer(int nScrollPos, const char* szEffect) +void CXConsole::DrawBuffer(int, const char*) { - if (m_pFont && m_pRenderer) - { - // The scroll position is in pixels for a 800x600 screen so we scale it to the current resolution. - Vec2 referenceSize(800.0f, 600.0f); - const float fontSizeIn800x600 = 14; - const float maxYPos = nScrollPos * (m_pRenderer->GetHeight() / referenceSize.y); - // We also scale the font from the original 800x600 size - float fontSize = fontSizeIn800x600 * (m_pRenderer->GetWidth() / referenceSize.x); - const float fontAspectRatio = 0.75f; - float minFontSize = 10.f; - float maxFontSize = 50.f; - ICVar* minFontCVar = GetCVar("r_minConsoleFontSize"); - if (minFontCVar) - { - minFontSize = minFontCVar->GetFVal(); - } - - ICVar* maxFontCVar = GetCVar("r_maxConsoleFontSize"); - if (maxFontCVar) - { - maxFontSize = maxFontCVar->GetFVal(); - } - - // Limit max font size in case minFontSize > maxFontSize - maxFontSize = AZStd::max(minFontSize, maxFontSize); - fontSize = AZStd::min(AZStd::max(fontSize, minFontSize), maxFontSize); - - STextDrawContext ctx; - //ctx.Reset(); - ctx.SetEffect(m_pFont->GetEffectId(szEffect)); - ctx.SetProportional(false); - ctx.SetCharWidthScale(0.5f); - ctx.SetSize(Vec2(fontSize, fontAspectRatio * fontSize)); - ctx.SetColor(ColorF(1, 1, 1, 1)); - ctx.SetFlags(eDrawText_CenterV | eDrawText_2D); - - float csize = 0.8f * ctx.GetCharHeight(); - ctx.SetSizeIn800x600(false); - - float yPos = maxYPos - csize - 3.0f; - float xPos = LINE_BORDER; - - float fCharWidth = (ctx.GetCharWidth() * ctx.GetCharWidthScale()); - - //int ypos=nScrollPos-csize-3; - - //Draw the input line - if (m_bConsoleActive && !m_nProgressRange) - { - /*m_pRenderer->DrawString(xPos-nCharWidth, yPos, false, ">"); - m_pRenderer->DrawString(xPos, yPos, false, m_sInputBuffer.c_str()); - if(m_bDrawCursor) - m_pRenderer->DrawString(xPos+nCharWidth*m_nCursorPos, yPos, false, "_");*/ - - m_pFont->DrawString((float)(xPos - fCharWidth), (float)yPos, ">", false, ctx); - m_pFont->DrawString((float)xPos, (float)yPos, m_sInputBuffer.c_str(), false, ctx); - - if (m_bDrawCursor) - { - string szCursorLeft(m_sInputBuffer.c_str(), m_sInputBuffer.c_str() + m_nCursorPos); - int n = m_pFont->GetTextLength(szCursorLeft.c_str(), false); - - m_pFont->DrawString((float)(xPos + (fCharWidth * n)), (float)yPos, "_", false, ctx); - } - } - - yPos -= csize; - - ConsoleBufferRItor ritor; - ritor = m_dqConsoleBuffer.rbegin(); - int nScroll = 0; - while (ritor != m_dqConsoleBuffer.rend() && yPos >= 0) - { - if (nScroll >= m_nScrollLine) - { - const char* buf = ritor->c_str();// GetBuf(k); - - if (*buf > 0 && *buf < 32) - { - buf++; // to jump over verbosity level character - } - if (yPos + csize > 0) - { - m_pFont->DrawString((float)xPos, (float)yPos, buf, false, ctx); - } - yPos -= csize; - } - nScroll++; - - ++ritor; - } //k - } } @@ -1828,44 +1464,6 @@ int CXConsole::GetLineCount() const ////////////////////////////////////////////////////////////////////////// void CXConsole::ScrollConsole() { - if (!m_pRenderer) - { - return; - } - - int nCurrHeight = m_pRenderer->GetHeight(); - - switch (m_sdScrollDir) - { - ///////////////////////////////// - case sdDOWN: // The console is scrolling down - - // Vlads note: console should go down immediately, otherwise it can look very bad on startup - //m_nScrollPos+=nCurrHeight/2; - m_nScrollPos = m_nTempScrollMax; - - if (m_nScrollPos > m_nTempScrollMax) - { - m_nScrollPos = m_nTempScrollMax; - m_sdScrollDir = sdNONE; - } - break; - ///////////////////////////////// - case sdUP: // The console is scrolling up - - m_nScrollPos -= nCurrHeight;//2; - - if (m_nScrollPos < 0) - { - m_nScrollPos = 0; - m_sdScrollDir = sdNONE; - } - break; - ///////////////////////////////// - case sdNONE: - break; - ///////////////////////////////// - } } @@ -2004,11 +1602,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) int devOnlyMask = VF_DEV_ONLY; int dediOnlyMask = VF_DEDI_ONLY; int excludeMask = cheatMask | constMask | readOnlyMask | devOnlyMask | dediOnlyMask; -#if defined(CVARS_WHITELIST) - CSystem* pSystem = static_cast(gEnv->pSystem); - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); - bool excludeWhitelist = true; -#endif // defined(CVARS_WHITELIST) if (numArgs > 1) { @@ -2041,13 +1634,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) excludeMask &= ~dediOnlyMask; } -#if defined(CVARS_WHITELIST) - if (azstricmp(arg, "whitelist") == 0) - { - excludeWhitelist = false; - } -#endif // defined(CVARS_WHITELIST) - --numArgs; } } @@ -2065,11 +1651,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) int devOnlyFlags = (command.m_nFlags & devOnlyMask); int dediOnlyFlags = (command.m_nFlags & dediOnlyMask); bool shouldLog = ((cheatFlags | devOnlyFlags | dediOnlyFlags) == 0) || (((cheatFlags | devOnlyFlags | dediOnlyFlags) & ~excludeMask) != 0); -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(command.m_sName, true) : true; - shouldLog &= (!whitelisted || (whitelisted & !excludeWhitelist)); -#endif // defined(CVARS_WHITELIST) - if (shouldLog) { CryLogAlways("[CVARS]: [COMMAND] %s%s%s%s%s", @@ -2077,11 +1658,7 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) (cheatFlags != 0) ? " [VF_CHEAT]" : "", (devOnlyFlags != 0) ? " [VF_DEV_ONLY]" : "", (dediOnlyFlags != 0) ? " [VF_DEDI_ONLY]" : "", -#if defined(CVARS_WHITELIST) - (whitelisted == true) ? " [WHITELIST]" : "" -#else "" -#endif // defined(CVARS_WHITELIST) ); ++commandCount; } @@ -2098,11 +1675,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) int devOnlyFlags = (flags & devOnlyMask); int dediOnlyFlags = (flags & dediOnlyMask); bool shouldLog = ((cheatFlags | constFlags | readOnlyFlags | devOnlyFlags | dediOnlyFlags) == 0) || (((cheatFlags | constFlags | readOnlyFlags | devOnlyFlags | dediOnlyFlags) & ~excludeMask) != 0); -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(pVariable->GetName(), true) : true; - shouldLog &= (!whitelisted || (whitelisted & !excludeWhitelist)); -#endif // defined(CVARS_WHITELIST) - if (shouldLog) { CryLogAlways("[CVARS]: [VARIABLE] %s%s%s%s%s%s%s", @@ -2112,11 +1684,7 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg) (readOnlyFlags != 0) ? " [VF_READONLY]" : "", (devOnlyFlags != 0) ? " [VF_DEV_ONLY]" : "", (dediOnlyFlags != 0) ? " [VF_DEDI_ONLY]" : "", -#if defined(CVARS_WHITELIST) - (whitelisted == true) ? " [WHITELIST]" : "" -#else "" -#endif // defined(CVARS_WHITELIST) ); ++cvarCount; } @@ -2467,13 +2035,6 @@ void CXConsole::ExecuteStringInternal(const char* command, const bool bFromConso if (!sTemp.empty() || (pCVar->GetType() == CVAR_STRING)) { - // renderer cvars will be updated in the render thread - if ((pCVar->GetFlags() & VF_RENDERER_CVAR) && m_pRenderer) - { - m_pRenderer->SetRendererCVar(pCVar, sTemp.c_str(), bSilentMode); - continue; - } - pCVar->Set(sTemp.c_str()); } } @@ -2500,36 +2061,8 @@ void CXConsole::ExecuteDeferredCommands() { TDeferredCommandList::iterator it; - // const float fontHeight = 10; - // ColorF col = Col_Yellow; - // - // float curX = 10; - // float curY = 10; - - //IRenderer* pRenderer = gEnv->pRenderer; - - // Print the deferred messages - // it = m_deferredCommands.begin(); - // if (it != m_deferredCommands.end()) - // { - // pRenderer->Draw2dLabel( curX, curY += fontHeight, 1.2f, &col.r, false - // , "Pending deferred commands = %d", m_deferredCommands.size() ); - // } - // - // for ( - // ; it != m_deferredCommands.end() - // ; ++it - // ) - // { - // pRenderer->Draw2dLabel( curX + fontHeight * 2.0f, curY += fontHeight, 1.2f, &col.r, false - // , "Cmd: %s", it->command.c_str() ); - // } - if (m_waitFrames) { - // pRenderer->Draw2dLabel( curX, curY += fontHeight, 1.2f, &col.r, false - // , "Waiting frames = %d", m_waitFrames ); - --m_waitFrames; return; } @@ -2538,10 +2071,6 @@ void CXConsole::ExecuteDeferredCommands() { if (m_waitSeconds > gEnv->pTimer->GetFrameStartTime()) { - // pRenderer->Draw2dLabel( curX, curY += fontHeight, 1.2f, &col.r, false - // , "Waiting seconds = %f" - // , m_waitSeconds.GetSeconds() - gEnv->pTimer->GetFrameStartTime().GetSeconds() ); - return; } @@ -2566,8 +2095,6 @@ void CXConsole::ExecuteDeferredCommands() break; } } - - //m_deferredExecution = false; } ////////////////////////////////////////////////////////////////////////// @@ -2816,11 +2343,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) } } //try to search in command list - -#if defined(CVARS_WHITELIST) - CSystem* pSystem = static_cast(gEnv->pSystem); - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); -#endif // defined(CVARS_WHITELIST) bool bArgumentAutoComplete = false; std::vector matches; @@ -2861,10 +2383,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) string cmd = string(sVar) + " " + pArgumentAutoComplete->GetValue(i); if (_strnicmp(m_sPrevTab.c_str(), cmd.c_str(), m_sPrevTab.length()) == 0) { -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(cmd, true) : true; - if (whitelisted) -#endif // defined(CVARS_WHITELIST) { bArgumentAutoComplete = true; matches.push_back(cmd); @@ -2886,10 +2404,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) { if (_strnicmp(m_sPrevTab.c_str(), itrCmds->first.c_str(), m_sPrevTab.length()) == 0) { -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(itrCmds->first, true) : true; - if (whitelisted) -#endif // defined(CVARS_WHITELIST) { matches.push_back((char* const)itrCmds->first.c_str()); } @@ -2909,10 +2423,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer) {//if(itrVars->first.compare(0,m_sPrevTab.length(),m_sPrevTab)==0) if (_strnicmp(m_sPrevTab.c_str(), itrVars->first, m_sPrevTab.length()) == 0) { -#if defined(CVARS_WHITELIST) - bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(itrVars->first, true) : true; - if (whitelisted) -#endif // defined(CVARS_WHITELIST) { matches.push_back((char* const)itrVars->first); } @@ -3143,71 +2653,18 @@ void CXConsole::PostLine(const char* lineOfText, size_t len) } ////////////////////////////////////////////////////////////////////////// -void CXConsole::ResetProgressBar(int nProgressBarRange) +void CXConsole::ResetProgressBar(int) { - m_nProgressRange = nProgressBarRange; - m_nProgress = 0; - - if (nProgressBarRange < 0) - { - nProgressBarRange = 0; - } - - if (!m_nProgressRange) - { - if (m_nLoadingBackTexID) - { - if (m_pRenderer) - { - m_pRenderer->RemoveTexture(m_nLoadingBackTexID); - } - m_nLoadingBackTexID = -1; - } - } - - static ICVar* log_Verbosity = GetCVar("log_Verbosity"); - - if (log_Verbosity && (!log_Verbosity->GetIVal())) - { - Clear(); - } } ////////////////////////////////////////////////////////////////////////// void CXConsole::TickProgressBar() { - if (m_nProgressRange != 0 && m_nProgressRange > m_nProgress) - { - m_nProgress++; - m_pSystem->UpdateLoadingScreen(); - } - if (m_pSystem->GetIRenderer()) - { - m_pSystem->GetIRenderer()->FlushRTCommands(false, false, false); // Try to switch render thread contexts to make RT always busy during loading - } } ////////////////////////////////////////////////////////////////////////// -void CXConsole::SetLoadingImage(const char* szFilename) +void CXConsole::SetLoadingImage(const char*) { - ITexture* pTex = 0; - - pTex = m_pSystem->GetIRenderer()->EF_LoadTexture(szFilename, FT_DONT_STREAM | FT_NOMIPS); - - if (!pTex || (pTex->GetFlags() & FT_FAILED)) - { - SAFE_RELEASE(pTex); - pTex = m_pSystem->GetIRenderer()->EF_LoadTexture("Textures/Console/loadscreen_default.dds", FT_DONT_STREAM | FT_NOMIPS); - } - - if (pTex) - { - m_nLoadingBackTexID = pTex->GetTextureID(); - } - else - { - m_nLoadingBackTexID = -1; - } } ////////////////////////////////////////////////////////////////////////// @@ -3339,12 +2796,6 @@ void CXConsole::ExecuteInputBuffer() AddCommandToHistory(sTemp.c_str()); -#if defined(CVARS_WHITELIST) - CSystem* pSystem = static_cast(gEnv->pSystem); - ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList(); - bool execute = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(sTemp, false) : true; - if (execute) -#endif // defined(CVARS_WHITELIST) { ExecuteStringInternal(sTemp.c_str(), true); // from console } diff --git a/Code/CryEngine/CrySystem/XConsole.h b/Code/CryEngine/CrySystem/XConsole.h index ed3a3e9b82..01649872ba 100644 --- a/Code/CryEngine/CrySystem/XConsole.h +++ b/Code/CryEngine/CrySystem/XConsole.h @@ -418,7 +418,6 @@ private: // ---------------------------------------------------------- CSystem* m_pSystem; IFFont* m_pFont; - IRenderer* m_pRenderer; ITimer* m_pTimer; ICVar* m_pSysDeactivateConsole; diff --git a/Code/CryEngine/CrySystem/XML/XmlUtils.cpp b/Code/CryEngine/CrySystem/XML/XmlUtils.cpp index de5a14ecd7..d4feec04f2 100644 --- a/Code/CryEngine/CrySystem/XML/XmlUtils.cpp +++ b/Code/CryEngine/CrySystem/XML/XmlUtils.cpp @@ -272,7 +272,6 @@ void CXmlUtils::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wpar case ESYSTEM_EVENT_LEVEL_POST_UNLOAD: case ESYSTEM_EVENT_LEVEL_LOAD_END: g_pCXmlNode_PoolAlloc->FreeMemoryIfEmpty(); - STLALLOCATOR_CLEANUP; break; } } diff --git a/Code/CryEngine/CrySystem/XML/xml.cpp b/Code/CryEngine/CrySystem/XML/xml.cpp index 601b14eeb3..438b35b6c8 100644 --- a/Code/CryEngine/CrySystem/XML/xml.cpp +++ b/Code/CryEngine/CrySystem/XML/xml.cpp @@ -1809,8 +1809,6 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString, ParseEnd(); } - SYNCHRONOUS_LOADING_TICK(); - delete [] pFileContents; return root; diff --git a/Code/CryEngine/CrySystem/ZLibCompressor.cpp b/Code/CryEngine/CrySystem/ZLibCompressor.cpp deleted file mode 100644 index 94d327940c..0000000000 --- a/Code/CryEngine/CrySystem/ZLibCompressor.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include "CrySystem_precompiled.h" -#include "CryZlib.h" -#include "ZLibCompressor.h" -#include "TypeInfo_impl.h" -#include - -// keep these in sync with the enums in IZLibCompressor.h -static const int k_stratMap[] = {Z_DEFAULT_STRATEGY, Z_FILTERED, Z_HUFFMAN_ONLY, Z_RLE}; -static const int k_methodMap[] = {Z_DEFLATED}; -static const int k_flushMap[] = {Z_NO_FLUSH, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH}; - -struct CZLibDeflateStream - : public IZLibDeflateStream -{ -protected: - virtual ~CZLibDeflateStream(); - -protected: - z_stream m_compressStream; - int m_zSize; - int m_zPeak; - int m_level; - int m_windowBits; - int m_memLevel; - int m_zlibFlush; - int m_bytesInput; - int m_bytesOutput; - EZLibStrategy m_strategy; - EZLibMethod m_method; - EZDeflateState m_curState; - bool m_streamOpened; - - - static voidpf ZAlloc( - voidpf pInOpaque, - uInt inItems, - uInt inSize); - static void ZFree( - voidpf pInOpaque, - voidpf pInAddress); - - EZDeflateState RunDeflate(); - -public: - CZLibDeflateStream( - int inLevel, - EZLibMethod inMethod, - int inWindowBits, - int inMemLevel, - EZLibStrategy inStrategy, - EZLibFlush inFlushMethod); - - virtual void SetOutputBuffer( - char* pInBuffer, - int inSize); - virtual int GetBytesOutput(); - - virtual void Input( - const char* pInSource, - int inSourceSize); - virtual void EndInput(); - - virtual EZDeflateState GetState(); - - virtual void GetStats( - SStats* pOutStats); - - virtual void Release(); -}; - -inline static int Lookup(int inIndex, const int* pInValues, [[maybe_unused]] int inMaxValues) -{ - CRY_ASSERT_MESSAGE(inIndex >= 0 && inIndex < inMaxValues, "CZLibDeflateStream mapping invalid"); - return pInValues[inIndex]; -} - -IZLibDeflateStream* CZLibCompressor::CreateDeflateStream(int inLevel, EZLibMethod inMethod, int inWindowBits, int inMemLevel, EZLibStrategy inStrategy, EZLibFlush inFlushMethod) -{ - return new CZLibDeflateStream(inLevel, inMethod, inWindowBits, inMemLevel, inStrategy, inFlushMethod); -} - -void CZLibCompressor::Release() -{ - delete this; -} - -void CZLibCompressor::MD5Init(SMD5Context* pIOCtx) -{ - COMPILE_TIME_ASSERT(sizeof(*pIOCtx) == sizeof(MD5Context)); - - ::MD5Init((MD5Context*)pIOCtx); -} - -void CZLibCompressor::MD5Update(SMD5Context* pIOCtx, const char* pInBuff, unsigned int len) -{ - ::MD5Update((MD5Context*)pIOCtx, (unsigned char*)pInBuff, len); -} - -void CZLibCompressor::MD5Final(SMD5Context* pIOCtx, char outDigest[16]) -{ - ::MD5Final((unsigned char*)outDigest, (MD5Context*)pIOCtx); -} - -CZLibCompressor::~CZLibCompressor() -{ -} - -CZLibDeflateStream::CZLibDeflateStream( - int inLevel, - EZLibMethod inMethod, - int inWindowBits, - int inMemLevel, - EZLibStrategy inStrategy, - EZLibFlush inFlushMethod) - : m_zSize(0) - , m_zPeak(0) - , m_level(inLevel) - , m_windowBits(inWindowBits) - , m_memLevel(inMemLevel) - , m_bytesInput(0) - , m_bytesOutput(0) - , m_strategy(inStrategy) - , m_method(inMethod) - , m_curState(eZDefState_AwaitingInput) - , m_streamOpened(false) -{ - memset(&m_compressStream, 0, sizeof(m_compressStream)); - m_zlibFlush = Lookup(inFlushMethod, k_flushMap, ARRAY_COUNT(k_flushMap)); -} - -CZLibDeflateStream::~CZLibDeflateStream() -{ -} - -void CZLibDeflateStream::Release() -{ - if (m_streamOpened) - { - int err = deflateEnd(&m_compressStream); - if (err != Z_OK) - { - CryLog("zlib deflateEnd() error %d returned when closing stream", err); - } - } - delete this; -} - -void CZLibDeflateStream::SetOutputBuffer( - char* pInBuffer, - int inSize) -{ - m_bytesOutput += m_compressStream.total_out; - - m_compressStream.next_out = (byte*)pInBuffer; - m_compressStream.avail_out = inSize; - m_compressStream.total_out = 0; -} - -void CZLibDeflateStream::GetStats( - IZLibDeflateStream::SStats* pOutStats) -{ - pOutStats->bytesInput = m_bytesInput; - pOutStats->bytesOutput = m_bytesOutput + m_compressStream.total_out; - pOutStats->curMemoryUsed = m_zSize; - pOutStats->peakMemoryUsed = m_zPeak; -} - -int CZLibDeflateStream::GetBytesOutput() -{ - return m_compressStream.total_out; -} - -void CZLibDeflateStream::Input( - const char* pInSource, - int inSourceSize) -{ - CRY_ASSERT_MESSAGE(m_curState == eZDefState_AwaitingInput, "CZLibDeflateStream::Input() called when stream is not awaiting input"); - - m_compressStream.next_in = (Bytef*)pInSource; - m_compressStream.avail_in = inSourceSize; - m_bytesInput += inSourceSize; -} - -void CZLibDeflateStream::EndInput() -{ - CRY_ASSERT_MESSAGE(m_curState == eZDefState_AwaitingInput, "CZLibDeflateStream::EndInput() called when stream is not awaiting input"); - - m_zlibFlush = Z_FINISH; -} - -voidpf CZLibDeflateStream::ZAlloc( - voidpf pInOpaque, - uInt inItems, - uInt inSize) -{ - CZLibDeflateStream* pStr = reinterpret_cast(pInOpaque); - - int size = inItems * inSize; - - int* ptr = (int*) CryModuleMalloc(sizeof(int) + size); - if (ptr) - { - *ptr = inItems * inSize; - ptr += 1; - - int newSize = pStr->m_zSize + size; - pStr->m_zSize = newSize; - if (newSize > pStr->m_zPeak) - { - pStr->m_zPeak = newSize; - } - } - return ptr; -} - -void CZLibDeflateStream::ZFree( - voidpf pInOpaque, - voidpf pInAddress) -{ - int* pPtr = reinterpret_cast(pInAddress); - if (pPtr) - { - CZLibDeflateStream* pStr = reinterpret_cast(pInOpaque); - pStr->m_zSize -= pPtr[-1]; - CryModuleFree(pPtr - 1); - } -} - -EZDeflateState CZLibDeflateStream::RunDeflate() -{ - bool runDeflate = false; - bool inputAvailable = (m_compressStream.avail_in > 0) || (m_zlibFlush == Z_FINISH); - bool outputAvailable = (m_compressStream.avail_out > 0); - - switch (m_curState) - { - case eZDefState_AwaitingInput: - case eZDefState_ConsumeOutput: - if (inputAvailable && outputAvailable) - { - runDeflate = true; - } - else if (inputAvailable || !outputAvailable) - { - m_curState = eZDefState_ConsumeOutput; - } - else - { - m_curState = eZDefState_AwaitingInput; - } - break; - - case eZDefState_Finished: - break; - - case eZDefState_Deflating: - CRY_ASSERT_MESSAGE(0, "Shouldn't be trying to run deflate whilst a deflate is in progress"); - break; - - case eZDefState_Error: - break; - - default: - CRY_ASSERT_MESSAGE(0, "unknown state"); - break; - } - - if (runDeflate) - { - if (!m_streamOpened) - { - m_streamOpened = true; - - // initialising with deflateInit2 requires that the next_in be initialised - m_compressStream.zalloc = &CZLibDeflateStream::ZAlloc; - m_compressStream.zfree = &CZLibDeflateStream::ZFree; - m_compressStream.opaque = this; - - int error = deflateInit2(&m_compressStream, m_level, Lookup(m_method, k_methodMap, ARRAY_COUNT(k_methodMap)), m_windowBits, m_memLevel, Lookup(m_strategy, k_stratMap, ARRAY_COUNT(k_stratMap))); - if (error != Z_OK) - { - m_curState = eZDefState_Error; - CryLog("zlib deflateInit2() error, err %d", error); - } - } - - if (m_curState != eZDefState_Error) - { - int error = deflate(&m_compressStream, m_zlibFlush); - - if (error == Z_STREAM_END) - { - // end of stream has been generated, only produced if we pass Z_FINISH into deflate - m_curState = eZDefState_Finished; - } - else if ((error == Z_OK && m_compressStream.avail_out == 0) || (error == Z_BUF_ERROR && m_compressStream.avail_out == 0)) - { - // output buffer has been filled - // data should be available for consumption by caller - m_curState = eZDefState_ConsumeOutput; - } - else if (m_compressStream.avail_in == 0) - { - // ran out of input data - // data may be available for consumption - but we need more input right now - m_curState = eZDefState_AwaitingInput; - } - else - { - // some sort of error has occurred - m_curState = eZDefState_Error; - CryLog("zlib deflate() error, err %d", error); - } - } - } - - return m_curState; -} - -EZDeflateState CZLibDeflateStream::GetState() -{ - return RunDeflate(); -} diff --git a/Code/CryEngine/CrySystem/ZLibCompressor.h b/Code/CryEngine/CrySystem/ZLibCompressor.h deleted file mode 100644 index 4c026d965f..0000000000 --- a/Code/CryEngine/CrySystem/ZLibCompressor.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_ZLIBCOMPRESSOR_H -#define CRYINCLUDE_CRYSYSTEM_ZLIBCOMPRESSOR_H -#pragma once - - -#include "IZLibCompressor.h" - -class CZLibCompressor - : public IZLibCompressor -{ -protected: - virtual ~CZLibCompressor(); - -public: - virtual IZLibDeflateStream* CreateDeflateStream(int inLevel, EZLibMethod inMethod, int inWindowBits, int inMemLevel, EZLibStrategy inStrategy, EZLibFlush inFlushMethod); - virtual void Release(); - - virtual void MD5Init(SMD5Context* pIOCtx); - virtual void MD5Update(SMD5Context* pIOCtx, const char* pInBuff, unsigned int len); - virtual void MD5Final(SMD5Context * pIOCtx, char outDigest[16]); -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ZLIBCOMPRESSOR_H diff --git a/Code/CryEngine/CrySystem/ZLibDecompressor.cpp b/Code/CryEngine/CrySystem/ZLibDecompressor.cpp deleted file mode 100644 index d75baf2c69..0000000000 --- a/Code/CryEngine/CrySystem/ZLibDecompressor.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : zlib inflate wrapper - - -#include "CrySystem_precompiled.h" - -#include "CryZlib.h" -#include "ZLibDecompressor.h" - -class CZLibInflateStream - : public IZLibInflateStream -{ -public: - CZLibInflateStream() - : m_bStreamOpened(false) - , m_zlibFlush(0) - , m_currentState(eZInfState_AwaitingInput) - , m_bytesInput(0) - , m_bytesOutput(0) - , m_zSize(0) - , m_zPeak(0) {} - - virtual void Release(); - - virtual void SetOutputBuffer(char* pInBuffer, unsigned int inSize); - virtual unsigned int GetBytesOutput(); - virtual void Input(const char* pInSource, unsigned int inSourceSize); - virtual void EndInput(); - virtual EZInflateState GetState(); - virtual void GetStats(IZLibInflateStream::SStats* pOutStats); - -private: - virtual ~CZLibInflateStream() {} - - EZInflateState RunInflate(); - - static voidpf ZAlloc(voidpf pInOpaque, uInt inItems, uInt inSize); - static void ZFree(voidpf pInOpaque, voidpf pInAddress); - - z_stream m_decompressStream; - bool m_bStreamOpened; - int m_zlibFlush; - EZInflateState m_currentState; - unsigned int m_bytesInput; - unsigned int m_bytesOutput; - unsigned int m_zSize; - unsigned int m_zPeak; -}; - -IZLibInflateStream* CZLibDecompressor::CreateInflateStream() -{ - return new CZLibInflateStream(); -} - -void CZLibDecompressor::Release() -{ - delete this; -} - -void CZLibInflateStream::Release() -{ - if (m_bStreamOpened) - { - int err = inflateEnd(&m_decompressStream); - if (err != Z_OK) - { - CryLog("zlib inflateEnd() error %d returned when closing stream", err); - } - } - - delete this; -} - -void CZLibInflateStream::SetOutputBuffer(char* pInBuffer, unsigned int inSize) -{ - m_bytesOutput += m_decompressStream.total_out; - - m_decompressStream.next_out = (byte*)pInBuffer; - m_decompressStream.avail_out = inSize; - m_decompressStream.total_out = 0; -} - -void CZLibInflateStream::GetStats(IZLibInflateStream::SStats* pOutStats) -{ - pOutStats->bytesInput = m_bytesInput; - pOutStats->bytesOutput = m_bytesOutput + m_decompressStream.total_out; - pOutStats->curMemoryUsed = m_zSize; - pOutStats->peakMemoryUsed = m_zPeak; -} - -unsigned int CZLibInflateStream::GetBytesOutput() -{ - return m_decompressStream.total_out; -} - -void CZLibInflateStream::Input(const char* pInSource, unsigned int inSourceSize) -{ - CRY_ASSERT_MESSAGE(m_currentState == eZInfState_AwaitingInput, "CZLibInflateStream::Input() called when stream is not awaiting input or has finished"); - - m_decompressStream.next_in = (Bytef*)pInSource; - m_decompressStream.avail_in = inSourceSize; - m_bytesInput += inSourceSize; -} - -void CZLibInflateStream::EndInput() -{ - CRY_ASSERT_MESSAGE(m_currentState == eZInfState_AwaitingInput, "CZLibInflateStream::EndInput() called when stream is not awaiting input"); - - m_zlibFlush = Z_FINISH; -} - -voidpf CZLibInflateStream::ZAlloc(voidpf pInOpaque, uInt inItems, uInt inSize) -{ - CZLibInflateStream* pStr = reinterpret_cast(pInOpaque); - - const unsigned int size = inItems * inSize; - - int* pPtr = (int*)CryModuleMalloc(sizeof(int) + size); - - if (pPtr) - { - *pPtr = inItems * inSize; - pPtr += 1; - - const unsigned int newSize = pStr->m_zSize + size; - pStr->m_zSize = newSize; - if (newSize > pStr->m_zPeak) - { - pStr->m_zPeak = newSize; - } - } - - return pPtr; -} - -void CZLibInflateStream::ZFree(voidpf pInOpaque, voidpf pInAddress) -{ - int* pPtr = reinterpret_cast(pInAddress); - - if (pPtr) - { - CZLibInflateStream* pStr = reinterpret_cast(pInOpaque); - pStr->m_zSize -= pPtr[-1]; - CryModuleFree(pPtr - 1); - } -} - -EZInflateState CZLibInflateStream::RunInflate() -{ - bool runInflate = false; - bool inputAvailable = (m_decompressStream.avail_in > 0) || (m_zlibFlush == Z_FINISH); - bool outputAvailable = (m_decompressStream.avail_out > 0); - - switch (m_currentState) - { - case eZInfState_AwaitingInput: - case eZInfState_ConsumeOutput: - if (inputAvailable && outputAvailable) - { - runInflate = true; - } - else if (inputAvailable || !outputAvailable) - { - m_currentState = eZInfState_ConsumeOutput; - } - else - { - m_currentState = eZInfState_AwaitingInput; - } - break; - - case eZInfState_Inflating: - CRY_ASSERT_MESSAGE(false, "Shouldn't be trying to run inflate whilst a inflate is in progress"); - break; - - case eZInfState_Error: - break; - - default: - CRY_ASSERT_MESSAGE(false, "unknown state"); - break; - } - - if (runInflate) - { - if (!m_bStreamOpened) - { - m_bStreamOpened = true; - - // initializing with inflateInit2 requires that the next_in be initialized - m_decompressStream.zalloc = &CZLibInflateStream::ZAlloc; - m_decompressStream.zfree = &CZLibInflateStream::ZFree; - m_decompressStream.opaque = this; - - const int error = inflateInit2(&m_decompressStream, -MAX_WBITS); - if (error != Z_OK) - { - m_currentState = eZInfState_Error; - CryLog("zlib inflateInit2() error, err %d", error); - } - } - - if (m_currentState != eZInfState_Error) - { - int error = inflate(&m_decompressStream, m_zlibFlush); - - if (error == Z_STREAM_END) - { - // end of stream has been generated, only produced if we pass Z_FINISH into inflate - m_currentState = eZInfState_Finished; - } - else if ((error == Z_OK && m_decompressStream.avail_out == 0) || (error == Z_BUF_ERROR && m_decompressStream.avail_out == 0)) - { - // output buffer has been filled - // data should be available for consumption by caller - m_currentState = eZInfState_ConsumeOutput; - } - else if (m_decompressStream.avail_in == 0) - { - // ran out of input data - // data may be available for consumption - but we need more input right now - m_currentState = eZInfState_AwaitingInput; - } - else - { - // some sort of error has occurred - m_currentState = eZInfState_Error; - CryLog("zlib inflate() error, err %d", error); - } - } - } - - return m_currentState; -} - -EZInflateState CZLibInflateStream::GetState() -{ - return RunInflate(); -} diff --git a/Code/CryEngine/CrySystem/ZLibDecompressor.h b/Code/CryEngine/CrySystem/ZLibDecompressor.h deleted file mode 100644 index 0a3ca0669f..0000000000 --- a/Code/CryEngine/CrySystem/ZLibDecompressor.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : zlib inflate wrapper - - -#ifndef CRYINCLUDE_CRYSYSTEM_ZLIBDECOMPRESSOR_H -#define CRYINCLUDE_CRYSYSTEM_ZLIBDECOMPRESSOR_H -#pragma once - - -#include "IZlibDecompressor.h" - -class CZLibDecompressor - : public IZLibDecompressor -{ -public: - virtual IZLibInflateStream* CreateInflateStream(); - virtual void Release(); - -private: - virtual ~CZLibDecompressor() {} -}; - -#endif // CRYINCLUDE_CRYSYSTEM_ZLIBDECOMPRESSOR_H diff --git a/Code/CryEngine/CrySystem/ZStdDecompressor.cpp b/Code/CryEngine/CrySystem/ZStdDecompressor.cpp deleted file mode 100644 index 0de76b82f8..0000000000 --- a/Code/CryEngine/CrySystem/ZStdDecompressor.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* -* 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. -* -*/ - -#include "CrySystem_precompiled.h" -#include -#include "ZStdDecompressor.h" - -bool CZStdDecompressor::DecompressData(const char* pIn, const uint inputSize, char* pOut, const uint outputSize) -{ - size_t result = ZSTD_decompress(pOut, outputSize, pIn, inputSize); - return !ZSTD_isError(result); -} - -void CZStdDecompressor::Release() -{ - delete this; -} diff --git a/Code/CryEngine/CrySystem/ZStdDecompressor.h b/Code/CryEngine/CrySystem/ZStdDecompressor.h deleted file mode 100644 index 200e5fe350..0000000000 --- a/Code/CryEngine/CrySystem/ZStdDecompressor.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - - -#include "IZStdDecompressor.h" - -class CZStdDecompressor - : public IZStdDecompressor -{ -public: - bool DecompressData(const char* pIn, const uint inputSize, char* pOut, const uint outputSize) override; - void Release() override; - -protected: - ~CZStdDecompressor() override = default; -}; - diff --git a/Code/CryEngine/CrySystem/ZipFile.h b/Code/CryEngine/CrySystem/ZipFile.h deleted file mode 100644 index e0c42088a3..0000000000 --- a/Code/CryEngine/CrySystem/ZipFile.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_ZIPFILE_H -#define CRYINCLUDE_CRYSYSTEM_ZIPFILE_H -#pragma once - - -#endif // CRYINCLUDE_CRYSYSTEM_ZIPFILE_H diff --git a/Code/CryEngine/CrySystem/ZipFileFormat_info.h b/Code/CryEngine/CrySystem/ZipFileFormat_info.h deleted file mode 100644 index d3fd4a3f54..0000000000 --- a/Code/CryEngine/CrySystem/ZipFileFormat_info.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#ifndef CRYINCLUDE_CRYSYSTEM_ZIPFILEFORMAT_INFO_H -#define CRYINCLUDE_CRYSYSTEM_ZIPFILEFORMAT_INFO_H -#pragma once - -#include "ZipFileFormat.h" - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Waddress-of-packed-member" -#endif - -STRUCT_INFO_BEGIN(ZipFile::CDREnd) -VAR_INFO(lSignature) -VAR_INFO(nDisk) -VAR_INFO(nCDRStartDisk) -VAR_INFO(numEntriesOnDisk) -VAR_INFO(numEntriesTotal) -VAR_INFO(lCDRSize) -VAR_INFO(lCDROffset) -VAR_INFO(nCommentLength) -STRUCT_INFO_END(ZipFile::CDREnd) - -STRUCT_INFO_BEGIN(ZipFile::DataDescriptor) -VAR_INFO(lCRC32) -VAR_INFO(lSizeCompressed) -VAR_INFO(lSizeUncompressed) -STRUCT_INFO_END(ZipFile::DataDescriptor) - -STRUCT_INFO_BEGIN(ZipFile::CDRFileHeader) -VAR_INFO(lSignature) -VAR_INFO(nVersionMadeBy) -VAR_INFO(nVersionNeeded) -VAR_INFO(nFlags) -VAR_INFO(nMethod) -VAR_INFO(nLastModTime) -VAR_INFO(nLastModDate) -VAR_INFO(desc) -VAR_INFO(nFileNameLength) -VAR_INFO(nExtraFieldLength) -VAR_INFO(nFileCommentLength) -VAR_INFO(nDiskNumberStart) -VAR_INFO(nAttrInternal) -VAR_INFO(lAttrExternal) -VAR_INFO(lLocalHeaderOffset) -STRUCT_INFO_END(ZipFile::CDRFileHeader) - -STRUCT_INFO_BEGIN(ZipFile::LocalFileHeader) -VAR_INFO(lSignature) -VAR_INFO(nVersionNeeded) -VAR_INFO(nFlags) -VAR_INFO(nMethod) -VAR_INFO(nLastModTime) -VAR_INFO(nLastModDate) -VAR_INFO(desc) -VAR_INFO(nFileNameLength) -VAR_INFO(nExtraFieldLength) -STRUCT_INFO_END(ZipFile::LocalFileHeader) - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - -#endif // CRYINCLUDE_CRYSYSTEM_ZIPFILEFORMAT_INFO_H diff --git a/Code/CryEngine/CrySystem/crash_face.bmp b/Code/CryEngine/CrySystem/crash_face.bmp deleted file mode 100644 index 887e5111c9..0000000000 --- a/Code/CryEngine/CrySystem/crash_face.bmp +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ced9f21365ad5a4159f31f602be10a00becf389fa289694026425e7a6bc73077 -size 9272 diff --git a/Code/CryEngine/CrySystem/crysystem_android_files.cmake b/Code/CryEngine/CrySystem/crysystem_android_files.cmake deleted file mode 100644 index 9164dce432..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_android_files.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - MobileDetectSpec_Android.cpp - MobileDetectSpec.cpp - MobileDetectSpec.h - ThermalInfoAndroid.h - ThermalInfoAndroid.cpp -) diff --git a/Code/CryEngine/CrySystem/crysystem_dlmalloc_files.cmake b/Code/CryEngine/CrySystem/crysystem_dlmalloc_files.cmake deleted file mode 100644 index 9f94bf6cff..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_dlmalloc_files.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - CryDLMalloc.c -) diff --git a/Code/CryEngine/CrySystem/crysystem_files.cmake b/Code/CryEngine/CrySystem/crysystem_files.cmake index bfc7b092fd..84250de95b 100644 --- a/Code/CryEngine/CrySystem/crysystem_files.cmake +++ b/Code/CryEngine/CrySystem/crysystem_files.cmake @@ -10,99 +10,40 @@ # set(FILES - AutoDetectSpec.cpp AZCrySystemInitLogSink.cpp - ClientHandler.cpp CmdLine.cpp CmdLineArg.cpp - CompressedFile.cpp ConsoleBatchFile.cpp ConsoleHelpGen.cpp - CryAsyncMemcpy.cpp - CrySizerStats.cpp DebugCallStack.cpp - GeneralMemoryHeap.cpp - HandlerBase.cpp IDebugCallStack.cpp - AsyncPakManager.cpp Log.cpp - SystemRender.cpp - NotificationNetwork.cpp - PhysRenderer.cpp - ResourceManager.cpp - ServerHandler.cpp - ServerThrottle.cpp - SyncLock.cpp System.cpp SystemCFG.cpp SystemEventDispatcher.cpp SystemInit.cpp - SystemScheduler.cpp SystemWin32.cpp Timer.cpp - UnixConsole.cpp - WindowsConsole.cpp XConsole.cpp XConsoleVariable.cpp - AutoDetectSpec.h - ClientHandler.h - HandlerBase.h - AsyncPakManager.h - PhysRenderer.h - ResourceManager.h - ServerHandler.h - ServerThrottle.h - SyncLock.h - SystemScheduler.h - UnixConsole.h - SystemInit.h - Serialization/MemoryReader.h - MemoryFragmentationProfiler.h XML/ReadWriteXMLSink.h - Serialization/ArchiveHost.h - Serialization/MemoryWriter.h - Serialization/JSONIArchive.h - Serialization/JSONOArchive.h - Serialization/BinArchive.h AZCrySystemInitLogSink.h AZCoreLogSink.h CmdLine.h CmdLineArg.h ConsoleBatchFile.h ConsoleHelpGen.h - CrySizerStats.h - CryWaterMark.h DebugCallStack.h - GeneralMemoryHeap.h IDebugCallStack.h - IThreadConfigManager.h Log.h - NotificationNetwork.h - resource.h SimpleStringPool.h CrySystem_precompiled.h System.h SystemCFG.h SystemEventDispatcher.h Timer.h - Validator.h - WindowsConsole.h XConsole.h XConsoleVariable.h - crash_face.bmp - ImageHandler.h - ImageHandler.cpp - DefragAllocator.cpp - MemoryAddressRange.cpp - PageMappingHeap.cpp - CustomMemoryHeap.cpp - MemoryManager.cpp - MTSafeAllocator.cpp - DefragAllocator.h - MemoryAddressRange.h - PageMappingHeap.h - MemoryManager.h - MTSafeAllocator.h XML/SerializeXMLReader.cpp XML/SerializeXMLWriter.cpp XML/xml.cpp @@ -116,64 +57,14 @@ set(FILES XML/XmlUtils.h XML/ReadXMLSink.cpp XML/WriteXMLSource.cpp - ZipFile.h - ZipFileFormat_info.h - PerfHUD.cpp - ProfileLogSystem.cpp - Sampler.cpp - PerfHUD.h - ProfileLogSystem.h - Sampler.h LocalizedStringManager.cpp LocalizedStringManager.h - CryThreadUtil_win32_thread.h - ThreadInfo.cpp - ThreadInfo.h - ThreadTask.h - ThreadTask.cpp - ThreadConfigManager.h - ThreadConfigManager.cpp - SystemThreading.cpp - ExtensionSystem/CryFactoryRegistryImpl.cpp - ExtensionSystem/CryFactoryRegistryImpl.h - ExtensionSystem/TestCases/TestExtensions.cpp - ExtensionSystem/TestCases/TestExtensions.h - MiniGUI/DrawContext.cpp - MiniGUI/MiniButton.cpp - MiniGUI/MiniGUI.cpp - MiniGUI/MiniInfoBox.cpp - MiniGUI/MiniMenu.cpp - MiniGUI/MiniTable.cpp - MiniGUI/DrawContext.h - MiniGUI/MiniButton.h - MiniGUI/MiniGUI.h - MiniGUI/MiniInfoBox.h - MiniGUI/MiniMenu.h - MiniGUI/MiniTable.h - ZLibCompressor.cpp - ZLibCompressor.h - SoftCode/SoftCodeMgr.cpp - SoftCode/SoftCodeMgr.h - OverloadSceneManager/OverloadSceneManager.cpp - OverloadSceneManager/OverloadSceneManager.h Huffman.cpp Huffman.h RemoteConsole/RemoteConsole.cpp RemoteConsole/RemoteConsole.h RemoteConsole/RemoteConsole_impl.inl RemoteConsole/RemoteConsole_none.inl - ServiceNetwork.cpp - ServiceNetwork.h - RemoteCommand.cpp - RemoteCommand.h - RemoteCommandHelpers.cpp - RemoteCommandHelpers.h - RemoteCommandServer.cpp - RemoteCommandClient.cpp - ZLibDecompressor.h - ZLibDecompressor.cpp - LZ4Decompressor.h - LZ4Decompressor.cpp LevelSystem/LevelSystem.cpp LevelSystem/LevelSystem.h LevelSystem/SpawnableLevelSystem.cpp @@ -184,39 +75,6 @@ set(FILES ViewSystem/View.h ViewSystem/ViewSystem.cpp ViewSystem/ViewSystem.h - ZStdDecompressor.h - ZStdDecompressor.cpp - Serialization/ArchiveHost.cpp - Serialization/BinArchive.cpp - Serialization/JSONIArchive.cpp - Serialization/JSONOArchive.cpp - Serialization/MemoryReader.cpp - Serialization/MemoryWriter.cpp - Serialization/Token.h - Serialization/XmlIArchive.cpp - Serialization/XmlIArchive.h - Serialization/XmlOArchive.cpp - Serialization/XmlOArchive.h - HMDCVars.h - HMDCVars.cpp - StreamEngine/StreamAsyncFileRequest.cpp - StreamEngine/StreamAsyncFileRequest_Jobs.cpp - StreamEngine/StreamEngine.cpp - StreamEngine/StreamIOThread.cpp - StreamEngine/StreamReadStream.cpp - StreamEngine/AZRequestReadStream.cpp - StreamEngine/StreamAsyncFileRequest.h - StreamEngine/StreamEngine.h - StreamEngine/StreamIOThread.h - StreamEngine/StreamReadStream.h - StreamEngine/AZRequestReadStream.h - VisRegTest.cpp - VisRegTest.h - CrashHandler.rc CrySystem_precompiled.cpp - CPUDetect.cpp - CPUDetect.h - CrySizerImpl.cpp - CrySizerImpl.h WindowsErrorReporting.cpp ) diff --git a/Code/CryEngine/CrySystem/crysystem_ios_files.cmake b/Code/CryEngine/CrySystem/crysystem_ios_files.cmake deleted file mode 100644 index eca0f5142c..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_ios_files.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - MobileDetectSpec_Ios.cpp - MobileDetectSpec.cpp - MobileDetectSpec.h -) diff --git a/Code/CryEngine/CrySystem/crysystem_mac_files.cmake b/Code/CryEngine/CrySystem/crysystem_mac_files.cmake deleted file mode 100644 index 7e539e6825..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_mac_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - SystemUtilsApple.h - SystemUtilsApple.mm -) diff --git a/Code/CryEngine/CrySystem/crysystem_test_files.cmake b/Code/CryEngine/CrySystem/crysystem_test_files.cmake deleted file mode 100644 index 650e9b0063..0000000000 --- a/Code/CryEngine/CrySystem/crysystem_test_files.cmake +++ /dev/null @@ -1,26 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Components/MathConversionTests.cpp - Serialization/Test_ArchiveHost.cpp - Tests/Test_CLog.cpp - Tests/Test_CommandRegistration.cpp - Tests/Test_CryPrimitives.cpp - Tests/Test_CrySizer.cpp - Tests/test_CrySystem.cpp - Tests/Test_Localization.cpp - Tests/test_Main.cpp - Tests/test_MaterialUtils.cpp - UnitTests/CryMathTests.cpp - UnitTests/CryPakUnitTests.cpp - DllMain.cpp -) diff --git a/Code/CryEngine/CrySystem/resource.h b/Code/CryEngine/CrySystem/resource.h deleted file mode 100644 index a5970a6475..0000000000 --- a/Code/CryEngine/CrySystem/resource.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* 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. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#define VS_VERSION_INFO 1 -#define IDD_CRITICAL_ERROR 101 -#define IDB_CONFIRM_SAVE 102 -#define IDB_DONT_SAVE 103 -#define IDD_CONFIRM_SAVE_LEVEL 127 -#define IDB_CRASH_FACE 128 -#define IDD_EXCEPTION 245 -#define IDC_CALLSTACK 1001 -#define IDC_EXCEPTION_CODE 1002 -#define IDC_EXCEPTION_ADDRESS 1003 -#define IDC_EXCEPTION_MODULE 1004 -#define IDC_EXCEPTION_DESC 1005 -#define IDB_EXIT 1008 -#define IDB_IGNORE 1010 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 129 -#define _APS_NEXT_COMMAND_VALUE 40072 -#define _APS_NEXT_CONTROL_VALUE 1003 -#define _APS_NEXT_SYMED_VALUE 104 -#endif -#endif diff --git a/Code/Framework/AtomCore/.p4ignore b/Code/Framework/AtomCore/.p4ignore deleted file mode 100644 index 6722cd96e7..0000000000 --- a/Code/Framework/AtomCore/.p4ignore +++ /dev/null @@ -1 +0,0 @@ -*.xml diff --git a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp b/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp index dbc0be55f9..dc7d26577b 100644 --- a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp +++ b/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp @@ -189,7 +189,7 @@ namespace AZ if (!WasLoadSuccess(result.GetOutcome())) { // This if is a hack around fault in the JSON serialization system - // Jira: https://jira.agscollab.com/browse/LY-106587 + // Jira: LY-106587 if (message != "No part of the string could be interpreted as a uuid.") { deserializeError.append(message); diff --git a/Code/Framework/AtomCore/AtomCore/std/parallel/concurrency_checker.h b/Code/Framework/AtomCore/AtomCore/std/parallel/concurrency_checker.h index 311b574fdf..4a952721b6 100644 --- a/Code/Framework/AtomCore/AtomCore/std/parallel/concurrency_checker.h +++ b/Code/Framework/AtomCore/AtomCore/std/parallel/concurrency_checker.h @@ -20,10 +20,12 @@ namespace AZStd { - //! Simple class for verifying that no concurrent access is occuring. + //! Simple class for verifying that no concurrent access is occurring. //! This is *not* a synchronization primitive, and is intended simply for checking that no concurrency issues exist. //! It will be compiled out in release builds. //! Use concurrency_checker like a mutex (i.e. call soft_lock() and soft_unlock() around all instances of your data access). + //! Use soft_lock_shared and soft_unlock_shared around places where multiple threads are allowed to have read access + //! at the same time as long as nothing else already has a soft lock //! It will assert if there are multiple threads accessing the locked code/data at the same time. //! Expected use case is for defensive programming: when you do not expect any concurrent access within a system, //! but want to verify that it stays that way in the future, without incurring the overhead of a mutex. @@ -34,7 +36,7 @@ namespace AZStd { #ifdef AZ_CONCURRENCY_CHECKER_ENABLED uint32_t count = ++m_concurrencyCounter; - AZ_Assert(count == 1, "Concurrency check failed. Multiple threads are trying to access data at the same time, or there is a lock/unlock mismatch."); + AZ_Assert(count == 1 && m_sharedConcurrencyCounter == 0, "Concurrency check failed. Multiple threads are trying to access data at the same time, or there is a lock/unlock mismatch."); #endif } @@ -46,9 +48,27 @@ namespace AZStd #endif } + AZ_FORCE_INLINE void soft_lock_shared() + { +#ifdef AZ_CONCURRENCY_CHECKER_ENABLED + AZ_Assert(m_concurrencyCounter == 0, "Concurrency check failed. A soft_lock_shared was attempted when there was already a soft_lock."); + ++m_sharedConcurrencyCounter; +#endif + } + + AZ_FORCE_INLINE void soft_unlock_shared() + { +#ifdef AZ_CONCURRENCY_CHECKER_ENABLED + AZ_Assert(m_sharedConcurrencyCounter != 0, "Concurrency check failed. There is a shared_lock/shared_unlock mismatch."); + --m_sharedConcurrencyCounter; +#endif + } + + private: #ifdef AZ_CONCURRENCY_CHECKER_ENABLED AZStd::atomic_uint32_t m_concurrencyCounter = 0; + AZStd::atomic_uint32_t m_sharedConcurrencyCounter = 0; #endif }; diff --git a/Code/Framework/AtomCore/Tests/ArrayView.cpp b/Code/Framework/AtomCore/Tests/ArrayView.cpp index 83fa20aaf0..56627d280e 100644 --- a/Code/Framework/AtomCore/Tests/ArrayView.cpp +++ b/Code/Framework/AtomCore/Tests/ArrayView.cpp @@ -293,15 +293,12 @@ namespace UnitTest { array_view view({ 1,2,3,4 }); - UnitTest::TestRunner::Instance().StartAssertTests(); + AZ_TEST_START_TRACE_SUPPRESSION; - EXPECT_EQ(0, UnitTest::TestRunner::Instance().m_numAssertsFailed); view[4]; - EXPECT_EQ(1, UnitTest::TestRunner::Instance().m_numAssertsFailed); view[5]; - EXPECT_EQ(2, UnitTest::TestRunner::Instance().m_numAssertsFailed); - UnitTest::TestRunner::Instance().StopAssertTests(); + AZ_TEST_STOP_TRACE_SUPPRESSION(2); } } diff --git a/Code/Framework/AtomCore/Tests/ConcurrencyCheckerTests.cpp b/Code/Framework/AtomCore/Tests/ConcurrencyCheckerTests.cpp new file mode 100644 index 0000000000..7cd1fa27ac --- /dev/null +++ b/Code/Framework/AtomCore/Tests/ConcurrencyCheckerTests.cpp @@ -0,0 +1,100 @@ +/* +* 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. +* +*/ + +#include + +#include + +using namespace AZStd; + +namespace UnitTest +{ + class ConcurrencyCheckerTestFixture + : public AllocatorsTestFixture + { + + void SetUp() override + { + AllocatorsFixture::SetUp(); + } + }; + + TEST_F(AllocatorsTestFixture, SoftLock_NoContention_NoAsserts) + { + concurrency_checker concurrencyChecker; + concurrencyChecker.soft_lock(); + concurrencyChecker.soft_unlock(); + concurrencyChecker.soft_lock(); + concurrencyChecker.soft_unlock(); + } + + TEST_F(AllocatorsTestFixture, SoftLock_AlreadyLocked_Assert) + { + concurrency_checker concurrencyChecker; + concurrencyChecker.soft_lock(); + AZ_TEST_START_TRACE_SUPPRESSION; + concurrencyChecker.soft_lock(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); + } + + TEST_F(AllocatorsTestFixture, SoftUnlock_NotAlreadyLocked_Assert) + { + concurrency_checker concurrencyChecker; + concurrencyChecker.soft_lock(); + concurrencyChecker.soft_unlock(); + AZ_TEST_START_TRACE_SUPPRESSION; + concurrencyChecker.soft_unlock(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); + } + + TEST_F(AllocatorsTestFixture, SoftLockShared_NoContention_NoAsserts) + { + concurrency_checker concurrencyChecker; + // Multiple shared locks can be made at once, + // as long as they are all unlocked before the next soft_lock + concurrencyChecker.soft_lock_shared(); + concurrencyChecker.soft_lock_shared(); + concurrencyChecker.soft_unlock_shared(); + concurrencyChecker.soft_unlock_shared(); + + concurrencyChecker.soft_lock(); + concurrencyChecker.soft_unlock(); + + concurrencyChecker.soft_lock_shared(); + concurrencyChecker.soft_lock_shared(); + concurrencyChecker.soft_unlock_shared(); + concurrencyChecker.soft_unlock_shared(); + + concurrencyChecker.soft_lock(); + concurrencyChecker.soft_unlock(); + } + + TEST_F(AllocatorsTestFixture, SoftLockShared_SharedLockAfterSoftLock_Assert) + { + concurrency_checker concurrencyChecker; + + concurrencyChecker.soft_lock(); + AZ_TEST_START_TRACE_SUPPRESSION; + concurrencyChecker.soft_lock_shared(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); + } + + TEST_F(AllocatorsTestFixture, SoftUnlockShared_NotAlreadyLocked_Assert) + { + concurrency_checker concurrencyChecker; + concurrencyChecker.soft_lock_shared(); + concurrencyChecker.soft_unlock_shared(); + AZ_TEST_START_TRACE_SUPPRESSION; + concurrencyChecker.soft_unlock_shared(); + AZ_TEST_STOP_TRACE_SUPPRESSION(1); + } +} diff --git a/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake b/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake index 26efd09fe1..24d23cb852 100644 --- a/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake +++ b/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake @@ -11,6 +11,7 @@ set(FILES ArrayView.cpp + ConcurrencyCheckerTests.cpp InstanceDatabase.cpp JsonSerializationUtilsTests.cpp lru_cache.cpp diff --git a/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java b/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java index b5d3de8164..5c1a120df6 100644 --- a/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java +++ b/Code/Framework/AzAndroid/java/com/amazon/lumberyard/LumberyardActivity.java @@ -244,7 +244,7 @@ public class LumberyardActivity extends NativeActivity boolean useMainObb = GetBooleanResource("use_main_obb"); boolean usePatchObb = GetBooleanResource("use_patch_obb"); - if (IsBootstrapInAPK() && (useMainObb || usePatchObb)) + if (AreAssetsInAPK() && (useMainObb || usePatchObb)) { Log.d(TAG, "Using OBB expansion files for game assets"); @@ -421,12 +421,12 @@ public class LumberyardActivity extends NativeActivity } //////////////////////////////////////////////////////////////// - private boolean IsBootstrapInAPK() + private boolean AreAssetsInAPK() { try { - InputStream bootstrap = getAssets().open("bootstrap.cfg", AssetManager.ACCESS_UNKNOWN); - bootstrap.close(); + InputStream engine = getAssets().open("engine.json", AssetManager.ACCESS_UNKNOWN); + engine.close(); return true; } catch (IOException exception) diff --git a/Code/Framework/AzCore/.p4ignore b/Code/Framework/AzCore/.p4ignore deleted file mode 100644 index 6722cd96e7..0000000000 --- a/Code/Framework/AzCore/.p4ignore +++ /dev/null @@ -1 +0,0 @@ -*.xml diff --git a/Code/Framework/AzCore/AzCore/Android/Utils.cpp b/Code/Framework/AzCore/AzCore/Android/Utils.cpp index efbbf50d1d..d6435c67be 100644 --- a/Code/Framework/AzCore/AzCore/Android/Utils.cpp +++ b/Code/Framework/AzCore/AzCore/Android/Utils.cpp @@ -148,7 +148,7 @@ namespace AZ } } - AZ_Assert(false, "Failed to locate the bootstrap.cfg path"); + AZ_Assert(false, "Failed to locate the engine.json path"); return nullptr; } diff --git a/Code/Framework/AzCore/AzCore/Android/Utils.h b/Code/Framework/AzCore/AzCore/Android/Utils.h index 222fac80ad..0862d53aa4 100644 --- a/Code/Framework/AzCore/AzCore/Android/Utils.h +++ b/Code/Framework/AzCore/AzCore/Android/Utils.h @@ -73,8 +73,8 @@ namespace AZ //! \return The pointer position of the relative asset path AZ::IO::FixedMaxPath StripApkPrefix(const char* filePath); - //! Searches application storage and the APK for bootstrap.cfg. Will return nullptr - //! if bootstrap.cfg is not found. + //! Searches application storage and the APK for engine.json. Will return nullptr + //! if engine.json is not found. const char* FindAssetsDirectory(); //! Calls into Java to show the splash screen on the main UI (Java) thread diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h index c8a245af68..11f4531124 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetCommon.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -216,16 +217,14 @@ namespace AZ /** * Setting for each reference (Asset) to control loading of referenced assets during serialization. */ - enum class AssetLoadBehavior : u8 - { - PreLoad = 0, ///< Serializer will "Pre load" dependencies, asset containers may load in parallel but will not signal AssetReady - QueueLoad = 1, ///< Serializer will queue an asynchronous load of the referenced asset and return the object to the user. User code should use the \ref AZ::Data::AssetBus to monitor for when it's ready. - NoLoad = 2, ///< Serializer will load reference information, but asset loading will be left to the user. User code should call Asset::QueueLoad and use the \ref AZ::Data::AssetBus to monitor for when it's ready. - ///< AssetContainers will skip NoLoad dependencies - + AZ_ENUM_WITH_UNDERLYING_TYPE(AssetLoadBehavior, u8, + (PreLoad, 0), ///< Serializer will "Pre load" dependencies, asset containers may load in parallel but will not signal AssetReady + (QueueLoad, 1), ///< Serializer will queue an asynchronous load of the referenced asset and return the object to the user. User code should use the \ref AZ::Data::AssetBus to monitor for when it's ready. + (NoLoad, 2), ///< Serializer will load reference information, but asset loading will be left to the user. User code should call Asset::QueueLoad and use the \ref AZ::Data::AssetBus to monitor for when it's ready. + ///< AssetContainers will skip NoLoad dependencies Count, - Default = QueueLoad, - }; + (Default, QueueLoad) + ); struct AssetFilterInfo { @@ -308,6 +307,8 @@ namespace AZ Asset(AssetLoadBehavior loadBehavior = AssetLoadBehavior::Default); /// Create an asset from a valid asset data (created asset), might not be loaded or currently loading. Asset(AssetData* assetData, AssetLoadBehavior loadBehavior); + /// Create an asset from a valid asset data (created asset) and set the asset id for both, might not be loaded or currently loading. + Asset(const AZ::Data::AssetId& id, AssetData* assetData, AssetLoadBehavior loadBehavior); /// Initialize asset pointer with id, type, and hint. No data construction will occur until QueueLoad is called. Asset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type, const AZStd::string& hint = AZStd::string()); @@ -788,6 +789,18 @@ namespace AZ SetData(assetData); } + //========================================================================= + template + Asset::Asset(const AssetId& id, AssetData* assetData, AssetLoadBehavior loadBehavior) + : m_assetId(id) + , m_assetType(azrtti_typeid()) + , m_loadBehavior(loadBehavior) + { + AZ_Assert(!assetData->m_assetId.IsValid(), "Asset data already has an ID set."); + assetData->m_assetId = id; + SetData(assetData); + } + //========================================================================= template Asset::Asset(const AssetId& id, const AZ::Data::AssetType& type, const AZStd::string& hint) @@ -1222,6 +1235,7 @@ namespace AZ } // namespace ProductDependencyInfo } // namespace Data + AZ_TYPE_INFO_SPECIALIZE(Data::AssetLoadBehavior, "{DAF9ECED-FEF3-4D7A-A220-8CFD6A5E6DA1}"); AZ_TYPE_INFO_TEMPLATE_WITH_NAME(AZ::Data::Asset, "Asset", "{C891BF19-B60C-45E2-BFD0-027D15DDC939}", AZ_TYPE_INFO_CLASS); } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetContainer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetContainer.cpp index 2ff6143912..4028f48b27 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetContainer.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetContainer.cpp @@ -269,13 +269,13 @@ namespace AZ { for (auto& [assetId, dependentAsset] : m_dependencies) { - if (dependentAsset->IsReady()) + if (dependentAsset->IsReady() || dependentAsset->IsError()) { HandleReadyAsset(dependentAsset); } } } - if (auto asset = m_rootAsset.GetStrongReference(); asset.IsReady()) + if (auto asset = m_rootAsset.GetStrongReference(); asset.IsReady() || asset.IsError()) { HandleReadyAsset(asset); } @@ -496,10 +496,10 @@ namespace AZ m_waitingCount -= 1; disconnectEbus = true; - if (m_waitingAssets.empty()) - { - allReady = true; - } + } + if (m_waitingAssets.empty()) + { + allReady = true; } } @@ -510,8 +510,15 @@ namespace AZ } } - if (allReady && m_initComplete) + // If there are no assets left to be loaded, trigger the final AssetContainer notification (ready or canceled). + // We guard against prematurely sending it (m_initComplete) because it's possible for assets to get removed from our waiting + // list *while* we're still building up the list, so the list would appear to be empty too soon. + // We also guard against sending it multiple times (m_finalNotificationSent), because in some error conditions, it may be + // possible to try to remove the same asset multiple times, which if it's the last asset, it could trigger multiple + // notifications. + if (allReady && m_initComplete && !m_finalNotificationSent) { + m_finalNotificationSent = true; if (m_rootAsset) { AssetManagerBus::Broadcast(&AssetManagerBus::Events::OnAssetContainerReady, this); diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetContainer.h b/Code/Framework/AzCore/AzCore/Asset/AssetContainer.h index fe385efae9..5fef0ba7fb 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetContainer.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetContainer.h @@ -137,6 +137,7 @@ namespace AZ AZStd::atomic_int m_invalidDependencies{ 0 }; AZStd::unordered_set m_unloadedDependencies; AZStd::atomic_bool m_initComplete{ false }; + AZStd::atomic_bool m_finalNotificationSent{false}; mutable AZStd::recursive_mutex m_preloadMutex; // AssetId -> List of assets it is still waiting on diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp index 767dadedf8..a72fe4e013 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.cpp @@ -70,6 +70,17 @@ namespace AZ } } + { + const AZ::Data::AssetLoadBehavior autoLoadBehavior = instance->GetAutoLoadBehavior(); + const AZ::Data::AssetLoadBehavior defaultAutoLoadBehavior = defaultInstance ? + defaultInstance->GetAutoLoadBehavior() : AZ::Data::AssetLoadBehavior::Default; + + result.Combine( + ContinueStoringToJsonObjectField(outputValue, "loadBehavior", + &autoLoadBehavior, &defaultAutoLoadBehavior, + azrtti_typeid(), context)); + } + { ScopedContextPath subPathHint(context, "m_assetHint"); const AZStd::string* hint = &instance->GetHint(); @@ -100,15 +111,37 @@ namespace AZ AssetId id; JSR::ResultCode result(JSR::Tasks::ReadField); + SerializedAssetTracker* assetTracker = + context.GetMetadata().Find(); + + { + Data::AssetLoadBehavior loadBehavior = instance->GetAutoLoadBehavior(); + + result = + ContinueLoadingFromJsonObjectField(&loadBehavior, + azrtti_typeid(), + inputValue, "loadBehavior", context); + + instance->SetAutoLoadBehavior(loadBehavior); + } + auto it = inputValue.FindMember("assetId"); if (it != inputValue.MemberEnd()) { ScopedContextPath subPath(context, "assetId"); - result = ContinueLoading(&id, azrtti_typeid(), it->value, context); + result.Combine(ContinueLoading(&id, azrtti_typeid(), it->value, context)); if (!id.m_guid.IsNull()) { - *instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), AssetLoadBehavior::NoLoad); - + *instance = AssetManager::Instance().FindOrCreateAsset(id, instance->GetType(), instance->GetAutoLoadBehavior()); + if (!instance->GetId().IsValid()) + { + // If the asset failed to be created, FindOrCreateAsset returns an asset instance with a null + // id. To preserve the asset id in the source json, reset the asset to an empty one, but with + // the right id. + const auto loadBehavior = instance->GetAutoLoadBehavior(); + *instance = Asset(id, instance->GetType()); + instance->SetAutoLoadBehavior(loadBehavior); + } result.Combine(context.Report(result, "Successfully created Asset with id.")); } @@ -142,6 +175,11 @@ namespace AZ "The asset hint is missing for Asset, so it will be left empty.")); } + if (assetTracker) + { + assetTracker->AddAsset(*instance); + } + bool success = result.GetOutcome() <= JSR::Outcomes::PartialSkip; bool defaulted = result.GetOutcome() == JSR::Outcomes::DefaultsUsed || result.GetOutcome() == JSR::Outcomes::PartialDefaults; AZStd::string_view message = @@ -150,5 +188,20 @@ namespace AZ "Not enough information was available to create an instance of Asset or data was corrupted."; return context.Report(result, message); } + + void SerializedAssetTracker::AddAsset(Asset& asset) + { + m_serializedAssets.emplace_back(asset); + } + + const AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() const + { + return m_serializedAssets; + } + + AZStd::vector>& SerializedAssetTracker::GetTrackedAssets() + { + return m_serializedAssets; + } } // namespace Data } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h index 3d5271035c..780066cd42 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Asset/AssetJsonSerializer.h @@ -13,6 +13,7 @@ #pragma once #include +#include #include namespace AZ @@ -37,5 +38,18 @@ namespace AZ private: JsonSerializationResult::Result LoadAsset(void* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context); }; + + class SerializedAssetTracker final + { + public: + AZ_RTTI(SerializedAssetTracker, "{1E067091-8C0A-44B1-A455-6E97663F6963}"); + + void AddAsset(Asset& asset); + AZStd::vector>& GetTrackedAssets(); + const AZStd::vector>& GetTrackedAssets() const; + + private: + AZStd::vector> m_serializedAssets; + }; } // namespace Data } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp b/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp index d861614309..1075c6a931 100644 --- a/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Asset/AssetManagerComponent.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -24,6 +24,11 @@ namespace AZ { + namespace Data + { + AZ_ENUM_DEFINE_REFLECT_UTILITIES(AssetLoadBehavior); + } + //========================================================================= // AssetDatabaseComponent // [6/25/2012] @@ -99,6 +104,8 @@ namespace AZ if (SerializeContext* serializeContext = azrtti_cast(context)) { + AZ::Data::AssetLoadBehaviorReflect(*serializeContext); + serializeContext->RegisterGenericType>(); serializeContext->Class() diff --git a/Code/Framework/AzCore/AzCore/Component/Component.cpp b/Code/Framework/AzCore/AzCore/Component/Component.cpp index f1e8aa1fb0..498e4d03d3 100644 --- a/Code/Framework/AzCore/AzCore/Component/Component.cpp +++ b/Code/Framework/AzCore/AzCore/Component/Component.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -173,7 +174,11 @@ namespace AZ //========================================================================= void ComponentDescriptor::ReleaseDescriptor() { - EBUS_EVENT(ComponentApplicationBus, UnregisterComponentDescriptor, this); + AZ::ComponentApplicationRequests* componentApplication = AZ::Interface::Get(); + if (componentApplication != nullptr) + { + componentApplication->UnregisterComponentDescriptor(this); + } delete this; } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp index d0f277a6b8..7b33359023 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp @@ -77,6 +77,27 @@ #endif // defined(AZ_ENABLE_DEBUG_TOOLS) #include +#include + +static void PrintEntityName(const AZ::ConsoleCommandContainer& arguments) +{ + if (arguments.empty()) + { + return; + } + + const auto entityIdStr = AZStd::string(arguments.front()); + const auto entityIdValue = AZStd::stoull(entityIdStr); + + AZStd::string entityName; + AZ::ComponentApplicationBus::BroadcastResult( + entityName, &AZ::ComponentApplicationBus::Events::GetEntityName, AZ::EntityId(entityIdValue)); + + AZ_Printf("Entity Debug", "EntityId: %" PRIu64 ", Entity Name: %s", entityIdValue, entityName.c_str()); +} + +AZ_CONSOLEFREEFUNC( + PrintEntityName, AZ::ConsoleFunctorFlags::Null, "Parameter: EntityId value, Prints the name of the entity to the console"); namespace AZ { @@ -462,8 +483,6 @@ namespace AZ // for the application root. CalculateAppRoot(); - // Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created. - SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry); SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {}); SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands); SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry); @@ -477,7 +496,7 @@ namespace AZ m_console = AZ::Interface::Get(); if (m_console == nullptr) { - m_console = aznew AZ::Console(); + m_console = aznew AZ::Console(*m_settingsRegistry); AZ::Interface::Register(m_console); m_ownsConsole = true; m_console->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead()); @@ -526,6 +545,11 @@ namespace AZ // are destroyed m_commandLine = {}; + m_entityAddedEvent.DisconnectAllHandlers(); + m_entityRemovedEvent.DisconnectAllHandlers(); + m_entityActivatedEvent.DisconnectAllHandlers(); + m_entityDeactivatedEvent.DisconnectAllHandlers(); + DestroyAllocator(); } @@ -911,27 +935,49 @@ namespace AZ SetSettingsRegistrySpecializations(specializations); AZStd::vector scratchBuffer; - // Retrieves the list gem module build targets that the active project depends on - SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, - AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) // In development builds apply the o3de registry and the command line to allow early overrides. This will // allow developers to override things like default paths or Asset Processor connection settings. Any additional // values will be replaced by later loads, so this step will happen again at the end of loading. SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + // Project User Registry is merged after the command line here to allow make sure the any command line override of the project path + // is used for merging the project's user registry SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); #endif + //! Retrieves the list gem targets that the project has load dependencies on + //! This populates the /Amazon/Gems//SourcePaths array entries which is required + //! by the MergeSettingsToRegistry_GemRegistry() function below to locate the gem's root folder + //! and merge in the gem's registry files. + //! But when running from a pre-built app from the O3DE SDK(Editor/AssetProcessor), the projects binary + //! directory is needed in order to located the load dependency registry files + //! That project binary folder is generated with the /user/Registry when CMake is configured + //! for the project + //! Therefore the order of merging must be as follows + //! 1. MergeSettingsToRegistry_ProjectUserRegistry - Populates the /Amazon/Project/Settings/Build/project_build_path + //! which contains the path to the project binary directory + //! 2. MergeSettingsToRegistry_TargetBuildDependencyRegistry - Loads the cmake_dependencies...setreg + //! file from the locations in order of + //! 1. /Registry + //! 2. /Registry + //! 3. /bin/$/Registry + //! 3. MergeSettingsToRegistry_GemRegistries - Merges the settings registry files from each gem's /Registry directory + + SettingsRegistryMergeUtils::MergeSettingsToRegistry_TargetBuildDependencyRegistry(registry, + AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_EngineRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_GemRegistries(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false); SettingsRegistryMergeUtils::MergeSettingsToRegistry_ProjectUserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer); SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true); #endif // Update the Runtime file paths in case the "{BootstrapSettingsRootKey}/assets" key was overriden by a setting registry - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); + SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(registry); } void ComponentApplication::SetSettingsRegistrySpecializations(SettingsRegistryInterface::Specializations& specializations) @@ -980,6 +1026,26 @@ namespace AZ handler.Connect(m_entityRemovedEvent); } + void ComponentApplication::RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler& handler) + { + handler.Connect(m_entityActivatedEvent); + } + + void ComponentApplication::RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler& handler) + { + handler.Connect(m_entityDeactivatedEvent); + } + + void ComponentApplication::SignalEntityActivated(AZ::Entity* entity) + { + m_entityActivatedEvent.Signal(entity); + } + + void ComponentApplication::SignalEntityDeactivated(AZ::Entity* entity) + { + m_entityDeactivatedEvent.Signal(entity); + } + //========================================================================= // AddEntity // [5/30/2012] @@ -1215,7 +1281,7 @@ namespace AZ // So auto load is turned off if option "AutoLoad" key is bool that is false if (valueName == "AutoLoad" && !value) { - // Strip off the AutoLoead entry from the path + // Strip off the AutoLoad entry from the path auto autoLoadKey = AZ::StringFunc::TokenizeLast(path, "/"); if (!autoLoadKey) { @@ -1279,13 +1345,13 @@ namespace AZ // Add all auto loadable non-asset gems to the list of gem modules to load if (!moduleLoadData.m_autoLoad) { - break; + continue; } for (AZ::OSString& dynamicLibraryPath : moduleLoadData.m_dynamicLibraryPaths) { auto CompareDynamicModuleDescriptor = [&dynamicLibraryPath](const DynamicModuleDescriptor& entry) { - return entry.m_dynamicLibraryPath.contains(dynamicLibraryPath); + return AZ::IO::PathView(entry.m_dynamicLibraryPath).Stem() == AZ::IO::PathView(dynamicLibraryPath).Stem(); }; if (auto moduleIter = AZStd::find_if(gemModules.begin(), gemModules.end(), CompareDynamicModuleDescriptor); moduleIter == gemModules.end()) diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h index 8617aa5f2e..fac2867074 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplication.h @@ -204,6 +204,10 @@ namespace AZ void UnregisterComponentDescriptor(const ComponentDescriptor* descriptor) override final; void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler& handler) override final; void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) override final; + void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler& handler) override final; + void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler& handler) override final; + void SignalEntityActivated(Entity* entity) override final; + void SignalEntityDeactivated(Entity* entity) override final; bool AddEntity(Entity* entity) override; bool RemoveEntity(Entity* entity) override; bool DeleteEntity(const EntityId& id) override; @@ -382,6 +386,8 @@ namespace AZ AZStd::unique_ptr m_settingsRegistry; EntityAddedEvent m_entityAddedEvent; EntityRemovedEvent m_entityRemovedEvent; + EntityAddedEvent m_entityActivatedEvent; + EntityRemovedEvent m_entityDeactivatedEvent; AZ::IConsole* m_console{}; Descriptor m_descriptor; bool m_isStarted{ false }; diff --git a/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h b/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h index 3582e6ebb8..c93f07f347 100644 --- a/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h +++ b/Code/Framework/AzCore/AzCore/Component/ComponentApplicationBus.h @@ -72,6 +72,8 @@ namespace AZ using EntityAddedEvent = AZ::Event; using EntityRemovedEvent = AZ::Event; + using EntityActivatedEvent = AZ::Event; + using EntityDeactivatedEvent = AZ::Event; //! Interface that components can use to make requests of the main application. class ComponentApplicationRequests @@ -102,6 +104,22 @@ namespace AZ //! @param handler the event handler to signal. virtual void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler& handler) = 0; + //! Registers an event handler that will be signalled whenever an entity is added. + //! @param handler the event handler to signal. + virtual void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler& handler) = 0; + + //! Registers an event handler that will be signalled whenever an entity is removed. + //! @param handler the event handler to signal. + virtual void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler& handler) = 0; + + //! Signals that the provided entity has been activated. + //! @param entity the entity being activated. + virtual void SignalEntityActivated(AZ::Entity* entity) = 0; + + //! Signals that the provided entity has been deactivated. + //! @param entity the entity being deactivated. + virtual void SignalEntityDeactivated(AZ::Entity* entity) = 0; + //! Adds an entity to the application's registry. //! Calling Init() on an entity automatically performs this operation. //! @param entity A pointer to the entity to add to the application's registry. diff --git a/Code/Framework/AzCore/AzCore/Component/Entity.cpp b/Code/Framework/AzCore/AzCore/Component/Entity.cpp index b18474e428..b7c161b53c 100644 --- a/Code/Framework/AzCore/AzCore/Component/Entity.cpp +++ b/Code/Framework/AzCore/AzCore/Component/Entity.cpp @@ -112,7 +112,11 @@ namespace AZ { EBUS_EVENT(EntitySystemBus, OnEntityDestruction, m_id); EBUS_EVENT_ID(m_id, EntityBus, OnEntityDestruction, m_id); - EBUS_EVENT(ComponentApplicationBus, RemoveEntity, this); + AZ::ComponentApplicationRequests* componentApplication = AZ::Interface::Get(); + if (componentApplication != nullptr) + { + componentApplication->RemoveEntity(this); + } m_stateEvent.Signal(State::Init, State::Destroying); } @@ -216,12 +220,22 @@ namespace AZ EBUS_EVENT_ID(m_id, EntityBus, OnEntityActivated, m_id); EBUS_EVENT(EntitySystemBus, OnEntityActivated, m_id); + AZ::ComponentApplicationRequests* componentApplication = AZ::Interface::Get(); + if (componentApplication != nullptr) + { + componentApplication->SignalEntityActivated(this); + } } void Entity::Deactivate() { AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore); + AZ::ComponentApplicationRequests* componentApplication = AZ::Interface::Get(); + if (componentApplication != nullptr) + { + componentApplication->SignalEntityDeactivated(this); + } EBUS_EVENT_ID(m_id, EntityBus, OnEntityDeactivated, m_id); EBUS_EVENT(EntitySystemBus, OnEntityDeactivated, m_id); diff --git a/Code/Framework/AzCore/AzCore/Component/TransformBus.h b/Code/Framework/AzCore/AzCore/Component/TransformBus.h index 2003b949e2..2a8d82c34c 100644 --- a/Code/Framework/AzCore/AzCore/Component/TransformBus.h +++ b/Code/Framework/AzCore/AzCore/Component/TransformBus.h @@ -172,78 +172,10 @@ namespace AZ //! Rotation modifiers //! @{ - //! @deprecated Use SetLocalRotation() - //! Sets the entity's rotation in the world. - //! The origin of the axes is the entity's position in world space. - //! @param eulerAnglesRadians A three-dimensional vector, containing Euler angles in radians, to rotate the entity by. - virtual void SetRotation([[maybe_unused]] const AZ::Vector3& eulerAnglesRadians) {} - - //! @deprecated Use SetLocalRotation() - //! Sets the entity's rotation around the world's X axis. - //! The origin of the axis is the entity's position in world space. - //! @param eulerAngleRadians The X coordinate Euler angle in radians to use for the entity's rotation. - virtual void SetRotationX([[maybe_unused]] float eulerAngleRadian) {} - - //! @deprecated Use SetLocalRotation() - //! Sets the entity's rotation around the world's Y axis. - //! The origin of the axis is the entity's position in world space. - //! @param eulerAngleRadians The Y coordinate Euler angle in radians to use for the entity's rotation. - virtual void SetRotationY([[maybe_unused]] float eulerAngleRadian) {} - - //! @deprecated Use SetLocalRotation() - //! Sets the entity's rotation around the world's Z axis. - //! The origin of the axis is the entity's position in world space. - //! @param eulerAngleRadians The Z coordinate Euler angle in radians to use for the entity's rotation. - virtual void SetRotationZ([[maybe_unused]] float eulerAngleRadian) {} - - //! @deprecated Use SetLocalRotationQuaternion() //! Sets the entity's rotation in the world in quaternion notation. //! The origin of the axes is the entity's position in world space. //! @param quaternion A quaternion that represents the rotation to use for the entity. - virtual void SetRotationQuaternion([[maybe_unused]] const AZ::Quaternion& quaternion) {} - - //! @deprecated Use RotateAroundLocalX() - //! Rotates the entity around the world's X axis. - //! The origin of the axis is the entity's position in world space. - //! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the X axis. - virtual void RotateByX([[maybe_unused]] float eulerAngleRadian) {} - - //! @deprecated Use RotateAroundLocalY() - //! Rotates the entity around the world's Y axis. - //! The origin of the axis is the entity's position in world space. - //! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the Y axis. - virtual void RotateByY([[maybe_unused]] float eulerAngleRadian) {} - - //! @deprecated Use RotateAroundLocalZ() - //! Rotates the entity around the world's Z axis. - //! The origin of the axis is the entity's position in world space. - //! @param eulerAngleRadians The Euler angle in radians by which to rotate the entity around the Z axis. - virtual void RotateByZ([[maybe_unused]] float eulerAngleRadian) {} - - //! @deprecated Use GetLocalRotation() - //! Gets the entity's rotation in the world in Euler angles rotation in radians. - //! @return A three-dimensional vector, containing Euler angles in radians, that represents the entity's rotation. - virtual AZ::Vector3 GetRotationEulerRadians() { return AZ::Vector3(FLT_MAX); } - - //! @deprecated Use GetLocalRotationQuaternion() - //! Gets the entity's rotation in the world in quaternion format. - //! @return A quaternion that represents the entity's rotation in world space. - virtual AZ::Quaternion GetRotationQuaternion() { return AZ::Quaternion::CreateZero(); } - - //! @deprecated Use GetLocalRotation() - //! Gets the entity's rotation around the world's X axis. - //! @return The Euler angle in radians by which the the entity is rotated around the X axis in world space. - virtual float GetRotationX() { return FLT_MAX; } - - //! @deprecated Use GetLocalRotation() - //! Gets the entity's rotation around the world's Y axis. - //! @return The Euler angle in radians by which the the entity is rotated around the Y axis in world space. - virtual float GetRotationY() { return FLT_MAX; } - - //! @deprecated Use GetLocalRotation() - //! Gets the entity's rotation around the world's Z axis. - //! @return The Euler angle in radians by which the the entity is rotated around the Z axis in world space. - virtual float GetRotationZ() { return FLT_MAX; } + virtual void SetWorldRotationQuaternion([[maybe_unused]] const AZ::Quaternion& quaternion) {} //! Get angles in radian for each principle axis around which the world transform is //! rotated in the order of z-axis and y-axis and then x-axis. @@ -287,71 +219,21 @@ namespace AZ //! Scale modifiers //! @{ - //! @deprecated Use SetLocalScale() - //! Scales the entity along the world's axes. The origin of the axes is the entity's position in the world. - //! @param scale A three-dimensional vector that represents the multipliers with which to scale the entity in world space. - virtual void SetScale([[maybe_unused]] const AZ::Vector3& scale) {} - - //! @deprecated Use SetLocalScaleX() - //! Scales the entity along the world's X axis. The origin of the axis is the entity's position in the world. - //! @param scaleX The multiplier by which to scale the entity along the X axis in world space. - virtual void SetScaleX([[maybe_unused]] float scaleX) {} - - //! @deprecated Use SetLocalScaleY() - //! Scales the entity along the world's Y axis. The origin of the axis is the entity's position in the world. - //! @param scaleY The multiplier by which to scale the entity along the Y axis in world space. - virtual void SetScaleY([[maybe_unused]] float scaleY) {} - - //! @deprecated Use SetLocalScaleZ() - //! Scales the entity along the world's Z axis. The origin of the axis is the entity's position in the world. - //! @param scaleZ The multiplier by which to scale the entity along the Z axis in world space. - virtual void SetScaleZ([[maybe_unused]] float scaleZ) {} - - //! @deprecated Use GetLocalScale() - //! Gets the scale of the entity in world space. - //! @return A three-dimensional vector that represents the scale of the entity in world space. - virtual AZ::Vector3 GetScale() { return AZ::Vector3(FLT_MAX); } - - //! @deprecated Use GetLocalScale() - //! Gets the amount by which an entity is scaled along the world's X axis. - //! @return The amount by which an entity is scaled along the X axis in world space. - virtual float GetScaleX() { return FLT_MAX; } - - //! @deprecated Use GetLocalScale() - //! Gets the amount by which an entity is scaled along the world's Y axis. - //! @return The amount by which an entity is scaled along the Y axis in world space. - virtual float GetScaleY() { return FLT_MAX; } - - //! @deprecated Use GetLocalScale() - //! Gets the amount by which an entity is scaled along the world's Z axis. - //! @return The amount by which an entity is scaled along the Z axis in world space. - virtual float GetScaleZ() { return FLT_MAX; } - - //! Set local scale of the transform. - //! @param scale The new scale to set along three local axes. - virtual void SetLocalScale([[maybe_unused]] const AZ::Vector3& scale) {} - - //! Set local scale of the transform on x-axis. - //! @param scaleX The new x-axis scale to set. - virtual void SetLocalScaleX([[maybe_unused]] float scaleX) {} - - //! Set local scale of the transform on y-axis. - //! @param scaleY The new y-axis scale to set. - virtual void SetLocalScaleY([[maybe_unused]] float scaleY) {} - - //! Set local scale of the transform on z-axis. - //! @param scaleZ The new z-axis scale to set. - virtual void SetLocalScaleZ([[maybe_unused]] float scaleZ) {} - - //! Get the scale value on each axis in local space - //! @return The scale value of type Vector3 along each axis in local space. + //! @deprecated GetLocalScale is deprecated, and is left only to allow migration of legacy vector scale. + //! Get the legacy vector scale value in local space. + //! @return The scale value in local space. virtual AZ::Vector3 GetLocalScale() { return AZ::Vector3(FLT_MAX); } - //! Get the scale value on each axis in world space. - //! Note the transform will be skewed when it is rotated and has a parent transform scaled, in which - //! case the returned world-scale from this function will be inaccurate. - //! @return The scale value of type Vector3 along each axis in world space. - virtual AZ::Vector3 GetWorldScale() { return AZ::Vector3(FLT_MAX); } + //! Set the uniform scale value in local space. + virtual void SetLocalUniformScale([[maybe_unused]] float scale) {} + + //! Get the uniform scale value in local space. + //! @return The uniform scale value in local space. + virtual float GetLocalUniformScale() { return FLT_MAX; } + + //! Get the uniform scale value in world space. + //! @return The uniform scale value in world space. + virtual float GetWorldUniformScale() { return FLT_MAX; } //! @} //! Transform hierarchy diff --git a/Code/Framework/AzCore/AzCore/Console/Console.cpp b/Code/Framework/AzCore/AzCore/Console/Console.cpp index 788a127830..3cb33b564a 100644 --- a/Code/Framework/AzCore/AzCore/Console/Console.cpp +++ b/Code/Framework/AzCore/AzCore/Console/Console.cpp @@ -13,7 +13,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -43,6 +45,12 @@ namespace AZ { } + Console::Console(AZ::SettingsRegistryInterface& settingsRegistryInterface) + : Console() + { + RegisterCommandInvokerWithSettingsRegistry(settingsRegistryInterface); + } + Console::~Console() { // on console destruction relink the console functors back to the deferred head @@ -111,51 +119,51 @@ namespace AZ void Console::ExecuteConfigFile(AZStd::string_view configFileName) { - IO::FixedMaxPath filePathFixed = configFileName; - if (AZ::IO::FileIOBase* fileIOBase = AZ::IO::FileIOBase::GetInstance()) + auto settingsRegistry = AZ::SettingsRegistry::Get(); + // If the config file is a settings registry file use the SettingsRegistryInterface MergeSettingsFile function + // otherwise use the SettingsRegistryMergeUtils MergeSettingsToRegistry_ConfigFile function to merge an INI-style + // file to the settings registry + AZ::IO::PathView configFile(configFileName); + if (configFile.Extension() == ".setreg") { - fileIOBase->ResolvePath(filePathFixed, configFileName); + settingsRegistry->MergeSettingsFile(configFile.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch); } - - IO::SystemFile file; - if (!file.Open(filePathFixed.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY)) + else if (configFile.Extension() == ".setregpatch") { - AZLOG_ERROR("Failed to load '%s'. File could not be opened.", filePathFixed.c_str()); - return; + settingsRegistry->MergeSettingsFile(configFile.Native(), AZ::SettingsRegistryInterface::Format::JsonPatch); } - const IO::SizeType length = file.Length(); - if (length == 0) + else { - AZLOG_ERROR("Failed to load '%s'. File is empty.", filePathFixed.c_str()); - return; - } - file.Seek(0, IO::SystemFile::SF_SEEK_BEGIN); - AZStd::string fileBuffer; - fileBuffer.resize(length); - IO::SizeType bytesRead = file.Read(length, fileBuffer.data()); - file.Close(); - // Resize again just in case bytesRead is less than length for some reason - fileBuffer.resize(bytesRead); - - AZLOG_INFO("Loading config file %s", filePathFixed.c_str()); - - AZStd::vector separatedCommands; - auto BreakCommandsByLine = [&separatedCommands](AZStd::string_view token) - { - separatedCommands.emplace_back(token); - }; - StringFunc::TokenizeVisitor(fileBuffer, BreakCommandsByLine, "\n\r"); - - for (const auto& commandView : separatedCommands) - { - ConsoleCommandContainer commandArgsView; - auto ConvertCommandStringToArray = [&commandArgsView](AZStd::string_view token) + AZ::SettingsRegistryMergeUtils::ConfigParserSettings configParserSettings; + configParserSettings.m_registryRootPointerPath = "/Amazon/AzCore/Runtime/ConsoleCommands"; + configParserSettings.m_commandLineSettings.m_delimiterFunc = [](AZStd::string_view line) { - commandArgsView.emplace_back(token); + SettingsRegistryInterface::CommandLineArgumentSettings::JsonPathValue pathValue; + AZStd::string_view parsedLine = line; + + // Splits the line based on the or + if (auto path = AZ::StringFunc::TokenizeNext(parsedLine, "=:"); path.has_value()) + { + pathValue.m_path = AZ::StringFunc::StripEnds(*path); + pathValue.m_value = AZ::StringFunc::StripEnds(parsedLine); + } + // If the value is empty, then the line either contained an equal sign followed only by whitespace or the line was empty + // 1. line="testInit=", pathValue.m_path="testInit", pathValue.m_value="" + // 2. line="testInit 1", pathValue.m_path="testInit 1", pathValue.m_value="" + // Therefore the path is split the path on whitespace in order to retrieve a value + if (pathValue.m_value.empty()) + { + parsedLine = pathValue.m_path; + if (auto path = AZ::StringFunc::TokenizeNext(parsedLine, " \t"); path.has_value()) + { + pathValue.m_path = AZ::StringFunc::StripEnds(*path); + pathValue.m_value = AZ::StringFunc::StripEnds(parsedLine); + } + + } + return pathValue; }; - constexpr AZStd::string_view commandSeparators = " ="; - StringFunc::TokenizeVisitor(commandView, ConvertCommandStringToArray, commandSeparators); - PerformCommand(commandArgsView, ConsoleSilentMode::NotSilent, ConsoleInvokedFrom::AzConsole, ConsoleFunctorFlags::Null, ConsoleFunctorFlags::Null); + AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_ConfigFile(*settingsRegistry, configFile.Native(), configParserSettings); } } @@ -447,4 +455,134 @@ namespace AZ return result; } + + struct ConsoleCommandKeyNotificationHandler + { + ConsoleCommandKeyNotificationHandler(AZ::SettingsRegistryInterface& registry, Console& console) + : m_settingsRegistry(registry) + , m_console(console) + { + } + + // Responsible for using the Json Serialization Issue Callback system + // to determine when a JSON Patch or JSON Merge Patch modifies a value + // at a path underneath the IConsole::ConsoleRootCommandKey JSON pointer + JsonSerializationResult::ResultCode operator()(AZStd::string_view message, + JsonSerializationResult::ResultCode result, AZStd::string_view path) + { + AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRootCommandKey, AZ::IO::PosixPathSeparator }; + AZ::IO::PathView inputKey{ path, AZ::IO::PosixPathSeparator }; + if (result.GetTask() == JsonSerializationResult::Tasks::Merge + && result.GetProcessing() == JsonSerializationResult::Processing::Completed + && inputKey.IsRelativeTo(consoleRootCommandKey)) + { + if (auto type = m_settingsRegistry.GetType(path); type != SettingsRegistryInterface::Type::NoType) + { + operator()(path, type); + } + } + + // This is the default issue reporting, that logs using the warning category + if (result.GetProcessing() != JsonSerializationResult::Processing::Completed) + { + scratchBuffer.append(message.begin(), message.end()); + scratchBuffer.append("\n Reason: "); + result.AppendToString(scratchBuffer, path); + scratchBuffer.append("."); + AZ_Warning("JSON Serialization", false, "%s", scratchBuffer.c_str()); + + scratchBuffer.clear(); + } + return result; + } + + void operator()(AZStd::string_view path, SettingsRegistryInterface::Type type) + { + using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; + + AZ::IO::PathView consoleRootCommandKey{ IConsole::ConsoleRootCommandKey, AZ::IO::PosixPathSeparator }; + AZ::IO::PathView inputKey{ path, AZ::IO::PosixPathSeparator }; + if (inputKey.IsRelativeTo(consoleRootCommandKey)) + { + FixedValueString command = inputKey.LexicallyRelative(consoleRootCommandKey).Native(); + ConsoleCommandContainer commandArgs; + // Argument string which stores the value from the Settings Registry long enough + // to pass into the PerformCommand. The ConsoleCommandContainer stores string_views + // and therefore doesn't own the memory. + FixedValueString commandArgString; + + if (type == SettingsRegistryInterface::Type::String) + { + if (m_settingsRegistry.Get(commandArgString, path)) + { + auto ConvertCommandArgumentToArray = [&commandArgs](AZStd::string_view token) + { + commandArgs.emplace_back(token); + }; + constexpr AZStd::string_view commandSeparators = " \t\n\r"; + StringFunc::TokenizeVisitor(commandArgString, ConvertCommandArgumentToArray, commandSeparators); + } + } + else if (type == SettingsRegistryInterface::Type::Boolean) + { + bool commandArgBool{}; + if (m_settingsRegistry.Get(commandArgBool, path)) + { + commandArgString = commandArgBool ? "true" : "false"; + commandArgs.emplace_back(commandArgString); + } + } + else if (type == SettingsRegistryInterface::Type::Integer) + { + // Try converting to a signed 64-bit number first and then an unsigned 64-bit number + AZ::s64 commandArgInt{}; + AZ::u64 commandArgUInt{}; + if (m_settingsRegistry.Get(commandArgInt, path)) + { + AZStd::to_string(commandArgString, commandArgInt); + commandArgs.emplace_back(commandArgString); + } + else if (m_settingsRegistry.Get(commandArgUInt, path)) + { + AZStd::to_string(commandArgString, commandArgUInt); + commandArgs.emplace_back(commandArgString); + } + } + else if (type == SettingsRegistryInterface::Type::FloatingPoint) + { + double commandArgFloat{}; + if (m_settingsRegistry.Get(commandArgFloat, path)) + { + AZStd::to_string(commandArgString, commandArgFloat); + commandArgs.emplace_back(commandArgString); + } + } + CVarFixedString commandTrace(command); + for (AZStd::string_view commandArg : commandArgs) + { + commandTrace.push_back(' '); + commandTrace += commandArg; + } + + m_console.PerformCommand(command, commandArgs, ConsoleSilentMode::NotSilent, ConsoleInvokedFrom::AzConsole, ConsoleFunctorFlags::Null, ConsoleFunctorFlags::Null); + } + } + + AZ::Console& m_console; + AZ::SettingsRegistryInterface& m_settingsRegistry; + AZStd::string scratchBuffer; + }; + + void Console::RegisterCommandInvokerWithSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry) + { + // Make sure the there is a JSON object at the path of AZ::IConsole::ConsoleRootCommandKey + // So that JSON Patch is able to add values underneath that object (JSON Patch doesn't create intermediate objects) + settingsRegistry.MergeSettings(R"({ "Amazon": { "AzCore": { "Runtime": { "ConsoleCommands": {} } }}})", + SettingsRegistryInterface::Format::JsonMergePatch); + m_consoleCommandKeyHandler = settingsRegistry.RegisterNotifier(ConsoleCommandKeyNotificationHandler{ settingsRegistry, *this }); + + JsonApplyPatchSettings applyPatchSettings; + applyPatchSettings.m_reporting = ConsoleCommandKeyNotificationHandler{ settingsRegistry, *this }; + settingsRegistry.SetApplyPatchSettings(applyPatchSettings); + } } diff --git a/Code/Framework/AzCore/AzCore/Console/Console.h b/Code/Framework/AzCore/AzCore/Console/Console.h index 1c9c6897f6..ba614824fe 100644 --- a/Code/Framework/AzCore/AzCore/Console/Console.h +++ b/Code/Framework/AzCore/AzCore/Console/Console.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -29,6 +30,9 @@ namespace AZ AZ_CLASS_ALLOCATOR(Console, AZ::OSAllocator, 0); Console(); + //! Constructor overload which registers a notifier with the Settings Registry that will execute + //! a console command whenever a key is set under the AZ::IConsole::ConsoleCommandRootKey JSON object + explicit Console(AZ::SettingsRegistryInterface& settingsRegistry); ~Console() override; //! IConsole interface @@ -67,6 +71,7 @@ namespace AZ void RegisterFunctor(ConsoleFunctorBase* functor) override; void UnregisterFunctor(ConsoleFunctorBase* functor) override; void LinkDeferredFunctors(ConsoleFunctorBase*& deferredHead) override; + void RegisterCommandInvokerWithSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry) override; //! @} private: @@ -96,6 +101,7 @@ namespace AZ ConsoleFunctorBase* m_head; using CommandMap = AZStd::unordered_map>; CommandMap m_commands; + AZ::SettingsRegistryInterface::NotifyEventHandler m_consoleCommandKeyHandler; friend class ConsoleFunctorBase; }; diff --git a/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl b/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl index 0257564d43..18ed27e517 100644 --- a/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl +++ b/Code/Framework/AzCore/AzCore/Console/ConsoleTypeHelpers.inl @@ -148,7 +148,15 @@ namespace AZ { AZ::CVarFixedString convertCandidate{ arguments.front() }; char* endPtr = nullptr; - MAX_TYPE value = static_cast(strtoll(convertCandidate.c_str(), &endPtr, 0)); + MAX_TYPE value; + if constexpr (AZStd::is_unsigned_v) + { + value = aznumeric_cast(strtoull(convertCandidate.c_str(), &endPtr, 0)); + } + else + { + value = aznumeric_cast(strtoll(convertCandidate.c_str(), &endPtr, 0)); + } if (endPtr == convertCandidate.c_str()) { diff --git a/Code/Framework/AzCore/AzCore/Console/IConsole.h b/Code/Framework/AzCore/AzCore/Console/IConsole.h index 9f5ede7f4c..b976f3a9db 100644 --- a/Code/Framework/AzCore/AzCore/Console/IConsole.h +++ b/Code/Framework/AzCore/AzCore/Console/IConsole.h @@ -22,8 +22,10 @@ namespace AZ { + class SettingsRegistryInterface; class CommandLine; + //! @class IConsole //! A simple console class for providing text based variable and process interaction. class IConsole @@ -33,6 +35,8 @@ namespace AZ using FunctorVisitor = AZStd::function; + inline static constexpr AZStd::string_view ConsoleRootCommandKey = "/Amazon/AzCore/Runtime/ConsoleCommands"; + IConsole() = default; virtual ~IConsole() = default; @@ -145,6 +149,12 @@ namespace AZ //! Returns the AZ::Event<> invoked whenever a console command could not be found. DispatchCommandNotFoundEvent& GetDispatchCommandNotFoundEvent(); + //! Register a notification event handler with the Settings Registry + //! That is responsible for updating console commands whenever + //! a key is found underneath the "/Amazon/AzCore/Runtime/ConsoleCommands" JSON entry + //! @param Settings Registry reference to register notifier with + virtual void RegisterCommandInvokerWithSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry) = 0; + AZ_DISABLE_COPY_MOVE(IConsole); protected: diff --git a/Code/Framework/AzCore/AzCore/Console/LoggerSystemComponent.cpp b/Code/Framework/AzCore/AzCore/Console/LoggerSystemComponent.cpp index 6c142975e0..c004e2c406 100644 --- a/Code/Framework/AzCore/AzCore/Console/LoggerSystemComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Console/LoggerSystemComponent.cpp @@ -126,9 +126,11 @@ namespace AZ char buffer[MaxLogBufferSize]; const AZStd::size_t length = azvsnprintf(buffer, MaxLogBufferSize, format, args); - buffer[AZStd::min(length, MaxLogBufferSize - 2)] = '\n'; buffer[AZStd::min(length + 1, MaxLogBufferSize - 1)] = '\0'; + m_logEvent.Signal(level, buffer, file, function, line); + // Force a new-line before calling the AZ::Debug::Trace functions, as they assume a newline is present + buffer[AZStd::min(length + 1, MaxLogBufferSize - 2)] = '\n'; switch (level) { case LogLevel::Warn: @@ -142,8 +144,6 @@ namespace AZ AZ::Debug::Trace::Output("Logger", buffer); break; } - - m_logEvent.Signal(level, buffer, file, function, line); } void LoggerSystemComponent::SetLevel(const AZ::ConsoleCommandContainer& arguments) diff --git a/Code/Framework/AzCore/AzCore/EBus/Event.inl b/Code/Framework/AzCore/AzCore/EBus/Event.inl index 82f5645ccd..3786f1c26b 100644 --- a/Code/Framework/AzCore/AzCore/EBus/Event.inl +++ b/Code/Framework/AzCore/AzCore/EBus/Event.inl @@ -233,6 +233,14 @@ namespace AZ AZ_Assert(handler->m_event == this, "Entry event does not match"); handler->Disconnect(); } + + // Free up any owned memory + AZStd::vector freeHandlers; + m_handlers.swap(freeHandlers); + AZStd::vector freeAdds; + m_addList.swap(freeAdds); + AZStd::stack freeFree; + m_freeList.swap(freeFree); } diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.h b/Code/Framework/AzCore/AzCore/IO/Path/Path.h index 61294cd637..6c1b519224 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.h +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.h @@ -95,6 +95,12 @@ namespace AZ::IO constexpr int Compare(AZStd::string_view pathString) const noexcept; constexpr int Compare(const value_type* pathString) const noexcept; + // Extension for fixed strings + //! extension: fixed string types with MaxPathLength capacity + //! Returns a new instance of an AZStd::fixed_string with capacity of MaxPathLength + //! made from the internal string + constexpr AZStd::fixed_string FixedMaxPathString() const noexcept; + // decomposition //! Given a windows path of "C:\O3DE\foo\bar\name.txt" and a posix path of //! "/O3DE/foo/bar/name.txt" diff --git a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl index 1e42fc9df7..05a92c5247 100644 --- a/Code/Framework/AzCore/AzCore/IO/Path/Path.inl +++ b/Code/Framework/AzCore/AzCore/IO/Path/Path.inl @@ -915,6 +915,11 @@ namespace AZ::IO return compare_string_view(path); } + constexpr AZStd::fixed_string PathView::FixedMaxPathString() const noexcept + { + return AZStd::fixed_string(m_path.begin(), m_path.end()); + } + // decomposition constexpr auto PathView::RootName() const -> PathView { diff --git a/Code/Framework/AzCore/AzCore/Math/Aabb.cpp b/Code/Framework/AzCore/AzCore/Math/Aabb.cpp index 3f7cb4ecf5..367594be63 100644 --- a/Code/Framework/AzCore/AzCore/Math/Aabb.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Aabb.cpp @@ -227,7 +227,7 @@ namespace AZ // the min and max of each part and sum them to get the min and max co-ordinate of the transformed box. For a given new axis, // the coefficients for what proportion of each original axis is rotated onto that new axis are the same as the components we // would get by performing the inverse rotation on the new axis, so we need to take the conjugate to get the inverse rotation. - axisCoeffs = transform.GetScale() * (transform.GetRotation().GetConjugate().TransformVector(axis)); + axisCoeffs = transform.GetUniformScale() * (transform.GetRotation().GetConjugate().TransformVector(axis)); a = axisCoeffs * m_min; b = axisCoeffs * m_max; diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp new file mode 100644 index 0000000000..0b7e3300cf --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp @@ -0,0 +1,485 @@ +/* +* 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. +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace AZ::JsonMathMatrixSerializerInternal +{ + template + JsonSerializationResult::Result LoadArray(MatrixType& output, const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + constexpr size_t ElementCount = RowCount * ColumnCount; + static_assert(ElementCount == 9 || ElementCount == 12 || ElementCount == 16, + "MathMatrixSerializer only support Matrix3x3, Matrix3x4 and Matrix4x4."); + + rapidjson::SizeType arraySize = inputValue.Size(); + if (arraySize < ElementCount) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, + "Not enough numbers in JSON array to load math matrix from."); + } + + AZ::BaseJsonSerializer* floatSerializer = context.GetRegistrationContext()->GetSerializerForType(azrtti_typeid()); + if (!floatSerializer) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "Failed to find the JSON float serializer."); + } + + constexpr const char* names[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"}; + float values[ElementCount]; + for (int i = 0; i < ElementCount; ++i) + { + ScopedContextPath subPath(context, names[i]); + JSR::Result intermediate = floatSerializer->Load(values + i, azrtti_typeid(), inputValue[i], context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + } + + size_t valueIndex = 0; + for (size_t r = 0; r < RowCount; ++r) + { + for (size_t c = 0; c < ColumnCount; ++c) + { + output.SetElement(aznumeric_caster(r), aznumeric_caster(c), values[valueIndex++]); + } + } + + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read math matrix."); + } + + JsonSerializationResult::Result LoadFloatFromObject( + float& output, + const rapidjson::Value& inputValue, + JsonDeserializerContext& context, + const char* name, + const char* altName) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + AZ::BaseJsonSerializer* floatSerializer = context.GetRegistrationContext()->GetSerializerForType(azrtti_typeid()); + if (!floatSerializer) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "Failed to find the json float serializer."); + } + + const char* nameUsed = name; + JSR::ResultCode result(JSR::Tasks::ReadField); + auto iterator = inputValue.FindMember(rapidjson::StringRef(name)); + if (iterator == inputValue.MemberEnd()) + { + nameUsed = altName; + iterator = inputValue.FindMember(rapidjson::StringRef(altName)); + if (iterator == inputValue.MemberEnd()) + { + // field not found so leave default value + result.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed)); + nameUsed = nullptr; + } + } + + if (nameUsed) + { + ScopedContextPath subPath(context, nameUsed); + JSR::Result intermediate = floatSerializer->Load(&output, azrtti_typeid(), iterator->value, context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + else + { + result.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success)); + } + } + + return context.Report(result, "Successfully read float."); + } + + JsonSerializationResult::Result LoadVector3FromObject( + Vector3& output, + const rapidjson::Value& inputValue, + JsonDeserializerContext& context, + AZStd::fixed_vector names) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + constexpr size_t ElementCount = 3; // Vector3 + + JSR::ResultCode result(JSR::Tasks::ReadField); + float values[ElementCount]; + for (int i = 0; i < ElementCount; ++i) + { + values[i] = output.GetElement(i); + auto name = names[i * 2]; + auto altName = names[(i * 2) + 1]; + + JSR::Result intermediate = LoadFloatFromObject(values[i], inputValue, context, name.data(), altName.data()); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + else + { + result.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success)); + } + } + + for (int i = 0; i < ElementCount; ++i) + { + output.SetElement(i, values[i]); + } + + return context.Report(result, "Successfully read math matrix."); + } + + JsonSerializationResult::Result LoadQuaternionAndScale( + AZ::Quaternion& quaternion, + float& scale, + const rapidjson::Value& inputValue, + JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + JSR::ResultCode result(JSR::Tasks::ReadField); + scale = 1.0f; + JSR::Result intermediateScale = LoadFloatFromObject(scale, inputValue, context, "scale", "Scale"); + if (intermediateScale.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediateScale; + } + result.Combine(intermediateScale); + + if (AZ::IsClose(scale, 0.0f)) + { + result.Combine({ JSR::Tasks::ReadField, JSR::Outcomes::Unsupported }); + return context.Report(result, "Scale can not be zero."); + } + + AZ::Vector3 degreesRollPitchYaw = AZ::Vector3::CreateZero(); + JSR::Result intermediateDegrees = LoadVector3FromObject(degreesRollPitchYaw, inputValue, context, { "roll", "Roll", "pitch", "Pitch", "yaw", "Yaw" }); + if (intermediateDegrees.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediateDegrees; + } + result.Combine(intermediateDegrees); + + // the quaternion should be equivalent to a series of rotations in the order z, then y, then x + const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(degreesRollPitchYaw); + quaternion = AZ::Quaternion::CreateRotationX(eulerRadians.GetX()) * + AZ::Quaternion::CreateRotationY(eulerRadians.GetY()) * + AZ::Quaternion::CreateRotationZ(eulerRadians.GetZ()); + + return context.Report(result, "Successfully read math yaw, pitch, roll, and scale."); + } + + template + JsonSerializationResult::Result LoadObject(MatrixType& output, const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + output = MatrixType::CreateIdentity(); + + JSR::ResultCode result(JSR::Tasks::ReadField); + float scale; + AZ::Quaternion rotation; + + JSR::Result intermediate = LoadQuaternionAndScale(rotation, scale, inputValue, context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + result.Combine(intermediate); + + AZ::Vector3 translation = AZ::Vector3::CreateZero(); + JSR::Result intermediateTranslation = LoadVector3FromObject(translation, inputValue, context, { "x", "X", "y", "Y", "z", "Z" }); + if (intermediateTranslation.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediateTranslation; + } + result.Combine(intermediateTranslation); + + // composed a matrix by rotation, then scale, then translation + auto matrix = MatrixType::CreateFromQuaternion(rotation); + matrix.MultiplyByScale(Vector3{ scale }); + matrix.SetTranslation(translation); + + if (matrix == MatrixType::CreateIdentity()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Using identity matrix for empty object."); + } + + output = matrix; + return context.Report(result, "Successfully read math matrix."); + } + + template<> + JsonSerializationResult::Result LoadObject(Matrix3x3& output, const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + output = Matrix3x3::CreateIdentity(); + + JSR::ResultCode result(JSR::Tasks::ReadField); + float scale; + AZ::Quaternion rotation; + + JSR::Result intermediate = LoadQuaternionAndScale(rotation, scale, inputValue, context); + if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed) + { + return intermediate; + } + result.Combine(intermediate); + + // composed a matrix by rotation then scale + auto matrix = Matrix3x3::CreateFromQuaternion(rotation); + matrix.MultiplyByScale(Vector3{ scale }); + + if (matrix == Matrix3x3::CreateIdentity()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Using identity matrix for empty object."); + } + + output = matrix; + return context.Report(result, "Successfully read math matrix."); + } + + template + JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + + constexpr size_t ElementCount = RowCount * ColumnCount; + static_assert(ElementCount == 9 || ElementCount == 12 || ElementCount == 16, + "MathMatrixSerializer only support Matrix3x3, Matrix3x4 and Matrix4x4."); + + AZ_Assert(azrtti_typeid() == outputValueTypeId, + "Unable to deserialize Matrix%zux%zu to json because the provided type is %s", + RowCount, ColumnCount, outputValueTypeId.ToString().c_str()); + AZ_UNUSED(outputValueTypeId); + + MatrixType* matrix = reinterpret_cast(outputValue); + AZ_Assert(matrix, "Output value for JsonMatrix%zux%zuSerializer can't be null.", RowCount, ColumnCount); + + switch (inputValue.GetType()) + { + case rapidjson::kArrayType: + return LoadArray(*matrix, inputValue, context); + case rapidjson::kObjectType: + return LoadObject(*matrix, inputValue, context); + + 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 matrix can only be read from arrays or objects."); + + default: + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unknown, + "Unknown json type encountered in math matrix."); + } + } + + template + AZ::Quaternion CreateQuaternion(const MatrixType& matrix); + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x3& matrix) + { + return Quaternion::CreateFromMatrix3x3(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x4& matrix) + { + return Quaternion::CreateFromMatrix3x4(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix4x4& matrix) + { + return Quaternion::CreateFromMatrix4x4(matrix); + } + + template + JsonSerializationResult::Result StoreRotationAndScale(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, + const Uuid& valueTypeId, JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + AZ_UNUSED(valueTypeId); + + const MatrixType* matrix = reinterpret_cast(inputValue); + AZ_Assert(matrix, "Input value for JsonMatrixSerializer can't be null."); + const MatrixType* defaultMatrix = reinterpret_cast(defaultValue); + + if (!context.ShouldKeepDefaults() && defaultMatrix && *matrix == *defaultMatrix) + { + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default math Matrix used."); + } + + MatrixType matrixToExport = *matrix; + AZ::Vector3 scale = matrixToExport.ExtractScale(); + + AZ::Quaternion rotation = CreateQuaternion(matrixToExport); + auto degrees = rotation.GetEulerDegrees(); + outputValue.AddMember(rapidjson::StringRef("roll"), degrees.GetX(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("pitch"), degrees.GetY(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("yaw"), degrees.GetZ(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("scale"), scale.GetX(), context.GetJsonAllocator()); + + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Success, "Math Matrix successfully stored."); + } + + template + JsonSerializationResult::Result StoreTranslation(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds. + AZ_UNUSED(valueTypeId); + + const MatrixType* matrix = reinterpret_cast(inputValue); + AZ_Assert(matrix, "Input value for JsonMatrixSerializer can't be null."); + const MatrixType* defaultMatrix = reinterpret_cast(defaultValue); + + if (!context.ShouldKeepDefaults() && defaultMatrix && *matrix == *defaultMatrix) + { + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default math Matrix used."); + } + + auto translation = matrix->GetTranslation(); + outputValue.AddMember(rapidjson::StringRef("x"), translation.GetX(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("y"), translation.GetY(), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef("z"), translation.GetZ(), context.GetJsonAllocator()); + + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::Success, "Math Matrix successfully stored."); + } +} + +namespace AZ +{ + // Matrix3x3 + + AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix3x3Serializer, SystemAllocator, 0); + + JsonSerializationResult::Result JsonMatrix3x3Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + return JsonMathMatrixSerializerInternal::Load( + outputValue, + outputValueTypeId, + inputValue, + context); + } + + JsonSerializationResult::Result JsonMatrix3x3Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + outputValue.SetObject(); + + return JsonMathMatrixSerializerInternal::StoreRotationAndScale( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + } + + + // Matrix3x4 + + AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix3x4Serializer, SystemAllocator, 0); + + JsonSerializationResult::Result JsonMatrix3x4Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + return JsonMathMatrixSerializerInternal::Load( + outputValue, + outputValueTypeId, + inputValue, + context); + } + + JsonSerializationResult::Result JsonMatrix3x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + outputValue.SetObject(); + + auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + + auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + + result.GetResultCode().Combine(resultTranslation); + return result; + } + + // Matrix4x4 + + AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix4x4Serializer, SystemAllocator, 0); + + JsonSerializationResult::Result JsonMatrix4x4Serializer::Load(void* outputValue, const Uuid& outputValueTypeId, + const rapidjson::Value& inputValue, JsonDeserializerContext& context) + { + return JsonMathMatrixSerializerInternal::Load( + outputValue, + outputValueTypeId, + inputValue, + context); + } + + JsonSerializationResult::Result JsonMatrix4x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue, + const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) + { + outputValue.SetObject(); + + auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + + auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation( + outputValue, + inputValue, + defaultValue, + valueTypeId, + context); + + result.GetResultCode().Combine(resultTranslation); + return result; + } +} diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h new file mode 100644 index 0000000000..81c9635a79 --- /dev/null +++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h @@ -0,0 +1,54 @@ +/* +* 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. +* +*/ + +#pragma once + +#include + +namespace AZ +{ + class JsonMatrix3x3Serializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(JsonMatrix3x3Serializer, "{8C76CD6A-8576-4604-A746-CF7A7F20F366}", 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; + }; + + class JsonMatrix3x4Serializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(JsonMatrix3x4Serializer, "{E801333B-4AF1-4F43-976C-579670B02DC5}", 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; + }; + + class JsonMatrix4x4Serializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(JsonMatrix4x4Serializer, "{46E888FC-248A-4910-9221-4E101A10AEA1}", 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; + }; +} diff --git a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp index e918f8fdb3..3c683f1988 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp +++ b/Code/Framework/AzCore/AzCore/Math/MathReflection.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -366,6 +367,9 @@ namespace AZ { context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); + context.Serializer()->HandlesType(); + context.Serializer()->HandlesType(); + context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); context.Serializer()->HandlesType(); diff --git a/Code/Framework/AzCore/AzCore/Math/MathUtils.h b/Code/Framework/AzCore/AzCore/Math/MathUtils.h index 4a331e4a83..a7fedf5ffa 100644 --- a/Code/Framework/AzCore/AzCore/Math/MathUtils.h +++ b/Code/Framework/AzCore/AzCore/Math/MathUtils.h @@ -13,16 +13,17 @@ #pragma once #include +#include +#include +#include #include #include #include -#include + #include #include -#include +#include #include -#include -#include // We have a separate inline define for math functions. // The performance of these functions is very sensitive to inlining, and some compilers don't deal well with this. @@ -308,12 +309,12 @@ namespace AZ AZ_MATH_INLINE bool IsClose(float a, float b, float tolerance = Constants::Tolerance) { - return (fabsf(a - b) <= tolerance); + return (AZStd::abs(a - b) <= tolerance); } AZ_MATH_INLINE bool IsClose(double a, double b, double tolerance = Constants::Tolerance) { - return (fabs(a - b) <= tolerance); + return (AZStd::abs(a - b) <= tolerance); } //! Returns x >= 0.0f ? 1.0f : -1.0f. @@ -402,12 +403,12 @@ namespace AZ AZ_MATH_INLINE float GetAbs(float a) { - return fabsf(a); + return AZStd::abs(a); } AZ_MATH_INLINE double GetAbs(double a) { - return std::abs(a); + return AZStd::abs(a); } AZ_MATH_INLINE float GetMod(float a, float b) @@ -441,7 +442,7 @@ namespace AZ template AZ_MATH_INLINE bool IsCloseMag(T x, T y, T epsilonValue = std::numeric_limits::epsilon()) { - return (std::fabs(x - y) <= epsilonValue * GetMax(GetMax(T(1.0), std::fabs(x)), std::fabs(y))); + return (AZStd::abs(x - y) <= epsilonValue * GetMax(GetMax(T(1.0), AZStd::abs(x)), AZStd::abs(y))); } //! ClampIfCloseMag(x, y, epsilon) returns y when x and y are within epsilon of each other (taking magnitude into account). Otherwise returns x. diff --git a/Code/Framework/AzCore/AzCore/Math/Obb.cpp b/Code/Framework/AzCore/AzCore/Math/Obb.cpp index eb511669d0..9226ddd28f 100644 --- a/Code/Framework/AzCore/AzCore/Math/Obb.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Obb.cpp @@ -154,7 +154,7 @@ namespace AZ return Obb::CreateFromPositionRotationAndHalfLengths( transform.TransformPoint(obb.GetPosition()), transform.GetRotation() * obb.GetRotation(), - transform.GetScale() * obb.GetHalfLengths() + transform.GetUniformScale() * obb.GetHalfLengths() ); } } diff --git a/Code/Framework/AzCore/AzCore/Math/Quaternion.cpp b/Code/Framework/AzCore/AzCore/Math/Quaternion.cpp index 143fe59ca7..06443c0698 100644 --- a/Code/Framework/AzCore/AzCore/Math/Quaternion.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Quaternion.cpp @@ -348,13 +348,20 @@ namespace AZ return result.GetW() >= 0.0f ? result : -result; } - const Quaternion Quaternion::CreateFromEulerAnglesDegrees(Vector3& anglesInDegrees) + const Quaternion Quaternion::CreateFromEulerAnglesDegrees(const Vector3& anglesInDegrees) { Quaternion result; result.SetFromEulerDegrees(anglesInDegrees); return result; } + const Quaternion Quaternion::CreateFromEulerAnglesRadians(const Vector3& anglesInRadians) + { + Quaternion result; + result.SetFromEulerRadians(anglesInRadians); + return result; + } + Quaternion Quaternion::Slerp(const Quaternion& dest, float t) const { const float DestDot = Dot(dest); diff --git a/Code/Framework/AzCore/AzCore/Math/Quaternion.h b/Code/Framework/AzCore/AzCore/Math/Quaternion.h index c4502063de..4d3b6641db 100644 --- a/Code/Framework/AzCore/AzCore/Math/Quaternion.h +++ b/Code/Framework/AzCore/AzCore/Math/Quaternion.h @@ -83,8 +83,11 @@ namespace AZ static Quaternion CreateShortestArc(const Vector3& v1, const Vector3& v2); - /// Creates a quaternion using rotation in degrees about the axes. First rotated about the X axis, followed by the Y axis, then the Z axis. - static const Quaternion CreateFromEulerAnglesDegrees(Vector3& anglesInDegrees); + //! Creates a quaternion using rotation in degrees about the axes. First rotated about the X axis, followed by the Y axis, then the Z axis. + static const Quaternion CreateFromEulerAnglesDegrees(const Vector3& anglesInDegrees); + + //! Creates a quaternion using rotation in radians about the axes. First rotated about the X axis, followed by the Y axis, then the Z axis. + static const Quaternion CreateFromEulerAnglesRadians(const Vector3& anglesInRadians); //! Stores the vector to an array of 4 floats. The floats need only be 4 byte aligned, 16 byte alignment is not required. void StoreToFloat4(float* values) const; diff --git a/Code/Framework/AzCore/AzCore/Math/Random.h b/Code/Framework/AzCore/AzCore/Math/Random.h index 5ae37433ec..8b2763df50 100644 --- a/Code/Framework/AzCore/AzCore/Math/Random.h +++ b/Code/Framework/AzCore/AzCore/Math/Random.h @@ -86,4 +86,101 @@ namespace AZ Normal, UniformReal }; + + //! Halton sequences are deterministic, quasi-random sequences with low discrepancy. They + //! are useful for generating evenly distributed points. + //! See https://en.wikipedia.org/wiki/Halton_sequence for more information. + + //! Returns a single halton number. + //! @param index The index of the number. Indices start at 1. Using index 0 will return 0. + //! @param base The numerical base of the halton number. + inline float GetHaltonNumber(uint32_t index, uint32_t base) + { + float fraction = 1.0f; + float result = 0.0f; + + while (index > 0) + { + fraction = fraction / base; + result += fraction * (index % base); + index = aznumeric_cast(index / base); + } + + return result; + } + + //! A helper class for generating arrays of Halton sequences in n dimensions. + //! The class holds the state of which bases to use, the starting offset + //! of each dimension and how much to increment between each index for each + //! dimension. + template + class HaltonSequence + { + public: + + //! Initializes a Halton sequence with some bases. By default there is no + //! offset and the index increments by 1 between each number. + HaltonSequence(AZStd::array bases) + : m_bases(bases) + { + m_offsets.fill(1); // Halton sequences start at index 1. + m_increments.fill(1); // By default increment by 1 between each number. + } + + //! Fills a provided container from begin to end with a Halton sequence. + //! Entries are expected to be, or implicitly converted to, AZStd::array. + template + void FillHaltonSequence(Iterator begin, Iterator end) + { + AZStd::array indices = m_offsets; + + // Generator that returns the Halton number for all bases for a single entry. + auto f = [&]() + { + AZStd::array item; + for (auto d = 0; d < Dimensions; ++d) + { + item[d] = GetHaltonNumber(indices[d], m_bases[d]); + indices[d] += m_increments[d]; + } + return item; + }; + + AZStd::generate(begin, end, f); + } + + //! Returns a Halton sequence in an array of N length. + template + AZStd::array, N> GetHaltonSequence() + { + AZStd::array, N> result; + FillHaltonSequence(result.begin(), result.end()); + return result; + } + + //! Sets the offsets per dimension to start generating a sequence from. + //! By default, there is no offset (offset of 0 corresponds to starting at index 1). + void SetOffsets(AZStd::array offsets) + { + m_offsets = offsets; + + // Halton sequences start at index 1, so increment all the indices. + AZStd::for_each(m_offsets.begin(), m_offsets.end(), [](uint32_t &n){ n++; }); + } + + //! Sets the increment between numbers in the halton sequence per dimension + //! By default this is 1, meaning that no numbers are skipped. Can be negative + //! to generate numbers in reverse order. + void SetIncrements(AZStd::array increments) + { + m_increments = increments; + } + + private: + + AZStd::array m_bases; + AZStd::array m_offsets; + AZStd::array m_increments; + + }; } diff --git a/Code/Framework/AzCore/AzCore/Math/Spline.h b/Code/Framework/AzCore/AzCore/Math/Spline.h index 912c10f46f..1adfc9b2fa 100644 --- a/Code/Framework/AzCore/AzCore/Math/Spline.h +++ b/Code/Framework/AzCore/AzCore/Math/Spline.h @@ -441,10 +441,10 @@ namespace AZ const Transform& worldFromLocal, const Vector3& src, const Vector3& dir, const Spline& spline) { Transform worldFromLocalNormalized = worldFromLocal; - const Vector3 scale = worldFromLocalNormalized.ExtractScale(); + const float scale = worldFromLocalNormalized.ExtractUniformScale(); const Transform localFromWorldNormalized = worldFromLocalNormalized.GetInverse(); - const Vector3 localRayOrigin = localFromWorldNormalized.TransformPoint(src) * scale.GetReciprocal(); + const Vector3 localRayOrigin = localFromWorldNormalized.TransformPoint(src) / scale; const Vector3 localRayDirection = localFromWorldNormalized.TransformVector(dir); return spline.GetNearestAddressRay(localRayOrigin, localRayDirection); } diff --git a/Code/Framework/AzCore/AzCore/Math/Transform.cpp b/Code/Framework/AzCore/AzCore/Math/Transform.cpp index bb3f764492..62a390c138 100644 --- a/Code/Framework/AzCore/AzCore/Math/Transform.cpp +++ b/Code/Framework/AzCore/AzCore/Math/Transform.cpp @@ -130,8 +130,8 @@ namespace AZ const Transform* transform = reinterpret_cast(classPtr); float data[NumFloats]; transform->GetRotation().StoreToFloat4(data); - transform->GetScale().StoreToFloat3(&data[4]); - transform->GetTranslation().StoreToFloat3(&data[7]); + data[4] = transform->GetUniformScale(); + transform->GetTranslation().StoreToFloat3(&data[5]); for (int i = 0; i < NumFloats; i++) { @@ -159,8 +159,8 @@ namespace AZ size_t TransformSerializer::TextToData(const char* text, unsigned int textVersion, IO::GenericStream& stream, bool isDataBigEndian) { - const size_t dataBufferSize = AZStd::max(NumFloatsVersion0, NumFloats); - const size_t numElements = textVersion < 1 ? NumFloatsVersion0 : NumFloats; + const size_t dataBufferSize = AZStd::max(AZStd::max(NumFloatsVersion1, NumFloatsVersion0), NumFloats); + const size_t numElements = textVersion < 1 ? NumFloatsVersion0 : (textVersion == 1 ? NumFloatsVersion1 : NumFloats); size_t nextNumberIndex = 0; AZStd::array data; @@ -201,7 +201,34 @@ namespace AZ return true; } - // otherwise load as a separate rotation, scale and translation + // version 1 had a quaternion rotation, vector3 scale and vector3 translation + else if (version == 1) + { + float data[NumFloatsVersion1]; + if (stream.GetLength() < sizeof(data)) + { + return false; + } + + stream.Read(sizeof(data), reinterpret_cast(data)); + + for (unsigned int i = 0; i < AZ_ARRAY_SIZE(data); ++i) + { + AZ_SERIALIZE_SWAP_ENDIAN(data[i], isDataBigEndian); + } + + Quaternion rotation = Quaternion::CreateFromFloat4(data); + Vector3 vectorScale = Vector3::CreateFromFloat3(&data[4]); + Vector3 translation = Vector3::CreateFromFloat3(&data[7]); + + float uniformScale = vectorScale.GetMaxElement(); + + *reinterpret_cast(classPtr) = + Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateUniformScale(uniformScale); + return true; + } + + // otherwise load as a quaternion rotation, float scale and vector3 translation float data[NumFloats]; if (stream.GetLength() < sizeof(data)) { @@ -216,11 +243,11 @@ namespace AZ } Quaternion rotation = Quaternion::CreateFromFloat4(data); - Vector3 scale = Vector3::CreateFromFloat3(&data[4]); - Vector3 translation = Vector3::CreateFromFloat3(&data[7]); + float scale = data[4]; + Vector3 translation = Vector3::CreateFromFloat3(&data[5]); *reinterpret_cast(classPtr) = - Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateScale(scale); + Transform::CreateFromQuaternionAndTranslation(rotation, translation) * Transform::CreateUniformScale(scale); return true; } @@ -237,7 +264,7 @@ namespace AZ if (serializeContext) { serializeContext->Class() - ->Version(1) + ->Version(2) ->Serializer(); } @@ -250,7 +277,7 @@ namespace AZ Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)-> Attribute(Script::Attributes::Storage, Script::Attributes::StorageType::Value)-> Attribute(Script::Attributes::GenericConstructorOverride, &Internal::TransformDefaultConstructor)-> - Constructor()-> + Constructor()-> Method("GetBasis", &Transform::GetBasis)-> Method("GetBasisX", &Transform::GetBasisX)-> Method("GetBasisY", &Transform::GetBasisY)-> @@ -283,11 +310,11 @@ namespace AZ Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)-> Method("GetRotation", &Transform::GetRotation)-> Method("SetRotation", &Transform::SetRotation)-> - Method("GetScale", &Transform::GetScale)-> - Method("SetScale", &Transform::SetScale)-> - Method("ExtractScale", &Transform::ExtractScale)-> + Method("GetUniformScale", &Transform::GetUniformScale)-> + Method("SetUniformScale", &Transform::SetUniformScale)-> + Method("ExtractUniformScale", &Transform::ExtractUniformScale)-> Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)-> - Method("MultiplyByScale", &Transform::MultiplyByScale)-> + Method("MultiplyByUniformScale", &Transform::MultiplyByUniformScale)-> Method("GetInverse", &Transform::GetInverse)-> Method("Invert", &Transform::Invert)-> Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::All)-> @@ -305,7 +332,7 @@ namespace AZ Method("CreateFromQuaternionAndTranslation", &Transform::CreateFromQuaternionAndTranslation)-> Method("CreateFromMatrix3x3", &Transform::CreateFromMatrix3x3)-> Method("CreateFromMatrix3x3AndTranslation", &Transform::CreateFromMatrix3x3AndTranslation)-> - Method("CreateScale", &Transform::CreateScale)-> + Method("CreateUniformScale", &Transform::CreateUniformScale)-> Method("CreateTranslation", &Transform::CreateTranslation)-> Method("ConstructFromValuesNumeric", &Internal::ConstructTransformFromValues); } @@ -315,7 +342,7 @@ namespace AZ { Transform result; Matrix3x3 tmp = value; - result.m_scale = tmp.ExtractScale(); + result.m_scale = tmp.ExtractScale().GetMaxElement(); result.m_rotation = Quaternion::CreateFromMatrix3x3(tmp); result.m_translation = Vector3::CreateZero(); return result; @@ -325,7 +352,7 @@ namespace AZ { Transform result; Matrix3x3 tmp = value; - result.m_scale = tmp.ExtractScale(); + result.m_scale = tmp.ExtractScale().GetMaxElement(); result.m_rotation = Quaternion::CreateFromMatrix3x3(tmp); result.m_translation = p; return result; @@ -335,7 +362,7 @@ namespace AZ { Transform result; Matrix3x4 tmp = value; - result.m_scale = tmp.ExtractScale(); + result.m_scale = tmp.ExtractScale().GetMaxElement(); result.m_rotation = Quaternion::CreateFromMatrix3x4(tmp); result.m_translation = value.GetTranslation(); return result; diff --git a/Code/Framework/AzCore/AzCore/Math/Transform.h b/Code/Framework/AzCore/AzCore/Math/Transform.h index eb1a12a912..3fe6ddc98a 100644 --- a/Code/Framework/AzCore/AzCore/Math/Transform.h +++ b/Code/Framework/AzCore/AzCore/Math/Transform.h @@ -25,10 +25,13 @@ namespace AZ : public SerializeContext::IDataSerializer { public: - // number of floats in the serialized representation, 4 for rotation, 3 for scale and 3 for translation - static constexpr int NumFloats = 10; + // number of floats in the serialized representation, 4 for rotation, 1 for scale and 3 for translation + static constexpr int NumFloats = 8; - // number of floats in the old format, which stored a 3x4 matrix + // number of floats in version 1, which used 4 for rotation, 3 for scale and 3 for translation + static constexpr int NumFloatsVersion1 = 10; + + // number of floats in version 0, which stored a 3x4 matrix static constexpr int NumFloatsVersion0 = 12; size_t Save(const void* classPtr, IO::GenericStream& stream, bool isDataBigEndian) override; @@ -45,7 +48,7 @@ namespace AZ static constexpr float MaxTransformScale = 1e9f; //! @} - //! The basic transformation class, represented using a quaternion rotation, vector scale and vector translation. + //! The basic transformation class, represented using a quaternion rotation, float scale and vector translation. //! By design, cannot represent skew transformations. class Transform { @@ -63,7 +66,7 @@ namespace AZ Transform() = default; //! Construct a transform from components. - Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale); + Transform(const Vector3& translation, const Quaternion& rotation, float scale); //! Creates an identity transform. static Transform CreateIdentity(); @@ -82,15 +85,22 @@ namespace AZ static Transform CreateFromQuaternionAndTranslation(const class Quaternion& q, const Vector3& p); //! Constructs from a Matrix3x3, translation is set to zero. + //! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes, + //! the largest matrix scale value will be used to uniformly scale the Transform. static Transform CreateFromMatrix3x3(const class Matrix3x3& value); - //! Constructs from a Matrix3x3, translation is set to zero. + //! Constructs from a Matrix3x3 and translation Vector3. + //! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes, + //! the largest matrix scale value will be used to uniformly scale the Transform. static Transform CreateFromMatrix3x3AndTranslation(const class Matrix3x3& value, const Vector3& p); + //! Constructs from a Matrix3x4. + //! Note that Transform only allows uniform scale, so if the matrix has different scale values along its axes, + //! the largest matrix scale value will be used to uniformly scale the Transform. static Transform CreateFromMatrix3x4(const Matrix3x4& value); - //! Sets the matrix to be a scale matrix, translation is set to zero. - static Transform CreateScale(const Vector3& scale); + //! Sets the transform to apply (uniform) scale only, no rotation or translation. + static Transform CreateUniformScale(const float scale); //! Sets the matrix to be a translation matrix, rotation part is set to identity. static Transform CreateTranslation(const Vector3& translation); @@ -119,13 +129,13 @@ namespace AZ const Quaternion& GetRotation() const; void SetRotation(const Quaternion& rotation); - const Vector3& GetScale() const; - void SetScale(const Vector3& v); + float GetUniformScale() const; + void SetUniformScale(const float scale); - //! Sets the transforms scale to a unit value and returns the previous scale value. - Vector3 ExtractScale(); + //! Sets the transform's scale to a unit value and returns the previous scale value. + float ExtractUniformScale(); - void MultiplyByScale(const Vector3& scale); + void MultiplyByUniformScale(float scale); Transform operator*(const Transform& rhs) const; Transform& operator*=(const Transform& rhs); @@ -159,7 +169,7 @@ namespace AZ private: Quaternion m_rotation; - Vector3 m_scale; + float m_scale; Vector3 m_translation; }; diff --git a/Code/Framework/AzCore/AzCore/Math/Transform.inl b/Code/Framework/AzCore/AzCore/Math/Transform.inl index 63425e6e41..5f71316b52 100644 --- a/Code/Framework/AzCore/AzCore/Math/Transform.inl +++ b/Code/Framework/AzCore/AzCore/Math/Transform.inl @@ -12,7 +12,7 @@ namespace AZ { - AZ_MATH_INLINE Transform::Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale) + AZ_MATH_INLINE Transform::Transform(const Vector3& translation, const Quaternion& rotation, float scale) : m_translation(translation) , m_rotation(rotation) , m_scale(scale) @@ -25,7 +25,7 @@ namespace AZ { Transform result; result.m_rotation = Quaternion::CreateIdentity(); - result.m_scale = Vector3::CreateOne(); + result.m_scale = 1.0f; result.m_translation = Vector3::CreateZero(); return result; } @@ -49,7 +49,7 @@ namespace AZ { Transform result; result.m_rotation = q; - result.m_scale = Vector3::CreateOne(); + result.m_scale = 1.0f; result.m_translation = Vector3::CreateZero(); return result; } @@ -58,12 +58,12 @@ namespace AZ { Transform result; result.m_rotation = q; - result.m_scale = Vector3::CreateOne(); + result.m_scale = 1.0f; result.m_translation = p; return result; } - AZ_MATH_INLINE Transform Transform::CreateScale(const Vector3& scale) + AZ_MATH_INLINE Transform Transform::CreateUniformScale(float scale) { Transform result; result.m_rotation = Quaternion::CreateIdentity(); @@ -76,7 +76,7 @@ namespace AZ { Transform result; result.m_rotation = Quaternion::CreateIdentity(); - result.m_scale = Vector3::CreateOne(); + result.m_scale = 1.0f; result.m_translation = translation; return result; } @@ -104,17 +104,17 @@ namespace AZ AZ_MATH_INLINE Vector3 Transform::GetBasisX() const { - return m_rotation.TransformVector(Vector3::CreateAxisX(m_scale.GetX())); + return m_rotation.TransformVector(Vector3::CreateAxisX(m_scale)); } AZ_MATH_INLINE Vector3 Transform::GetBasisY() const { - return m_rotation.TransformVector(Vector3::CreateAxisY(m_scale.GetY())); + return m_rotation.TransformVector(Vector3::CreateAxisY(m_scale)); } AZ_MATH_INLINE Vector3 Transform::GetBasisZ() const { - return m_rotation.TransformVector(Vector3::CreateAxisZ(m_scale.GetZ())); + return m_rotation.TransformVector(Vector3::CreateAxisZ(m_scale)); } AZ_MATH_INLINE void Transform::GetBasisAndTranslation(Vector3* basisX, Vector3* basisY, Vector3* basisZ, Vector3* pos) const @@ -150,24 +150,24 @@ namespace AZ m_rotation = rotation; } - AZ_MATH_INLINE const Vector3& Transform::GetScale() const + AZ_MATH_INLINE float Transform::GetUniformScale() const { return m_scale; } - AZ_MATH_INLINE void Transform::SetScale(const Vector3& scale) + AZ_MATH_INLINE void Transform::SetUniformScale(const float scale) { m_scale = scale; } - AZ_MATH_INLINE Vector3 Transform::ExtractScale() + AZ_MATH_INLINE float Transform::ExtractUniformScale() { - const Vector3 scale = m_scale; - m_scale = Vector3::CreateOne(); + const float scale = m_scale; + m_scale = 1.0f; return scale; } - AZ_MATH_INLINE void Transform::MultiplyByScale(const Vector3& scale) + AZ_MATH_INLINE void Transform::MultiplyByUniformScale(float scale) { m_scale *= scale; } @@ -204,10 +204,9 @@ namespace AZ AZ_MATH_INLINE Transform Transform::GetInverse() const { - // note - need to be careful about how to calculate inverse when there is non-uniform scale Transform out; out.m_rotation = m_rotation.GetConjugate(); - out.m_scale = m_scale.GetReciprocal(); + out.m_scale = 1.0f / m_scale; out.m_translation = -out.m_scale * (out.m_rotation.TransformVector(m_translation)); return out; } @@ -219,27 +218,27 @@ namespace AZ AZ_MATH_INLINE bool Transform::IsOrthogonal(float tolerance) const { - return m_scale.IsClose(Vector3::CreateOne(), tolerance); + return AZ::IsClose(m_scale, 1.0f, tolerance); } AZ_MATH_INLINE Transform Transform::GetOrthogonalized() const { Transform result; result.m_rotation = m_rotation; - result.m_scale = Vector3::CreateOne(); + result.m_scale = 1.0f; result.m_translation = m_translation; return result; } AZ_MATH_INLINE void Transform::Orthogonalize() { - *this = GetOrthogonalized(); + m_scale = 1.0f; } AZ_MATH_INLINE bool Transform::IsClose(const Transform& rhs, float tolerance) const { return m_rotation.IsClose(rhs.m_rotation, tolerance) - && m_scale.IsClose(rhs.m_scale, tolerance) + && AZ::IsClose(m_scale, rhs.m_scale, tolerance) && m_translation.IsClose(rhs.m_translation, tolerance); } @@ -268,21 +267,21 @@ namespace AZ AZ_MATH_INLINE void Transform::SetFromEulerDegrees(const Vector3& eulerDegrees) { m_translation = Vector3::CreateZero(); - m_scale = Vector3::CreateOne(); + m_scale = 1.0f; m_rotation.SetFromEulerDegrees(eulerDegrees); } AZ_MATH_INLINE void Transform::SetFromEulerRadians(const Vector3& eulerRadians) { m_translation = Vector3::CreateZero(); - m_scale = Vector3::CreateOne(); + m_scale = 1.0f; m_rotation.SetFromEulerRadians(eulerRadians); } AZ_MATH_INLINE bool Transform::IsFinite() const { return m_rotation.IsFinite() - && m_scale.IsFinite() + && AZ::IsFiniteFloat(m_scale) && m_translation.IsFinite(); } diff --git a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp index 0a3e02ee0d..36c40265af 100644 --- a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp @@ -60,14 +60,14 @@ namespace AZ { // Scale is transitioning to a single uniform scale value, but since it's still internally represented as a Vector3, // we need to pick one number to use for load/store operations. - float scale = transformInstance->GetScale().GetMaxElement(); + float scale = transformInstance->GetUniformScale(); JSR::ResultCode loadResult = ContinueLoadingFromJsonObjectField(&scale, azrtti_typeid(), inputValue, ScaleTag, context); result.Combine(loadResult); - transformInstance->SetScale(AZ::Vector3(scale)); + transformInstance->SetUniformScale(scale); } return context.Report( @@ -124,8 +124,8 @@ namespace AZ // Scale is transitioning to a single uniform scale value, but since it's still internally represented as a Vector3, // we need to pick one number to use for load/store operations. - float scale = transformInstance->GetScale().GetMaxElement(); - float defaultScale = defaultTransformInstance ? defaultTransformInstance->GetScale().GetMaxElement() : 0.0f; + float scale = transformInstance->GetUniformScale(); + float defaultScale = defaultTransformInstance ? defaultTransformInstance->GetUniformScale() : 0.0f; JSR::ResultCode storeResult = ContinueStoringToJsonObjectField( outputValue, ScaleTag, &scale, defaultTransformInstance ? &defaultScale : nullptr, azrtti_typeid(), diff --git a/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp b/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp index 78f6ac0fb1..9e5b586c39 100644 --- a/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp +++ b/Code/Framework/AzCore/AzCore/Memory/OverrunDetectionAllocator.cpp @@ -103,7 +103,7 @@ namespace AZ } } - /// Returns a pointer to the beginning of master vector of SmallAllocationGroups. + /// Returns a pointer to the beginning of vector of SmallAllocationGroups. SmallAllocationGroup* ArrayHead() { return this - m_index; @@ -169,7 +169,7 @@ namespace AZ return m_marker == MARKER; } - /// Returns the master index of the SmallAllocationGroup containing this allocation + /// Returns the index of the SmallAllocationGroup containing this allocation uint32_t GetSmallAllocationIndex() const { return (uint32_t)(m_data & 0xFFFFFFFF); diff --git a/Code/Framework/AzCore/AzCore/Module/ModuleManager.cpp b/Code/Framework/AzCore/AzCore/Module/ModuleManager.cpp index fe41050b00..0ce3ee5d8d 100644 --- a/Code/Framework/AzCore/AzCore/Module/ModuleManager.cpp +++ b/Code/Framework/AzCore/AzCore/Module/ModuleManager.cpp @@ -512,7 +512,7 @@ namespace AZ // Load DLLs specified in the application descriptor for (const auto& moduleDescriptor : modules) { - // For each module that is loaded, attempt to set the module's folder as a path for dependent module resolution + // For each module that is loaded, attempt to set the module's folder as a path for dependent module resolution moduleSearchPathHelper.SetModuleSearchPath(moduleDescriptor); LoadModuleOutcome result = LoadDynamicModule(moduleDescriptor.m_dynamicLibraryPath.c_str(), lastStepToPerform, maintainReferences); diff --git a/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.cpp b/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.cpp index 63aad1ecf4..e31c3b0a1e 100644 --- a/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.cpp +++ b/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.cpp @@ -19,7 +19,7 @@ namespace AZ { inline namespace PlatformDefaults { - static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformES3, PlatformIOS, PlatformOSX, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient }; + static const char* PlatformNames[PlatformId::NumPlatformIds] = { PlatformPC, PlatformAndroid, PlatformIOS, PlatformMac, PlatformProvo, PlatformSalem, PlatformJasper, PlatformServer, PlatformAll, PlatformAllClient }; const char* PlatformIdToPalFolder(AZ::PlatformId platform) { @@ -31,11 +31,11 @@ namespace AZ { case AZ::PC: return "PC"; - case AZ::ES3: + case AZ::ANDROID_ID: return "Android"; case AZ::IOS: return "iOS"; - case AZ::OSX: + case AZ::MAC_ID: return "Mac"; case AZ::PROVO: return "Provo"; @@ -66,11 +66,11 @@ namespace AZ } else if (osPlatform == PlatformCodeNameMac) { - return PlatformOSX; + return PlatformMac; } else if (osPlatform == PlatformCodeNameAndroid) { - return PlatformES3; + return PlatformAndroid; } else if (osPlatform == PlatformCodeNameiOS) { @@ -207,13 +207,13 @@ namespace AZ platformCodes.emplace_back(PlatformCodeNameWindows); platformCodes.emplace_back(PlatformCodeNameLinux); break; - case PlatformId::ES3: + case PlatformId::ANDROID_ID: platformCodes.emplace_back(PlatformCodeNameAndroid); break; case PlatformId::IOS: platformCodes.emplace_back(PlatformCodeNameiOS); break; - case PlatformId::OSX: + case PlatformId::MAC_ID: platformCodes.emplace_back(PlatformCodeNameMac); break; case PlatformId::PROVO: diff --git a/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.h b/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.h index 2d67c860cd..ba8c55f5f5 100644 --- a/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.h +++ b/Code/Framework/AzCore/AzCore/PlatformId/PlatformDefaults.h @@ -27,9 +27,9 @@ namespace AZ inline namespace PlatformDefaults { constexpr char PlatformPC[] = "pc"; - constexpr char PlatformES3[] = "es3"; + constexpr char PlatformAndroid[] = "android"; constexpr char PlatformIOS[] = "ios"; - constexpr char PlatformOSX[] = "osx_gl"; + constexpr char PlatformMac[] = "mac"; constexpr char PlatformProvo[] = "provo"; constexpr char PlatformSalem[] = "salem"; constexpr char PlatformJasper[] = "jasper"; @@ -54,9 +54,9 @@ namespace AZ AZ_ENUM_WITH_UNDERLYING_TYPE(PlatformId, int, (Invalid, -1), PC, - ES3, + ANDROID_ID, IOS, - OSX, + MAC_ID, PROVO, SALEM, JASPER, @@ -73,9 +73,9 @@ namespace AZ { Platform_NONE = 0x00, Platform_PC = 1 << PlatformId::PC, - Platform_ES3 = 1 << PlatformId::ES3, + Platform_ANDROID = 1 << PlatformId::ANDROID_ID, Platform_IOS = 1 << PlatformId::IOS, - Platform_OSX = 1 << PlatformId::OSX, + Platform_MAC = 1 << PlatformId::MAC_ID, Platform_PROVO = 1 << PlatformId::PROVO, Platform_SALEM = 1 << PlatformId::SALEM, Platform_JASPER = 1 << PlatformId::JASPER, @@ -87,7 +87,7 @@ namespace AZ // A special platform that will always correspond to all non-server platforms, even if new ones are added Platform_ALL_CLIENT = 1ULL << 31, - AllNamedPlatforms = Platform_PC | Platform_ES3 | Platform_IOS | Platform_OSX | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER, + AllNamedPlatforms = Platform_PC | Platform_ANDROID | Platform_IOS | Platform_MAC | Platform_PROVO | Platform_SALEM | Platform_JASPER | Platform_SERVER, }; AZ_DEFINE_ENUM_BITWISE_OPERATORS(PlatformFlags); diff --git a/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.cpp b/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.cpp index 0258869a0c..d56140be28 100644 --- a/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.cpp +++ b/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.cpp @@ -28,8 +28,8 @@ namespace AZ return "Android64"; case PlatformID::PLATFORM_APPLE_IOS: return "iOS"; - case PlatformID::PLATFORM_APPLE_OSX: - return "OSX"; + case PlatformID::PLATFORM_APPLE_MAC: + return "Mac"; #if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) #define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ case PlatformID::PLATFORM_##PUBLICNAME:\ diff --git a/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.h b/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.h index ce1a11d8ce..e8e7cef6dd 100644 --- a/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.h +++ b/Code/Framework/AzCore/AzCore/PlatformId/PlatformId.h @@ -23,7 +23,7 @@ namespace AZ PLATFORM_WINDOWS_64, PLATFORM_LINUX_64, PLATFORM_APPLE_IOS, - PLATFORM_APPLE_OSX, + PLATFORM_APPLE_MAC, PLATFORM_ANDROID_64, // ARMv8 / 64-bit #if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) #define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ diff --git a/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl b/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl index 079c70c878..537d3e5c83 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl +++ b/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl @@ -1020,29 +1020,60 @@ namespace AZ } }; - /// OnDemand reflection for AZStd::set + + template + class Iterator_VM> + { + public: + using ContainerType = AZStd::unordered_set; + using IteratorType = typename ContainerType::iterator; + Iterator_VM(ContainerType& container) + : m_iterator(container.begin()) + , m_end(container.end()) + {} + + const t_Key& GetKeyUnchecked() const + { + return *m_iterator; + } + + bool IsNotAtEnd() const + { + return m_iterator != m_end; + } + + t_Key& ModValueUnchecked() + { + return *m_iterator; + } + + void Next() + { + ++m_iterator; + } + + private: + IteratorType m_iterator; + IteratorType m_end; + }; + + /// OnDemand reflection for AZStd::unordered_set template struct OnDemandReflection< AZStd::unordered_set > { using ContainerType = AZStd::unordered_set; using KeyListType = AZStd::vector; - static AZ::Outcome Erase(ContainerType& thisMap, Key& key) + using ValueIteratorType = Iterator_VM; + + static bool EraseCheck_VM(ContainerType& thisSet, Key& key) { - const auto result = thisMap.erase(key); - if (result) - { - return AZ::Success(); - } - else - { - return AZ::Failure(); - } + return thisSet.erase(key) != 0; } - static void Insert(ContainerType& thisSet, Key& key) + static ContainerType& ErasePost_VM(ContainerType& thisSet, [[maybe_unused]] Key&) { - thisSet.insert(key); + return thisSet; } static KeyListType GetKeys(ContainerType& thisSet) @@ -1055,6 +1086,17 @@ namespace AZ return keys; } + static ContainerType& Insert(ContainerType& thisSet, Key& key) + { + thisSet.insert(key); + return thisSet; + } + + static ValueIteratorType Iterate_VM(ContainerType& thisContainer) + { + return ValueIteratorType(thisContainer); + } + static void Swap(ContainerType& thisSet, ContainerType& otherSet) { thisSet.swap(otherSet); @@ -1064,33 +1106,68 @@ namespace AZ { if (BehaviorContext* behaviorContext = azrtti_cast(context)) { + BranchOnResultInfo emptyBranchInfo; + emptyBranchInfo.m_returnResultInBranches = true; + emptyBranchInfo.m_trueToolTip = "The container is empty"; + emptyBranchInfo.m_falseToolTip = "The container is not empty"; + auto ContainsTransparent = [](const ContainerType& containerType, typename ContainerType::key_type& key)->bool { return containerType.contains(key); }; + ExplicitOverloadInfo explicitOverloadInfo; behaviorContext->Class() - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) + ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly) ->Attribute(AZ::ScriptCanvasAttributes::PrettyName, ScriptCanvasOnDemandReflection::OnDemandPrettyName::Get(*behaviorContext)) ->Attribute(AZ::Script::Attributes::ToolTip, ScriptCanvasOnDemandReflection::OnDemandToolTip::Get(*behaviorContext)) ->Attribute(AZ::Script::Attributes::Category, ScriptCanvasOnDemandReflection::OnDemandCategoryName::Get(*behaviorContext)) ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn) ->Method("BucketCount", static_cast(&ContainerType::bucket_count)) - ->Method("Erase", &Erase) - ->Method("Empty", [](ContainerType& thisSet)->bool { return thisSet.empty(); }) + ->Method("Empty", static_cast(&ContainerType::empty), { { { "Container", "The container to check if it is empty", nullptr, {} } } }) + ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Is Empty", "Containers")) + ->Attribute(AZ::ScriptCanvasAttributes::BranchOnResult, emptyBranchInfo) + ->Method("EraseCheck_VM", &EraseCheck_VM) + ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent) + ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) + ->Method("Erase", &ErasePost_VM) + ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent) + ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Erase", "Containers")) + ->Attribute(AZ::ScriptCanvasAttributes::CheckedOperation, CheckedOperationInfo("EraseCheck_VM", {}, "Out", "Key Not Found", true)) + ->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "" }, { "ContainerGroup" })) ->Method("contains", ContainsTransparent) + ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Has Key", "Containers")) ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent) ->Method("Insert", &Insert) + ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent) + ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Insert", "Containers")) + ->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "", "" }, { "ContainerGroup" })) ->Method(k_sizeName, [](ContainerType* thisPtr) { return aznumeric_cast(thisPtr->size()); }) ->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::Length) ->Method("GetKeys", &GetKeys) ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) + ->Method("GetSize", [](ContainerType& thisPtr) { return aznumeric_cast(thisPtr.size()); }) + ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Get Size", "Containers")) + ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent) ->Method("Reserve", static_cast(&ContainerType::reserve)) ->Method("Swap", &Swap) + ->Method("Clear", [](ContainerType& thisContainer)->ContainerType& { thisContainer.clear(); return thisContainer; }) + ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent) + ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Clear All Elements", "Containers")) + ->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup" }, { "ContainerGroup" })) + ->Method(k_iteratorConstructorName, &Iterate_VM) + ; + + behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly) + ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn) + ->Method(k_iteratorGetKeyName, &ValueIteratorType::GetKeyUnchecked) + ->Method(k_iteratorModValueName, &ValueIteratorType::ModValueUnchecked) + ->Method(k_iteratorIsNotAtEndName, &ValueIteratorType::IsNotAtEnd) + ->Method(k_iteratorNextName, &ValueIteratorType::Next) ; } } - }; template <> diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp index 635d160434..31a2cfc09e 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp @@ -165,7 +165,7 @@ namespace AZ if (HasResult() != overload->HasResult()) { - AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all"); + AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str()); return false; } @@ -176,7 +176,7 @@ namespace AZ if (!(methodResult->m_typeId == overloadResult->m_typeId && methodResult->m_traits == overloadResult->m_traits)) { - AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all"); + AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str()); return false; } } @@ -575,7 +575,7 @@ namespace AZ } else { - AZ_Error("BehaviorContext", false, "safety check declared for method %s but it was not found in the class"); + AZ_Error("BehaviorContext", false, "Method: %s, declared safety check: %s, but it was not found in class: %s", method.m_name.c_str(), m_name.c_str(), checkedOperationInfo.m_safetyCheckName.c_str()); } } } diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp index c64b86ae0f..f6aac0fa16 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp @@ -34,10 +34,17 @@ namespace BehaviorContextUtilitiesCPP using argument_type = const BehaviorParameter*; using result_type = size_t; result_type operator()(const argument_type& value) const - { - result_type result = AZStd::hash()(value->m_typeId); - AZStd::hash_combine(result, CleanTraits(value->m_traits)); - return result; + { + if (value) + { + result_type result = AZStd::hash()(value->m_typeId); + AZStd::hash_combine(result, CleanTraits(value->m_traits)); + return result; + } + else + { + return 0; + } } }; @@ -45,7 +52,11 @@ namespace BehaviorContextUtilitiesCPP { bool operator()(const BehaviorParameter* left, const BehaviorParameter* right) const { - return left->m_typeId == right->m_typeId && CleanTraits(left->m_traits) == CleanTraits(right->m_traits); + return (left == nullptr && right == nullptr) + || (left != nullptr + && right != nullptr + && left->m_typeId == right->m_typeId + && CleanTraits(left->m_traits) == CleanTraits(right->m_traits)); } }; @@ -137,7 +148,7 @@ namespace AZ for (size_t argIndex = 0, argSentinel = overload.GetNumArguments(); argIndex < argSentinel; ++argIndex) { auto overloadedArgIter = variance.m_input.find(argIndex); - if (overloadedArgIter != variance.m_input.end()) + if (overloadedArgIter != variance.m_input.end() && overloadedArgIter->second[overloadIndex]) { // if this doesn't work try the type name overloadName += ReplaceCppArtifacts(overloadedArgIter->second[overloadIndex]->m_name); @@ -185,16 +196,24 @@ namespace AZ { auto argument = overloads[overloadIndex].first->GetArgument(0); - const bool isThisPointer - = (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0 - || AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes); + if (argument) + { + const bool isThisPointer + = (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0 + || AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes); - oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer; + oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer; + } types.insert(argument); stripedArgs.emplace_back(argument); } + if (types.size() == overloads.size()) + { + variance.m_unambiguousInput.insert(0); + } + if (types.size() > 1 && (onThis == VariantOnThis::Yes || !oneArgIsThisPointer)) { variance.m_input.insert(AZStd::make_pair(0, stripedArgs)); @@ -210,11 +229,15 @@ namespace AZ for (size_t overloadIndex = 0, overloadSentinel = overloads.size(); overloadIndex < overloadSentinel; ++overloadIndex) { auto argument = overloads[overloadIndex].first->GetArgument(argIndex); - types.insert(argument); stripedArgs.emplace_back(argument); } + if (types.size() == overloads.size()) + { + variance.m_unambiguousInput.insert(0); + } + if (types.size() > 1) { variance.m_input.insert(AZStd::make_pair(argIndex, stripedArgs)); diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h index 4663635cdf..0dc9ecc969 100644 --- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h +++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h @@ -27,6 +27,8 @@ namespace AZ struct OverloadVariance { AZStd::unordered_map> m_input; + // the indices of inputs that make selection of overload unambiguous + AZStd::unordered_set m_unambiguousInput; AZStd::vector m_output; }; diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp index ac1e61a5aa..9bf6247e97 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp @@ -2048,10 +2048,6 @@ LUA_API const Node* lua_getDummyNode() return true; } - else - { - AZ_Warning("Script", false, "Index %d is not a function!", functionIndex); - } return false; } @@ -2078,7 +2074,6 @@ LUA_API const Node* lua_getDummyNode() } else { - AZ_Warning("Script", lua_isnil(m_nativeContext, -1), "Name %s exists but is not a function!", functionName); lua_pop(m_nativeContext, 1); } @@ -5888,7 +5883,6 @@ LUA_API const Node* lua_getDummyNode() else { lua_pop(m_impl->m_lua, 1); - AZ_Warning("Script", false, "%s is not a function!", functionName); } return false; } @@ -5906,7 +5900,6 @@ LUA_API const Node* lua_getDummyNode() else { lua_pop(m_impl->m_lua, 1); - AZ_Warning("Script", false, "CacheIndex %d is not a function!", cachedIndex); } return false; } diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp index 015554538f..11d4db2e07 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptSystemComponent.cpp @@ -937,7 +937,7 @@ void ScriptSystemComponent::Reflect(ReflectContext* reflection) ->Enum(PlatformID::PLATFORM_LINUX_64)>("Linux") ->Enum(PlatformID::PLATFORM_ANDROID_64)>("Android64") ->Enum(PlatformID::PLATFORM_APPLE_IOS)>("iOS") - ->Enum(PlatformID::PLATFORM_APPLE_OSX)>("OSX") + ->Enum(PlatformID::PLATFORM_APPLE_MAC)>("Mac") #if defined(AZ_EXPAND_FOR_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) #define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ ->Enum(PlatformID::PLATFORM_##PUBLICNAME)>(#CodeName) diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h index 7cb81829ef..41d80f42a3 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h +++ b/Code/Framework/AzCore/AzCore/Script/ScriptTimePoint.h @@ -24,9 +24,7 @@ namespace AZ AZ_TYPE_INFO_SPECIALIZE(AZStd::chrono::system_clock::time_point, "{5C48FD59-7267-405D-9C06-1EA31379FE82}"); - /** - * Wrapper that reflects a AZStd::chrono::system_clock::time_point to script. - */ + //! Wrapper that reflects a AZStd::chrono::system_clock::time_point to script. class ScriptTimePoint { public: @@ -38,33 +36,45 @@ namespace AZ explicit ScriptTimePoint(AZStd::chrono::system_clock::time_point timePoint) : m_timePoint(timePoint) {} - AZStd::string ToString() const - { - return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count()); - } + //! Formats the time point in a string formatted as: "Time ". + AZStd::string ToString() const; - const AZStd::chrono::system_clock::time_point& Get() { return m_timePoint; } + //! Returns the time point. + const AZStd::chrono::system_clock::time_point& Get() const; - // Returns the time point in seconds - double GetSeconds() const - { - typedef AZStd::chrono::duration double_seconds; - return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); - } + //! Returns the time point in seconds + double GetSeconds() const; - // Returns the time point in milliseconds - double GetMilliseconds() const - { - typedef AZStd::chrono::duration double_ms; - return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); - } + //! Returns the time point in milliseconds + double GetMilliseconds() const; static void Reflect(ReflectContext* reflection); protected: - AZStd::chrono::system_clock::time_point m_timePoint; }; + + inline AZStd::string ScriptTimePoint::ToString() const + { + return AZStd::string::format("Time %llu", m_timePoint.time_since_epoch().count()); + } + + inline const AZStd::chrono::system_clock::time_point& ScriptTimePoint::Get() const + { + return m_timePoint; + } + + inline double ScriptTimePoint::GetSeconds() const + { + typedef AZStd::chrono::duration double_seconds; + return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); + } + + inline double ScriptTimePoint::GetMilliseconds() const + { + typedef AZStd::chrono::duration double_ms; + return AZStd::chrono::duration_cast(m_timePoint.time_since_epoch()).count(); + } } diff --git a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl index 90b9ba5afd..dfd0707ed2 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl +++ b/Code/Framework/AzCore/AzCore/Serialization/EditContextConstants.inl @@ -53,6 +53,10 @@ namespace AZ //! RemoveableByUser : A bool which determines if the component can be removed by the user. //! Setting this to false prevents the user from removing this component. Default behavior is removeable by user. const static AZ::Crc32 RemoveableByUser = AZ_CRC("RemoveableByUser", 0x32c7fd50); + //! An int which, if specified, causes a component to be forced to a particular position in the sorted list of + //! components on an entity, and prevents dragging or moving operations which would affect that position. + const static AZ::Crc32 FixedComponentListIndex = AZ_CRC_CE("FixedComponentListIndex"); + const static AZ::Crc32 AppearsInAddComponentMenu = AZ_CRC("AppearsInAddComponentMenu", 0x53790e31); const static AZ::Crc32 ForceAutoExpand = AZ_CRC("ForceAutoExpand", 0x1a5c79d2); // Ignores expansion state set by user, enforces expansion. const static AZ::Crc32 AutoExpand = AZ_CRC("AutoExpand", 0x306ff5c0); // Expands automatically unless user changes expansion state. @@ -119,6 +123,7 @@ namespace AZ const static AZ::Crc32 NameLabelOverride = AZ_CRC("NameLabelOverride", 0x9ff79cab); const static AZ::Crc32 AssetPickerTitle = AZ_CRC_CE("AssetPickerTitle"); + const static AZ::Crc32 HideProductFilesInAssetPicker = AZ_CRC_CE("HideProductFilesInAssetPicker"); const static AZ::Crc32 ChildNameLabelOverride = AZ_CRC("ChildNameLabelOverride", 0x73dd2909); //! Container attribute that is used to override labels for its elements given the index of the element const static AZ::Crc32 IndexedChildNameLabelOverride = AZ_CRC("IndexedChildNameLabelOverride", 0x5f313ac2); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp index 13a25e5aa6..d5a1730364 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp @@ -74,7 +74,7 @@ namespace AZ "Unable to retrieve the correct container information for AZStd::array instance."); } - Flags flags = Flags::None; + ContinuationFlags flags = ContinuationFlags::None; Uuid elementTypeId = Uuid::CreateNull(); auto typeEnumCallback = [&elementTypeId, &flags](const Uuid&, const SerializeContext::ClassElement* genericClassElement) { @@ -82,7 +82,7 @@ namespace AZ elementTypeId = genericClassElement->m_typeId; if (genericClassElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - flags = Flags::ResolvePointer; + flags = ContinuationFlags::ResolvePointer; } return false; }; @@ -161,7 +161,7 @@ namespace AZ "Not enough entries in JSON array to load an AZStd::array from."); } - Flags flags = Flags::None; + ContinuationFlags flags = ContinuationFlags::None; Uuid elementTypeId = Uuid::CreateNull(); auto typeEnumCallback = [&elementTypeId, &flags](const Uuid&, const SerializeContext::ClassElement* genericClassElement) { @@ -169,7 +169,7 @@ namespace AZ elementTypeId = genericClassElement->m_typeId; if (genericClassElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - flags = Flags::ResolvePointer; + flags = ContinuationFlags::ResolvePointer; } return false; }; diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp index 6c67fd284a..9a426a1e59 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp @@ -208,22 +208,28 @@ namespace AZ // BaseJsonSerializer // - JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading(void* object, const Uuid& typeId, const rapidjson::Value& value, - JsonDeserializerContext& context, Flags flags) + BaseJsonSerializer::OperationFlags BaseJsonSerializer::GetOperationsFlags() const { - return flags & Flags::ResolvePointer ? - JsonDeserializer::LoadToPointer(object, typeId, value, context) : - JsonDeserializer::Load(object, typeId, value, context); + return OperationFlags::None; } - JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring(rapidjson::Value& output, const void* object, - const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, Flags flags) + JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading( + void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags) + { + return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer + ? JsonDeserializer::LoadToPointer(object, typeId, value, context) + : JsonDeserializer::Load(object, typeId, value, context); + } + + JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring( + rapidjson::Value& output, const void* object, const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, + ContinuationFlags flags) { using namespace JsonSerializationResult; - if (flags & Flags::ReplaceDefault && !context.ShouldKeepDefaults()) + if ((flags & ContinuationFlags::ReplaceDefault) == ContinuationFlags::ReplaceDefault && !context.ShouldKeepDefaults()) { - if (flags & Flags::ResolvePointer) + if ((flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer) { return JsonSerializer::StoreFromPointer(output, object, nullptr, typeId, context); } @@ -248,7 +254,7 @@ namespace AZ } } - return flags & Flags::ResolvePointer ? + return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer ? JsonSerializer::StoreFromPointer(output, object, defaultObject, typeId, context) : JsonSerializer::Store(output, object, defaultObject, typeId, context); } @@ -265,8 +271,9 @@ namespace AZ return JsonSerializer::StoreTypeName(output, typeId, context); } - JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoadingFromJsonObjectField(void* object, const Uuid& typeId, const rapidjson::Value& value, - rapidjson::Value::StringRefType memberName, JsonDeserializerContext& context, Flags flags) + JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoadingFromJsonObjectField( + void* object, const Uuid& typeId, const rapidjson::Value& value, rapidjson::Value::StringRefType memberName, + JsonDeserializerContext& context, ContinuationFlags flags) { using namespace JsonSerializationResult; @@ -291,7 +298,7 @@ namespace AZ JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoringToJsonObjectField(rapidjson::Value& output, rapidjson::Value::StringRefType newMemberName, const void* object, const void* defaultObject, - const Uuid& typeId, JsonSerializerContext& context, Flags flags) + const Uuid& typeId, JsonSerializerContext& context, ContinuationFlags flags) { using namespace JsonSerializationResult; diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h index f6ced44583..06c5eda6de 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h @@ -161,13 +161,19 @@ namespace AZ public: AZ_RTTI(BaseJsonSerializer, "{7291FFDC-D339-40B5-BB26-EA067A327B21}"); - enum Flags + enum class ContinuationFlags { - None = 0, //! No extra flags. + 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. }; + 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. + }; + virtual ~BaseJsonSerializer() = default; //! Transforms the data from the rapidjson Value to outputValue, if the conversion is possible and supported. @@ -180,6 +186,9 @@ namespace AZ virtual JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context) = 0; + //! Returns the operation flags which tells the Json Serialization how this custom json serializer can be used. + virtual OperationFlags GetOperationsFlags() const; + protected: //! Continues loading of a (sub)value. Use this function to load member variables for instance. This is more optimal than //! directly calling the json serialization. @@ -187,8 +196,9 @@ namespace AZ //! @param typeId Type id of the object passed in. //! @param value The value in the JSON document where the deserializer will start reading data from. //! @param context The context used during deserialization. Use the value passed in from Load. - JsonSerializationResult::ResultCode ContinueLoading(void* object, const Uuid& typeId, const rapidjson::Value& value, - JsonDeserializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueLoading( + void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, + ContinuationFlags flags = ContinuationFlags::None); //! Continues storing of a (sub)value. Use this function to store member variables for instance. This is more optimal than //! directly calling the json serialization. @@ -200,8 +210,9 @@ namespace AZ //! the settings. //! @param typeId The type id of the object and default object. //! @param context The context used during serialization. Use the value passed in from Store. - JsonSerializationResult::ResultCode ContinueStoring(rapidjson::Value& output, const void* object, const void* defaultObject, - const Uuid& typeId, JsonSerializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueStoring( + rapidjson::Value& output, const void* object, const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, + ContinuationFlags flags = ContinuationFlags::None); //! Retrieves the type id from a json object or json string. //! @param typeId The retrieved type id. @@ -222,12 +233,14 @@ namespace AZ const Uuid& typeId, JsonSerializerContext& context); //! Helper function similar to ContinueLoading, but loads the data as a member of 'value' rather than 'value' itself, if it exists. - JsonSerializationResult::ResultCode ContinueLoadingFromJsonObjectField(void* object, const Uuid& typeId, const rapidjson::Value& value, - rapidjson::Value::StringRefType memberName, JsonDeserializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueLoadingFromJsonObjectField( + void* object, const Uuid& typeId, const rapidjson::Value& value, rapidjson::Value::StringRefType memberName, + JsonDeserializerContext& context, ContinuationFlags flags = ContinuationFlags::None); //! Helper function similar to ContinueStoring, but stores the data as a member of 'output' rather than overwriting 'output'. - JsonSerializationResult::ResultCode ContinueStoringToJsonObjectField(rapidjson::Value& output, rapidjson::Value::StringRefType newMemberName, - const void* object, const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context, Flags flags = Flags::None); + JsonSerializationResult::ResultCode ContinueStoringToJsonObjectField( + rapidjson::Value& output, rapidjson::Value::StringRefType newMemberName, const void* object, const void* defaultObject, + const Uuid& typeId, JsonSerializerContext& context, ContinuationFlags flags = ContinuationFlags::None); //! Checks if a value is an explicit default. This useful for containers where not storing anything as a default would mean //! a slot wouldn't be used so something has to be added to represent the fully default target. @@ -238,6 +251,7 @@ namespace AZ rapidjson::Value GetExplicitDefault(); }; - AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::Flags) + AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::ContinuationFlags) + AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::BaseJsonSerializer::OperationFlags) } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp index c15cb9ef54..400a3b7949 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp @@ -75,9 +75,10 @@ namespace AZ auto elementCallback = [this, &array, &retVal, &index, &context] (void* elementPtr, const Uuid& elementId, const SerializeContext::ClassData*, const SerializeContext::ClassElement* classElement) { - Flags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; - flags |= Flags::ReplaceDefault; + ContinuationFlags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; + flags |= ContinuationFlags::ReplaceDefault; ScopedContextPath subPath(context, index); index++; @@ -161,8 +162,9 @@ namespace AZ container->EnumTypes(typeEnumCallback); AZ_Assert(classElement, "No class element found for the type in the basic container."); - Flags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; + ContinuationFlags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; const size_t capacity = container->IsFixedCapacity() ? container->Capacity(outputValue) : std::numeric_limits::max(); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 8d0da9e54a..9c4641741e 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -10,6 +10,7 @@ * */ +#include "AzCore/RTTI/TypeInfo.h" #include #include #include @@ -22,6 +23,19 @@ namespace AZ { + JsonSerializationResult::ResultCode JsonDeserializer::DeserializerDefaultCheck(BaseJsonSerializer* serializer, void* object, + const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context) + { + using namespace AZ::JsonSerializationResult; + + bool isExplicitDefault = IsExplicitDefault(value); + bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) == + BaseJsonSerializer::OperationFlags::ManualDefault; + return !isExplicitDefault || (isExplicitDefault && manuallyDefaults) + ? 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) { @@ -33,17 +47,12 @@ namespace AZ "Target object for Json Serialization is pointing to nothing during loading."); } - if (IsExplicitDefault(value)) - { - return context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); - } - BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); if (serializer) { - return serializer->Load(object, typeId, value, context); + return DeserializerDefaultCheck(serializer, object, typeId, value, context); } - + const SerializeContext::ClassData* classData = context.GetSerializeContext()->FindClassData(typeId); if (!classData) { @@ -53,32 +62,41 @@ namespace AZ if (classData->m_azRtti && classData->m_azRtti->GetGenericTypeId() != typeId) { + if (((classData->m_azRtti->GetTypeTraits() & (AZ::TypeTraits::is_signed | AZ::TypeTraits::is_unsigned)) != AZ::TypeTraits{0}) && + context.GetSerializeContext()->GetUnderlyingTypeId(typeId) == classData->m_typeId) + { + // This value is from an enum, where a field has been reflected using ClassBuilder::Field, but the enum + // type itself has not been reflected using EnumBuilder. Treat it as an enum. + return LoadEnum(object, *classData, value, context); + } serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId()); if (serializer) { - return serializer->Load(object, typeId, value, context); + return DeserializerDefaultCheck(serializer, object, typeId, value, context); } } + + if (IsExplicitDefault(value)) + { + return context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default."); + } if (classData->m_azRtti && (classData->m_azRtti->GetTypeTraits() & AZ::TypeTraits::is_enum) == AZ::TypeTraits::is_enum) { return LoadEnum(object, *classData, value, context); } - else if (classData->m_container) + if (classData->m_container) { return context.Report(Tasks::ReadField, Outcomes::Unsupported, "The Json Serializer uses custom serializers to load containers. If this message is encountered " "then a serializer for the target containers is missing, isn't registered or doesn't exist."); } - else if (value.IsObject()) + if (value.IsObject()) { return LoadClass(object, *classData, value, context); } - else - { - return context.Report(Tasks::ReadField, Outcomes::Unsupported, - AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name)); - } + return context.Report(Tasks::ReadField, Outcomes::Unsupported, + AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name)); } JsonSerializationResult::ResultCode JsonDeserializer::LoadToPointer(void* object, const Uuid& typeId, @@ -220,8 +238,16 @@ namespace AZ AZ::TypeId underlyingTypeId = AZ::TypeId::CreateNull(); if (!attributeReader.Read(underlyingTypeId)) { - return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, - "Unable to find underlying type of enum in class data."); + // for non-reflected enums, the passed-in classData already represents the enum's underlying type + if (context.GetSerializeContext()->GetUnderlyingTypeId(classData.m_typeId) == classData.m_typeId) + { + underlyingTypeId = classData.m_typeId; + } + else + { + return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, + "Unable to find underlying type of enum in class data."); + } } const SerializeContext::ClassData* underlyingClassData = context.GetSerializeContext()->FindClassData(underlyingTypeId); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h index 89e527b9ae..5954082ee0 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h @@ -113,5 +113,13 @@ namespace AZ //! Checks if a value is an explicit default. This means the value is an object with no members. static bool IsExplicitDefault(const rapidjson::Value& value); + + private: + static JsonSerializationResult::ResultCode DeserializerDefaultCheck( + BaseJsonSerializer* serializer, + void* object, + const Uuid& typeId, + const rapidjson::Value& value, + JsonDeserializerContext& context); }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp index e359888da7..de9aa70362 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.cpp @@ -11,13 +11,17 @@ */ #include +#include #include #include #include +#include #include namespace AZ { + using ReporterString = AZStd::fixed_string<1024>; + JsonSerializationResult::ResultCode JsonMerger::ApplyPatch(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonApplyPatchSettings& settings) @@ -105,8 +109,7 @@ namespace AZ } else { - AZ::OSString message = AZ::OSString::format(R"(Unknown operation "%.*s".)", - aznumeric_cast(operationName.length()), operationName.data()); + auto message = ReporterString::format(R"(Unknown operation "%.*s".)", AZ_STRING_ARG(operationName)); return settings.m_reporting(message.c_str(), ResultCode(Tasks::Merge, Outcomes::Unknown), element); } @@ -131,6 +134,14 @@ namespace AZ JsonSerializationResult::ResultCode JsonMerger::ApplyMergePatch(rapidjson::Value& target, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonApplyPatchSettings& settings) + { + StackedString element(StackedString::Format::JsonPointer); + return ApplyMergePatchInternal(target, allocator, patch, settings, element); + } + + JsonSerializationResult::ResultCode JsonMerger::ApplyMergePatchInternal(rapidjson::Value& target, + rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, + JsonApplyPatchSettings& settings, StackedString& element) { using namespace JsonSerializationResult; @@ -150,14 +161,18 @@ namespace AZ { if (targetField != target.MemberEnd()) { - result.Combine(ApplyMergePatch(targetField->value, allocator, field.value, settings)); + ScopedStackedString fieldNameScope{ element, + AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + result.Combine(ApplyMergePatchInternal(targetField->value, allocator, field.value, settings, element)); } else { rapidjson::Value name; name.CopyFrom(field.name, allocator, true); rapidjson::Value value; - result.Combine(ApplyMergePatch(value, allocator, field.value, settings)); + ScopedStackedString fieldNameScope{ element, + AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + result.Combine(ApplyMergePatchInternal(value, allocator, field.value, settings, element)); target.AddMember(AZStd::move(name), AZStd::move(value), allocator); } } @@ -165,7 +180,14 @@ namespace AZ { if (targetField != target.MemberEnd()) { + ScopedStackedString fieldNameScope{ element, + AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + AZStd::string_view jsonPath = element.Get(); + target.RemoveMember(targetField); + result.Combine(settings.m_reporting(ReporterString::format( + R"(Successfully removed member from "%.*s" using JSON Merge Patch)", AZ_STRING_ARG(jsonPath)), + ResultCode(Tasks::Merge, Outcomes::Success), element)); } } else @@ -173,6 +195,12 @@ namespace AZ if (targetField != target.MemberEnd()) { targetField->value.CopyFrom(field.value, allocator, true); + + ScopedStackedString fieldNameScope{ element, AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + AZStd::string_view jsonPath = element.Get(); + result.Combine(settings.m_reporting(ReporterString::format( + R"(Successfully updated JSON field "%.*s" using JSON Merge Patch)", AZ_STRING_ARG(jsonPath)), + ResultCode(Tasks::Merge, Outcomes::Success), element)); } else { @@ -181,6 +209,12 @@ namespace AZ name.CopyFrom(field.name, allocator, true); value.CopyFrom(field.value, allocator, true); target.AddMember(AZStd::move(name), AZStd::move(value), allocator); + + ScopedStackedString fieldNameScope{ element, AZStd::string_view(field.name.GetString(), field.name.GetStringLength()) }; + AZStd::string_view jsonPath = element.Get(); + result.Combine(settings.m_reporting(ReporterString::format( + R"(Successfully added JSON field "%.*s" using JSON Merge Patch)", AZ_STRING_ARG(jsonPath)), + ResultCode(Tasks::Merge, Outcomes::Success), element)); } } } @@ -190,7 +224,7 @@ namespace AZ target.CopyFrom(patch, allocator, true); } result.Combine(settings.m_reporting("Successfully applied patch to target using JSON Merge Patch.", - ResultCode(Tasks::Merge, Outcomes::Success), StackedString(StackedString::Format::JsonPointer))); + ResultCode(Tasks::Merge, Outcomes::Success), element)); return result; } @@ -268,9 +302,11 @@ namespace AZ const rapidjson::Pointer::Token* const tokens = path.GetTokens(); if (path.GetTokenCount() == 0) { + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); target = AZStd::move(newValue); return settings.m_reporting(R"(Successfully applied "add" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } rapidjson::Pointer parent = rapidjson::Pointer(tokens, path.GetTokenCount() - 1); @@ -342,8 +378,10 @@ namespace AZ ResultCode(Tasks::Merge, Outcomes::TypeMismatch), element); } + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); return settings.m_reporting(R"(Successfully applied "add" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Remove(rapidjson::Value& target, const rapidjson::Pointer& path, @@ -393,8 +431,10 @@ namespace AZ ResultCode(Tasks::Merge, Outcomes::TypeMismatch), element); } + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); return settings.m_reporting(R"(Successfully applied "remove" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Replace(rapidjson::Value& target, @@ -420,8 +460,10 @@ namespace AZ memberValue->CopyFrom(value->value, allocator); + rapidjson::StringBuffer pointerPathString; + path.Stringify(pointerPathString); return settings.m_reporting(R"(Successfully applied "replace" operation.)", - ResultCode(Tasks::Merge, Outcomes::Success), element); + ResultCode(Tasks::Merge, Outcomes::Success), pointerPathString.GetString()); } JsonSerializationResult::ResultCode JsonMerger::ApplyPatch_Move(rapidjson::Value& target, diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h index a33bac117b..127897c6ff 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonMerger.h @@ -42,6 +42,11 @@ namespace AZ rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, JsonApplyPatchSettings& settings); + //! Implementation of the JSON Merge Patch algorithm: https://tools.ietf.org/html/rfc7386 + static JsonSerializationResult::ResultCode ApplyMergePatchInternal(rapidjson::Value& target, + rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& patch, + JsonApplyPatchSettings& settings, StackedString& element); + //! Function to create JSON Merge Patches: https://tools.ietf.org/html/rfc7386 static JsonSerializationResult::ResultCode CreateMergePatch(rapidjson::Value& patch, rapidjson::Document::AllocatorType& allocator, const rapidjson::Value& source, diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp index fa244d3dae..437a648e1e 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp @@ -215,10 +215,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."); - Flags keyLoadFlags = Flags::None; + ContinuationFlags keyLoadFlags = ContinuationFlags::None; if (keyElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - keyLoadFlags = Flags::ResolvePointer; + keyLoadFlags = ContinuationFlags::ResolvePointer; *reinterpret_cast(keyAddress) = nullptr; } JSR::ResultCode keyResult = ContinueLoading(keyAddress, keyElement->m_typeId, key, context, keyLoadFlags); @@ -231,10 +231,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."); - Flags valueLoadFlags = Flags::None; + ContinuationFlags valueLoadFlags = ContinuationFlags::None; if (valueElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER) { - valueLoadFlags = Flags::ResolvePointer; + valueLoadFlags = ContinuationFlags::ResolvePointer; *reinterpret_cast(valueAddress) = nullptr; } JSR::ResultCode valueResult = ContinueLoading(valueAddress, valueElement->m_typeId, value, context, valueLoadFlags); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp index 9e707f8644..0ab32ac08d 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.cpp @@ -82,7 +82,7 @@ namespace AZ { // If the target type is the same as the type already stored in the smart pointer than no new // instance is created and the existing instance will be updated with the data in the json document. - result = ContinueLoading(instance, elementClassId, inputValue, context, Flags::ResolvePointer); + result = ContinueLoading(instance, elementClassId, inputValue, context, ContinuationFlags::ResolvePointer); return false; } } @@ -93,7 +93,7 @@ namespace AZ // the wrong address. In these cases explicitly reset the smart pointer. This will erase the existing // data but that's fine as it's not being used. void* element = nullptr; - result = ContinueLoading(&element, elementClassId, inputValue, context, Flags::ResolvePointer); + result = ContinueLoading(&element, elementClassId, inputValue, context, ContinuationFlags::ResolvePointer); if (result.GetProcessing() != JSR::Processing::Halted && result.GetProcessing() != JSR::Processing::Altered) { void* elementPtr = container->ReserveElement(instance, nullptr); @@ -155,8 +155,14 @@ namespace AZ container->EnumElements(const_cast(defaultValue), defaultInputCallback); } - JSR::ResultCode result = ContinueStoring(outputValue, inputValue, defaultValue, inputPtrType, context, Flags::ResolvePointer); + JSR::ResultCode result = + ContinueStoring(outputValue, inputValue, defaultValue, inputPtrType, context, ContinuationFlags::ResolvePointer); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "Successfully processed smart pointer." : "A problem occurred while processing a smart pointer."); } + + BaseJsonSerializer::OperationFlags JsonSmartPointerSerializer::GetOperationsFlags() const + { + return OperationFlags::ManualDefault; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h index 8c550cb824..9a0cf61be9 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/SmartPointerSerializer.h @@ -28,5 +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; }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp index 9ea22592bc..5b43cec817 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp @@ -99,8 +99,9 @@ namespace AZ ScopedContextPath subPath(context, i); - Flags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; + ContinuationFlags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; JSR::ResultCode result = ContinueStoring(elementValues[i], elementAddress, defaultElementAddress, classElements[i]->m_typeId, context, flags); @@ -179,8 +180,9 @@ namespace AZ void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i); AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i); - Flags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? - Flags::ResolvePointer : Flags::None; + ContinuationFlags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER + ? ContinuationFlags::ResolvePointer + : ContinuationFlags::None; while (arrayIndex < inputValue.Size()) { diff --git a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h index e5bc76cd19..6806232337 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h +++ b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h @@ -14,8 +14,6 @@ #include -#include - #include #include diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp index 609eb03a2c..f6b804494e 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.cpp @@ -88,4 +88,28 @@ namespace AZ { return index < m_names.size() ? m_names[index] : AZStd::string_view(); } + + SettingsRegistryInterface::CommandLineArgumentSettings::CommandLineArgumentSettings() + { + m_delimiterFunc = [](AZStd::string_view line) -> JsonPathValue + { + constexpr AZStd::string_view CommandLineArgumentDelimiters{ "=:" }; + JsonPathValue pathValue; + pathValue.m_value = line; + + // Splits the line on the first delimiter and stores that in the pathValue.m_path variable + // The StringFunc::TokenizeNext function updates the pathValue.m_value parameter in place + // to contain all the text after the first delimiter + // So if pathValue.m_value="foo = Hello Ice Cream=World:17", the call to TokenizeNext would + // split the value as follows + // pathValue.m_path = "foo" + // pathValue.m_value = "Hello Ice Cream=World:17" + if (auto path = AZ::StringFunc::TokenizeNext(pathValue.m_value, CommandLineArgumentDelimiters); path.has_value()) + { + pathValue.m_path = AZ::StringFunc::StripEnds(*path); + } + pathValue.m_value = AZ::StringFunc::StripEnds(pathValue.m_value); + return pathValue; + }; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h index 768841cc09..2d9b0d83e5 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistry.h @@ -26,6 +26,7 @@ namespace AZ { + struct JsonApplyPatchSettings; //! The Settings Registry is the central storage for global settings. Having application-wide settings //! stored in a central location allows different tools such as command lines, consoles, configuration //! files, etc. to work in a universal way. @@ -260,21 +261,20 @@ namespace AZ virtual bool Remove(AZStd::string_view path) = 0; //! Structure which contains configuration settings for how to parse a single command line argument - //! It supports supplying a functor for determining if a character is a delimiter + //! It supports supplying a functor for splitting a line into JSON path and JSON value struct CommandLineArgumentSettings { - inline static constexpr AZStd::string_view CommandLineArgumentDelimiters{ "=:"}; - CommandLineArgumentSettings() + struct JsonPathValue { - m_delimiterFunc = [](const char delimiter) -> bool - { - return CommandLineArgumentDelimiters.find_first_of(delimiter) != AZStd::string_view::npos; - }; - } - - //! Callback function which is invoked to determine whether a delimiter has been found - //! return value of true indicates that a delimiter has been found - using DelimiterFunc = AZStd::function; + AZStd::string_view m_path; + AZStd::string_view m_value; + }; + + CommandLineArgumentSettings(); + + //! Callback function which is invoked to determine how to split a command line argument + //! into a JSON path and a JSON value + using DelimiterFunc = AZStd::function; DelimiterFunc m_delimiterFunc; }; //! Merges a single command line argument into the settings registry. Command line arguments @@ -322,6 +322,14 @@ namespace AZ //! @return True if the registry folder was successfully merged, otherwise false. virtual bool MergeSettingsFolder(AZStd::string_view path, const Specializations& specializations, AZStd::string_view platform = {}, AZStd::string_view rootKey = "", AZStd::vector* scratchBuffer = nullptr) = 0; + + //! Stores the settings structure which is used when merging settings to the Settings Registry + //! using JSON Merge Patch or JSON Merge Patch. + //! The settings contain an issue reporting callback which can be used to track patching process. + //! Potential application of the reporting callback could be to update a UI whenever a key receives an updated value + //! @param applyPatchSettings The ApplyPatchSettings which are using during JSON Merging + virtual void SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) = 0; + virtual void GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) = 0; }; inline SettingsRegistryInterface::Visitor::~Visitor() = default; diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp index 9ea76817af..3dd4931374 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp @@ -11,8 +11,10 @@ */ #include +#include #include #include +#include #include #include #include @@ -419,9 +421,6 @@ namespace AZ bool SettingsRegistryImpl::MergeCommandLineArgument(AZStd::string_view argument, AZStd::string_view rootKey, const CommandLineArgumentSettings& commandLineSettings) { - const char* front = argument.begin(); - const char* back = argument.end(); - if (!commandLineSettings.m_delimiterFunc) { AZ_Error("SettingsRegistry", false, @@ -429,87 +428,40 @@ namespace AZ aznumeric_cast(argument.size()), argument.data()); return false; } - const char* split = AZStd::find_if(front, back, commandLineSettings.m_delimiterFunc); - if (split == front || // There is no key - split == (back-1) || // There is no value - split == back) // Split character not found. + + auto [key, value] = commandLineSettings.m_delimiterFunc(argument); + if (key.empty()) { + // They key where to set the JSON value cannot be empty + // The value of the JSON can be though + // This is so that a key can be set to empty string using "/KeyPath=" return false; } - const char* keyStart = front; - while (std::isspace(*keyStart)) // This is safe because it will eventually stop on = + // Prepend the rootKey as an anchor to the argument key + SettingsRegistryInterface::FixedValueString keyPath{ rootKey.ends_with('/') + ? rootKey.substr(0, rootKey.size() - 1) + : rootKey }; + // Append the JSON reference token prefix of '/' to the keyPath + if (!key.starts_with('/')) { - keyStart++; + keyPath.push_back('/'); } - if (keyStart == split) // Key is just white spaces + if ((key.size() + keyPath.size()) > keyPath.max_size()) { + // The key portion is longer than the FixedValueString max size that can be stored + // This limitation is arbitrary, if an AZStd::string is used or if the C++17 std::to_chars + // function is used, there wouldn't need to be a limitation return false; } - const char* keyEnd = split; - while (std::isspace(*--keyEnd)); - keyEnd++; + keyPath += key; + key = keyPath; - char buffer[MaxJsonPathLength]; - AZStd::string_view key; - bool keyHasDivider = *keyStart == '/'; - if (!rootKey.empty()) + if (value.empty()) { - bool rootKeyHasDivider = (rootKey[rootKey.length() - 1]) == '/'; - size_t count; - if (!rootKeyHasDivider && !keyHasDivider) - { - count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "%.*s/%.*s", - aznumeric_cast(rootKey.length()), rootKey.data(), - aznumeric_cast(keyEnd - keyStart), keyStart); - } - else if (rootKeyHasDivider && keyHasDivider) - { - count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "%.*s%.*s", - aznumeric_cast(rootKey.length()) - 1, rootKey.data(), - aznumeric_cast(keyEnd - keyStart), keyStart); - } - else - { - count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "%.*s%.*s", - aznumeric_cast(rootKey.length()), rootKey.data(), - aznumeric_cast(keyEnd - keyStart), keyStart); - } - if (count >= AZ_ARRAY_SIZE(buffer) - 1) - { - return false; - } - key = AZStd::string_view(buffer, count); - } - else if (!keyHasDivider) - { - size_t count = azsnprintf(buffer, AZ_ARRAY_SIZE(buffer), "/%.*s", - aznumeric_cast(keyEnd - keyStart), keyStart); - if (count >= AZ_ARRAY_SIZE(buffer) - 1) - { - return false; - } - key = AZStd::string_view(buffer, count); - } - else - { - key = AZStd::string_view(keyStart, keyEnd); + return Set(key, value); } - const char* valueStart = split + 1; - while (std::isspace(*valueStart) && valueStart < back) - { - valueStart++; - } - if (valueStart == back) - { - return false; // The value is empty - } - const char* valueEnd = back; - while (std::isspace(*(--valueEnd))); - valueEnd++; - - AZStd::string_view value(valueStart, valueEnd); if (value == "true") { return Set(key, true); @@ -519,23 +471,35 @@ namespace AZ return Set(key, false); } - if (value.length() - 1 >= MaxCommandLineArgumentLength) + SettingsRegistryInterface::FixedValueString valueString; + if (value.size() > valueString.max_size()) { + // The value portion is longer than the FixedValueString max size that can be stored + // This limitation is arbitrary, if an AZStd::string is used or if the C++17 std::to_chars + // function is used, there wouldn't need to be a limitation return false; } - char argumentString[MaxCommandLineArgumentLength]; - snprintf(argumentString, AZ_ARRAY_SIZE(argument), "%.*s", aznumeric_cast(value.length()), value.data()); - char* argumentStringEnd = argumentString + value.length(); + valueString = value; + const char* valueStringEnd = valueString.c_str() + valueString.size(); + errno = 0; char* convertEnd = nullptr; - s64 intValue = strtoll(argumentString, &convertEnd, 0); - if (convertEnd == argumentStringEnd) + s64 intValue = strtoll(valueString.c_str(), &convertEnd, 0); + if (errno != ERANGE && convertEnd == valueStringEnd) { return Set(key, intValue); } + errno = 0; convertEnd = nullptr; - double floatingPointValue = strtod(argumentString, &convertEnd); - if (convertEnd == argumentStringEnd) + u64 uintValue = strtoull(valueString.c_str(), &convertEnd, 0); + if (errno != ERANGE && convertEnd == valueStringEnd) + { + return Set(key, uintValue); + } + errno = 0; + convertEnd = nullptr; + double floatingPointValue = strtod(valueString.c_str(), &convertEnd); + if (errno != ERANGE && convertEnd == valueStringEnd) { return Set(key, floatingPointValue); } @@ -611,7 +575,7 @@ namespace AZ } else { - if (MaxFilePathLength < path.length() + 1) + if (AZ::IO::MaxPathLength < path.length() + 1) { AZ_Error("Settings Registry", false, R"(Path "%.*s" is too long. Either make sure that the provided path is terminated or use a shorter path.)", @@ -623,10 +587,8 @@ namespace AZ .AddMember(StringRef("Path"), AZStd::move(pathValue), m_settings.GetAllocator()); return false; } - char filePath[MaxFilePathLength]; - azstrncpy(filePath, AZ_ARRAY_SIZE(filePath), path.data(), path.length()); - filePath[path.length()] = 0; - result = MergeSettingsFileInternal(filePath, format, rootKey, *scratchBuffer); + AZ::IO::FixedMaxPathString filePath(path); + result = MergeSettingsFileInternal(filePath.c_str(), format, rootKey, *scratchBuffer); } scratchBuffer->clear(); @@ -660,7 +622,7 @@ namespace AZ additionalSpaceRequired += AZ_ARRAY_SIZE(PlatformFolder) + platform.length() + 2; // +2 for the two slashes. } - if (path.length() + additionalSpaceRequired > MaxFilePathLength) + if (path.length() + additionalSpaceRequired > AZ::IO::MaxPathLength) { AZ_Error("Settings Registry", false, "Folder path for the Setting Registry is too long: %.*s", static_cast(path.size()), path.data()); @@ -673,7 +635,7 @@ namespace AZ RegistryFileList fileList; scratchBuffer->clear(); - AZStd::fixed_string folderPath{ path }; + AZ::IO::FixedMaxPathString folderPath{ path }; constexpr AZStd::string_view pathSeparators{ AZ_CORRECT_AND_WRONG_DATABASE_SEPARATOR }; if (pathSeparators.find_first_of(folderPath.back()) == AZStd::string_view::npos) { @@ -919,6 +881,13 @@ namespace AZ const Specializations& specializations, const rapidjson::Pointer& historyPointer, AZStd::string_view folderPath) { using namespace rapidjson; + + if (&lhs == &rhs) + { + // Early return to avoid setting the collisionFound reference to true + // std::sort is allowed to pass in the same memory address for the left and right elements + return false; + } AZ_Assert(!lhs.m_tags.empty(), "Comparing a settings file without at least a name tag."); AZ_Assert(!rhs.m_tags.empty(), "Comparing a settings file without at least a name tag."); @@ -926,7 +895,7 @@ namespace AZ // Sort by the name first so the registry file gets applied with all its specializations. if (lhs.m_tags[0] != rhs.m_tags[0]) { - return strcmp(lhs.m_relativePath, rhs.m_relativePath) < 0; + return lhs.m_relativePath < rhs.m_relativePath; } // Then sort by size first so the files with the fewest specializations get applied first. @@ -956,14 +925,14 @@ namespace AZ } collisionFound = true; - AZ_Error("Settings Registry", false, R"(Two registry files point to the same specialization: "%s" and "%s")", - lhs.m_relativePath, rhs.m_relativePath); + AZ_Error("Settings Registry", false, R"(Two registry files in "%.*s" point to the same specialization: "%s" and "%s")", + AZ_STRING_ARG(folderPath), lhs.m_relativePath.c_str(), rhs.m_relativePath.c_str()); historyPointer.Create(m_settings, m_settings.GetAllocator()).SetObject() .AddMember(StringRef("Error"), StringRef("Too many files in registry folder."), m_settings.GetAllocator()) .AddMember(StringRef("Path"), Value(folderPath.data(), aznumeric_caster(folderPath.length()), m_settings.GetAllocator()), m_settings.GetAllocator()) - .AddMember(StringRef("File1"), Value(lhs.m_relativePath, m_settings.GetAllocator()), m_settings.GetAllocator()) - .AddMember(StringRef("File2"), Value(rhs.m_relativePath, m_settings.GetAllocator()), m_settings.GetAllocator()); + .AddMember(StringRef("File1"), Value(lhs.m_relativePath.c_str(), m_settings.GetAllocator()), m_settings.GetAllocator()) + .AddMember(StringRef("File2"), Value(rhs.m_relativePath.c_str(), m_settings.GetAllocator()), m_settings.GetAllocator()); return false; } @@ -1036,9 +1005,9 @@ namespace AZ // thats the name tag. AZStd::sort(AZStd::next(output.m_tags.begin()), output.m_tags.end()); - if (filePathSize < AZ_ARRAY_SIZE(output.m_relativePath)) + if (filePathSize < output.m_relativePath.max_size()) { - azstrcpy(output.m_relativePath, AZ_ARRAY_SIZE(output.m_relativePath), filename); + output.m_relativePath = filename; return true; } else @@ -1093,15 +1062,23 @@ namespace AZ jsonPatch.ParseInsitu(scratchBuffer.data()); if (jsonPatch.HasParseError()) { + auto nativeUI = AZ::Interface::Get(); if (jsonPatch.GetParseError() == rapidjson::kParseErrorDocumentEmpty) { - AZ_Warning("Settings Registry", false, R"(Unable to parse registry file "%s" due to json error "%s" at offset %llu.)", + AZ_Warning("Settings Registry", false, R"(Unable to parse registry file "%s" due to json error "%s" at offset %zu.)", path, GetParseError_En(jsonPatch.GetParseError()), jsonPatch.GetErrorOffset()); } else { - AZ_Error("Settings Registry", false, R"(Unable to parse registry file "%s" due to json error "%s" at offset %llu.)", path, + using ErrorString = AZStd::fixed_string<4096>; + auto jsonError = ErrorString::format(R"(Unable to parse registry file "%s" due to json error "%s" at offset %zu.)", path, GetParseError_En(jsonPatch.GetParseError()), jsonPatch.GetErrorOffset()); + AZ_Error("Settings Registry", false, "%s", jsonError.c_str()); + + if (nativeUI) + { + nativeUI->DisplayOkDialog("Setreg(Patch) Merge Issue", AZStd::string_view(jsonError), false); + } } pointer.Create(m_settings, m_settings.GetAllocator()).SetObject() @@ -1145,7 +1122,7 @@ namespace AZ JsonSerializationResult::ResultCode mergeResult(JsonSerializationResult::Tasks::Merge); if (rootKey.empty()) { - mergeResult = JsonSerialization::ApplyPatch(m_settings, m_settings.GetAllocator(), jsonPatch, mergeApproach); + mergeResult = JsonSerialization::ApplyPatch(m_settings, m_settings.GetAllocator(), jsonPatch, mergeApproach, m_applyPatchSettings); } else { @@ -1153,7 +1130,7 @@ namespace AZ if (root.IsValid()) { Value& rootValue = root.Create(m_settings, m_settings.GetAllocator()); - mergeResult = JsonSerialization::ApplyPatch(rootValue, m_settings.GetAllocator(), jsonPatch, mergeApproach); + mergeResult = JsonSerialization::ApplyPatch(rootValue, m_settings.GetAllocator(), jsonPatch, mergeApproach, m_applyPatchSettings); } else { @@ -1180,4 +1157,13 @@ namespace AZ return true; } + + void SettingsRegistryImpl::SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) + { + m_applyPatchSettings = applyPatchSettings; + } + void SettingsRegistryImpl::GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) + { + applyPatchSettings = m_applyPatchSettings; + } } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h index 0cd5da131a..a80c12534b 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -35,9 +36,6 @@ namespace AZ AZ_CLASS_ALLOCATOR(SettingsRegistryImpl, AZ::OSAllocator, 0); AZ_RTTI(AZ::SettingsRegistryImpl, "{E9C34190-F888-48CA-83C9-9F24B4E21D72}", AZ::SettingsRegistryInterface); - static constexpr size_t MaxFilePathLength = AZ_MAX_PATH_LEN; - static constexpr size_t MaxJsonPathLength = 1024; - static constexpr size_t MaxCommandLineArgumentLength = 1024; static constexpr size_t MaxRegistryFolderEntries = 128; SettingsRegistryImpl(); @@ -80,11 +78,14 @@ namespace AZ bool MergeSettingsFolder(AZStd::string_view path, const Specializations& specializations, AZStd::string_view platform, AZStd::string_view rootKey = "", AZStd::vector* scratchBuffer = nullptr) override; + void SetApplyPatchSettings(const AZ::JsonApplyPatchSettings& applyPatchSettings) override; + void GetApplyPatchSettings(AZ::JsonApplyPatchSettings& applyPatchSettings) override; + private: using TagList = AZStd::fixed_vector; struct RegistryFile { - char m_relativePath[MaxFilePathLength]{ 0 }; + AZ::IO::FixedMaxPathString m_relativePath; TagList m_tags; bool m_isPatch{ false }; bool m_isPlatformFile{ false }; @@ -109,5 +110,6 @@ namespace AZ rapidjson::Document m_settings; JsonSerializerSettings m_serializationSettings; JsonDeserializerSettings m_deserializationSettings; + JsonApplyPatchSettings m_applyPatchSettings; }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index 56dfbdcb71..2abef3f808 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -88,6 +88,35 @@ namespace AZ::Internal m_enginePaths.emplace_back(EngineInfo{AZ::IO::FixedMaxPath{value}.LexicallyNormal(), {}}); } + AZ::SettingsRegistryInterface::VisitResponse Traverse( + [[maybe_unused]] AZStd::string_view path, AZStd::string_view valueName, + AZ::SettingsRegistryInterface::VisitAction action, AZ::SettingsRegistryInterface::Type type) override + { + auto response = AZ::SettingsRegistryInterface::VisitResponse::Continue; + if (action == AZ::SettingsRegistryInterface::VisitAction::Begin) + { + if (type == AZ::SettingsRegistryInterface::Type::Array) + { + if (valueName.compare("engines") != 0) + { + response = AZ::SettingsRegistryInterface::VisitResponse::Skip; + } + } + } + else if (action == AZ::SettingsRegistryInterface::VisitAction::Value) + { + if (type == AZ::SettingsRegistryInterface::Type::String) + { + if (valueName.compare("path") != 0) + { + response = AZ::SettingsRegistryInterface::VisitResponse::Skip; + } + } + } + + return response; + } + AZStd::vector m_enginePaths{}; }; @@ -340,46 +369,6 @@ namespace AZ::SettingsRegistryMergeUtils return sectionName; } - // Encodes a key, value delimited line such that the entire "key" can be stored as a single - // JSON Pointer key by escaping the tilde(~) and forward slash(/) - template - static AZStd::fixed_string EncodeLineForJsonPointer(AZStd::string_view token, - const AZ::SettingsRegistryInterface::CommandLineArgumentSettings::DelimiterFunc& delimiterFunc) - { - if (!delimiterFunc) - { - // Since the delimiter function is not valid, return the token unchanged - return AZStd::fixed_string{ token }; - } - // Iterate over the line and escape the '~' and '/' values - AZStd::fixed_string encodedToken; - size_t chIndex = 0; - for (; chIndex < token.size(); ++chIndex) - { - const char ch = token[chIndex]; - if (delimiterFunc(ch)) - { - // If the delimiter is found, this indicates that the end of the key has been found - break; - } - switch (ch) - { - case '~': - encodedToken += "~0"; - break; - case '/': - encodedToken += "~1"; - break; - default: - encodedToken += ch; - } - } - - // Copy over the rest of the post delimited line to the encoded token - encodedToken.append(token.data() + chIndex, token.data() + token.size()); - return encodedToken; - } - void QuerySpecializationsFromRegistry(SettingsRegistryInterface& registry, SettingsRegistryInterface::Specializations& specializations) { // Append any specializations stored in the registry @@ -499,14 +488,7 @@ namespace AZ::SettingsRegistryMergeUtils } } - // Check if the "key" portion of the line has '~' or '/' as the SettingsRegistry uses JSON Pointer - // to set the "value" portion. Those characters need to be escaped with ~0 and ~1 respectively - // to allow them to be embedded in a single json key - // Iterate over the line and escape the '~' and '/' values - AZStd::fixed_string escapedLine = EncodeLineForJsonPointer(line, - configParserSettings.m_commandLineSettings.m_delimiterFunc); - - registry.MergeCommandLineArgument(escapedLine, currentJsonPointerPath, configParserSettings.m_commandLineSettings); + registry.MergeCommandLineArgument(line, currentJsonPointerPath, configParserSettings.m_commandLineSettings); // Skip past the newline character if found frontIter = lineEndIter + (foundNewLine ? 1 : 0); @@ -541,13 +523,6 @@ namespace AZ::SettingsRegistryMergeUtils return configFileParsed; } - void MergeSettingsToRegistry_Bootstrap(SettingsRegistryInterface& registry) - { - ConfigParserSettings parserSettings; - parserSettings.m_registryRootPointerPath = BootstrapSettingsRootKey; - MergeSettingsToRegistry_ConfigFile(registry, "bootstrap.cfg", parserSettings); - } - void MergeSettingsToRegistry_AddRuntimeFilePaths(SettingsRegistryInterface& registry) { using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; @@ -599,6 +574,34 @@ namespace AZ::SettingsRegistryMergeUtils ? devWriteStorage.value() : projectUserPath.Native()); + // Set the project in-memory build path if the ProjectBuildPath key has been supplied + if (AZ::IO::FixedMaxPath projectBuildPath; registry.Get(projectBuildPath.Native(), ProjectBuildPath)) + { + registry.Remove(FilePathKey_ProjectBuildPath); + registry.Remove(FilePathKey_ProjectConfigurationBinPath); + AZ::IO::FixedMaxPath buildConfigurationPath = normalizedProjectPath / projectBuildPath; + if (IO::SystemFile::Exists(buildConfigurationPath.c_str())) + { + registry.Set(FilePathKey_ProjectBuildPath, buildConfigurationPath.LexicallyNormal().Native()); + } + + // Add the specific build configuration paths to the Settings Registry + // First try /bin/$ and if that path doesn't exist + // try /bin/$/$ + buildConfigurationPath /= "bin"; + if (IO::SystemFile::Exists((buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).c_str())) + { + registry.Set(FilePathKey_ProjectConfigurationBinPath, + (buildConfigurationPath / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native()); + } + else if (IO::SystemFile::Exists((buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).c_str())) + { + registry.Set(FilePathKey_ProjectConfigurationBinPath, + (buildConfigurationPath / AZ_TRAIT_OS_PLATFORM_CODENAME / AZ_BUILD_CONFIGURATION_TYPE).LexicallyNormal().Native()); + } + + } + // Project name - if it was set via merging project.json use that value, otherwise use the project path's folder name. auto projectNameKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) @@ -689,6 +692,14 @@ namespace AZ::SettingsRegistryMergeUtils mergePath /= SettingsRegistryInterface::RegistryFolder; registry.MergeSettingsFolder(mergePath.Native(), specializations, platform, "", scratchBuffer); } + + AZ::IO::FixedMaxPath projectBinPath; + if (registry.Get(projectBinPath.Native(), FilePathKey_ProjectConfigurationBinPath)) + { + // Append the project build path path to the project root + projectBinPath /= SettingsRegistryInterface::RegistryFolder; + registry.MergeSettingsFolder(projectBinPath.Native(), specializations, platform, "", scratchBuffer); + } } void MergeSettingsToRegistry_EngineRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform, @@ -934,7 +945,8 @@ namespace AZ::SettingsRegistryMergeUtils "project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}, OptionKeyToRegsetKey{ "project-cache-path", - AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}}; + AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}, + OptionKeyToRegsetKey{"project-build-path", ProjectBuildPath} }; AZStd::fixed_vector overrideArgs; diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h index 4e00c0e6ec..b482530d24 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h @@ -52,6 +52,14 @@ namespace AZ::SettingsRegistryMergeUtils //! project settings can be stored inline static constexpr char FilePathKey_ProjectUserPath[] = "/Amazon/AzCore/Runtime/FilePaths/SourceProjectUserPath"; + //! User facing key which represents the root of a project cmake build tree. i.e the ${CMAKE_BINARY_DIR} + //! A relative path is taking relative to the *project* root, NOT *engine* root. + inline constexpr AZStd::string_view ProjectBuildPath = "/Amazon/Project/Settings/Build/project_build_path"; + //! In-Memory only key which stores an absolute path to the project build directory + inline constexpr AZStd::string_view FilePathKey_ProjectBuildPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectBuildPath"; + //! In-Memory only key which stores the configuration directory containing the built binaries + inline constexpr AZStd::string_view FilePathKey_ProjectConfigurationBinPath = "/Amazon/AzCore/Runtime/FilePaths/ProjectConfigurationBinPath"; + //! Development write storage path may be considered temporary or cache storage on some platforms inline static constexpr char FilePathKey_DevWriteStorage[] = "/Amazon/AzCore/Runtime/FilePaths/DevWriteStorage"; @@ -128,7 +136,7 @@ namespace AZ::SettingsRegistryMergeUtils //! Callback function that is after a has been filtered through the CommentPrefixFunc //! to determine if the text matches a section header //! returns a view of the section name if the line contains a section - //! Otherwise an empty view is returend + //! Otherwise an empty view is returned using SectionHeaderFunc = AZStd::function; //! Root JSON pointer path to place all key=values pairs of configuration data within @@ -164,9 +172,6 @@ namespace AZ::SettingsRegistryMergeUtils bool MergeSettingsToRegistry_ConfigFile(SettingsRegistryInterface& registry, AZStd::string_view filePath, const ConfigParserSettings& configParserSettings); - //! Loads bootstrap.cfg into the Settings Registry. This file does not support specializations. - void MergeSettingsToRegistry_Bootstrap(SettingsRegistryInterface& registry); - //! Extracts file path information from the environment and bootstrap to calculate the various file paths and adds those //! to the Settings Registry under the FilePathsRootKey. void MergeSettingsToRegistry_AddRuntimeFilePaths(SettingsRegistryInterface& registry); diff --git a/Code/Framework/AzCore/AzCore/Slice/SliceComponent.cpp b/Code/Framework/AzCore/AzCore/Slice/SliceComponent.cpp index 592989ebda..2340d7c786 100644 --- a/Code/Framework/AzCore/AzCore/Slice/SliceComponent.cpp +++ b/Code/Framework/AzCore/AzCore/Slice/SliceComponent.cpp @@ -1740,7 +1740,10 @@ namespace AZ if (!iter->IsInstantiated()) { #if defined(AZ_ENABLE_TRACING) - Data::Asset thisAsset = Data::AssetManager::Instance().FindAsset(GetMyAsset()->GetId(), AZ::Data::AssetLoadBehavior::Default); + Data::Asset thisAsset = GetMyAsset() + ? Data::Asset(Data::AssetManager::Instance().FindAsset( + GetMyAsset()->GetId(), AZ::Data::AssetLoadBehavior::Default)) + : Data::Asset(); AZ_Warning("Slice", false, "Removing %d instances of slice asset %s from parent asset %s due to failed instantiation. " "Saving parent asset will result in loss of slice data.", iter->GetInstances().size(), diff --git a/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h b/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h index e15071f56c..873bb5ad22 100644 --- a/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h +++ b/Code/Framework/AzCore/AzCore/UnitTest/MockComponentApplication.h @@ -33,6 +33,10 @@ namespace UnitTest MOCK_METHOD1(UnregisterComponentDescriptor, void (const AZ::ComponentDescriptor*)); MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&)); MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityActivatedEventHandler, void(AZ::EntityActivatedEvent::Handler&)); + MOCK_METHOD1(RegisterEntityDeactivatedEventHandler, void(AZ::EntityDeactivatedEvent::Handler&)); + MOCK_METHOD1(SignalEntityActivated, void(AZ::Entity*)); + MOCK_METHOD1(SignalEntityDeactivated, void(AZ::Entity*)); MOCK_METHOD1(RemoveEntity, bool (AZ::Entity*)); MOCK_METHOD1(DeleteEntity, bool (const AZ::EntityId&)); MOCK_METHOD1(GetEntityName, AZStd::string (const AZ::EntityId&)); diff --git a/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h b/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h index f4abbd9867..447b38e553 100644 --- a/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h +++ b/Code/Framework/AzCore/AzCore/UnitTest/Mocks/MockSettingsRegistry.h @@ -54,6 +54,9 @@ namespace AZ MOCK_METHOD5( MergeSettingsFolder, bool(AZStd::string_view, const Specializations&, AZStd::string_view, AZStd::string_view, AZStd::vector*)); + + MOCK_METHOD1(SetApplyPatchSettings, void(const JsonApplyPatchSettings&)); + MOCK_METHOD1(GetApplyPatchSettings, void(JsonApplyPatchSettings&)); }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/Utils/Utils.cpp b/Code/Framework/AzCore/AzCore/Utils/Utils.cpp index 71f01cb349..7025b3977e 100644 --- a/Code/Framework/AzCore/AzCore/Utils/Utils.cpp +++ b/Code/Framework/AzCore/AzCore/Utils/Utils.cpp @@ -169,5 +169,10 @@ namespace AZ::Utils template AZ::Outcome, AZStd::string> ReadFile(AZStd::string_view filePath, size_t maxFileSize); template AZ::Outcome, AZStd::string> ReadFile(AZStd::string_view filePath, size_t maxFileSize); - + AZ::IO::FixedMaxPathString GetO3deManifestDirectory() + { + AZ::IO::FixedMaxPath path = GetHomeDirectory(); + path /= ".o3de"; + return path.Native(); + } } diff --git a/Code/Framework/AzCore/AzCore/Utils/Utils.h b/Code/Framework/AzCore/AzCore/Utils/Utils.h index f6152d0e9b..4e64ce5a39 100644 --- a/Code/Framework/AzCore/AzCore/Utils/Utils.h +++ b/Code/Framework/AzCore/AzCore/Utils/Utils.h @@ -88,6 +88,9 @@ namespace AZ //! Retrieves the project name from the settings registry AZ::SettingsRegistryInterface::FixedValueString GetProjectName(); + //! Retrieves the full directory to the Home directory, i.e. " or overrideHomeDirectory" + AZ::IO::FixedMaxPathString GetHomeDirectory(); + //! Retrieves the full directory to the O3DE manifest directory, i.e. "/.o3de" AZ::IO::FixedMaxPathString GetO3deManifestDirectory(); diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index 5357ed66a6..dc0fb13f00 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -290,6 +290,8 @@ set(FILES Math/MathScriptHelpers.h Math/MathUtils.cpp Math/MathUtils.h + Math/MathMatrixSerializer.h + Math/MathMatrixSerializer.cpp Math/MathVectorSerializer.h Math/MathVectorSerializer.cpp Math/Matrix3x3.cpp diff --git a/Code/Framework/AzCore/AzCore/std/azstd_files.cmake b/Code/Framework/AzCore/AzCore/std/azstd_files.cmake index 8de54138ee..ebf26cad68 100644 --- a/Code/Framework/AzCore/AzCore/std/azstd_files.cmake +++ b/Code/Framework/AzCore/AzCore/std/azstd_files.cmake @@ -31,6 +31,7 @@ set(FILES iterator.h limits.h numeric.h + math.h optional.h ratio.h reference_wrapper.h diff --git a/Code/Framework/AzCore/AzCore/std/math.h b/Code/Framework/AzCore/AzCore/std/math.h new file mode 100644 index 0000000000..9e9be7944a --- /dev/null +++ b/Code/Framework/AzCore/AzCore/std/math.h @@ -0,0 +1,31 @@ +/* + * 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. + * + */ + +#pragma once + +#include + +namespace AZStd +{ + using std::abs; + using std::acos; + using std::asin; + using std::atan; + using std::atan2; + using std::cos; + using std::exp2; + using std::fmod; + using std::round; + using std::sin; + using std::sqrt; + using std::tan; +} // namespace AZStd diff --git a/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp b/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp index 169a4db6ff..ec97727148 100644 --- a/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp +++ b/Code/Framework/AzCore/Platform/Android/AzCore/Module/DynamicModuleHandle_Android.cpp @@ -11,14 +11,16 @@ */ #include +#include #include namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { + return {}; } void* OpenModule(const AZ::OSString& fileName, bool&) @@ -26,10 +28,9 @@ namespace AZ // Android 19 does not have RTLD_NOLOAD but it should be OK since only the Editor expects to reopen modules return dlopen(fileName.c_str(), RTLD_NOW); } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp index 8457ff14a6..7dd889e94d 100644 --- a/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp +++ b/Code/Framework/AzCore/Platform/Common/Apple/AzCore/Module/DynamicModuleHandle_Apple.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - path = exePath; - path.push_back('/'); - } + return AZ::Utils::GetExecutableDirectory(); } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,9 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/Common/Unimplemented/AzCore/Utils/Utils_Unimplemented.cpp b/Code/Framework/AzCore/Platform/Common/Unimplemented/AzCore/Utils/Utils_Unimplemented.cpp index 20a9edbe2c..0ea17e938a 100644 --- a/Code/Framework/AzCore/Platform/Common/Unimplemented/AzCore/Utils/Utils_Unimplemented.cpp +++ b/Code/Framework/AzCore/Platform/Common/Unimplemented/AzCore/Utils/Utils_Unimplemented.cpp @@ -14,7 +14,7 @@ namespace AZ::Utils { - AZ::IO::FixedMaxPathString GetO3deManifestDirectory() + AZ::IO::FixedMaxPathString GetHomeDirectory() { return {}; } diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp index 1c16f50203..8e2b40aaca 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Module/DynamicModuleHandle_UnixLike.cpp @@ -11,9 +11,11 @@ */ #include -#include // for AZ_MAX_PATH_LEN +#include +#include #include +#include #include #include @@ -21,9 +23,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path); + AZ::IO::FixedMaxPath GetModulePath(); void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen); - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath); + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath); } class DynamicModuleHandleUnixLike @@ -36,40 +38,55 @@ namespace AZ : DynamicModuleHandle(fullFileName) , m_handle(nullptr) { - AZ::OSString path; - AZ::OSString fileName; - AZ::OSString fullPath = ""; - AZ::OSString::size_type finalSlash = m_fileName.find_last_of("/"); - if (finalSlash != AZ::OSString::npos) + AZ::IO::FixedMaxPath fullFilePath(AZStd::string_view{m_fileName}); + if (fullFilePath.HasFilename()) { - // Path up to and including final slash - path = m_fileName.substr(0, finalSlash + 1); - // Everything after the final slash - // If m_fileName ends in /, the end result is path/lib.dylib, which just fails to load. - fileName = m_fileName.substr(finalSlash + 1); - } - else - { - // If no slash found, assume empty path, only file name - path = ""; - Platform::GetModulePath(path); - fileName = m_fileName; + AZ::IO::FixedMaxPathString fileNamePath{fullFilePath.Filename().Native()}; + if (!fileNamePath.starts_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX)) + { + fileNamePath = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileNamePath; + } + + if (!fileNamePath.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)) + { + fileNamePath += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + } + + fullFilePath.ReplaceFilename(AZStd::string_view(fileNamePath)); } - if (fileName.substr(0, 3) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX) + Platform::ConstructModuleFullFileName(fullFilePath); + + // Check if the module exist at the given path within the current working directory + // If it doesn't attempt to append the path to the executable path + if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str())) { - fileName = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX + fileName; + auto candidatePath = Platform::GetModulePath() / fullFilePath; + if (AZ::IO::SystemFile::Exists(candidatePath.c_str())) + { + fullFilePath = candidatePath; + } } - size_t extensionLen = strlen(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION); - if (fileName.substr(fileName.length() - extensionLen, extensionLen) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION) + // If the path still doesn't exist at this point, check the SettingsRegistryMergeUtils + // FilePathKey_ProjectBuildPath key to see if a project-build-path argument has been supplied + if (!AZ::IO::SystemFile::Exists(fullFilePath.c_str())) { - fileName = fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if(AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + projectModulePath /= fullFilePath; + if (AZ::IO::SystemFile::Exists(projectModulePath.c_str())) + { + fullFilePath = projectModulePath; + } + } + } } - - Platform::ConstructModuleFullFileName(path, fileName, fullPath); - m_fileName = fullPath; + m_fileName = AZStd::string_view{fullFilePath.Native()}; } ~DynamicModuleHandleUnixLike() override @@ -81,9 +98,9 @@ namespace AZ { AZ::Debug::Trace::Printf("Module", "Attempting to load module:%s\n", m_fileName.c_str()); bool alreadyOpen = false; - + m_handle = Platform::OpenModule(m_fileName, alreadyOpen); - + if(m_handle) { if (alreadyOpen) diff --git a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Utils/Utils_UnixLike.cpp b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Utils/Utils_UnixLike.cpp index 2763baac1d..7fd8a639c3 100644 --- a/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Utils/Utils_UnixLike.cpp +++ b/Code/Framework/AzCore/Platform/Common/UnixLike/AzCore/Utils/Utils_UnixLike.cpp @@ -25,15 +25,22 @@ namespace AZ void NativeErrorMessageBox(const char*, const char*) {} - AZ::IO::FixedMaxPathString GetO3deManifestDirectory() + AZ::IO::FixedMaxPathString GetHomeDirectory() { + constexpr AZStd::string_view overrideHomeDirKey = "/Amazon/Settings/override_home_dir"; + AZ::IO::FixedMaxPathString overrideHomeDir; + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if (settingsRegistry->Get(overrideHomeDir, overrideHomeDirKey)) + { + AZ::IO::FixedMaxPath path{overrideHomeDir}; + return path.Native(); + } + } + if (const char* homePath = std::getenv("HOME"); homePath != nullptr) { AZ::IO::FixedMaxPath path{homePath}; - if (!path.empty()) - { - path /= ".o3de"; - } return path.Native(); } return {}; diff --git a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp index 49d5360faa..9daabfb86b 100644 --- a/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp +++ b/Code/Framework/AzCore/Platform/Common/WinAPI/AzCore/Module/DynamicModuleHandle_WinAPI.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace AZ @@ -31,13 +32,13 @@ namespace AZ { // Ensure filename ends in ".dll" // Otherwise filenames like "gem.1.0.0" fail to load (.0 is assumed to be the extension). - if (m_fileName.substr(m_fileName.length() - 4) != AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION) + if (!m_fileName.ends_with(AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION)) { - m_fileName = m_fileName + AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; + m_fileName += AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION; } AZ::IO::PathView modulePathView{ m_fileName }; - // If the module path doesn't have a directory within it, prepend it to the path + // If the module path doesn't have a directory within it, prepend the executable directory to the path // and check if the new path exist if (modulePathView.HasFilename() && !modulePathView.HasParentPath()) { @@ -54,6 +55,27 @@ namespace AZ } } } + + // If the module file path does not exist, attempt to search for the module within + // the project's build directory + if (!AZ::IO::SystemFile::Exists(m_fileName.c_str())) + { + // The Settings Registry may not exist in early startup if modules are loaded + // before the ComponentApplication is crated(such as in the Editor main.cpp) + // Therefore an existence check is needed + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if(AZ::IO::FixedMaxPath projectModulePath; + settingsRegistry->Get(projectModulePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectConfigurationBinPath)) + { + projectModulePath /= AZStd::string_view(m_fileName); + if (AZ::IO::SystemFile::Exists(projectModulePath.c_str())) + { + m_fileName.assign(projectModulePath.c_str(), projectModulePath.Native().size()); + } + } + } + } } ~DynamicModuleHandleWindows() override diff --git a/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp b/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp index 8457ff14a6..7dd889e94d 100644 --- a/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp +++ b/Code/Framework/AzCore/Platform/Linux/AzCore/Module/DynamicModuleHandle_Linux.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - path = exePath; - path.push_back('/'); - } + return AZ::Utils::GetExecutableDirectory(); } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,9 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath&) { - fullPath = path + fileName; } } } diff --git a/Code/Framework/AzCore/Platform/Mac/AzCore/PlatformId/PlatformId_Mac.h b/Code/Framework/AzCore/Platform/Mac/AzCore/PlatformId/PlatformId_Mac.h index d361e79f05..42dcd3e2f7 100644 --- a/Code/Framework/AzCore/Platform/Mac/AzCore/PlatformId/PlatformId_Mac.h +++ b/Code/Framework/AzCore/Platform/Mac/AzCore/PlatformId/PlatformId_Mac.h @@ -13,5 +13,5 @@ namespace AZ { - static const PlatformID g_currentPlatform = PlatformID::PLATFORM_APPLE_OSX; + static const PlatformID g_currentPlatform = PlatformID::PLATFORM_APPLE_MAC; } diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp index 2ade67955b..18cef227db 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Utils/Utils_Windows.cpp @@ -22,15 +22,25 @@ namespace AZ::Utils ::MessageBox(0, message, title, MB_OK | MB_ICONERROR); } - AZ::IO::FixedMaxPathString GetO3deManifestDirectory() + AZ::IO::FixedMaxPathString GetHomeDirectory() { + constexpr AZStd::string_view overrideHomeDirKey = "/Amazon/Settings/override_home_dir"; + AZ::IO::FixedMaxPathString overrideHomeDir; + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + if (settingsRegistry->Get(overrideHomeDir, overrideHomeDirKey)) + { + AZ::IO::FixedMaxPath path{overrideHomeDir}; + return path.Native(); + } + } + char userProfileBuffer[AZ::IO::MaxPathLength]{}; size_t variableSize = 0; auto err = getenv_s(&variableSize, userProfileBuffer, AZ::IO::MaxPathLength, "USERPROFILE"); if (!err) { AZ::IO::FixedMaxPath path{ userProfileBuffer }; - path /= ".o3de"; return path.Native(); } diff --git a/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp b/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp index 8a082a01a6..a389162ccc 100644 --- a/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp +++ b/Code/Framework/AzCore/Platform/iOS/AzCore/Module/DynamicModuleHandle_iOS.cpp @@ -10,7 +10,6 @@ * */ -#include // for AZ_MAX_PATH_LEN #include #include #include @@ -19,15 +18,9 @@ namespace AZ { namespace Platform { - void GetModulePath(AZ::OSString& path) + AZ::IO::FixedMaxPath GetModulePath() { - char exePath[AZ_MAX_PATH_LEN]; - if (AZ::Utils::GetExecutableDirectory(exePath, AZ_ARRAY_SIZE(exePath)) == - AZ::Utils::ExecutablePathResult::Success) - { - AZ::OSString frameworks = "/Frameworks/"; - path = exePath + frameworks; - } + return AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "Frameworks"; } void* OpenModule(const AZ::OSString& fileName, bool& alreadyOpen) @@ -40,10 +33,15 @@ namespace AZ } return handle; } - - void ConstructModuleFullFileName(const AZ::OSString& path, const AZ::OSString& fileName, AZ::OSString& fullPath) + + void ConstructModuleFullFileName(AZ::IO::FixedMaxPath& fullPath) { - fullPath = path + fileName + ".framework/" + fileName; + // Append .framework to the name of full path + // Afterwards use the AZ::IO::Path Append function append the filename as a child + // of the framework directory + AZ::IO::FixedMaxPathString fileName{ fullPath.Filename().Native() }; + fullPath.ReplaceFilename(AZ::IO::PathView(AZStd::string_view(fileName + ".framework"))); + fullPath /= fileName; } } } diff --git a/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp b/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp index 42b77f6976..f9616702f1 100644 --- a/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp +++ b/Code/Framework/AzCore/Tests/AZTestShared/Math/MathTestHelpers.cpp @@ -68,7 +68,7 @@ namespace AZ return os << "translation: " << transform.GetTranslation() << " rotation: " << transform.GetRotation() - << " scale: " << transform.GetScale(); + << " scale: " << transform.GetUniformScale(); } std::ostream& operator<<(std::ostream& os, const Color& color) diff --git a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp index 38b9cd609b..9c6f85f08a 100644 --- a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp +++ b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.cpp @@ -31,6 +31,8 @@ namespace UnitTest ErrorHandler::ErrorHandler(const char* errorPattern) : m_errorCount(0) , m_warningCount(0) + , m_expectedErrorCount(0) + , m_expectedWarningCount(0) , m_errorPattern(errorPattern) { AZ::Debug::TraceMessageBus::Handler::BusConnect(); @@ -51,6 +53,16 @@ namespace UnitTest return m_warningCount; } + int ErrorHandler::GetExpectedErrorCount() const + { + return m_expectedErrorCount; + } + + int ErrorHandler::GetExpectedWarningCount() const + { + return m_expectedWarningCount; + } + bool ErrorHandler::SuppressExpectedErrors([[maybe_unused]] const char* window, const char* message) { return AZStd::string(message).find(m_errorPattern) != AZStd::string::npos; @@ -61,7 +73,9 @@ namespace UnitTest [[maybe_unused]] const char* func, const char* message) { m_errorCount++; - return SuppressExpectedErrors(window, message); + bool suppress = SuppressExpectedErrors(window, message); + m_expectedErrorCount += suppress; + return suppress; } bool ErrorHandler::OnPreWarning( @@ -69,7 +83,9 @@ namespace UnitTest [[maybe_unused]] const char* func, const char* message) { m_warningCount++; - return SuppressExpectedErrors(window, message); + bool suppress = SuppressExpectedErrors(window, message); + m_expectedWarningCount += suppress; + return suppress; } bool ErrorHandler::OnPrintf(const char* window, const char* message) diff --git a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.h b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.h index 044c3d1111..56ef340d22 100644 --- a/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.h +++ b/Code/Framework/AzCore/Tests/AZTestShared/Utils/Utils.h @@ -30,8 +30,14 @@ namespace UnitTest public: explicit ErrorHandler(const char* errorPattern); ~ErrorHandler(); + //! Returns the total number of errors encountered (including those which match the expected pattern). int GetErrorCount() const; + //! Returns the total number of warnings encountered (including those which match the expected pattern). int GetWarningCount() const; + //! Returns the number of errors encountered which matched the expected pattern. + int GetExpectedErrorCount() const; + //! Returns the number of warnings encountered which matched the expected pattern. + int GetExpectedWarningCount() const; bool SuppressExpectedErrors(const char* window, const char* message); // AZ::Debug::TraceMessageBus @@ -44,6 +50,8 @@ namespace UnitTest AZStd::string m_errorPattern; int m_errorCount; int m_warningCount; + int m_expectedErrorCount; + int m_expectedWarningCount; }; } diff --git a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp index 78e2288a4c..d6122b81f1 100644 --- a/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp +++ b/Code/Framework/AzCore/Tests/Asset/AssetManagerLoadingTests.cpp @@ -1042,11 +1042,7 @@ namespace UnitTest -#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS TEST_F(AssetJobsFloodTest, DISABLED_ContainerCoreTest_BasicDependencyManagement_Success) -#else - TEST_F(AssetJobsFloodTest, ContainerCoreTest_BasicDependencyManagement_Success) -#endif // !AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS { m_assetHandlerAndCatalog->AssetCatalogRequestBus::Handler::BusConnect(); // Setup has already created/destroyed assets diff --git a/Code/Framework/AzCore/Tests/Asset/AssetManagerStreamingTests.cpp b/Code/Framework/AzCore/Tests/Asset/AssetManagerStreamingTests.cpp index c55a95cf2a..f29c9ac6c4 100644 --- a/Code/Framework/AzCore/Tests/Asset/AssetManagerStreamingTests.cpp +++ b/Code/Framework/AzCore/Tests/Asset/AssetManagerStreamingTests.cpp @@ -351,6 +351,7 @@ namespace UnitTest public AZ::Data::AssetCatalog { static inline const AZ::Uuid TestAssetId{"{E970B177-5F45-44EB-A2C4-9F29D9A0B2A2}"}; + static inline const AZ::Uuid MissingAssetId{"{11111111-1111-1111-1111-111111111111}"}; static inline constexpr AZStd::string_view TestAssetPath = "test"; void SetUp() override @@ -431,24 +432,40 @@ namespace UnitTest // AssetCatalogRequestBus implementation // Minimalist mocks to provide our desired asset path or asset id - AZStd::string GetAssetPathById([[maybe_unused]] const AZ::Data::AssetId& id) override + AZStd::string GetAssetPathById(const AZ::Data::AssetId& id) override { - return TestAssetPath; + if (id == TestAssetId) + { + return TestAssetPath; + } + + return ""; } + AZ::Data::AssetId GetAssetIdByPath( - [[maybe_unused]] const char* path, [[maybe_unused]] const AZ::Data::AssetType& typeToRegister, + const char* path, [[maybe_unused]] const AZ::Data::AssetType& typeToRegister, [[maybe_unused]] bool autoRegisterIfNotFound) override { - return TestAssetId; + if (path == TestAssetPath) + { + return TestAssetId; + } + + return AZ::Data::AssetId(); } // Return the mocked-out information for our test asset - AZ::Data::AssetInfo GetAssetInfoById([[maybe_unused]] const AZ::Data::AssetId& id) override + AZ::Data::AssetInfo GetAssetInfoById(const AZ::Data::AssetId& id) override { AZ::Data::AssetInfo assetInfo; - assetInfo.m_assetId = TestAssetId; - assetInfo.m_assetType = AZ::AzTypeInfo::Uuid(); - assetInfo.m_relativePath = TestAssetPath; + + if (id == TestAssetId) + { + assetInfo.m_assetId = TestAssetId; + assetInfo.m_assetType = AZ::AzTypeInfo::Uuid(); + assetInfo.m_relativePath = TestAssetPath; + } + return assetInfo; } @@ -456,15 +473,20 @@ namespace UnitTest // Set the mocked-out asset load to have a 0-byte length so that the load skips I/O and immediately returns success AZ::Data::AssetStreamInfo GetStreamInfoForLoad( - [[maybe_unused]] const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override + const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) override { EXPECT_TRUE(type == AZ::AzTypeInfo::Uuid()); AZ::Data::AssetStreamInfo info; + info.m_dataOffset = 0; - info.m_streamName = TestAssetPath; info.m_dataLen = 0; info.m_streamFlags = AZ::IO::OpenMode::ModeRead; + if (id == TestAssetId) + { + info.m_streamName = TestAssetPath; + } + return info; } @@ -489,4 +511,27 @@ namespace UnitTest EXPECT_TRUE(testAsset.IsReady()); } + // This test verifies that even if the asset loading returns immediately with an error, all of the loading code works + // successfully. The test itself loads a missing asset twice - the first time is a non-immediate error, where the error + // isn't reported until the DispatchEvents() call. The second time is an immediate error, because now the asset is already + // registered in an Error state. If the test fails, it will likely get caught in the shutdown of the test class, if any + // assets still exist at the point that the asset handler is unregistered. If they're present, then handling of the immediate + // error didn't work, as it left around extra references to the asset that haven't been cleaned up. + TEST_F(AssetManagerStreamerImmediateCompletionTests, ImmediateAssetError_WorksSuccessfully) + { + AZ::Data::AssetLoadParameters loadParams; + + // Attempt to load a missing asset the first time. It will get an error, but not until the DispatchEvents() call happens. + auto testAsset1 = AssetManager::Instance().GetAsset(MissingAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams); + AZ::Data::AssetManager::Instance().DispatchEvents(); + EXPECT_TRUE(testAsset1.IsError()); + + // While the reference to the missing asset still exists, try to get it again. This will cause a more immediate error in + // the AssetContainer code, which should still get handled correctly. In the failure condition, it will instead leave the + // AssetContainer in a state where it never sends the final OnAssetContainerReady/Canceled message. + auto testAsset2 = AssetManager::Instance().GetAsset(MissingAssetId, AZ::Data::AssetLoadBehavior::Default, loadParams); + AZ::Data::AssetManager::Instance().DispatchEvents(); + EXPECT_TRUE(testAsset2.IsError()); + } + } // namespace UnitTest diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp index a494207850..3e4ddac3af 100644 --- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp @@ -104,6 +104,11 @@ namespace JsonSerializationTests AZ::AllocatorInstance::Destroy(); } + void Reflect(AZStd::unique_ptr& context) override + { + context->RegisterGenericType(); + } + AZStd::shared_ptr CreateSerializer() override { return AZStd::make_shared(); @@ -130,6 +135,7 @@ namespace JsonSerializationTests auto instance = AZStd::make_shared(); instance->Create(id, false); instance->SetHint("TestFile"); + instance->SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); return instance; } @@ -153,6 +159,7 @@ namespace JsonSerializationTests "guid": "{BBEAC89F-8BAD-4A9D-BF6E-D0DF84A8DFD6}", "subId": 1 }, + "loadBehavior": "PreLoad", "assetHint": "TestFile" })"; } diff --git a/Code/Framework/AzCore/Tests/BehaviorContextFixture.h b/Code/Framework/AzCore/Tests/BehaviorContextFixture.h index 687aee8aa4..6ae97e1304 100644 --- a/Code/Framework/AzCore/Tests/BehaviorContextFixture.h +++ b/Code/Framework/AzCore/Tests/BehaviorContextFixture.h @@ -49,9 +49,13 @@ namespace UnitTest // ComponentApplicationBus AZ::ComponentApplication* GetApplication() override { return nullptr; } void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override {} + void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override {} void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override {} void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override {} - void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override {} + void RegisterEntityActivatedEventHandler(AZ::EntityActivatedEvent::Handler&) override {} + void RegisterEntityDeactivatedEventHandler(AZ::EntityDeactivatedEvent::Handler&) override {} + void SignalEntityActivated(AZ::Entity*) override {} + void SignalEntityDeactivated(AZ::Entity*) override {} bool AddEntity(AZ::Entity*) override { return true; } bool RemoveEntity(AZ::Entity*) override { return true; } bool DeleteEntity(const AZ::EntityId&) override { return true; } diff --git a/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp b/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp index e56ae53646..5f3debca90 100644 --- a/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp +++ b/Code/Framework/AzCore/Tests/Console/ConsoleTests.cpp @@ -13,24 +13,25 @@ #include #include #include - +#include +#include namespace AZ { using namespace UnitTest; - AZ_CVAR(bool, testBool, false, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(char, testChar, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int8_t, testInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int16_t, testInt16, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int32_t, testInt32, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(int64_t, testInt64, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(uint8_t, testUInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(bool, testBool, false, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(char, testChar, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int8_t, testInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int16_t, testInt16, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int32_t, testInt32, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(int64_t, testInt64, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(uint8_t, testUInt8, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(uint16_t, testUInt16, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(uint32_t, testUInt32, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(uint64_t, testUInt64, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(float, testFloat, 0, nullptr, ConsoleFunctorFlags::Null, ""); - AZ_CVAR(double, testDouble, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, testFloat, 0, nullptr, ConsoleFunctorFlags::Null, ""); + AZ_CVAR(double, testDouble, 0, nullptr, ConsoleFunctorFlags::Null, ""); AZ_CVAR(AZ::CVarFixedString, testString, "default", nullptr, ConsoleFunctorFlags::Null, ""); @@ -189,7 +190,7 @@ namespace AZ TEST_F(ConsoleTests, CVar_GetSetTest_Vector2) { - testVec2 = AZ::Vector2{ 0.0f, 0.0f}; + testVec2 = AZ::Vector2{ 0.0f, 0.0f }; TestCVarHelper(testVec2, "testVec2", "testVec2 1 1", "testVec2 asdf", AZ::Vector2(100, 100), AZ::Vector2(0, 0), AZ::Vector2(1, 1)); } @@ -350,3 +351,245 @@ namespace AZ } } } + + +namespace ConsoleSettingsRegistryTests +{ + //! ConfigFile MergeUtils Test + struct ConfigFileParams + { + AZStd::string_view m_testConfigFileName; + AZStd::string_view m_testConfigContents; + }; + class ConsoleSettingsRegistryFixture + : public UnitTest::ScopedAllocatorSetupFixture + , public ::testing::WithParamInterface + { + public: + void SetUp() override + { + m_registry = AZStd::make_unique(); + // Store off the old global settings registry to restore after each test + m_oldSettingsRegistry = AZ::SettingsRegistry::Get(); + if (m_oldSettingsRegistry != nullptr) + { + AZ::SettingsRegistry::Unregister(m_oldSettingsRegistry); + } + AZ::SettingsRegistry::Register(m_registry.get()); + + // Create a TestFile in the Test Directory + m_testFolder = AZ::IO::FixedMaxPath(AZ::Utils::GetExecutableDirectory()) / "ConsoleTestFolder"; + auto configFileParams = GetParam(); + CreateTestFile(m_testFolder / configFileParams.m_testConfigFileName, configFileParams.m_testConfigContents); + } + + void TearDown() override + { + // Remove the Test Directory + DeleteFolderRecursive(m_testFolder); + + // Restore the old global settings registry + AZ::SettingsRegistry::Unregister(m_registry.get()); + if (m_oldSettingsRegistry != nullptr) + { + AZ::SettingsRegistry::Register(m_oldSettingsRegistry); + m_oldSettingsRegistry = {}; + } + m_registry.reset(); + } + + void TestClassFunc(const AZ::ConsoleCommandContainer& someStrings) + { + m_stringArgCount = someStrings.size(); + } + + AZ_CONSOLEFUNC(ConsoleSettingsRegistryFixture, TestClassFunc, AZ::ConsoleFunctorFlags::Null, ""); + + static void DeleteFolderRecursive(const AZ::IO::PathView& path) + { + auto callback = [&path](AZStd::string_view filename, bool isFile) -> bool + { + if (isFile) + { + auto filePath = AZ::IO::FixedMaxPath(path) / filename; + AZ::IO::SystemFile::Delete(filePath.c_str()); + } + else + { + if (filename != "." && filename != "..") + { + auto folderPath = AZ::IO::FixedMaxPath(path) / filename; + DeleteFolderRecursive(folderPath); + } + } + return true; + }; + auto searchPath = AZ::IO::FixedMaxPath(path) / "*"; + AZ::IO::SystemFile::FindFiles(searchPath.c_str(), callback); + AZ::IO::SystemFile::DeleteDir(AZ::IO::FixedMaxPathString(path.Native()).c_str()); + } + + static bool CreateTestFile(const AZ::IO::FixedMaxPath& testPath, AZStd::string_view content) + { + AZ::IO::SystemFile file; + if (!file.Open(testPath.c_str(), AZ::IO::SystemFile::OpenMode::SF_OPEN_CREATE + | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY)) + { + AZ_Assert(false, "Unable to open test file for writing: %s", testPath.c_str()); + return false; + } + + if (file.Write(content.data(), content.size()) != content.size()) + { + AZ_Assert(false, "Unable to write content to test file: %s", testPath.c_str()); + return false; + } + + return true; + } + + protected: + size_t m_stringArgCount{}; + AZStd::unique_ptr m_registry; + AZ::IO::FixedMaxPath m_testFolder; + + private: + AZ::SettingsRegistryInterface* m_oldSettingsRegistry{}; + }; + + static bool s_consoleFreeFunctionInvoked = false; + static void TestSettingsRegistryFreeFunc(const AZ::ConsoleCommandContainer& someStrings) + { + EXPECT_TRUE(someStrings.empty()); + s_consoleFreeFunctionInvoked = true; + } + + AZ_CONSOLEFREEFUNC(TestSettingsRegistryFreeFunc, AZ::ConsoleFunctorFlags::Null, ""); + + TEST_P(ConsoleSettingsRegistryFixture, Console_AbleToLoadSettingsFile_Successfully) + { + AZ::Console testConsole(*m_registry); + testConsole.LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead()); + AZ::Interface::Register(&testConsole); + AZ_CVAR_SCOPED(int32_t, testInit, 0, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + s_consoleFreeFunctionInvoked = false; + testInit = {}; + AZ::testChar = {}; + AZ::testBool = {}; + AZ::testInt8 = {}; + AZ::testInt16 = {}; + AZ::testInt32 = {}; + AZ::testInt64 = {}; + AZ::testUInt8 = {}; + AZ::testUInt16 = {}; + AZ::testUInt32 = {}; + AZ::testUInt64 = {}; + AZ::testFloat= {}; + AZ::testDouble = {}; + AZ::testString = {}; + + auto configFileParams = GetParam(); + auto testFilePath = m_testFolder / configFileParams.m_testConfigFileName; + EXPECT_TRUE(AZ::IO::SystemFile::Exists(testFilePath.c_str())); + testConsole.ExecuteConfigFile(testFilePath.Native()); + EXPECT_TRUE(s_consoleFreeFunctionInvoked); + EXPECT_EQ(3, testInit); + EXPECT_TRUE(static_cast(AZ::testBool)); + EXPECT_EQ('Q', AZ::testChar); + EXPECT_EQ(24, AZ::testInt8); + EXPECT_EQ(-32, AZ::testInt16); + EXPECT_EQ(41, AZ::testInt32); + EXPECT_EQ(-51, AZ::testInt64); + EXPECT_EQ(3, AZ::testUInt8); + EXPECT_EQ(5, AZ::testUInt16); + EXPECT_EQ(6, AZ::testUInt32); + EXPECT_EQ(0xFFFF'FFFF'FFFF'FFFF, AZ::testUInt64); + EXPECT_FLOAT_EQ(1.0f, AZ::testFloat); + EXPECT_DOUBLE_EQ(2, AZ::testDouble); + EXPECT_STREQ("Stable", static_cast(AZ::testString).c_str()); + EXPECT_EQ(3, m_stringArgCount); + AZ::Interface::Unregister(&testConsole); + } + + + static constexpr AZStd::string_view UserINIStyleContent = + R"( + testInit = 3 + testBool true + testChar Q + testInt8 24 + testInt16 -32 + testInt32 41 + testInt64 -51 + testUInt8 3 + testUInt16 5 + testUInt32 6 + testUInt64 18446744073709551615 + testFloat 1.0 + testDouble 2 + testString Stable + ConsoleSettingsRegistryFixture.testClassFunc Foo Bar Baz + TestSettingsRegistryFreeFunc + )"; + + static constexpr AZStd::string_view UserJsonMergePatchContent = + R"( + { + "Amazon": { + "AzCore": { + "Runtime": { + "ConsoleCommands": { + "testInit": 3, + "testBool": true, + "testChar": "Q", + "testInt8": 24, + "testInt16": -32, + "testInt32": 41, + "testInt64": -51, + "testUInt8": 3, + "testUInt16": 5, + "testUInt32": 6, + "testUInt64": 18446744073709551615, + "testFloat": 1.0, + "testDouble": 2, + "testString": "Stable", + "ConsoleSettingsRegistryFixture.testClassFunc": "Foo Bar Baz", + "TestSettingsRegistryFreeFunc": "" + } + } + } + } + } + )"; + static constexpr AZStd::string_view UserJsonPatchContent = + R"( + [ + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInit", "value": 3 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testBool", "value": true }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testChar", "value": "Q" }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt8", "value": 24 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt16", "value": -32 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt32", "value": 41 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testInt64", "value": -51 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt8", "value": 3 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt16", "value": 5 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt32", "value": 6 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testUInt64", "value": 18446744073709551615 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testFloat", "value": 1.0 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testDouble", "value": 2 }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/testString", "value": "Stable" }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/ConsoleSettingsRegistryFixture.testClassFunc", "value": "Foo Bar Baz" }, + { "op": "add", "path": "/Amazon/AzCore/Runtime/ConsoleCommands/TestSettingsRegistryFreeFunc", "value": "" } + ] + )"; + + INSTANTIATE_TEST_CASE_P( + ExecuteCommandFromSettingsFile, + ConsoleSettingsRegistryFixture, + ::testing::Values( + ConfigFileParams{"user.cfg", UserINIStyleContent}, + ConfigFileParams{"user.setreg", UserJsonMergePatchContent}, + ConfigFileParams{"user.setregpatch", UserJsonPatchContent} + ) + ); +} diff --git a/Code/Framework/AzCore/Tests/Math/MathTestData.h b/Code/Framework/AzCore/Tests/Math/MathTestData.h index cd3ade7854..c82c5caea7 100644 --- a/Code/Framework/AzCore/Tests/Math/MathTestData.h +++ b/Code/Framework/AzCore/Tests/Math/MathTestData.h @@ -61,8 +61,8 @@ namespace MathTestData }; static const AZ::Transform NonOrthogonalTransforms[] = { - AZ::Transform::CreateScale(AZ::Vector3(2.4f, 0.3f, 1.7f)), - AZ::Transform::CreateRotationX(2.2f) * AZ::Transform::CreateScale(AZ::Vector3(0.2f, 0.8f, 1.4f)) + AZ::Transform::CreateUniformScale(2.4f), + AZ::Transform::CreateRotationX(2.2f) * AZ::Transform::CreateUniformScale(0.8f) }; static const AZ::Transform OrthogonalTransforms[] = { diff --git a/Code/Framework/AzCore/Tests/Math/ObbTests.cpp b/Code/Framework/AzCore/Tests/Math/ObbTests.cpp index a90d66f288..de267b4265 100644 --- a/Code/Framework/AzCore/Tests/Math/ObbTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/ObbTests.cpp @@ -59,11 +59,11 @@ namespace UnitTest TEST(MATH_Obb, TestScaleTransform) { Obb obb = Obb::CreateFromPositionRotationAndHalfLengths(position, rotation, halfLengths); - Vector3 scaleFactors = Vector3(1.0f, 2.0f, 3.0f); - Transform transform = Transform::CreateScale(scaleFactors); + float scale = 3.0f; + Transform transform = Transform::CreateUniformScale(scale); obb = transform * obb; - EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(1.0f, 4.0f, 9.0f))); - EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(0.5f, 1.0f, 1.5f))); + EXPECT_THAT(obb.GetPosition(), IsClose(Vector3(3.0f, 6.0f, 9.0f))); + EXPECT_THAT(obb.GetHalfLengths(), IsClose(Vector3(1.5f, 1.5f, 1.5f))); } TEST(MATH_Obb, TestSetPosition) diff --git a/Code/Framework/AzCore/Tests/Math/RandomTests.cpp b/Code/Framework/AzCore/Tests/Math/RandomTests.cpp new file mode 100644 index 0000000000..7fe3acff54 --- /dev/null +++ b/Code/Framework/AzCore/Tests/Math/RandomTests.cpp @@ -0,0 +1,114 @@ +/* +* 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. +* +*/ + +#include +#include + +using namespace AZ; + +namespace UnitTest +{ + TEST(MATH_Random, GetHaltonNumber) + { + EXPECT_FLOAT_EQ(0.5, GetHaltonNumber(1, 2)); + EXPECT_FLOAT_EQ(898.0f / 2187.0f, GetHaltonNumber(1234, 3)); + EXPECT_FLOAT_EQ(5981.0f / 15625.0f, GetHaltonNumber(4321, 5)); + } + + TEST(MATH_Random, HaltonSequenceStandard) + { + HaltonSequence<3> sequence({ 2, 3, 5 }); + auto regularSequence = sequence.GetHaltonSequence<5>(); + + EXPECT_FLOAT_EQ(1.0f / 2.0f, regularSequence[0][0]); + EXPECT_FLOAT_EQ(1.0f / 3.0f, regularSequence[0][1]); + EXPECT_FLOAT_EQ(1.0f / 5.0f, regularSequence[0][2]); + + EXPECT_FLOAT_EQ(1.0f / 4.0f, regularSequence[1][0]); + EXPECT_FLOAT_EQ(2.0f / 3.0f, regularSequence[1][1]); + EXPECT_FLOAT_EQ(2.0f / 5.0f, regularSequence[1][2]); + + EXPECT_FLOAT_EQ(3.0f / 4.0f, regularSequence[2][0]); + EXPECT_FLOAT_EQ(1.0f / 9.0f, regularSequence[2][1]); + EXPECT_FLOAT_EQ(3.0f / 5.0f, regularSequence[2][2]); + + EXPECT_FLOAT_EQ(1.0f / 8.0f, regularSequence[3][0]); + EXPECT_FLOAT_EQ(4.0f / 9.0f, regularSequence[3][1]); + EXPECT_FLOAT_EQ(4.0f / 5.0f, regularSequence[3][2]); + + EXPECT_FLOAT_EQ(5.0f / 8.0f, regularSequence[4][0]); + EXPECT_FLOAT_EQ(7.0f / 9.0f, regularSequence[4][1]); + EXPECT_FLOAT_EQ(1.0f / 25.0f, regularSequence[4][2]); + } + + TEST(MATH_Random, HaltonSequenceOffsets) + { + HaltonSequence<3> sequence({ 2, 3, 5 }); + sequence.SetOffsets({ 1, 2, 3 }); + auto offsetSequence = sequence.GetHaltonSequence<2>(); + + EXPECT_FLOAT_EQ(1.0f / 4.0f, offsetSequence[0][0]); + EXPECT_FLOAT_EQ(1.0f / 9.0f, offsetSequence[0][1]); + EXPECT_FLOAT_EQ(4.0f / 5.0f, offsetSequence[0][2]); + + EXPECT_FLOAT_EQ(3.0f / 4.0f, offsetSequence[1][0]); + EXPECT_FLOAT_EQ(4.0f / 9.0f, offsetSequence[1][1]); + EXPECT_FLOAT_EQ(1.0f / 25.0f, offsetSequence[1][2]); + } + + TEST(MATH_Random, HaltonSequenceIncrements) + { + HaltonSequence<3> sequence({ 2, 3, 5 }); + sequence.SetOffsets({ 1, 2, 3 }); + sequence.SetIncrements({ 1, 2, 3 }); + auto incrementedSequence = sequence.GetHaltonSequence<2>(); + + EXPECT_FLOAT_EQ(1.0f / 4.0f, incrementedSequence[0][0]); + EXPECT_FLOAT_EQ(1.0f / 9.0f, incrementedSequence[0][1]); + EXPECT_FLOAT_EQ(4.0f / 5.0f, incrementedSequence[0][2]); + + EXPECT_FLOAT_EQ(3.0f / 4.0f, incrementedSequence[1][0]); + EXPECT_FLOAT_EQ(7.0f / 9.0f, incrementedSequence[1][1]); + EXPECT_FLOAT_EQ(11.0f / 25.0f, incrementedSequence[1][2]); + } + + TEST(MATH_Random, FillHaltonSequence) + { + HaltonSequence<3> sequence({ 2, 3, 5 }); + auto regularSequence = sequence.GetHaltonSequence<5>(); + + struct Point + { + Point() = default; + Point(AZStd::array arr) + :x(arr[0]) + ,y(arr[1]) + ,z(arr[2]) + {} + + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + }; + + AZStd::array ownedContainer; + sequence.FillHaltonSequence(ownedContainer.begin(), ownedContainer.end()); + + for (size_t i = 0; i < regularSequence.size(); ++i) + { + EXPECT_FLOAT_EQ(regularSequence[i][0], ownedContainer[i].x); + EXPECT_FLOAT_EQ(regularSequence[i][1], ownedContainer[i].y); + EXPECT_FLOAT_EQ(regularSequence[i][2], ownedContainer[i].z); + } + } + +} diff --git a/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp b/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp index 400a845913..943aba9b76 100644 --- a/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/TransformPerformanceTests.cpp @@ -180,13 +180,13 @@ namespace Benchmark } } - BENCHMARK_F(BM_MathTransform, CreateScale)(benchmark::State& state) + BENCHMARK_F(BM_MathTransform, CreateUniformScale)(benchmark::State& state) { for (auto _ : state) { for (auto& testData : m_testDataArray) { - AZ::Transform result = AZ::Transform::CreateScale(testData.v3); + AZ::Transform result = AZ::Transform::CreateUniformScale(testData.value[0]); benchmark::DoNotOptimize(result); } } @@ -344,39 +344,39 @@ namespace Benchmark } } - BENCHMARK_F(BM_MathTransform, GetScale)(benchmark::State& state) + BENCHMARK_F(BM_MathTransform, GetUniformScale)(benchmark::State& state) { for (auto _ : state) { for (auto& testData : m_testDataArray) { - AZ::Vector3 result = testData.t1.GetScale(); + float result = testData.t1.GetUniformScale(); benchmark::DoNotOptimize(result); } } } - BENCHMARK_F(BM_MathTransform, SetScale)(benchmark::State& state) + BENCHMARK_F(BM_MathTransform, SetUniformScale)(benchmark::State& state) { for (auto _ : state) { for (auto& testData : m_testDataArray) { AZ::Transform testTransform = testData.t2; - testTransform.SetScale(testData.v3); + testTransform.SetUniformScale(testData.value[0]); benchmark::DoNotOptimize(testTransform); } } } - BENCHMARK_F(BM_MathTransform, ExtractScale)(benchmark::State& state) + BENCHMARK_F(BM_MathTransform, ExtractUniformScale)(benchmark::State& state) { for (auto _ : state) { for (auto& testData : m_testDataArray) { AZ::Transform testTransform = testData.t2; - AZ::Vector3 result = testTransform.ExtractScale(); + float result = testTransform.ExtractUniformScale(); benchmark::DoNotOptimize(result); } } diff --git a/Code/Framework/AzCore/Tests/Math/TransformTests.cpp b/Code/Framework/AzCore/Tests/Math/TransformTests.cpp index d0343211c3..529347f31d 100644 --- a/Code/Framework/AzCore/Tests/Math/TransformTests.cpp +++ b/Code/Framework/AzCore/Tests/Math/TransformTests.cpp @@ -159,37 +159,14 @@ namespace UnitTest INSTANTIATE_TEST_CASE_P(MATH_Transform, TransformCreateFromQuaternionFixture, ::testing::ValuesIn(MathTestData::UnitQuaternions)); - using TransformCreateFromMatrix3x3Fixture = ::testing::TestWithParam; - - TEST_P(TransformCreateFromMatrix3x3Fixture, CreateFromMatrix3x3) + TEST(MATH_Transform, CreateUniformScale) { - const AZ::Matrix3x3 matrix3x3 = GetParam(); - const AZ::Transform transform = AZ::Transform::CreateFromMatrix3x3(matrix3x3); - EXPECT_THAT(transform.GetTranslation(), IsClose(AZ::Vector3::CreateZero())); - const AZ::Vector3 vector(2.3f, -0.6, 1.8f); - EXPECT_THAT(transform.TransformPoint(vector), IsClose(matrix3x3 * vector)); - } - - TEST_P(TransformCreateFromMatrix3x3Fixture, CreateFromMatrix3x3AndTranslation) - { - const AZ::Matrix3x3 matrix3x3 = GetParam(); - const AZ::Vector3 translation(-2.6f, 1.7f, 0.8f); - const AZ::Transform transform = AZ::Transform::CreateFromMatrix3x3AndTranslation(matrix3x3, translation); - EXPECT_THAT(transform.GetTranslation(), IsClose(translation)); - const AZ::Vector3 vector(2.3f, -0.6, 1.8f); - EXPECT_THAT(transform.TransformPoint(vector), IsClose(matrix3x3 * vector + translation)); - } - - INSTANTIATE_TEST_CASE_P(MATH_Transform, TransformCreateFromMatrix3x3Fixture, ::testing::ValuesIn(MathTestData::Matrix3x3s)); - - TEST(MATH_Transform, CreateScale) - { - const AZ::Vector3 scale(1.7f, 0.3f, 2.4f); - const AZ::Transform transform = AZ::Transform::CreateScale(scale); + const float scale = 1.7f; + const AZ::Transform transform = AZ::Transform::CreateUniformScale(scale); const AZ::Vector3 vector(0.2f, -1.6f, 0.4f); EXPECT_THAT(transform.GetTranslation(), IsClose(AZ::Vector3::CreateZero())); const AZ::Vector3 transformedVector = transform.TransformPoint(vector); - const AZ::Vector3 expected(0.34f, -0.48f, 0.96f); + const AZ::Vector3 expected(0.34f, -2.72f, 0.68f); EXPECT_THAT(transformedVector, IsClose(expected)); } @@ -237,10 +214,10 @@ namespace UnitTest TEST(MATH_Transform, MultiplyByTransform) { const AZ::Transform transform1 = AZ::Transform::CreateRotationY(0.3f); - const AZ::Transform transform2 = AZ::Transform::CreateScale(AZ::Vector3(1.3f, 1.5f, 0.4f)); + const AZ::Transform transform2 = AZ::Transform::CreateUniformScale(1.3f); const AZ::Transform transform3 = AZ::Transform::CreateFromQuaternionAndTranslation( AZ::Quaternion(0.42f, 0.46f, -0.66f, 0.42f), AZ::Vector3(2.8f, -3.7f, 1.6f)); - const AZ::Transform transform4 = AZ::Transform::CreateRotationX(-0.7f) * AZ::Transform::CreateScale(AZ::Vector3(0.6f, 1.3f, 0.7f)); + const AZ::Transform transform4 = AZ::Transform::CreateRotationX(-0.7f) * AZ::Transform::CreateUniformScale(0.6f); AZ::Transform transform5 = transform1; transform5 *= transform4; const AZ::Vector3 vector(1.9f, 2.3f, 0.2f); @@ -254,14 +231,14 @@ namespace UnitTest TEST(MATH_Transform, TranslationCorrectInTransformHierarchy) { AZ::Transform parent = AZ::Transform::CreateRotationZ(AZ::DegToRad(45.0f)); - parent.SetScale(AZ::Vector3(3.0f, 2.0f, 1.0f)); + parent.SetUniformScale(3.0f); parent.SetTranslation(AZ::Vector3(0.2f, 0.3f, 0.4f)); AZ::Transform child = AZ::Transform::CreateRotationZ(AZ::DegToRad(90.0f)); child.SetTranslation(AZ::Vector3(0.5f, 0.6f, 0.7f)); const AZ::Transform overallTransform = parent * child; const AZ::Vector3 overallTranslation = overallTransform.GetTranslation(); - const AZ::Vector3 expectedTranslation(0.412132f, 2.20919f, 1.1f); - EXPECT_THAT(overallTranslation, IsClose(AZ::Vector3(0.412132f, 2.20919f, 1.1f))); + const AZ::Vector3 expectedTranslation(-0.012132f, 2.633452f, 2.5f); + EXPECT_THAT(overallTranslation, IsClose(expectedTranslation)); } TEST(MATH_Transform, TransformPointVector3) @@ -337,14 +314,14 @@ namespace UnitTest TEST_P(TransformScaleFixture, Scale) { const AZ::Transform orthogonalTransform = GetParam(); - EXPECT_THAT(orthogonalTransform.GetScale(), IsClose(AZ::Vector3::CreateOne())); + EXPECT_NEAR(orthogonalTransform.GetUniformScale(), 1.0f, AZ::Constants::Tolerance); AZ::Transform unscaledTransform = orthogonalTransform; - unscaledTransform.ExtractScale(); - EXPECT_THAT(unscaledTransform.GetScale(), IsClose(AZ::Vector3::CreateOne())); - const AZ::Vector3 scale(2.8f, 0.7f, 1.3f); + unscaledTransform.ExtractUniformScale(); + EXPECT_NEAR(unscaledTransform.GetUniformScale(), 1.0f, AZ::Constants::Tolerance); + const float scale = 2.8f; AZ::Transform scaledTransform = orthogonalTransform; - scaledTransform.MultiplyByScale(scale); - EXPECT_THAT(scaledTransform.GetScale(), IsClose(scale)); + scaledTransform.MultiplyByUniformScale(scale); + EXPECT_NEAR(scaledTransform.GetUniformScale(), scale, AZ::Constants::Tolerance); } INSTANTIATE_TEST_CASE_P(MATH_Transform, TransformScaleFixture, ::testing::ValuesIn(MathTestData::OrthogonalTransforms)); @@ -353,24 +330,11 @@ namespace UnitTest { EXPECT_TRUE(AZ::Transform::CreateIdentity().IsOrthogonal()); EXPECT_TRUE(AZ::Transform::CreateRotationZ(0.3f).IsOrthogonal()); - EXPECT_FALSE(AZ::Transform::CreateScale(AZ::Vector3(0.8f, 0.3f, 1.2f)).IsOrthogonal()); + EXPECT_FALSE(AZ::Transform::CreateUniformScale(0.8f).IsOrthogonal()); EXPECT_TRUE(AZ::Transform::CreateFromQuaternion(AZ::Quaternion(-0.52f, -0.08f, 0.56f, 0.64f)).IsOrthogonal()); AZ::Transform transform; transform.SetFromEulerRadians(AZ::Vector3(0.2f, 0.4f, 0.1f)); EXPECT_TRUE(transform.IsOrthogonal()); - - // want to test each possible way the transform could fail to be orthogonal, which we can do by testing for one - // axis, then using a rotation which cycles the axes - const AZ::Transform axisCycle = AZ::Transform::CreateFromQuaternion(AZ::Quaternion(0.5f, 0.5f, 0.5f, 0.5f)); - - // a transform which is normalized in 2 axes, but not the third - AZ::Transform nonOrthogonalTransform1 = AZ::Transform::CreateScale(AZ::Vector3(1.0f, 1.0f, 2.0f)); - - for (int i = 0; i < 3; i++) - { - EXPECT_FALSE(nonOrthogonalTransform1.IsOrthogonal()); - nonOrthogonalTransform1 = axisCycle * nonOrthogonalTransform1; - } } using TransformSetFromEulerDegreesFixture = ::testing::TestWithParam; @@ -459,16 +423,17 @@ namespace UnitTest { const char* objectStreamBuffer = R"DELIMITER( - + )DELIMITER"; AZ::Transform* deserializedTransform = AZ::Utils::LoadObjectFromBuffer(objectStreamBuffer, strlen(objectStreamBuffer) + 1); const AZ::Vector3 expectedTranslation(513.7845459f, 492.5420837f, 32.0000000f); - const AZ::Vector3 expectedScale(1.5f, 0.5f, 1.2f); + const float expectedScale = 1.5f; const AZ::Quaternion expectedRotation(0.2624075f, 0.4405251f, 0.2029076f, 0.8342113f); const AZ::Transform expectedTransform = - AZ::Transform::CreateFromQuaternionAndTranslation(expectedRotation, expectedTranslation) * AZ::Transform::CreateScale(expectedScale); + AZ::Transform::CreateFromQuaternionAndTranslation(expectedRotation, expectedTranslation) * + AZ::Transform::CreateUniformScale(expectedScale); EXPECT_TRUE(deserializedTransform->IsClose(expectedTransform)); azfree(deserializedTransform); diff --git a/Code/Framework/AzCore/Tests/ScriptMath.cpp b/Code/Framework/AzCore/Tests/ScriptMath.cpp index cb673e92e7..dce63051c9 100644 --- a/Code/Framework/AzCore/Tests/ScriptMath.cpp +++ b/Code/Framework/AzCore/Tests/ScriptMath.cpp @@ -1275,10 +1275,10 @@ namespace UnitTest script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(1, 0, 0)))"); script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 1, 0)):IsClose(Vector3(0, 0.866, 0.5)))"); script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 0, 1)):IsClose(Vector3(0, -0.5, 0.866)))"); - script->Execute("t1 = Transform.CreateScale(Vector3(1, 2, 3))"); - script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(1, 0, 0)))"); + script->Execute("t1 = Transform.CreateUniformScale(2)"); + script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(2, 0, 0)))"); script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 1, 0)):IsClose(Vector3(0, 2, 0)))"); - script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 0, 1)):IsClose(Vector3(0, 0, 3)))"); + script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 0, 1)):IsClose(Vector3(0, 0, 2)))"); script->Execute("t1 = Transform.CreateTranslation(Vector3(1, 2, 3))"); script->Execute("AZTestAssert(t1:TransformVector(Vector3(1, 0, 0)):IsClose(Vector3(1, 0, 0)))"); script->Execute("AZTestAssert(t1:TransformVector(Vector3(0, 1, 0)):IsClose(Vector3(0, 1, 0)))"); @@ -1341,19 +1341,19 @@ namespace UnitTest script->Execute("AZTestAssert(t3:GetTranslation():IsClose(Vector3(-5.90, 25.415, 19.645), 0.001))"); ////test inverse, should handle non-orthogonal matrices - script->Execute("t1 = Transform.CreateRotationX(1) * Transform.CreateScale(Vector3(1, 2, 3))"); + script->Execute("t1 = Transform.CreateRotationX(1) * Transform.CreateUniformScale(2)"); script->Execute("AZTestAssert((t1*t1:GetInverse()):IsClose(Transform.CreateIdentity()))"); ////scale access - script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(40)) * Transform.CreateScale(Vector3(2, 3, 4))"); - script->Execute("AZTestAssert(t1:GetScale():IsClose(Vector3(2, 3, 4)))"); - script->Execute("AZTestAssert(t1:ExtractScale():IsClose(Vector3(2, 3, 4)))"); - script->Execute("AZTestAssert(t1:GetScale():IsClose(Vector3.CreateOne()))"); - script->Execute("t1:MultiplyByScale(Vector3(3, 4, 5))"); - script->Execute("AZTestAssert(t1:GetScale():IsClose(Vector3(3, 4, 5)))"); + script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(40)) * Transform.CreateUniformScale(3)"); + script->Execute("AZTestAssertFloatClose(t1:GetUniformScale(), 3)"); + script->Execute("AZTestAssertFloatClose(t1:ExtractUniformScale(), 3)"); + script->Execute("AZTestAssertFloatClose(t1:GetUniformScale(), 1)"); + script->Execute("t1:MultiplyByUniformScale(2)"); + script->Execute("AZTestAssertFloatClose(t1:GetUniformScale(), 2)"); ////orthogonalize - script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateScale(Vector3(2, 3, 4))"); + script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateUniformScale(3)"); script->Execute("t1:SetTranslation(Vector3(1,2,3))"); script->Execute("t2 = t1:GetOrthogonalized()"); script->Execute("AZTestAssertFloatClose(t2:GetBasisX():GetLength(), 1)"); @@ -1372,7 +1372,7 @@ namespace UnitTest script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30))"); script->Execute("t1:SetTranslation(Vector3(1, 2, 3))"); script->Execute("AZTestAssert(t1:IsOrthogonal(0.05))"); - script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateScale(Vector3(2, 3, 4))"); + script->Execute("t1 = Transform.CreateRotationX(Math.DegToRad(30)) * Transform.CreateUniformScale(2)"); script->Execute("AZTestAssert( not t1:IsOrthogonal(0.05))"); ////IsClose diff --git a/Code/Framework/AzCore/Tests/Serialization.cpp b/Code/Framework/AzCore/Tests/Serialization.cpp index 35cf17c2e0..036942f9dd 100644 --- a/Code/Framework/AzCore/Tests/Serialization.cpp +++ b/Code/Framework/AzCore/Tests/Serialization.cpp @@ -1232,6 +1232,10 @@ namespace UnitTest void UnregisterComponentDescriptor(const ComponentDescriptor*) override { } void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler&) override { } void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler&) override { } + void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler&) override { } + void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler&) override { } + void SignalEntityActivated(Entity*) override { } + void SignalEntityDeactivated(Entity*) override { } bool AddEntity(Entity*) override { return false; } bool RemoveEntity(Entity*) override { return false; } bool DeleteEntity(const EntityId&) override { return false; } @@ -1252,6 +1256,7 @@ namespace UnitTest m_serializeContext.reset(aznew AZ::SerializeContext()); ComponentApplicationBus::Handler::BusConnect(); + AZ::Interface::Register(this); AZ::AllocatorInstance::Create(); AZ::AllocatorInstance::Create(); @@ -1270,6 +1275,7 @@ namespace UnitTest AZ::AllocatorInstance::Destroy(); AZ::AllocatorInstance::Destroy(); + AZ::Interface::Unregister(this); ComponentApplicationBus::Handler::BusDisconnect(); } diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp index 08de21b54f..47e05997fc 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/BaseJsonSerializerTests.cpp @@ -119,7 +119,8 @@ namespace JsonSerializationTests int value = 0; int* ptrValue = &value; - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_NE(nullptr, ptrValue); @@ -134,7 +135,8 @@ namespace JsonSerializationTests json.Set(42); int* ptrValue = nullptr; - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_NE(nullptr, ptrValue); @@ -150,7 +152,8 @@ namespace JsonSerializationTests rapidjson::Value json(rapidjson::kObjectType); int* ptrValue = nullptr; - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_NE(nullptr, ptrValue); @@ -165,7 +168,8 @@ namespace JsonSerializationTests rapidjson::Value json(rapidjson::kNullType); int* ptrValue = reinterpret_cast(azmalloc(sizeof(int), alignof(int), AZ::SystemAllocator)); - ResultCode result = ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, Flags::ResolvePointer); + ResultCode result = + ContinueLoading(&ptrValue, azrtti_typeid(), json, *m_jsonDeserializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); ASSERT_EQ(nullptr, ptrValue); @@ -194,8 +198,8 @@ namespace JsonSerializationTests int value = 42; int* ptrValue = &value; - ResultCode result = ContinueStoring(*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, - Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("42"); @@ -210,8 +214,9 @@ namespace JsonSerializationTests int value2 = 42; int* defaultPtrValue = &value2; - ResultCode result = - ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, + ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("{}"); @@ -224,7 +229,7 @@ namespace JsonSerializationTests int* ptrValue = nullptr; ResultCode result = ContinueStoring( - *m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + *m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("null"); @@ -238,8 +243,9 @@ namespace JsonSerializationTests int value2 = 42; int* defaultPtrValue = &value2; - ResultCode result = - ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, + ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("null"); @@ -252,8 +258,9 @@ namespace JsonSerializationTests int* ptrValue = nullptr; int* defaultPtrValue = nullptr; - ResultCode result = - ContinueStoring(*m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, Flags::ResolvePointer); + ResultCode result = ContinueStoring( + *m_jsonDocument, &ptrValue, &defaultPtrValue, azrtti_typeid(), *m_jsonSerializationContext, + ContinuationFlags::ResolvePointer); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("null"); @@ -265,8 +272,8 @@ namespace JsonSerializationTests int value = 42; - ResultCode result = ContinueStoring(*m_jsonDocument, &value, nullptr, azrtti_typeid(), *m_jsonSerializationContext, - Flags::ReplaceDefault); + ResultCode result = ContinueStoring( + *m_jsonDocument, &value, nullptr, azrtti_typeid(), *m_jsonSerializationContext, ContinuationFlags::ReplaceDefault); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("42"); @@ -280,7 +287,7 @@ namespace JsonSerializationTests int* ptrValue = &value; ResultCode result = ContinueStoring(*m_jsonDocument, &ptrValue, nullptr, azrtti_typeid(), *m_jsonSerializationContext, - Flags::ResolvePointer | Flags::ReplaceDefault); + ContinuationFlags::ResolvePointer | ContinuationFlags::ReplaceDefault); EXPECT_EQ(Processing::Completed, result.GetProcessing()); Expect_DocStrEq("42"); @@ -293,8 +300,8 @@ namespace JsonSerializationTests int value = 42; AZ::Uuid unknownType("{09AE3CEC-EBFC-41EC-A7F6-949721521716}"); - ResultCode result = ContinueStoring(*m_jsonDocument, &value, nullptr, unknownType, *m_jsonSerializationContext, - Flags::ReplaceDefault); + ResultCode result = + ContinueStoring(*m_jsonDocument, &value, nullptr, unknownType, *m_jsonSerializationContext, ContinuationFlags::ReplaceDefault); EXPECT_EQ(Processing::Halted, result.GetProcessing()); } diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h index 4f0825ff1b..c0f470378c 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h @@ -90,9 +90,14 @@ namespace JsonSerializationTests virtual ~JsonSerializerConformityTestDescriptor() = default; virtual AZStd::shared_ptr CreateSerializer() = 0; - + //! Create an instance of the target type with all values set to default. virtual AZStd::shared_ptr CreateDefaultInstance() = 0; + //! Create an instance of the target type that constructed with default constructor. + //! This will be the same instance that Json Serialization creates for dynamic types. Typically it's the same + //! as from CreateDefaultInstance(), except of types, such as pointers, that need to do minimal (de)serialization + //! to initialize an object. + virtual AZStd::shared_ptr CreateDefaultConstructedInstance() { return CreateDefaultInstance(); } //! Create an instance of the target type with some values set and some kept on defaults. //! If the target type doesn't support partial specialization this can be ignored and //! tests for partial support will be skipped. @@ -316,10 +321,10 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto original = this->m_description.CreateDefaultInstance(); - ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*original), + ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); if (this->m_features.m_mandatoryFields.empty()) @@ -339,6 +344,42 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeEmptyObjectThroughMainLoad_SucceedsAndObjectMatchesDefaults) + { + using namespace AZ::JsonSerializationResult; + + if (this->m_features.SupportsJsonType(rapidjson::kObjectType)) + { + this->m_jsonDocument->Parse("{}"); + ASSERT_FALSE(this->m_jsonDocument->HasParseError()); + + auto serializer = this->m_description.CreateSerializer(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); + auto original = this->m_description.CreateDefaultInstance(); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load( + instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, settings); + + if (this->m_features.m_mandatoryFields.empty()) + { + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + } + else + { + EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome()); + bool validProcessing = + result.GetProcessing() == Processing::Altered || + result.GetProcessing() == Processing::PartialAlter; + EXPECT_TRUE(validProcessing); + } + EXPECT_TRUE(this->m_description.AreEqual(*original, *instance)); + } + } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults) { using namespace AZ::JsonSerializationResult; @@ -349,7 +390,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto original = this->m_description.CreateDefaultInstance(); this->m_deserializationSettings->m_clearContainers = false; @@ -384,7 +425,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto original = this->m_description.CreateDefaultInstance(); this->m_deserializationSettings->m_clearContainers = true; @@ -488,7 +529,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto compare = this->m_description.CreateFullySetInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), @@ -499,6 +540,28 @@ namespace JsonSerializationTests EXPECT_TRUE(this->m_description.AreEqual(*instance, *compare)); } + TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance) + { + using namespace AZ::JsonSerializationResult; + + AZStd::string_view json = this->m_description.GetJsonFor_Load_DeserializeFullySetInstance(); + 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(); + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, settings); + + 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_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported) { using namespace AZ::JsonSerializationResult; @@ -518,7 +581,7 @@ namespace JsonSerializationTests ASSERT_NE(this->m_jsonDocument->MemberEnd(), memberToErase); this->m_jsonDocument->RemoveMember(memberToErase); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); @@ -546,7 +609,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto compare = this->m_description.CreatePartialDefaultInstance(); ASSERT_NE(nullptr, compare); @@ -567,7 +630,7 @@ namespace JsonSerializationTests ASSERT_FALSE(this->m_jsonDocument->HasParseError()); auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); AZ::ScopedContextReporter reporter(*this->m_jsonDeserializationContext, [](AZStd::string_view message, ResultCode result, AZStd::string_view path) -> ResultCode @@ -604,7 +667,7 @@ namespace JsonSerializationTests } auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); auto compare = this->m_description.CreateFullySetInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), @@ -635,7 +698,7 @@ namespace JsonSerializationTests } auto serializer = this->m_description.CreateSerializer(); - auto instance = this->m_description.CreateDefaultInstance(); + auto instance = this->m_description.CreateDefaultConstructedInstance(); ResultCode result = serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext); @@ -693,6 +756,36 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeDefaultInstanceThroughMainStore_EmptyJsonReturned) + { + using namespace AZ::JsonSerializationResult; + + auto serializer = this->m_description.CreateSerializer(); + auto instance = this->m_description.CreateDefaultInstance(); + rapidjson::Value convertedValue = this->CreateExplicitDefault(); + + AZ::JsonSerializerSettings settings; + settings.m_serializeContext = this->m_jsonDeserializationContext->GetSerializeContext(); + settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext(); + ResultCode result = AZ::JsonSerialization::Store( + convertedValue, this->m_jsonDocument->GetAllocator(), instance.get(), instance.get(), azrtti_typeid(*instance), settings); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + if (convertedValue.IsObject() && !this->m_features.m_mandatoryFields.empty()) + { + ASSERT_EQ(convertedValue.MemberCount(), this->m_features.m_mandatoryFields.size()); + for (const AZStd::string& mandatoryField : this->m_features.m_mandatoryFields) + { + EXPECT_NE(convertedValue.MemberEnd(), convertedValue.FindMember(mandatoryField.c_str())); + } + } + else + { + EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + this->Expect_ExplicitDefault(convertedValue); + } + } + TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeWithDefaultsKept_FullyWrittenJson) { using namespace AZ::JsonSerializationResult; @@ -924,6 +1017,20 @@ namespace JsonSerializationTests } } + TYPED_TEST_P(JsonSerializerConformityTests, GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared) + { + if (this->m_features.SupportsJsonType(rapidjson::kObjectType)) + { + if (!this->m_features.m_mandatoryFields.empty()) + { + auto serializer = this->m_description.CreateSerializer(); + bool manuallyHandlesDefaults = (serializer->GetOperationsFlags() & AZ::BaseJsonSerializer::OperationFlags::ManualDefault) == + AZ::BaseJsonSerializer::OperationFlags::ManualDefault; + EXPECT_TRUE(manuallyHandlesDefaults); + } + } + } + REGISTER_TYPED_TEST_CASE_P(JsonSerializerConformityTests, Registration_SerializerIsRegisteredWithContext_SerializerFound, @@ -934,14 +1041,16 @@ namespace JsonSerializationTests Load_InvalidTypeOfArrayType_ReturnsUnsupported, Load_InvalidTypeOfStringType_ReturnsUnsupported, Load_InvalidTypeOfNumberType_ReturnsUnsupported, - + Load_DeserializeUnreflectedType_ReturnsUnsupported, Load_DeserializeEmptyObject_SucceedsAndObjectMatchesDefaults, + Load_DeserializeEmptyObjectThroughMainLoad_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArrayWithClearEnabled_SucceedsAndObjectMatchesDefaults, Load_DeserializeEmptyArrayWithClearedTarget_SucceedsAndObjectMatchesDefaults, Load_InterruptClearingTarget_ContainerIsNotCleared, Load_DeserializeFullySetInstance_SucceedsAndObjectMatchesFullySetInstance, + Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance, Load_DeserializePartialInstance_SucceedsAndObjectMatchesParialInstance, Load_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported, Load_InsertAdditionalData_SucceedsAndObjectMatchesFullySetInstance, @@ -950,6 +1059,7 @@ namespace JsonSerializationTests Store_SerializeUnreflectedType_ReturnsUnsupported, Store_SerializeDefaultInstance_EmptyJsonReturned, + Store_SerializeDefaultInstanceThroughMainStore_EmptyJsonReturned, Store_SerializeWithDefaultsKept_FullyWrittenJson, Store_SerializeFullySetInstance_StoredSuccessfullyAndJsonMatches, Store_SerializeWithoutDefault_StoredSuccessfullyAndJsonMatches, @@ -957,10 +1067,12 @@ namespace JsonSerializationTests Store_SerializePartialInstance_StoredSuccessfullyAndJsonMatches, Store_SerializeEmptyArray_StoredSuccessfullyAndJsonMatches, Store_HaltedThroughCallback_StoreFailsAndHaltReported, - + StoreLoad_RoundTripWithPartialDefault_IdenticalInstances, StoreLoad_RoundTripWithFullSet_IdenticalInstances, - StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances); + StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances, + + GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared); } // namespace JsonSerializationTests namespace AZ diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/MathMatrixSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/MathMatrixSerializerTests.cpp new file mode 100644 index 0000000000..b9d1edab76 --- /dev/null +++ b/Code/Framework/AzCore/Tests/Serialization/Json/MathMatrixSerializerTests.cpp @@ -0,0 +1,562 @@ +/* +* 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. +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace JsonSerializationTests +{ + namespace DataHelper + { + // Build Matrix + + template + MatrixType BuildMatrixRotationWithSale(const AZ::Vector3& angles, float scale) + { + // start a matrix with angle degrees + const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(angles); + const auto rotX = MatrixType::CreateRotationX(eulerRadians.GetX()); + const auto rotY = MatrixType::CreateRotationY(eulerRadians.GetY()); + const auto rotZ = MatrixType::CreateRotationZ(eulerRadians.GetZ()); + auto matrix = rotX * rotY * rotZ; + + // apply a scale + matrix.MultiplyByScale(AZ::Vector3{ scale }); + return matrix; + } + + template + MatrixType BuildMatrix(const AZ::Vector3& angles, float scale, const AZ::Vector3& translation) + { + auto matrix = BuildMatrixRotationWithSale(angles, scale); + matrix.SetTranslation(translation); + return matrix; + } + + template <> + AZ::Matrix3x3 BuildMatrix(const AZ::Vector3& angles, float scale, const AZ::Vector3&) + { + return BuildMatrixRotationWithSale(angles, scale); + } + + // Arbitrary Matrix + + template + MatrixType CreateArbitraryMatrixRotationAndSale(AZ::SimpleLcgRandom& random) + { + // start a matrix with arbitrary degrees + float roll = random.GetRandomFloat() * 360.0f; + float pitch = random.GetRandomFloat() * 360.0f; + float yaw = random.GetRandomFloat() * 360.0f; + const AZ::Vector3 eulerRadians = AZ::Vector3DegToRad(AZ::Vector3{ roll, pitch, yaw }); + const auto rotX = MatrixType::CreateRotationX(eulerRadians.GetX()); + const auto rotY = MatrixType::CreateRotationY(eulerRadians.GetY()); + const auto rotZ = MatrixType::CreateRotationZ(eulerRadians.GetZ()); + auto matrix = rotX * rotY * rotZ; + + // apply a scale + matrix.MultiplyByScale(AZ::Vector3{ random.GetRandomFloat() }); + return matrix; + } + + template + void AssignArbitrarySetTranslation(MatrixType& matrix, AZ::SimpleLcgRandom& random) + { + float x = random.GetRandomFloat() * 10000.0f; + float y = random.GetRandomFloat() * 10000.0f; + float z = random.GetRandomFloat() * 10000.0f; + matrix.SetTranslation(AZ::Vector3{ x, y, z }); + } + + template + MatrixType CreateArbitraryMatrix(size_t seed); + + template <> + AZ::Matrix3x3 CreateArbitraryMatrix(size_t seed) + { + AZ::SimpleLcgRandom random(seed); + return CreateArbitraryMatrixRotationAndSale(random); + } + + template <> + AZ::Matrix3x4 CreateArbitraryMatrix(size_t seed) + { + AZ::SimpleLcgRandom random(seed); + auto matrix = CreateArbitraryMatrixRotationAndSale(random); + AssignArbitrarySetTranslation(matrix, random); + return matrix; + } + + template <> + AZ::Matrix4x4 CreateArbitraryMatrix(size_t seed) + { + AZ::SimpleLcgRandom random(seed); + auto matrix = CreateArbitraryMatrixRotationAndSale(random); + AssignArbitrarySetTranslation(matrix, random); + return matrix; + } + + // CreateQuaternion + + template + AZ::Quaternion CreateQuaternion(const MatrixType& matrix); + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x3& matrix) + { + return AZ::Quaternion::CreateFromMatrix3x3(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix3x4& matrix) + { + return AZ::Quaternion::CreateFromMatrix3x4(matrix); + } + + template<> + AZ::Quaternion CreateQuaternion(const AZ::Matrix4x4& matrix) + { + return AZ::Quaternion::CreateFromMatrix4x4(matrix); + } + + template + void AddRotation(rapidjson::Value& value, const MatrixType& matrix, rapidjson::Document::AllocatorType& allocator) + { + AZ::Quaternion rotation = CreateQuaternion(matrix); + const auto degrees = rotation.GetEulerDegrees(); + value.AddMember("yaw", degrees.GetX(), allocator); + value.AddMember("pitch", degrees.GetY(), allocator); + value.AddMember("roll", degrees.GetZ(), allocator); + } + + void AddScale(rapidjson::Value& value, float scale, rapidjson::Document::AllocatorType& allocator) + { + value.AddMember("scale", scale, allocator); + } + + void AddTranslation(rapidjson::Value& value, const AZ::Vector3& translation, rapidjson::Document::AllocatorType& allocator) + { + value.AddMember("x", translation.GetX(), allocator); + value.AddMember("y", translation.GetY(), allocator); + value.AddMember("z", translation.GetZ(), allocator); + } + + template + void AddData(rapidjson::Value& value, const MatrixType& matrix, rapidjson::Document::AllocatorType& allocator); + + template <> + void AddData(rapidjson::Value& value, const AZ::Matrix3x3& matrix, rapidjson::Document::AllocatorType& allocator) + { + AddScale(value, matrix.RetrieveScale().GetX(), allocator); + AddRotation(value, matrix, allocator); + } + + template <> + void AddData(rapidjson::Value& value, const AZ::Matrix3x4& matrix, rapidjson::Document::AllocatorType& allocator) + { + AddScale(value, matrix.RetrieveScale().GetX(), allocator); + AddTranslation(value, matrix.GetTranslation(), allocator); + AddRotation(value, matrix, allocator); + } + + template <> + void AddData(rapidjson::Value& value, const AZ::Matrix4x4& matrix, rapidjson::Document::AllocatorType& allocator) + { + AddScale(value, matrix.RetrieveScale().GetX(), allocator); + AddTranslation(value, matrix.GetTranslation(), allocator); + AddRotation(value, matrix, allocator); + } + }; + + template + class MathMatrixSerializerTestDescription : + public JsonSerializerConformityTestDescriptor + { + public: + AZStd::shared_ptr CreateSerializer() override + { + return AZStd::make_shared(); + } + + AZStd::shared_ptr CreateDefaultInstance() override + { + return AZStd::make_shared(MatrixType::CreateIdentity()); + } + + AZStd::shared_ptr CreateFullySetInstance() override + { + auto angles = AZ::Vector3 { 0.0f, 0.0f, 0.0f }; + auto scale = 10.0f; + auto translation = AZ::Vector3{ 10.0f, 20.0f, 30.0f }; + auto matrix = DataHelper::BuildMatrix(angles, scale, translation); + return AZStd::make_shared(matrix); + } + + AZStd::string_view GetJsonForFullySetInstance() override + { + if constexpr (RowCount * ColumnCount == 9) + { + return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0}"; + } + else if constexpr (RowCount * ColumnCount == 12) + { + return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0,\"x\":10.0,\"y\":20.0,\"z\":30.0}"; + } + else if constexpr (RowCount * ColumnCount == 16) + { + return "{\"roll\":0.0,\"pitch\":0.0,\"yaw\":0.0,\"scale\":10.0,\"x\":10.0,\"y\":20.0,\"z\":30.0}"; + } + else + { + static_assert((RowCount >= 3 && RowCount <= 4) && (ColumnCount >= 3 && ColumnCount <= 4), + "Only matrix 3x3, 3x4 or 4x4 are supported by this test."); + } + return "{}"; + } + + void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override + { + features.EnableJsonType(rapidjson::kArrayType); + features.EnableJsonType(rapidjson::kObjectType); + features.m_fixedSizeArray = true; + features.m_supportsPartialInitialization = false; + features.m_supportsInjection = false; + } + + bool AreEqual(const MatrixType& lhs, const MatrixType& rhs) override + { + for (int r = 0; r < RowCount; ++r) + { + for (int c = 0; c < ColumnCount; ++c) + { + if (!AZ::IsClose(lhs.GetElement(r, c), rhs.GetElement(r, c), AZ::Constants::Tolerance)) + { + return false; + } + } + } + return true; + } + }; + + using MathMatrixSerializerConformityTestTypes = ::testing::Types< + MathMatrixSerializerTestDescription, + MathMatrixSerializerTestDescription, + MathMatrixSerializerTestDescription + >; + INSTANTIATE_TYPED_TEST_CASE_P(JsonMathMatrixSerializer, JsonSerializerConformityTests, MathMatrixSerializerConformityTestTypes); + + template + class JsonMathMatrixSerializerTests + : public BaseJsonSerializerFixture + { + public: + using Descriptor = T; + + void SetUp() override + { + BaseJsonSerializerFixture::SetUp(); + m_serializer = AZStd::make_unique(); + } + + void TearDown() override + { + m_serializer.reset(); + BaseJsonSerializerFixture::TearDown(); + } + + protected: + AZStd::unique_ptr m_serializer; + }; + + struct Matrix3x3Descriptor + { + using MatrixType = AZ::Matrix3x3; + using Serializer = AZ::JsonMatrix3x3Serializer; + constexpr static size_t RowCount = 3; + constexpr static size_t ColumnCount = 3; + constexpr static size_t ElementCount = RowCount * ColumnCount; + constexpr static bool HasTranslation = false; + }; + + struct Matrix3x4Descriptor + { + using MatrixType = AZ::Matrix3x4; + using Serializer = AZ::JsonMatrix3x4Serializer; + constexpr static size_t RowCount = 3; + constexpr static size_t ColumnCount = 4; + constexpr static size_t ElementCount = RowCount * ColumnCount; + constexpr static bool HasTranslation = true; + }; + + struct Matrix4x4Descriptor + { + using MatrixType = AZ::Matrix4x4; + using Serializer = AZ::JsonMatrix4x4Serializer; + constexpr static size_t RowCount = 4; + constexpr static size_t ColumnCount = 4; + constexpr static size_t ElementCount = RowCount * ColumnCount; + constexpr static bool HasTranslation = true; + }; + + using JsonMathMatrixSerializerTypes = ::testing::Types < + Matrix3x3Descriptor, Matrix3x4Descriptor, Matrix4x4Descriptor>; + TYPED_TEST_CASE(JsonMathMatrixSerializerTests, JsonMathMatrixSerializerTypes); + + // Load array tests + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_Array_ReturnsConvertAndLoadsMatrix) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray(); + for (size_t i = 0; i < JsonMathMatrixSerializerTests::Descriptor::ElementCount; ++i) + { + arrayValue.PushBack(static_cast(i + 1), this->m_jsonDocument->GetAllocator()); + } + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::Success, result.GetOutcome()); + + for (int r = 0; r < JsonMathMatrixSerializerTests::Descriptor::RowCount; ++r) + { + for (int c = 0; c < JsonMathMatrixSerializerTests::Descriptor::ColumnCount; ++c) + { + auto testValue = static_cast((r * JsonMathMatrixSerializerTests::Descriptor::ColumnCount) + c + 1); + EXPECT_FLOAT_EQ(testValue, output.GetElement(r, c)); + } + } + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_InvalidEntries_ReturnsUnsupportedAndLeavesMatrixUntouched) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray(); + for (size_t i = 0; i < JsonMathMatrixSerializerTests::Descriptor::ElementCount; ++i) + { + if (i == 1) + { + arrayValue.PushBack(rapidjson::StringRef("Invalid"), this->m_jsonDocument->GetAllocator()); + } + else + { + arrayValue.PushBack(static_cast(i + 1), this->m_jsonDocument->GetAllocator()); + } + } + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome()); + + for (int r = 0; r < JsonMathMatrixSerializerTests::Descriptor::RowCount; ++r) + { + for (int c = 0; c < JsonMathMatrixSerializerTests::Descriptor::ColumnCount; ++c) + { + EXPECT_FLOAT_EQ(0.0f, output.GetElement(r, c)); + } + } + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_FloatSerializerMissingForArray_ReturnsCatastrophic) + { + using namespace AZ::JsonSerializationResult; + + this->m_jsonRegistrationContext->EnableRemoveReflection(); + this->m_jsonRegistrationContext->template Serializer()->template HandlesType(); + this->m_jsonRegistrationContext->DisableRemoveReflection(); + + rapidjson::Value& arrayValue = this->m_jsonDocument->SetArray(); + for (size_t i = 0; i < JsonMathMatrixSerializerTests::Descriptor::ElementCount + 1; ++i) + { + arrayValue.PushBack(static_cast(i + 1), this->m_jsonDocument->GetAllocator()); + } + + typename JsonMathMatrixSerializerTests::Descriptor::MatrixType output; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + EXPECT_EQ(Outcomes::Catastrophic, result.GetOutcome()); + + this->m_jsonRegistrationContext->template Serializer()->template HandlesType(); + } + + // Load object tests + TYPED_TEST(JsonMathMatrixSerializerTests, Load_ValidObjectLowerCase_ReturnsSuccessAndLoadsMatrix) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& objectValue = this->m_jsonDocument->SetObject(); + auto input = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + DataHelper::AddData(objectValue, input, this->m_jsonDocument->GetAllocator()); + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_TRUE(input == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_ValidObjectWithExtraFields_ReturnsPartialConvertAndLoadsMatrix) + { + using namespace AZ::JsonSerializationResult; + + rapidjson::Value& objectValue = this->m_jsonDocument->SetObject(); + auto input = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + DataHelper::AddScale(objectValue, input.RetrieveScale().GetX(), this->m_jsonDocument->GetAllocator()); + DataHelper::AddRotation(objectValue, input, this->m_jsonDocument->GetAllocator()); + objectValue.AddMember(rapidjson::StringRef("extra"), "no value", this->m_jsonDocument->GetAllocator()); + + auto output = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::DefaultsUsed, result.GetOutcome()); + EXPECT_TRUE(input == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, SaveLoad_Identity_LoadsDefaultMatrixWithIdentity) + { + using namespace AZ::JsonSerializationResult; + + auto defaultValue = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + + rapidjson::Value& objectInput = this->m_jsonDocument->SetObject(); + this->m_serializer->Store( + objectInput, + &defaultValue, + &defaultValue, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonSerializationContext); + + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + objectInput.Accept(writer); + + auto output = defaultValue; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + + EXPECT_TRUE(defaultValue == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, LoadSave_Zero_SavesAndLoadsIdentityMatrix) + { + using namespace AZ::JsonSerializationResult; + + auto defaultValue = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateIdentity(); + auto input = JsonMathMatrixSerializerTests::Descriptor::MatrixType::CreateZero(); + + rapidjson::Value& objectInput = this->m_jsonDocument->SetObject(); + this->m_serializer->Store( + objectInput, + &input, + &defaultValue, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonSerializationContext); + + auto output = defaultValue; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid::Descriptor::MatrixType>(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + + ASSERT_EQ(Outcomes::Unsupported, result.GetOutcome()); + EXPECT_TRUE(defaultValue == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, Load_InvalidFields_ReturnsUnsupportedAndLeavesMatrixUntouched) + { + using namespace AZ::JsonSerializationResult; + using Descriptor = typename JsonMathMatrixSerializerTests::Descriptor; + + const auto defaultValue = Descriptor::MatrixType::CreateIdentity(); + rapidjson::Value& objectValue = this->m_jsonDocument->SetObject(); + auto input = Descriptor::MatrixType::CreateIdentity(); + DataHelper::AddData(objectValue, input, this->m_jsonDocument->GetAllocator()); + objectValue["yaw"] = "Invalid"; + + auto output = Descriptor::MatrixType::CreateZero(); + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + ASSERT_EQ(Outcomes::Unsupported, result.GetOutcome()); + EXPECT_TRUE(input == output); + } + + TYPED_TEST(JsonMathMatrixSerializerTests, LoadSave_Arbitrary_SavesAndLoadsArbitraryMatrix) + { + using namespace AZ::JsonSerializationResult; + using Descriptor = typename JsonMathMatrixSerializerTests::Descriptor; + + auto defaultValue = Descriptor::MatrixType::CreateIdentity(); + size_t elementCount = Descriptor::RowCount * Descriptor::ColumnCount; + auto input = DataHelper::CreateArbitraryMatrix(elementCount); + + rapidjson::Value& objectInput = this->m_jsonDocument->SetObject(); + this->m_serializer->Store( + objectInput, + &input, + &defaultValue, + azrtti_typeid(), + *this->m_jsonSerializationContext); + + auto output = defaultValue; + ResultCode result = this->m_serializer->Load( + &output, + azrtti_typeid(), + *this->m_jsonDocument, + *this->m_jsonDeserializationContext); + + EXPECT_EQ(Processing::Completed, result.GetProcessing()); + + for (int r = 0; r < Descriptor::RowCount; ++r) + { + for (int c = 0; c < Descriptor::ColumnCount; ++c) + { + EXPECT_NEAR(input.GetElement(r, c), output.GetElement(r, c), AZ::Constants::Tolerance); + } + } + } + +} // namespace JsonSerializationTests diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp index 2fc131aae2..75391d81d4 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/SmartPointerSerializerTests.cpp @@ -32,6 +32,11 @@ namespace JsonSerializationTests return AZStd::make_shared(); } + AZStd::shared_ptr CreateDefaultConstructedInstance() override + { + return AZStd::make_shared(); + } + void Reflect(AZStd::unique_ptr& context) override { context->RegisterGenericType(); @@ -228,13 +233,19 @@ namespace JsonSerializationTests public: using SmartPointer = typename SmartPointerSimpleDerivedClassTestDescription::SmartPointer; - AZStd::shared_ptr CreateDefaultInstance() override + // This test is specific for derived classes being used as a default value. + AZStd::shared_ptr CreateDefaultConstructedInstance() override { auto result = AZStd::make_shared(); *result = SmartPointer(aznew SimpleInheritence()); return result; } + AZStd::shared_ptr CreateDefaultInstance() override + { + return CreateDefaultConstructedInstance(); + } + AZStd::string_view GetJsonForPartialDefaultInstance() override { return R"( @@ -386,13 +397,19 @@ namespace JsonSerializationTests public: using SmartPointer = typename SmartPointerComplexDerivedClassTestDescription::SmartPointer; - AZStd::shared_ptr CreateDefaultInstance() override + // This test is specific for derived classes being used as a default value. + AZStd::shared_ptr CreateDefaultConstructedInstance() override { auto result = AZStd::make_shared(); *result = SmartPointer(aznew MultipleInheritence()); return result; } + AZStd::shared_ptr CreateDefaultInstance() override + { + return CreateDefaultConstructedInstance(); + } + AZStd::string_view GetJsonForPartialDefaultInstance() override { return R"( diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h index b01dbe9b0d..ae313632af 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h @@ -21,7 +21,7 @@ namespace JsonSerializationTests { using JsonSerializationTestCases = ::testing::Types< // Structures - SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper, + SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper, NonReflectedEnumWrapper, // Pointers SimpleNullPointer, SimpleAssignedPointer, ComplexAssignedPointer, ComplexNullInheritedPointer, ComplexAssignedDifferentInheritedPointer, ComplexAssignedSameInheritedPointer, diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp index 5be031d70a..6da3120f59 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp @@ -373,6 +373,57 @@ namespace JsonSerializationTests return MakeInstanceWithoutDefaults(AZStd::move(instance), json); } + // NonReflectedEnumWrapper + bool NonReflectedEnumWrapper::Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const + { + return !fullReflection || (m_enumClass == rhs.m_enumClass && m_rawEnum== rhs.m_rawEnum); + } + + void NonReflectedEnumWrapper::Reflect(AZStd::unique_ptr& context, bool fullReflection) + { + if (fullReflection) + { + // Note that the enums are not reflected using context->Enum<> + + context->Class() + ->Field("enumClass", &NonReflectedEnumWrapper::m_enumClass) + ->Field("rawEnum", &NonReflectedEnumWrapper::m_rawEnum); + } + } + + InstanceWithSomeDefaults NonReflectedEnumWrapper::GetInstanceWithSomeDefaults() + { + auto instance = AZStd::make_unique(); + instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2; + + const char* strippedDefaults = R"( + { + "enumClass": 2 + })"; + const char* keptDefaults = R"( + { + "enumClass": 2, + "rawEnum": 0 + })"; + + return MakeInstanceWithSomeDefaults(AZStd::move(instance), + strippedDefaults, keptDefaults); + } + + InstanceWithoutDefaults NonReflectedEnumWrapper::GetInstanceWithoutDefaults() + { + auto instance = AZStd::make_unique(); + instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2; + instance->m_rawEnum = NonReflectedEnumWrapper::SimpleRawEnum::RawOption1; + + const char* json = R"( + { + "enumClass": 2, + "rawEnum": 1 + })"; + return MakeInstanceWithoutDefaults(AZStd::move(instance), json); + } + // TemplatedClass bool TemplatedClass::Equals(const TemplatedClass& rhs, bool fullReflection) const diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h index db5db23fba..1830ca9e6f 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h +++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h @@ -134,6 +134,35 @@ namespace JsonSerializationTests SimpleRawEnum m_rawEnum{}; }; + struct NonReflectedEnumWrapper + { + enum class SimpleEnumClass + { + Option1 = 1, + Option2, + }; + enum SimpleRawEnum + { + RawOption1 = 1, + RawOption2, + }; + AZ_CLASS_ALLOCATOR(NonReflectedEnumWrapper, AZ::SystemAllocator, 0); + AZ_RTTI(NonReflectedEnumWrapper, "{A80D5B6B-2FD1-46E9-A7A9-44C5E2650526}"); + + static constexpr bool SupportsPartialDefaults = true; + + NonReflectedEnumWrapper() = default; + virtual ~NonReflectedEnumWrapper() = default; + + bool Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const; + static void Reflect(AZStd::unique_ptr& context, bool fullReflection); + static InstanceWithSomeDefaults GetInstanceWithSomeDefaults(); + static InstanceWithoutDefaults GetInstanceWithoutDefaults(); + + SimpleEnumClass m_enumClass{}; + SimpleRawEnum m_rawEnum{}; + }; + template struct TemplatedClass { @@ -158,5 +187,7 @@ namespace AZ { AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleEnumClass, "{AF6F1964-5B20-4689-BF23-F36B9C9AAE6A}"); AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleRawEnum, "{EB24207F-B48F-4D8B-940D-3CD06A371739}"); + AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleEnumClass, "{E80E4A41-B29E-4B7C-B630-3B599172C837}"); + AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleRawEnum, "{C42AF28D-4F84-4540-972A-5B6EEFAB13FF}"); AZ_TYPE_INFO_TEMPLATE(JsonSerializationTests::TemplatedClass, "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", AZ_TYPE_INFO_TYPENAME); } diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TransformSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/TransformSerializerTests.cpp index 12711b1e1a..750f2ebc9c 100644 --- a/Code/Framework/AzCore/Tests/Serialization/Json/TransformSerializerTests.cpp +++ b/Code/Framework/AzCore/Tests/Serialization/Json/TransformSerializerTests.cpp @@ -44,7 +44,7 @@ namespace JsonSerializationTests AZStd::shared_ptr CreateFullySetInstance() override { return AZStd::make_shared( - AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), AZ::Vector3(9.0f)); + AZ::Vector3(1.0f, 2.0f, 3.0f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), 9.0f); } AZStd::string_view GetJsonForFullySetInstance() override @@ -95,7 +95,7 @@ namespace JsonSerializationTests AZ::Transform expectedTransform( AZ::Vector3(2.25f, 3.5f, 4.75f), AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f), - AZ::Vector3(5.5f)); + 5.5f); rapidjson::Document json; json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ], "Rotation": [ 0.25, 0.5, 0.75, 1.0 ], "Scale": 5.5 })"); @@ -112,7 +112,7 @@ namespace JsonSerializationTests AZ::Transform testTransform = AZ::Transform::CreateIdentity(); AZ::Transform expectedTransform = AZ::Transform::CreateFromQuaternion(AZ::Quaternion(0.25f, 0.5f, 0.75f, 1.0f)); - expectedTransform.SetScale(AZ::Vector3(5.5f)); + expectedTransform.SetUniformScale(5.5f); rapidjson::Document json; json.Parse(R"({ "Rotation": [ 0.25, 0.5, 0.75, 1.0 ], "Scale": 5.5 })"); @@ -128,7 +128,7 @@ namespace JsonSerializationTests { AZ::Transform testTransform = AZ::Transform::CreateIdentity(); AZ::Transform expectedTransform = AZ::Transform::CreateTranslation(AZ::Vector3(2.25f, 3.5f, 4.75f)); - expectedTransform.SetScale(AZ::Vector3(5.5f)); + expectedTransform.SetUniformScale(5.5f); rapidjson::Document json; json.Parse(R"({ "Translation": [ 2.25, 3.5, 4.75 ], "Scale": 5.5 })"); @@ -189,7 +189,7 @@ namespace JsonSerializationTests TEST_F(JsonTransformSerializerTests, Load_FullySetTransform_ReturnsSuccessWithOnlyScale) { AZ::Transform testTransform = AZ::Transform::CreateIdentity(); - AZ::Transform expectedTransform = AZ::Transform::CreateScale(AZ::Vector3(5.5f)); + AZ::Transform expectedTransform = AZ::Transform::CreateUniformScale(5.5f); rapidjson::Document json; json.Parse(R"({ "Scale" : 5.5 })"); diff --git a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp index fb9b1a4aa4..c18e83ab63 100644 --- a/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp +++ b/Code/Framework/AzCore/Tests/Settings/SettingsRegistryConsoleUtilsTests.cpp @@ -55,7 +55,7 @@ namespace SettingsRegistryConsoleUtilsTests { constexpr const char* settingsKey = "/TestKey"; constexpr const char* expectedValue = "TestValue"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; EXPECT_TRUE(testConsole.PerformCommand(AZ::SettingsRegistryConsoleUtils::SettingsRegistrySet, { settingsKey, expectedValue })); @@ -69,7 +69,7 @@ namespace SettingsRegistryConsoleUtilsTests { constexpr const char* settingsKey = "/TestKey"; constexpr const char* expectedValue = "TestValue"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); // Scopes the console functor handle so that it destructs and unregisters the console functors { @@ -89,7 +89,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* settingsKey2 = "/TestKey2"; constexpr const char* expectedValue = R"(TestValue)"; constexpr const char* expectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; @@ -109,7 +109,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* settingsKey2 = "/TestKey2"; constexpr const char* expectedValue = R"(TestValue)"; constexpr const char* expectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); // Add settings to settings registry EXPECT_TRUE(m_registry->Set(settingsKey, expectedValue)); @@ -137,7 +137,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* settingsKey2 = "/TestKey2"; constexpr const char* expectedValue = R"(TestValue)"; constexpr const char* expectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; @@ -195,7 +195,7 @@ namespace SettingsRegistryConsoleUtilsTests constexpr const char* SettingsKey2 = "TestKey2"; constexpr const char* ExpectedValue = R"(TestValue)"; constexpr const char* ExpectedValue2 = R"(Hello World)"; - AZ::Console testConsole; + AZ::Console testConsole(*m_registry); AZ::SettingsRegistryConsoleUtils::ConsoleFunctorHandle handle{ AZ::SettingsRegistryConsoleUtils::RegisterAzConsoleCommands(*m_registry, testConsole) }; diff --git a/Code/Framework/AzCore/Tests/SettingsRegistryMergeUtilsTests.cpp b/Code/Framework/AzCore/Tests/SettingsRegistryMergeUtilsTests.cpp index 36b9757ce3..751d9ded6c 100644 --- a/Code/Framework/AzCore/Tests/SettingsRegistryMergeUtilsTests.cpp +++ b/Code/Framework/AzCore/Tests/SettingsRegistryMergeUtilsTests.cpp @@ -372,15 +372,15 @@ mac_remote_filesystem=0 -- We need to know this before we establish VFS because different platform assets -- are stored in different root folders in the cache. These correspond to the names -- In the asset processor config file. This value also controls what config file is read --- when you read system_xxxx_xxxx.cfg (for example, system_windows_pc.cfg or system_android_es3.cfg) +-- when you read system_xxxx_xxxx.cfg (for example, system_windows_pc.cfg or system_android_android.cfg) -- by default, pc assets (in the 'pc' folder) are used, with RC being fed 'pc' as the platform -- by default on console we use the default assets=pc for better iteration times -- we should turn on console specific assets only when in release and/or testing assets and/or loading performance -- that way most people will not need to have 3 different caches taking up disk space assets = pc -android_assets = es3 +android_assets = android ios_assets = ios -mac_assets = osx_gl +mac_assets = mac -- Add the IP address of your console to the white list that will connect to the asset processor here -- You can list addresses or CIDR's. CIDR's are helpful if you are using DHCP. A CIDR looks like an ip address with @@ -438,9 +438,9 @@ mac_wait_for_connect=0 ConfigFileParams::SettingsKeyValuePair{"/ios_remote_filesystem", AZ::s64{0}}, ConfigFileParams::SettingsKeyValuePair{"/mac_remote_filesystem", AZ::s64{0}}, ConfigFileParams::SettingsKeyValuePair{"/assets", AZStd::string_view{"pc"}}, - ConfigFileParams::SettingsKeyValuePair{"/android_assets", AZStd::string_view{"es3"}}, + ConfigFileParams::SettingsKeyValuePair{"/android_assets", AZStd::string_view{"android"}}, ConfigFileParams::SettingsKeyValuePair{"/ios_assets", AZStd::string_view{"ios"}}, - ConfigFileParams::SettingsKeyValuePair{"/mac_assets", AZStd::string_view{"osx_gl"}}, + ConfigFileParams::SettingsKeyValuePair{"/mac_assets", AZStd::string_view{"mac"}}, ConfigFileParams::SettingsKeyValuePair{"/connect_to_remote", AZ::s64{0}}, ConfigFileParams::SettingsKeyValuePair{"/windows_connect_to_remote", AZ::s64{1}}, ConfigFileParams::SettingsKeyValuePair{"/android_connect_to_remote", AZ::s64{0}}, @@ -478,20 +478,20 @@ test_asset_processor_tag = test_value [Platform pc] tags=tools,renderer,dx12,vulkan -[Platform es3] +[Platform android] tags=android,mobile,renderer,vulkan ; With Comments at the end [Platform ios] tags=mobile,renderer,metal -[Platform osx_gl] +[Platform mac] tags=tools,renderer,metal)" , AZStd::fixed_vector{ ConfigFileParams::SettingsKeyValuePair{"/test_asset_processor_tag", AZStd::string_view{"test_value"}}, ConfigFileParams::SettingsKeyValuePair{"/Platform pc/tags", AZStd::string_view{"tools,renderer,dx12,vulkan"}}, - ConfigFileParams::SettingsKeyValuePair{"/Platform es3/tags", AZStd::string_view{"android,mobile,renderer,vulkan"}}, + ConfigFileParams::SettingsKeyValuePair{"/Platform android/tags", AZStd::string_view{"android,mobile,renderer,vulkan"}}, ConfigFileParams::SettingsKeyValuePair{"/Platform ios/tags", AZStd::string_view{"mobile,renderer,metal"}}, - ConfigFileParams::SettingsKeyValuePair{"/Platform osx_gl/tags", AZStd::string_view{"tools,renderer,metal"}}, + ConfigFileParams::SettingsKeyValuePair{"/Platform mac/tags", AZStd::string_view{"tools,renderer,metal"}}, }} ) ); diff --git a/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp b/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp index f7651664bd..fc07db5b52 100644 --- a/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp +++ b/Code/Framework/AzCore/Tests/SettingsRegistryTests.cpp @@ -1228,27 +1228,33 @@ namespace SettingsRegistryTests TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyIsTooLong_ReturnsFalse) { - AZStd::string argument = AZStd::string::format("Te%*cst=Value", aznumeric_cast(AZ::SettingsRegistryImpl::MaxJsonPathLength), ' '); + constexpr int LongKeySize = 1024; + AZStd::string argument = AZStd::string::format("Te%*cst=Value", LongKeySize, ' '); EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, {}, {})); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyIsTooLongWithDivider_ReturnsFalse) { - AZStd::string argument = AZStd::string::format("/Te%*cst=Value", aznumeric_cast(AZ::SettingsRegistryImpl::MaxJsonPathLength), ' '); + constexpr int LongKeySize = 1024; + AZStd::string argument = AZStd::string::format("/Te%*cst=Value", LongKeySize, ' '); EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, "/Path", {})); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsTooLong_ReturnsFalse) { - AZStd::string argument = AZStd::string::format("Test=Val%*cue", aznumeric_cast(AZ::SettingsRegistryImpl::MaxCommandLineArgumentLength), ' '); + constexpr int LongValueSize = 1024; + AZStd::string argument = AZStd::string::format("Test=Val%*cue", LongValueSize, ' '); EXPECT_FALSE(m_registry->MergeCommandLineArgument(argument, {}, {})); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/Test")); } - TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingValue_ReturnsFalse) + TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingValue_ReturnsEmptyString) { - EXPECT_FALSE(m_registry->MergeCommandLineArgument("Test=", {}, {})); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::NoType, m_registry->GetType("/Test")); + EXPECT_TRUE(m_registry->MergeCommandLineArgument("Test=", {}, {})); + EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType("/Test")); + AZ::SettingsRegistryInterface::FixedValueString value; + EXPECT_TRUE(m_registry->Get(value, "/Test")); + EXPECT_TRUE(value.empty()); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_MissingKey_ReturnsFalse) @@ -1271,9 +1277,13 @@ namespace SettingsRegistryTests EXPECT_FALSE(m_registry->MergeCommandLineArgument(" =Value", {}, {})); } - TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsSpaces_ReturnsFalse) + TEST_F(SettingsRegistryTest, MergeCommandLineArgument_ValueIsSpaces_ReturnsEmptyString) { - EXPECT_FALSE(m_registry->MergeCommandLineArgument("Key= ", {}, {})); + EXPECT_TRUE(m_registry->MergeCommandLineArgument("Key= ", {}, {})); + EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType("/Key")); + AZ::SettingsRegistryInterface::FixedValueString value; + EXPECT_TRUE(m_registry->Get(value, "/Key")); + EXPECT_TRUE(value.empty()); } TEST_F(SettingsRegistryTest, MergeCommandLineArgument_KeyAndValueAreSpaces_ReturnsFalse) @@ -1367,9 +1377,8 @@ namespace SettingsRegistryTests TEST_F(SettingsRegistryTest, MergeSettingsFile_PathAsSubStringThatsTooLong_ReturnsFalse) { - char path[AZ::SettingsRegistryImpl::MaxFilePathLength + 1]; - memset(path, '1', sizeof(path)); - AZStd::string_view subPath(path, AZ::SettingsRegistryImpl::MaxFilePathLength); + constexpr AZStd::fixed_string path(AZ::IO::MaxPathLength + 1, '1'); + const AZStd::string_view subPath(path); AZ_TEST_START_TRACE_SUPPRESSION; bool result = m_registry->MergeSettingsFile(subPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch, {}, nullptr); @@ -1719,8 +1728,7 @@ namespace SettingsRegistryTests TEST_F(SettingsRegistryTest, MergeSettingsFolder_PathTooLong_ReportsErrorAndReturnsFalse) { - char path[AZ::SettingsRegistryImpl::MaxFilePathLength + 1]{}; - memset(path, 'a', AZ_ARRAY_SIZE(path)); + constexpr AZStd::fixed_string path(AZ::IO::MaxPathLength + 1, 'a'); AZ_TEST_START_TRACE_SUPPRESSION; bool result = m_registry->MergeSettingsFolder(path, { "editor", "test" }, {}, nullptr); @@ -1741,7 +1749,7 @@ namespace SettingsRegistryTests m_testFolder->push_back(AZ_CORRECT_DATABASE_SEPARATOR); *m_testFolder += AZ::SettingsRegistryInterface::RegistryFolder; bool result = m_registry->MergeSettingsFolder(*m_testFolder, { "editor", "test" }, {}, nullptr); - AZ_TEST_STOP_TRACE_SUPPRESSION(2); + EXPECT_GT(::UnitTest::TestRunner::Instance().StopAssertTests(), 0); EXPECT_FALSE(result); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Object, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/0")); // Folder and specialization settings. @@ -1751,11 +1759,5 @@ namespace SettingsRegistryTests EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/Path")); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/File1")); EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/1/File2")); - - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::Object, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/Error")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/Path")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/File1")); - EXPECT_EQ(AZ::SettingsRegistryInterface::Type::String, m_registry->GetType(AZ_SETTINGS_REGISTRY_HISTORY_KEY "/2/File2")); } } // namespace SettingsRegistryTests diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake index 2129761bfe..78b2701d92 100644 --- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake +++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake @@ -111,6 +111,7 @@ set(FILES Serialization/Json/JsonSerializerMock.h Serialization/Json/MapSerializerTests.cpp Serialization/Json/MathVectorSerializerTests.cpp + Serialization/Json/MathMatrixSerializerTests.cpp Serialization/Json/SmartPointerSerializerTests.cpp Serialization/Json/StringSerializerTests.cpp Serialization/Json/TestCases.h @@ -151,6 +152,7 @@ set(FILES Math/PlaneTests.cpp Math/QuaternionPerformanceTests.cpp Math/QuaternionTests.cpp + Math/RandomTests.cpp Math/ShapeIntersectionPerformanceTests.cpp Math/ShapeIntersectionTests.cpp Math/SfmtTests.cpp diff --git a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp index ba313812ce..c65ba373f8 100644 --- a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp +++ b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp @@ -52,8 +52,6 @@ #include #include #include -#include -#include #include #include #include @@ -66,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -197,7 +194,6 @@ namespace AzFramework ApplicationRequests::Bus::Handler::BusConnect(); AZ::UserSettingsFileLocatorBus::Handler::BusConnect(); - NetSystemRequestBus::Handler::BusConnect(); } Application::~Application() @@ -207,7 +203,6 @@ namespace AzFramework Stop(); } - NetSystemRequestBus::Handler::BusDisconnect(); AZ::UserSettingsFileLocatorBus::Handler::BusDisconnect(); ApplicationRequests::Bus::Handler::BusDisconnect(); @@ -241,8 +236,6 @@ namespace AzFramework // Archive classes relies on the FileIOBase DirectInstance to close // files properly m_directFileIO.reset(); - - // The AZ::Console skips destruction and always leaks to allow it to be used in static memory } void Application::Start(const Descriptor& descriptor, const StartupParameters& startupParameters) @@ -285,13 +278,6 @@ namespace AzFramework m_pimpl.reset(); - /* The following line of code is a temporary fix. - * GridMate's ReplicaChunkDescriptor is stored in a global environment variable 'm_globalDescriptorTable' - * which does not get cleared when Application shuts down. We need to un-reflect here to clear ReplicaChunkDescriptor - * so that ReplicaChunkDescriptor::m_vdt doesn't get flooded when we repeatedly instantiate Application in unit tests. - */ - AZ::ReflectionEnvironment::GetReflectionManager()->RemoveReflectContext(); - // Free any memory owned by the command line container. m_commandLine = CommandLine(); @@ -320,8 +306,6 @@ namespace AzFramework azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), - azrtti_typeid(), - azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), @@ -457,9 +441,6 @@ namespace AzFramework void Application::CreateReflectionManager() { ComponentApplication::CreateReflectionManager(); - - // Setup NetworkContext - AZ::ReflectionEnvironment::GetReflectionManager()->AddReflectContext(); } //////////////////////////////////////////////////////////////////////////// @@ -479,19 +460,6 @@ namespace AzFramework return uuid; } - //////////////////////////////////////////////////////////////////////////// - NetworkContext* Application::GetNetworkContext() - { - NetworkContext* result = nullptr; - - if (auto reflectionManager = AZ::ReflectionEnvironment::GetReflectionManager()) - { - result = reflectionManager->GetReflectContext(); - } - - return result; - } - void Application::ResolveEnginePath(AZStd::string& engineRelativePath) const { AZ::IO::FixedMaxPath fullPath = m_engineRoot / engineRelativePath; @@ -711,8 +679,6 @@ namespace AzFramework { auto fileIoBase = m_archiveFileIO.get(); // Set up the default file aliases based on the settings registry - fileIoBase->SetAlias("@assets@", ""); - fileIoBase->SetAlias("@root@", GetEngineRoot()); fileIoBase->SetAlias("@engroot@", GetEngineRoot()); fileIoBase->SetAlias("@projectroot@", GetEngineRoot()); fileIoBase->SetAlias("@exefolder@", GetExecutableFolder()); @@ -726,8 +692,8 @@ namespace AzFramework pathAliases.clear(); if (m_settingsRegistry->Get(pathAliases.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder)) { - fileIoBase->SetAlias("@projectplatformcache@", pathAliases.c_str()); fileIoBase->SetAlias("@assets@", pathAliases.c_str()); + fileIoBase->SetAlias("@projectplatformcache@", pathAliases.c_str()); fileIoBase->SetAlias("@root@", pathAliases.c_str()); // Deprecated Use @projectplatformcache@ } pathAliases.clear(); diff --git a/Code/Framework/AzFramework/AzFramework/Application/Application.h b/Code/Framework/AzFramework/AzFramework/Application/Application.h index 4d7e45a423..6b1283be34 100644 --- a/Code/Framework/AzFramework/AzFramework/Application/Application.h +++ b/Code/Framework/AzFramework/AzFramework/Application/Application.h @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -49,7 +48,6 @@ namespace AzFramework : public AZ::ComponentApplication , public AZ::UserSettingsFileLocatorBus::Handler , public ApplicationRequests::Bus::Handler - , public NetSystemRequestBus::Handler { public: // Base class for platform specific implementations of the application. @@ -138,11 +136,6 @@ namespace AzFramework // Convenience function that should be called instead of the standard exit() function to ensure platform requirements are met. static void Exit(int errorCode) { ApplicationRequests::Bus::Broadcast(&ApplicationRequests::TerminateOnError, errorCode); } - ////////////////////////////////////////////////////////////////////////// - //! NetSystemEventBus::Handler - ////////////////////////////////////////////////////////////////////////// - NetworkContext* GetNetworkContext() override; - protected: /** diff --git a/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp b/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp index b0285616df..4a80db2b24 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp +++ b/Code/Framework/AzFramework/AzFramework/Archive/Archive.cpp @@ -2008,13 +2008,12 @@ namespace AZ::IO // if no bind root is specified, compute one: strBindRoot = !bindRoot.empty() ? bindRoot : szFullPath->ParentPath().Native(); - // Check if archive file disk exist on disk or inside of pak. - bool bFileExists = IsFileExist(szFullPath->Native()); - - if (!bFileExists && (nFactoryFlags & ZipDir::CacheFactory::FLAGS_READ_ONLY)) + // Check if archive file disk exist on disk. + const bool pakOnDisk = FileIOBase::GetDirectInstance()->Exists(szFullPath->c_str()); + if (!pakOnDisk && (nFactoryFlags & ZipDir::CacheFactory::FLAGS_READ_ONLY)) { // Archive file not found. - AZ_TracePrintf("Archive", "Cannot open Archive file %s\n", szFullPath->c_str()); + AZ_TracePrintf("Archive", "Archive file %s does not exist\n", szFullPath->c_str()); return nullptr; } @@ -2492,8 +2491,6 @@ namespace AZ::IO void Archive::FindCompressionInfo(bool& found, AZ::IO::CompressionInfo& info, const AZStd::string_view filename) { - constexpr uint32_t s_compressionTag = static_cast('Z') << 24 | static_cast('C') << 16 | static_cast('R') << 8 | static_cast('Y'); - if (!found) { auto correctedFilename = AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(filename); @@ -2519,7 +2516,6 @@ namespace AZ::IO found = true; info.m_archiveFilename.InitFromRelativePath(archive->GetFilePath()); - info.m_compressionTag.m_code = s_compressionTag; info.m_offset = pFileData->GetFileDataOffset(); info.m_compressedSize = entry->desc.lSizeCompressed; info.m_uncompressedSize = entry->desc.lSizeUncompressed; @@ -2539,9 +2535,8 @@ namespace AZ::IO break; } - info.m_decompressor = [&s_compressionTag]([[maybe_unused]] const AZ::IO::CompressionInfo& info, const void* compressed, size_t compressedSize, void* uncompressed, size_t uncompressedBufferSize)->bool + info.m_decompressor = []([[maybe_unused]] const AZ::IO::CompressionInfo& info, const void* compressed, size_t compressedSize, void* uncompressed, size_t uncompressedBufferSize)->bool { - AZ_Assert(info.m_compressionTag.m_code == s_compressionTag, "Provided compression info isn't supported by this decompressor."); size_t nSizeUncompressed = uncompressedBufferSize; return ZipDir::ZipRawUncompress(uncompressed, &nSizeUncompressed, compressed, compressedSize) == 0; }; diff --git a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveFindData.cpp b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveFindData.cpp index 678f4e40bf..1794ae90e7 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveFindData.cpp +++ b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveFindData.cpp @@ -50,6 +50,7 @@ namespace AZ::IO , tWrite{ writeTime } { } + ArchiveFileIterator::ArchiveFileIterator(FindData* findData, AZStd::string_view filename, const FileDesc& fileDesc) : m_findData{ findData } , m_filename{ filename } @@ -108,13 +109,10 @@ namespace AZ::IO AZ::StringFunc::Path::GetFullPath(directory.c_str(), searchDirectory); AZ::StringFunc::Path::GetFullFileName(directory.c_str(), pattern); } - AZ::IO::FileIOBase::GetDirectInstance()->FindFiles(searchDirectory.c_str(), pattern.c_str(), [&](const char* filePath) -> bool { AZ::IO::FileDesc fileDesc; - - AZStd::string fullFilePath; - AZ::StringFunc::Path::GetFullFileName(filePath, fullFilePath); + AZStd::string filePathEntry{filePath}; if (AZ::IO::FileIOBase::GetDirectInstance()->IsDirectory(filePath)) { @@ -135,9 +133,8 @@ namespace AZ::IO fileDesc.tAccess = fileDesc.tWrite; fileDesc.tCreate = fileDesc.tWrite; } - [[maybe_unused]] auto result = m_mapFiles.emplace(AZStd::move(fullFilePath), fileDesc); - AZ_Assert(result.second, "Failed to insert FindData entry for %s", fullFilePath.c_str()); - + [[maybe_unused]] auto result = m_mapFiles.emplace(AZStd::move(filePathEntry), fileDesc); + AZ_Assert(result.second, "Failed to insert FindData entry for filePath %s", filePath); return true; }); } @@ -273,7 +270,9 @@ namespace AZ::IO } auto pakFileIter = m_mapFiles.begin(); - fileIterator.m_filename = pakFileIter->first; + AZStd::string fullFilePath; + AZ::StringFunc::Path::GetFullFileName(pakFileIter->first.c_str(), fullFilePath); + fileIterator.m_filename = AZStd::move(fullFilePath); fileIterator.m_fileDesc = pakFileIter->second; fileIterator.m_lastFetchValid = true; diff --git a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h index fd72c37b60..f5f1428ed6 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h +++ b/Code/Framework/AzFramework/AzFramework/Archive/ArchiveVars.h @@ -24,7 +24,7 @@ namespace AZ::IO ePakPriorityPakOnly = 2 }; - // variables that control behavior of Archive/StreamEngine subsystems + // variables that control behavior of the Archive subsystem struct ArchiveVars { #if defined(_RELEASE) @@ -51,7 +51,6 @@ namespace AZ::IO : ArchiveLocationPriority::ePakPriorityFileFirst }; // Which file location to favor (loose vs. pak files) int nMessageInvalidFileAccess{}; int nLogInvalidFileAccess{ IsReleaseConfig ? 0 : 1 }; - int nLoadFrontendShaderCache{ FRONTEND_SHADER_CACHE_DEFAULT }; int nDisableNonLevelRelatedPaks{ 1 }; int nWarnOnPakAccessFails{ 1 }; // Whether to treat failed pak access as a warning or log message int nSetLogLevel{ 3 }; diff --git a/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h b/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h index f5de1a0f3a..ce8403b033 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h +++ b/Code/Framework/AzFramework/AzFramework/Archive/IArchive.h @@ -115,7 +115,7 @@ namespace AZ::IO // If used, the source path will be treated as the destination path // and no transformations will be done. Pass this flag when the path is to be the actual // path on the disk/in the packs and doesn't need adjustment (or after it has come through adjustments already) - // if this is set, AdjustFileName will not map the input path into the master folder (Ex: Shaders will not be converted to Game\Shaders) + // if this is set, AdjustFileName will not map the input path into the folder (Ex: Shaders will not be converted to Game\Shaders) FLAGS_PATH_REAL = 1 << 16, // AdjustFileName will always copy the file path to the destination path: @@ -318,7 +318,6 @@ namespace AZ::IO virtual ArchiveFileIterator FindFirst(AZStd::string_view pDir, uint32_t nFlags = 0, bool bAllowUseFileSystem = false) = 0; virtual ArchiveFileIterator FindNext(AZ::IO::ArchiveFileIterator handle) = 0; virtual bool FindClose(AZ::IO::ArchiveFileIterator handle) = 0; - // virtual bool IsOutOfDate(const char * szCompiledName, const char * szMasterFile)=0; //returns file modification time virtual IArchive::FileTime GetModificationTime(AZ::IO::HandleType fileHandle) = 0; diff --git a/Code/Framework/AzFramework/AzFramework/Archive/INestedArchive.h b/Code/Framework/AzFramework/AzFramework/Archive/INestedArchive.h index 25d36f009b..29a1030cf0 100644 --- a/Code/Framework/AzFramework/AzFramework/Archive/INestedArchive.h +++ b/Code/Framework/AzFramework/AzFramework/Archive/INestedArchive.h @@ -47,7 +47,7 @@ namespace AZ::IO enum EPakFlags { // support for absolute and other complex path specifications - - // all paths will be treated relatively to the current directory (normally MasterCD) + // all paths will be treated relatively to the current directory FLAGS_ABSOLUTE_PATHS = 1, // if this is set, the object will only understand relative to the zip file paths, diff --git a/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.cpp b/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.cpp index 020feffc47..7280c4af5c 100644 --- a/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.cpp +++ b/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.cpp @@ -308,6 +308,56 @@ namespace AzFramework } } + //--------------------------------------------------------------------- + GenerateRelativeSourcePathRequest::GenerateRelativeSourcePathRequest(const AZ::OSString& sourcePath) + { + AZ_Assert(!sourcePath.empty(), "GenerateRelativeSourcePathRequest: asset path is empty"); + m_sourcePath = sourcePath; + } + + unsigned int GenerateRelativeSourcePathRequest::GetMessageType() const + { + return MessageType; + } + + void GenerateRelativeSourcePathRequest::Reflect(AZ::ReflectContext* context) + { + auto serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(1) + ->Field("SourcePath", &GenerateRelativeSourcePathRequest::m_sourcePath); + } + } + + //--------------------------------------------------------------------- + GenerateRelativeSourcePathResponse::GenerateRelativeSourcePathResponse( + bool resolved, const AZ::OSString& relativeSourcePath, const AZ::OSString& rootFolder) + { + m_relativeSourcePath = relativeSourcePath; + m_resolved = resolved; + m_rootFolder = rootFolder; + } + + unsigned int GenerateRelativeSourcePathResponse::GetMessageType() const + { + return GenerateRelativeSourcePathRequest::MessageType; + } + + void GenerateRelativeSourcePathResponse::Reflect(AZ::ReflectContext* context) + { + auto serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(1) + ->Field("RelativeSourcePath", &GenerateRelativeSourcePathResponse::m_relativeSourcePath) + ->Field("RootFolder", &GenerateRelativeSourcePathResponse::m_rootFolder) + ->Field("Resolved", &GenerateRelativeSourcePathResponse::m_resolved); + } + } + //--------------------------------------------------------------------- GetFullSourcePathFromRelativeProductPathRequest::GetFullSourcePathFromRelativeProductPathRequest(const AZ::OSString& relativeProductPath) { diff --git a/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.h b/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.h index 9661e61828..c15f75e3e7 100644 --- a/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.h +++ b/Code/Framework/AzFramework/AzFramework/Asset/AssetProcessorMessages.h @@ -288,6 +288,45 @@ namespace AzFramework bool m_resolved; }; + ////////////////////////////////////////////////////////////////////////// + class GenerateRelativeSourcePathRequest : public BaseAssetProcessorMessage + { + public: + AZ_CLASS_ALLOCATOR(GenerateRelativeSourcePathRequest, AZ::OSAllocator, 0); + AZ_RTTI(GenerateRelativeSourcePathRequest, "{B3865033-F5A3-4749-8147-7B1AB04D5F6D}", + BaseAssetProcessorMessage); + static void Reflect(AZ::ReflectContext* context); + + // For people that are debugging the network messages and just see MessageType as a value, + // the CRC value below is 739777771 (0x2C181CEB) + static constexpr unsigned int MessageType = + AZ_CRC_CE("AssetSystem::GenerateRelativeSourcePathRequest"); + + GenerateRelativeSourcePathRequest() = default; + GenerateRelativeSourcePathRequest(const AZ::OSString& sourcePath); + unsigned int GetMessageType() const override; + + AZ::OSString m_sourcePath; + }; + + class GenerateRelativeSourcePathResponse : public BaseAssetProcessorMessage + { + public: + AZ_CLASS_ALLOCATOR(GenerateRelativeSourcePathResponse, AZ::OSAllocator, 0); + AZ_RTTI(GenerateRelativeSourcePathResponse, "{938D33DB-C8F6-4FA4-BC81-2F139A9BE1D7}", + BaseAssetProcessorMessage); + static void Reflect(AZ::ReflectContext* context); + + GenerateRelativeSourcePathResponse() = default; + GenerateRelativeSourcePathResponse( + bool resolved, const AZ::OSString& relativeSourcePath, const AZ::OSString& rootFolder); + unsigned int GetMessageType() const override; + + AZ::OSString m_relativeSourcePath; + AZ::OSString m_rootFolder; ///< This is the folder it was found in (the watched/scanned folder, such as gems /assets/ folder) + bool m_resolved; + }; + ////////////////////////////////////////////////////////////////////////// class GetFullSourcePathFromRelativeProductPathRequest : public BaseAssetProcessorMessage diff --git a/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponent.cpp index 83c4907468..6b19084c2a 100644 --- a/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Asset/AssetSystemComponent.cpp @@ -202,6 +202,7 @@ namespace AzFramework // Requests GetUnresolvedDependencyCountsRequest::Reflect(context); GetRelativeProductPathFromFullSourceOrProductPathRequest::Reflect(context); + GenerateRelativeSourcePathRequest::Reflect(context); GetFullSourcePathFromRelativeProductPathRequest::Reflect(context); SourceAssetInfoRequest::Reflect(context); AssetInfoRequest::Reflect(context); @@ -234,6 +235,7 @@ namespace AzFramework // Responses GetUnresolvedDependencyCountsResponse::Reflect(context); GetRelativeProductPathFromFullSourceOrProductPathResponse::Reflect(context); + GenerateRelativeSourcePathResponse::Reflect(context); GetFullSourcePathFromRelativeProductPathResponse::Reflect(context); SourceAssetInfoResponse::Reflect(context); AssetInfoResponse::Reflect(context); diff --git a/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp b/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp index 644a7d099d..d1e4b4977a 100644 --- a/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp +++ b/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp @@ -22,8 +22,6 @@ #include #include #include -#include -#include #include #include #include @@ -42,8 +40,6 @@ namespace AzFramework AzFramework::AssetCatalogComponent::CreateDescriptor(), AzFramework::CustomAssetTypeComponent::CreateDescriptor(), AzFramework::FileTag::ExcludeFileComponent::CreateDescriptor(), - AzFramework::NetBindingComponent::CreateDescriptor(), - AzFramework::NetBindingSystemComponent::CreateDescriptor(), AzFramework::TransformComponent::CreateDescriptor(), AzFramework::NonUniformScaleComponent::CreateDescriptor(), AzFramework::GameEntityContextComponent::CreateDescriptor(), diff --git a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h index 682e886061..ee8b79bf06 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h +++ b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.h @@ -1,22 +1,22 @@ /* -* 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. -* -*/ + * 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. + * + */ #pragma once #include #include -#include #include #include +#include namespace AzFramework { @@ -64,15 +64,13 @@ namespace AzFramework the EditContext. TController can friend itself to the editor component to make this work if required. */ template - class ComponentAdapter - : public AZ::Component + class ComponentAdapter : public AZ::Component { public: - AZ_RTTI((ComponentAdapter, "{644A9187-4FDB-42C1-9D59-DD75304B551A}", TController, TConfiguration), AZ::Component); ComponentAdapter() = default; - ComponentAdapter(const TConfiguration& configuration); + explicit ComponentAdapter(const TConfiguration& configuration); static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); @@ -85,7 +83,6 @@ namespace AzFramework void Deactivate() override; protected: - static void Reflect(AZ::ReflectContext* context); // AZ::Component overrides ... diff --git a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl index a1b0826193..5c36ff0bf7 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl +++ b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapter.inl @@ -1,14 +1,14 @@ /* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ + * 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. + * + */ #include @@ -32,10 +32,12 @@ namespace AzFramework if (auto serializeContext = azrtti_cast(context)) { + // clang-format off serializeContext->Class() ->Version(1) ->Field("Controller", &ComponentAdapter::m_controller) ; + // clang-format on } } @@ -66,9 +68,6 @@ namespace AzFramework GetDependentServicesHelper(services, typename AZ::HasComponentDependentServices::type()); } - ////////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - template void ComponentAdapter::Init() { @@ -78,7 +77,7 @@ namespace AzFramework template void ComponentAdapter::Activate() { - m_controller.Activate(GetEntityId()); + ComponentActivateHelper::Activate(m_controller, AZ::EntityComponentIdPair(GetEntityId(), GetId())); } template diff --git a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h index 158ee95f39..f0ef262a71 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h +++ b/Code/Framework/AzFramework/AzFramework/Components/ComponentAdapterHelpers.h @@ -13,6 +13,7 @@ #pragma once #include +#include namespace AzFramework { @@ -27,18 +28,43 @@ namespace AzFramework template struct ComponentInitHelper { - static void Init(T& common) + static void Init([[maybe_unused]] T& controller) { - AZ_UNUSED(common); } }; template struct ComponentInitHelper().Init())>> { - static void Init(T& common) + static void Init(T& controller) { - common.Init(); + controller.Init(); + } + }; + + template + struct ComponentActivateHelper + { + static void Activate([[maybe_unused]] T& controller, [[maybe_unused]] const AZ::EntityComponentIdPair& entityComponentIdPair) + { + } + }; + + template + struct ComponentActivateHelper().Activate(AZ::EntityId()))>> + { + static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair) + { + controller.Activate(entityComponentIdPair.GetEntityId()); + } + }; + + template + struct ComponentActivateHelper().Activate(AZ::EntityComponentIdPair()))>> + { + static void Activate(T& controller, const AZ::EntityComponentIdPair& entityComponentIdPair) + { + controller.Activate(entityComponentIdPair); } }; diff --git a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp index 095d986fa1..d51f3645d3 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/NonUniformScaleComponent.cpp @@ -36,28 +36,7 @@ namespace AzFramework void NonUniformScaleComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { - incompatible.push_back(AZ_CRC_CE("DebugDrawObbService")); - incompatible.push_back(AZ_CRC_CE("DebugDrawService")); - incompatible.push_back(AZ_CRC_CE("EMotionFXActorService")); - incompatible.push_back(AZ_CRC_CE("EMotionFXSimpleMotionService")); - incompatible.push_back(AZ_CRC_CE("GradientTransformService")); - incompatible.push_back(AZ_CRC_CE("LegacyMeshService")); - incompatible.push_back(AZ_CRC_CE("LookAtService")); - incompatible.push_back(AZ_CRC_CE("SequenceService")); - incompatible.push_back(AZ_CRC_CE("ClothMeshService")); - incompatible.push_back(AZ_CRC_CE("PhysXJointService")); - incompatible.push_back(AZ_CRC_CE("PhysXCharacterControllerService")); - incompatible.push_back(AZ_CRC_CE("PhysXRagdollService")); - incompatible.push_back(AZ_CRC_CE("WhiteBoxService")); - incompatible.push_back(AZ_CRC_CE("NavigationAreaService")); - incompatible.push_back(AZ_CRC_CE("GeometryService")); - incompatible.push_back(AZ_CRC_CE("CapsuleShapeService")); - incompatible.push_back(AZ_CRC_CE("CompoundShapeService")); - incompatible.push_back(AZ_CRC_CE("CylinderShapeService")); - incompatible.push_back(AZ_CRC_CE("DiskShapeService")); - incompatible.push_back(AZ_CRC_CE("SphereShapeService")); - incompatible.push_back(AZ_CRC_CE("SplineService")); - incompatible.push_back(AZ_CRC_CE("TubeShapeService")); + incompatible.push_back(AZ_CRC_CE("NonUniformScaleService")); } void NonUniformScaleComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 910d6749af..b3c4f1b256 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -11,10 +11,12 @@ */ #include +#include #include #include #include #include +#include #include #include @@ -325,99 +327,13 @@ namespace AzFramework return localZ; } - void TransformComponent::SetRotation(const AZ::Vector3& eulerAnglesRadian) + void TransformComponent::SetWorldRotationQuaternion(const AZ::Quaternion& quaternion) { - AZ_Warning("TransformComponent", false, "SetRotation is deprecated, please use SetLocalRotation"); - - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetRotation(AZ::ConvertEulerRadiansToQuaternion(eulerAnglesRadian)); - SetWorldTM(newWorldTransform); - } - - void TransformComponent::SetRotationQuaternion(const AZ::Quaternion& quaternion) - { - AZ_Warning("TransformComponent", false, "SetRotationQuaternion is deprecated, please use SetLocalRotationQuaternion"); - AZ::Transform newWorldTransform = m_worldTM; newWorldTransform.SetRotation(quaternion); SetWorldTM(newWorldTransform); } - void TransformComponent::SetRotationX(float eulerAngleRadian) - { - AZ_Warning("TransformComponent", false, "SetRotationX is deprecated, please use SetLocalRotation"); - - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationX(eulerAngleRadian)); - SetWorldTM(newWorldTransform); - } - - void TransformComponent::SetRotationY(float eulerAngleRadian) - { - AZ_Warning("TransformComponent", false, "SetRotationY is deprecated, please use SetLocalRotation"); - - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationY(eulerAngleRadian)); - SetWorldTM(newWorldTransform); - } - - void TransformComponent::SetRotationZ(float eulerAngleRadian) - { - AZ_Warning("TransformComponent", false, "SetRotationZ is deprecated, please use SetLocalRotation"); - - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetRotation(AZ::Quaternion::CreateRotationZ(eulerAngleRadian)); - SetWorldTM(newWorldTransform); - } - - void TransformComponent::RotateByX(float eulerAngleRadian) - { - AZ_Warning("TransformComponent", false, "RotateByX is deprecated, please use RotateAroundLocalX"); - RotateAroundLocalX(eulerAngleRadian); - } - - void TransformComponent::RotateByY(float eulerAngleRadian) - { - AZ_Warning("TransformComponent", false, "RotateByY is deprecated, please use RotateAroundLocalY"); - RotateAroundLocalY(eulerAngleRadian); - } - - void TransformComponent::RotateByZ(float eulerAngleRadian) - { - AZ_Warning("TransformComponent", false, "RotateByZ is deprecated, please use RotateAroundLocalZ"); - RotateAroundLocalZ(eulerAngleRadian); - } - - AZ::Vector3 TransformComponent::GetRotationEulerRadians() - { - AZ_Warning("TransformComponent", false, "GetRotationEulerRadians is deprecated, please use GetWorldRotation"); - return m_worldTM.GetRotation().GetEulerRadians(); - } - - AZ::Quaternion TransformComponent::GetRotationQuaternion() - { - AZ_Warning("TransformComponent", false, "GetRotationQuaternion is deprecated, please use GetWorldRotationQuaternion"); - return m_worldTM.GetRotation(); - } - - float TransformComponent::GetRotationX() - { - AZ_Warning("TransformComponent", false, "GetRotationX is deprecated, please use GetWorldRotation"); - return GetRotationEulerRadians().GetX(); - } - - float TransformComponent::GetRotationY() - { - AZ_Warning("TransformComponent", false, "GetRotationY is deprecated, please use GetWorldRotation"); - return GetRotationEulerRadians().GetY(); - } - - float TransformComponent::GetRotationZ() - { - AZ_Warning("TransformComponent", false, "GetRotationZ is deprecated, please use GetWorldRotation"); - return GetRotationEulerRadians().GetZ(); - } - AZ::Vector3 TransformComponent::GetWorldRotation() { return m_worldTM.GetRotation().GetEulerRadians(); @@ -430,46 +346,26 @@ namespace AzFramework void TransformComponent::SetLocalRotation(const AZ::Vector3& eulerRadianAngles) { - AZ::Transform newLocalTM = AZ::ConvertEulerRadiansToTransform(eulerRadianAngles); - newLocalTM.SetScale(m_localTM.GetScale()); - newLocalTM.SetTranslation(m_localTM.GetTranslation()); + AZ::Transform newLocalTM = m_localTM; + newLocalTM.SetRotation(AZ::Quaternion::CreateFromEulerAnglesRadians(eulerRadianAngles)); SetLocalTM(newLocalTM); } void TransformComponent::SetLocalRotationQuaternion(const AZ::Quaternion& quaternion) { - AZ::Transform newLocalTM; - newLocalTM.SetScale(m_localTM.GetScale()); - newLocalTM.SetTranslation(m_localTM.GetTranslation()); + AZ::Transform newLocalTM = m_localTM; newLocalTM.SetRotation(quaternion); SetLocalTM(newLocalTM); } static AZ::Transform RotateAroundLocalHelper(float eulerAngleRadian, const AZ::Transform& localTM, AZ::Vector3 axis) { - //get the existing translation and scale - AZ::Vector3 translation = localTM.GetTranslation(); - AZ::Vector3 scale = localTM.GetScale(); - //normalize the axis before creating rotation axis.Normalize(); AZ::Quaternion rotate = AZ::Quaternion::CreateFromAxisAngle(axis, eulerAngleRadian); - //create new rotation transform - AZ::Quaternion currentRotate = localTM.GetRotation(); - AZ::Quaternion newRotate = rotate * currentRotate; - newRotate.Normalize(); - - //scale - AZ::Transform newLocalTM = AZ::Transform::CreateScale(scale); - - //rotate - AZ::Transform rotateLocalTM = AZ::Transform::CreateFromQuaternion(newRotate); - newLocalTM = rotateLocalTM * newLocalTM; - - //translate - newLocalTM.SetTranslation(translation); - + AZ::Transform newLocalTM = localTM; + newLocalTM.SetRotation((rotate * localTM.GetRotation()).GetNormalized()); return newLocalTM; } @@ -510,117 +406,27 @@ namespace AzFramework return m_localTM.GetRotation(); } - void TransformComponent::SetScale(const AZ::Vector3& scale) - { - AZ_Warning("TransformComponent", false, "SetScale is deprecated, please use SetLocalScale"); - - if (!m_worldTM.GetScale().IsClose(scale)) - { - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetScale(scale); - SetWorldTM(newWorldTransform); - } - } - - void TransformComponent::SetScaleX(float scaleX) - { - AZ_Warning("TransformComponent", false, "SetScaleX is deprecated, please use SetLocalScaleX"); - - AZ::Vector3 newScale = m_worldTM.GetScale(); - newScale.SetX(scaleX); - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetScale(newScale); - SetWorldTM(newWorldTransform); - } - - void TransformComponent::SetScaleY(float scaleY) - { - AZ_Warning("TransformComponent", false, "SetScaleY is deprecated, please use SetLocalScaleY"); - - AZ::Vector3 newScale = m_worldTM.GetScale(); - newScale.SetY(scaleY); - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetScale(newScale); - SetWorldTM(newWorldTransform); - } - - void TransformComponent::SetScaleZ(float scaleZ) - { - AZ_Warning("TransformComponent", false, "SetScaleZ is deprecated, please use SetLocalScaleZ"); - - AZ::Vector3 newScale = m_worldTM.GetScale(); - newScale.SetZ(scaleZ); - AZ::Transform newWorldTransform = m_worldTM; - newWorldTransform.SetScale(newScale); - SetWorldTM(newWorldTransform); - } - - AZ::Vector3 TransformComponent::GetScale() - { - AZ_Warning("TransformComponent", false, "GetScale is deprecated, please use GetLocalScale"); - return m_worldTM.GetScale(); - } - - float TransformComponent::GetScaleX() - { - AZ_Warning("TransformComponent", false, "GetScaleX is deprecated, please use GetLocalScale"); - return m_worldTM.GetScale().GetX(); - } - - float TransformComponent::GetScaleY() - { - AZ_Warning("TransformComponent", false, "GetScaleY is deprecated, please use GetLocalScale"); - return m_worldTM.GetScale().GetY(); - } - - float TransformComponent::GetScaleZ() - { - AZ_Warning("TransformComponent", false, "GetScaleZ is deprecated, please use GetLocalScale"); - return m_worldTM.GetScale().GetZ(); - } - - void TransformComponent::SetLocalScale(const AZ::Vector3& scale) - { - AZ::Transform newLocalTM = m_localTM; - newLocalTM.SetScale(scale); - SetLocalTM(newLocalTM); - } - - void TransformComponent::SetLocalScaleX(float scaleX) - { - AZ::Transform newLocalTM = m_localTM; - AZ::Vector3 newScale = newLocalTM.GetScale(); - newScale.SetX(scaleX); - newLocalTM.SetScale(newScale); - SetLocalTM(newLocalTM); - } - - void TransformComponent::SetLocalScaleY(float scaleY) - { - AZ::Transform newLocalTM = m_localTM; - AZ::Vector3 newScale = newLocalTM.GetScale(); - newScale.SetY(scaleY); - newLocalTM.SetScale(newScale); - SetLocalTM(newLocalTM); - } - - void TransformComponent::SetLocalScaleZ(float scaleZ) - { - AZ::Transform newLocalTM = m_localTM; - AZ::Vector3 newScale = newLocalTM.GetScale(); - newScale.SetZ(scaleZ); - newLocalTM.SetScale(newScale); - SetLocalTM(newLocalTM); - } - AZ::Vector3 TransformComponent::GetLocalScale() { - return m_localTM.GetScale(); + AZ_WarningOnce("TransformComponent", false, "GetLocalScale is deprecated, please use GetLocalUniformScale instead"); + return AZ::Vector3(m_localTM.GetUniformScale()); } - AZ::Vector3 TransformComponent::GetWorldScale() + void TransformComponent::SetLocalUniformScale(float scale) { - return m_worldTM.GetScale(); + AZ::Transform newLocalTM = m_localTM; + newLocalTM.SetUniformScale(scale); + SetLocalTM(newLocalTM); + } + + float TransformComponent::GetLocalUniformScale() + { + return m_localTM.GetUniformScale(); + } + + float TransformComponent::GetWorldUniformScale() + { + return m_worldTM.GetUniformScale(); } AZStd::vector TransformComponent::GetChildren() @@ -693,9 +499,8 @@ namespace AzFramework parentId = handler->GetParentId(); } #endif - - AZ::Entity* parentEntity = nullptr; - EBUS_EVENT_RESULT(parentEntity, AZ::ComponentApplicationBus, FindEntity, parentEntityId); + AZ::ComponentApplicationRequests* componentApplication = AZ::Interface::Get(); + AZ::Entity* parentEntity = (componentApplication != nullptr) ? componentApplication->FindEntity(parentEntityId) : nullptr; AZ_Assert(parentEntity, "We expect to have a parent entity associated with the provided parent's entity Id."); if (parentEntity) { @@ -744,8 +549,8 @@ namespace AzFramework m_parentId = parentId; if (m_parentId.IsValid()) { - AZ::Entity* parentEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(parentEntity, &AZ::ComponentApplicationBus::Events::FindEntity, m_parentId); + AZ::ComponentApplicationRequests* componentApplication = AZ::Interface::Get(); + AZ::Entity* parentEntity = (componentApplication != nullptr) ? componentApplication->FindEntity(m_parentId) : nullptr; m_parentActive = parentEntity && (parentEntity->GetState() == AZ::Entity::State::Active); m_onNewParentKeepWorldTM = isKeepWorldTM; @@ -832,6 +637,12 @@ namespace AzFramework EBUS_EVENT_PTR(m_notificationBus, AZ::TransformNotificationBus, OnTransformChanged, m_localTM, m_worldTM); m_transformChangedEvent.Signal(m_localTM, m_worldTM); + + AzFramework::IEntityBoundsUnion* boundsUnion = AZ::Interface::Get(); + if (boundsUnion != nullptr) + { + boundsUnion->OnTransformUpdated(GetEntity()); + } } void TransformComponent::ComputeWorldTM() @@ -871,15 +682,15 @@ namespace AzFramework AZ::SerializeContext* serializeContext = azrtti_cast(reflection); if (serializeContext) { - serializeContext->Class() - ->Version(4, &TransformComponentVersionConverter) + serializeContext->ClassDeprecate("NetBindable", "{80206665-D429-4703-B42E-94434F82F381}"); + + serializeContext->Class() + ->Version(5, &TransformComponentVersionConverter) ->Field("Parent", &TransformComponent::m_parentId) ->Field("Transform", &TransformComponent::m_worldTM) ->Field("LocalTransform", &TransformComponent::m_localTM) ->Field("ParentActivationTransformMode", &TransformComponent::m_parentActivationTransformMode) ->Field("IsStatic", &TransformComponent::m_isStatic) - ->Field("InterpolatePosition", &TransformComponent::m_interpolatePosition) - ->Field("InterpolateRotation", &TransformComponent::m_interpolateRotation) ; } @@ -922,45 +733,7 @@ namespace AzFramework ->Event("GetLocalX", &AZ::TransformBus::Events::GetLocalX) ->Event("GetLocalY", &AZ::TransformBus::Events::GetLocalY) ->Event("GetLocalZ", &AZ::TransformBus::Events::GetLocalZ) - ->Event("RotateByX", &AZ::TransformBus::Events::RotateByX) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("RotateByY", &AZ::TransformBus::Events::RotateByY) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("RotateByZ", &AZ::TransformBus::Events::RotateByZ) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetEulerRotation", &AZ::TransformBus::Events::SetRotation) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetRotationQuaternion", &AZ::TransformBus::Events::SetRotationQuaternion) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetRotationX", &AZ::TransformBus::Events::SetRotationX) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetRotationY", &AZ::TransformBus::Events::SetRotationY) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetRotationZ", &AZ::TransformBus::Events::SetRotationZ) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetEulerRotation", &AZ::TransformBus::Events::GetRotationEulerRadians) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetRotationQuaternion", &AZ::TransformBus::Events::GetRotationQuaternion) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetRotationX", &AZ::TransformBus::Events::GetRotationX) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetRotationY", &AZ::TransformBus::Events::GetRotationY) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetRotationZ", &AZ::TransformBus::Events::GetRotationZ) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) + ->Event("SetWorldRotationQuaternion", &AZ::TransformBus::Events::SetWorldRotationQuaternion) ->Event("GetWorldRotation", &AZ::TransformBus::Events::GetWorldRotation) ->Event("GetWorldRotationQuaternion", &AZ::TransformBus::Events::GetWorldRotationQuaternion) ->Event("SetLocalRotation", &AZ::TransformBus::Events::SetLocalRotation) @@ -972,38 +745,11 @@ namespace AzFramework ->Event("GetLocalRotationQuaternion", &AZ::TransformBus::Events::GetLocalRotationQuaternion) ->Attribute("Rotation", AZ::Edit::Attributes::PropertyRotation) ->VirtualProperty("Rotation", "GetLocalRotationQuaternion", "SetLocalRotationQuaternion") - ->Event("SetScale", &AZ::TransformBus::Events::SetScale) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetScaleX", &AZ::TransformBus::Events::SetScaleX) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetScaleY", &AZ::TransformBus::Events::SetScaleY) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetScaleZ", &AZ::TransformBus::Events::SetScaleZ) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetScale", &AZ::TransformBus::Events::GetScale) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetScaleX", &AZ::TransformBus::Events::GetScaleX) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetScaleY", &AZ::TransformBus::Events::GetScaleY) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("GetScaleZ", &AZ::TransformBus::Events::GetScaleZ) - ->Attribute(AZ::Script::Attributes::Deprecated, true) - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All) - ->Event("SetLocalScale", &AZ::TransformBus::Events::SetLocalScale) - ->Event("SetLocalScaleX", &AZ::TransformBus::Events::SetLocalScaleX) - ->Event("SetLocalScaleY", &AZ::TransformBus::Events::SetLocalScaleY) - ->Event("SetLocalScaleZ", &AZ::TransformBus::Events::SetLocalScaleZ) ->Event("GetLocalScale", &AZ::TransformBus::Events::GetLocalScale) ->Attribute("Scale", AZ::Edit::Attributes::PropertyScale) - ->VirtualProperty("Scale", "GetLocalScale", "SetLocalScale") - ->Event("GetWorldScale", &AZ::TransformBus::Events::GetWorldScale) + ->Event("SetLocalUniformScale", &AZ::TransformBus::Events::SetLocalUniformScale) + ->Event("GetLocalUniformScale", &AZ::TransformBus::Events::GetLocalUniformScale) + ->VirtualProperty("Uniform Scale", "GetLocalUniformScale", "SetLocalUniformScale") ->Event("GetChildren", &AZ::TransformBus::Events::GetChildren) ->Event("GetAllDescendants", &AZ::TransformBus::Events::GetAllDescendants) ->Event("GetEntityAndAllDescendants", &AZ::TransformBus::Events::GetEntityAndAllDescendants) diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h index abea0bd4dd..0301334a0d 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h @@ -17,7 +17,6 @@ #include #include #include -#include namespace AzToolsFramework { @@ -41,10 +40,9 @@ namespace AzFramework , public AZ::TransformBus::Handler , public AZ::TransformNotificationBus::Handler , private AZ::TransformHierarchyInformationBus::Handler - , public NetBindable { public: - AZ_COMPONENT(TransformComponent, AZ::TransformComponentTypeId, NetBindable, AZ::TransformInterface); + AZ_COMPONENT(TransformComponent, AZ::TransformComponentTypeId, AZ::TransformInterface); friend class AzToolsFramework::Components::TransformComponent; @@ -114,22 +112,7 @@ namespace AzFramework float GetLocalZ() override; // Rotation modifiers - void SetRotation(const AZ::Vector3& eulerAnglesRadian) override; - void SetRotationQuaternion(const AZ::Quaternion& quaternion) override; - void SetRotationX(float eulerAngleRadian) override; - void SetRotationY(float eulerAngleRadian) override; - void SetRotationZ(float eulerAngleRadian) override; - - void RotateByX(float eulerAngleRadian) override; - void RotateByY(float eulerAngleRadian) override; - void RotateByZ(float eulerAngleRadian) override; - - AZ::Vector3 GetRotationEulerRadians() override; - AZ::Quaternion GetRotationQuaternion() override; - - float GetRotationX() override; - float GetRotationY() override; - float GetRotationZ() override; + void SetWorldRotationQuaternion(const AZ::Quaternion& quaternion) override; AZ::Vector3 GetWorldRotation() override; AZ::Quaternion GetWorldRotationQuaternion() override; @@ -145,23 +128,11 @@ namespace AzFramework AZ::Quaternion GetLocalRotationQuaternion() override; // Scale Modifiers - void SetScale(const AZ::Vector3& scale) override; - void SetScaleX(float scaleX) override; - void SetScaleY(float scaleY) override; - void SetScaleZ(float scaleZ) override; - - AZ::Vector3 GetScale() override; - float GetScaleX() override; - float GetScaleY() override; - float GetScaleZ() override; - - void SetLocalScale(const AZ::Vector3& scale) override; - void SetLocalScaleX(float scaleX) override; - void SetLocalScaleY(float scaleY) override; - void SetLocalScaleZ(float scaleZ) override; - AZ::Vector3 GetLocalScale() override; - AZ::Vector3 GetWorldScale() override; + + void SetLocalUniformScale(float scale) override; + float GetLocalUniformScale() override; + float GetWorldUniformScale() override; // Transform hierarchy AZStd::vector GetChildren() override; @@ -218,11 +189,5 @@ namespace AzFramework bool m_parentActive = false; ///< Keeps track of the state of the parent entity. bool m_onNewParentKeepWorldTM = true; ///< If set, recompute localTM instead of worldTM when parent becomes active. bool m_isStatic = false; ///< If true, the transform is static and doesn't move while entity is active. - - //! @deprecated - //! @{ - AZ::InterpolationMode m_interpolatePosition = AZ::InterpolationMode::NoInterpolation; - AZ::InterpolationMode m_interpolateRotation = AZ::InterpolationMode::NoInterpolation; - //! @} }; } // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h b/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h index fb6b8d7d72..c3a60f7ec3 100644 --- a/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h +++ b/Code/Framework/AzFramework/AzFramework/Entity/EntityDebugDisplayBus.h @@ -60,6 +60,7 @@ namespace AzFramework virtual void DrawTrianglesIndexed(const AZStd::vector& vertices, const AZStd::vector& indices, const AZ::Color& color) { (void)vertices; (void)indices, (void)color; } virtual void DrawWireBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; } virtual void DrawSolidBox(const AZ::Vector3& min, const AZ::Vector3& max) { (void)min; (void)max; } + virtual void DrawWireOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; } virtual void DrawSolidOBB(const AZ::Vector3& center, const AZ::Vector3& axisX, const AZ::Vector3& axisY, const AZ::Vector3& axisZ, const AZ::Vector3& halfExtents) { (void)center; (void)axisX; (void)axisY; (void)axisZ; (void)halfExtents; } virtual void DrawPoint(const AZ::Vector3& p, int nSize = 1) { (void)p; (void)nSize; } virtual void DrawLine(const AZ::Vector3& p1, const AZ::Vector3& p2) { (void)p1; (void)p2; } @@ -70,18 +71,15 @@ namespace AzFramework virtual void DrawLine2d(const AZ::Vector2& p1, const AZ::Vector2& p2, float z) { (void)p1; (void)p2; (void)z; } virtual void DrawLine2dGradient(const AZ::Vector2& p1, const AZ::Vector2& p2, float z, const AZ::Vector4& firstColor, const AZ::Vector4& secondColor) { (void)p1; (void)p2; (void)z; (void)firstColor; (void)secondColor; } virtual void DrawWireCircle2d(const AZ::Vector2& center, float radius, float z) { (void)center; (void)radius; (void)z; } - virtual void DrawTerrainCircle(const AZ::Vector3& worldPos, float radius, float height) { (void)worldPos; (void)radius; (void)height; } - virtual void DrawTerrainCircle(const AZ::Vector3& center, float radius, float angle1, float angle2, float height) { (void)center; (void)radius; (void)angle1; (void)angle2; (void)height; } virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, int referenceAxis = 2) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)referenceAxis; } virtual void DrawArc(const AZ::Vector3& pos, float radius, float startAngleDegrees, float sweepAngleDegrees, float angularStepDegrees, const AZ::Vector3& fixedAxis) { (void)pos; (void)radius; (void)startAngleDegrees; (void)sweepAngleDegrees; (void)angularStepDegrees; (void)fixedAxis; } virtual void DrawCircle(const AZ::Vector3& pos, float radius, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)nUnchangedAxis; } virtual void DrawHalfDottedCircle(const AZ::Vector3& pos, float radius, const AZ::Vector3& viewPos, int nUnchangedAxis = 2 /*z axis*/) { (void)pos; (void)radius; (void)viewPos; (void)nUnchangedAxis; } - virtual void DrawCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; } + virtual void DrawWireCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height) { (void)pos; (void)dir; (void)radius; (void)height; } + virtual void DrawSolidCone(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius, float height, bool drawShaded = true) { (void)pos; (void)dir; (void)radius; (void)height; (void)drawShaded; } virtual void DrawWireCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height) { (void)center; (void)axis; (void)radius; (void)height; } virtual void DrawSolidCylinder(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float height, bool drawShaded = true) { (void)center; (void)axis; (void)radius; (void)height; (void)drawShaded; } virtual void DrawWireCapsule(const AZ::Vector3& center, const AZ::Vector3& axis, float radius, float heightStraightSection) { (void)center; (void)axis; (void)radius; (void)heightStraightSection; } - virtual void DrawTerrainRect(float x1, float y1, float x2, float y2, float height) { (void)x1; (void)y1; (void)x2; (void)y2; (void)height; } - virtual void DrawTerrainLine(AZ::Vector3 worldPos1, AZ::Vector3 worldPos2) { (void)worldPos1; (void)worldPos2; } virtual void DrawWireSphere(const AZ::Vector3& pos, float radius) { (void)pos; (void)radius; } virtual void DrawWireSphere(const AZ::Vector3& pos, const AZ::Vector3 radius) { (void)pos; (void)radius; } virtual void DrawWireDisk(const AZ::Vector3& pos, const AZ::Vector3& dir, float radius) { (void)pos; (void)dir; (void)radius; } @@ -91,11 +89,8 @@ namespace AzFramework virtual void DrawTextLabel(const AZ::Vector3& pos, float size, const char* text, const bool bCenter = false, int srcOffsetX = 0, int srcOffsetY = 0) { (void)pos; (void)size; (void)text; (void)bCenter; (void)srcOffsetX; (void)srcOffsetY; } virtual void Draw2dTextLabel(float x, float y, float size, const char* text, bool bCenter = false) { (void)x; (void)y; (void)size; (void)text; (void)bCenter; } virtual void DrawTextOn2DBox(const AZ::Vector3& pos, const char* text, float textScale, const AZ::Vector4& TextColor, const AZ::Vector4& TextBackColor) { (void)pos; (void)text; (void)textScale; (void)TextColor; (void)TextBackColor; } - virtual void DrawTextureLabel(ITexture* texture, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)texture; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; } - virtual void DrawTextureLabel(int textureId, const AZ::Vector3& pos, float sizeX, float sizeY, int texIconFlags) { (void)textureId; (void)pos; (void)sizeX; (void)sizeY; (void)texIconFlags; } virtual void SetLineWidth(float width) { (void)width; } virtual bool IsVisible(const AZ::Aabb& bounds) { (void)bounds; return false; } - virtual int SetFillMode(int nFillMode) { (void)nFillMode; return 0; } virtual float GetLineWidth() { return 0.0f; } virtual float GetAspectRatio() { return 0.0f; } virtual void DepthTestOff() {} diff --git a/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.cpp b/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.cpp index 999013fdf8..461d578e28 100644 --- a/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.cpp @@ -93,6 +93,8 @@ namespace AzFramework InitContext(); GameEntityContextRequestBus::Handler::BusConnect(); + + m_entityVisibilityBoundsUnionSystem.Connect(); } //========================================================================= @@ -100,6 +102,8 @@ namespace AzFramework //========================================================================= void GameEntityContextComponent::Deactivate() { + m_entityVisibilityBoundsUnionSystem.Disconnect(); + GameEntityContextRequestBus::Handler::BusDisconnect(); DestroyContext(); diff --git a/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.h b/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.h index 482b2133ca..35424fd09c 100644 --- a/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Entity/GameEntityContextComponent.h @@ -18,6 +18,7 @@ #include #include #include +#include #include "EntityContext.h" @@ -91,6 +92,9 @@ namespace AzFramework { required.push_back(AZ_CRC("SliceSystemService", 0x1a5b7aad)); } + + private: + AzFramework::EntityVisibilityBoundsUnionSystem m_entityVisibilityBoundsUnionSystem; }; } // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h index 7c5bcce6d6..dae5fa9fe7 100644 --- a/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h +++ b/Code/Framework/AzFramework/AzFramework/Font/FontInterface.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -40,17 +41,22 @@ namespace AzFramework //! Standard parameters for drawing text on screen struct TextDrawParameters { - ViewportId m_drawViewportId = InvalidViewportId; //! Viewport to draw into - AZ::Vector3 m_position; //! world space position for 3d draws, screen space x,y,depth for 2d. - AZ::Color m_color = AZ::Colors::White; //! Color to draw the text - AZ::Vector2 m_scale = AZ::Vector2(1.0f); //! font scale - TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //! Horizontal text alignment - TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //! Vertical text alignment - bool m_monospace = false; //! disable character proportional spacing - bool m_depthTest = false; //! Test character against the depth buffer - bool m_virtual800x600ScreenSize = true; //! Text placement and size are scaled relative to a virtual 800x600 resolution - bool m_scaleWithWindow = false; //! Font gets bigger as the window gets bigger - bool m_multiline = true; //! text respects ascii newline characters + ViewportId m_drawViewportId = InvalidViewportId; //!< Viewport to draw into + AZ::Vector3 m_position; //!< world space position for 3d draws, screen space x,y,depth for 2d. + AZ::Color m_color = AZ::Colors::White; //!< Color to draw the text + unsigned int m_effectIndex = 0; //!< effect index to apply + AZ::Vector2 m_scale = AZ::Vector2(1.0f); //!< font scale + float m_textSizeFactor = 12.0f; //!< font size in pixels + float m_lineSpacing = 1.0f; //!< Spacing between new lines, as a percentage of m_scale. + TextHorizontalAlignment m_hAlign = TextHorizontalAlignment::Left; //!< Horizontal text alignment + TextVerticalAlignment m_vAlign = TextVerticalAlignment::Top; //!< Vertical text alignment + bool m_useTransform = false; //!< Use specified transform + AZ::Matrix3x4 m_transform = AZ::Matrix3x4::Identity(); //!< Transform to apply to text quads + bool m_monospace = false; //!< disable character proportional spacing + bool m_depthTest = false; //!< Test character against the depth buffer + bool m_virtual800x600ScreenSize = false; //!< Text placement and size are scaled relative to a virtual 800x600 resolution + bool m_scaleWithWindow = false; //!< Font gets bigger as the window gets bigger + bool m_multiline = true; //!< text respects ascii newline characters }; class FontDrawInterface @@ -63,10 +69,13 @@ namespace AzFramework virtual void DrawScreenAlignedText2d( const TextDrawParameters& params, - const AZStd::string_view& string) = 0; + AZStd::string_view text) = 0; virtual void DrawScreenAlignedText3d( const TextDrawParameters& params, - const AZStd::string_view& string) = 0; + AZStd::string_view text) = 0; + virtual AZ::Vector2 GetTextSize( + const TextDrawParameters& params, + AZStd::string_view text) = 0; }; class FontQueryInterface diff --git a/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h b/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h deleted file mode 100644 index 3e69454f59..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h +++ /dev/null @@ -1,146 +0,0 @@ -/* -* 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. -* -*/ -#pragma once -#ifndef AZFRAMEWORK_NETWORK_DYNAMICSERIALIZABLEFIELDMARSHALER_H -#define AZFRAMEWORK_NETWORK_DYNAMICSERIALIZABLEFIELDMARSHALER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace GridMate -{ - /** - * Marshaler for DynamicSerializableField, contains a template param for allocating the memory buffer that it's going to use to write to. - */ - template - class DynamicSerializableFieldMarshaler - { - public: - DynamicSerializableFieldMarshaler() - : m_serializeContext(nullptr) - { - EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - } - - // Mainly here for unit test purposes. - DynamicSerializableFieldMarshaler(AZ::SerializeContext* context) - : m_serializeContext(context) - { - } - - AZ_FORCE_INLINE void Marshal(WriteBuffer& wb, const AZ::DynamicSerializableField& value) const - { - AZ_Error("DynamicSerializableFieldMarshaler", m_serializeContext, "Unknown SerializationContext. Aborting Marshal attempt.\n"); - if (m_serializeContext) - { - Marshaler sizeMarshaler; - Marshaler uuidMarshaler; - - AZStd::vector memoryBuffer(BufferSize); - - // Start buffer in write mode. - AZ::IO::ByteContainerStream memoryStream(&memoryBuffer); - - AZ::u32 bufferSize = 0; - - if (m_serializeContext->FindClassData(value.m_typeId)) - { - if (AZ::Utils::SaveObjectToStream(memoryStream, AZ::DataStream::StreamType::ST_BINARY, value.m_data, value.m_typeId, m_serializeContext)) - { - bufferSize = static_cast(memoryStream.GetCurPos()); - } - } - else - { - AZ_Error("DynamicSerializableFieldMarshaler", !value.IsValid(), "Could not save object to stream because type Id %s is not registered with the serializer.\n", value.m_typeId.ToString().c_str()); - } - - sizeMarshaler.Marshal(wb, bufferSize); - uuidMarshaler.Marshal(wb, value.m_typeId); - wb.WriteRaw(memoryBuffer.data(), bufferSize); - } - } - - AZ_FORCE_INLINE void Unmarshal(AZ::DynamicSerializableField& value, ReadBuffer& rb) const - { - value.DestroyData(m_serializeContext); - - AZ_Error("DynamicSerializableFieldMarshaler", m_serializeContext, "Unknown SerializationContext. Aborting Unmarshal attempt.\n"); - if (m_serializeContext) - { - Marshaler sizeMarshaler; - AZ::u32 marshaledBufferSize = 0; - sizeMarshaler.Unmarshal(marshaledBufferSize, rb); - - AZ_Assert(marshaledBufferSize <= BufferSize,"Trying to deserialize too much data for the allocated buffer size\n"); - - // Marshal out the TypeId so I can use it on the receiving end. - Marshaler uuidMarshaler; - uuidMarshaler.Unmarshal(value.m_typeId, rb); - - if (marshaledBufferSize > 0) - { - // See if there's some nice way to use this. - // - Can't make this a member variable, since both these methods are const. - AZStd::vector memoryBuffer(marshaledBufferSize + 1); - - if (rb.ReadRaw(memoryBuffer.data(), marshaledBufferSize)) - { - // Start buffer in read mode. - AZ::IO::ByteContainerStream memoryStream(&memoryBuffer); - - // we'll use a strict filter here, one that doesn't allow deserialization to automatically start loading assets, nor tolerates errors. - // this is becuase this is coming from a network interface and should always be error-free. - AZ::ObjectStream::FilterDescriptor filterToUse(&AZ::Data::AssetFilterNoAssetLoading, AZ::ObjectStream::FILTERFLAG_STRICT); - value.m_data = AZ::Utils::LoadObjectFromStream(memoryStream, m_serializeContext, &value.m_typeId, filterToUse); - } - } - } - } - - private: - AZ::SerializeContext* m_serializeContext; - }; - - /** - * Specialized marshaler for AZ::DynamicSerializableField - * Mainly here to hook into the DataSet Marshaler auto detection logic, and provide a default buffer size for the actual marshaler - */ - template<> - class Marshaler - : public DynamicSerializableFieldMarshaler<1024> - { - public: - - Marshaler() - { - } - - // Mainly here for unit test purposes. - Marshaler(AZ::SerializeContext* context) - : DynamicSerializableFieldMarshaler(context) - { - } - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h b/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h deleted file mode 100644 index 0116020cc0..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* 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. -* -*/ -#pragma once -#ifndef AZFRAMEWORK_NETWORK_ENTITYIDMARSHALER_H -#define AZFRAMEWORK_NETWORK_ENTITYIDMARSHALER_H - -#include -#include - -#include -#include - -namespace GridMate -{ - template<> - class Marshaler - { - public: - AZ_TYPE_INFO_LEGACY( Marshaler, "{23F4722F-D104-4E30-9342-43F4DDD1894D}", AZ::EntityId ); - - void Marshal(GridMate::WriteBuffer& wb, const AZ::EntityId& source) const - { - Marshaler idMarshaler; - idMarshaler.Marshal(wb,static_cast(source)); - } - - void Unmarshal(AZ::EntityId& target, GridMate::ReadBuffer& rb) const - { - AZ::u64 id = 0; - - Marshaler idMarshaler; - idMarshaler.Unmarshal(id,rb); - - target = AZ::EntityId(id); - } - }; - - template<> - class Marshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, const AZ::NamedEntityId& source) const - { - Marshaler idMarshaler; - idMarshaler.Marshal(wb, static_cast(source)); - - Marshaler stringMarshaler; - stringMarshaler.Marshal(wb, source.GetName()); - } - - void Unmarshal(AZ::NamedEntityId& target, GridMate::ReadBuffer& rb) const - { - AZ::u64 id = 0; - - Marshaler idMarshaler; - idMarshaler.Unmarshal(id, rb); - - AZStd::string name; - Marshaler stringMarshaler; - stringMarshaler.Unmarshal(name, rb); - - target = AZ::NamedEntityId(AZ::EntityId(id), name); - } - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp deleted file mode 100644 index 6aa32158f1..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* -* 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. -* -*/ -#include - -#include -#include -#include - -#include -#include -#include -#include - -using namespace GridMate; - -namespace AzFramework -{ - void InterestManagerComponent::Reflect(AZ::ReflectContext* context) - { - if (context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1); - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "InterestManagerComponent", "Interest manager instance") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)); - } - } - - // We need to register the chunk types for each handler here at reflect time - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(ProximityInterestChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(BitmaskInterestChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } - - void InterestManagerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("InterestManager", 0x79993873)); - } - - void InterestManagerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("InterestManager", 0x79993873)); - } - - - - InterestManagerComponent::InterestManagerComponent() - : m_im(nullptr) - , m_bitmaskHandler(nullptr) - , m_proximityHandler(nullptr) - , m_session(nullptr) - { - - } - - void InterestManagerComponent::Activate() - { - InterestManagerRequestsBus::Handler::BusConnect(); - NetBindingSystemEventsBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - } - - void InterestManagerComponent::Deactivate() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - NetBindingSystemEventsBus::Handler::BusDisconnect(); - InterestManagerRequestsBus::Handler::BusDisconnect(); - - ShutdownInterestManager(); - } - - void InterestManagerComponent::OnSystemTick() - { - if (m_im && m_im->IsReady()) - { - m_im->Update(); - } - } - - InterestManager* InterestManagerComponent::GetInterestManager() - { - return m_im.get(); - } - - BitmaskInterestHandler* InterestManagerComponent::GetBitmaskInterest() - { - return m_bitmaskHandler.get(); - } - - ProximityInterestHandler* InterestManagerComponent::GetProximityInterest() - { - return m_proximityHandler.get(); - } - - void InterestManagerComponent::OnNetworkSessionActivated(GridSession* session) - { - AZ_Assert(m_session == nullptr, "Already bound to the session"); - - AZ_TracePrintf("AzFramework", "Interest manager hooked up to the session '%s'\n", session->GetId().c_str()); - - m_session = session; - m_session->GetReplicaMgr()->SetAutoBroadcast(false); - - InitInterestManager(); - } - - void InterestManagerComponent::OnNetworkSessionDeactivated(GridSession* session) - { - if (m_session && m_session == session) - { - AZ_TracePrintf("AzFramework", "Interest manager disconnected from the session '%s'\n", session ? session->GetId().c_str() : "nullptr"); - - if (m_session->GetReplicaMgr()) - { - m_session->GetReplicaMgr()->SetAutoBroadcast(true); - } - - m_session = nullptr; - ShutdownInterestManager(); - } - else - { - AZ_Warning("AzFramework", false, "Interest manager was never active for session '%s'\n", session ? session->GetId().c_str() : "nullptr"); - } - } - - void InterestManagerComponent::InitInterestManager() - { - AZ_Assert(m_im == nullptr, "Already initialized interest manager"); - m_im = AZStd::make_unique(); - - InterestManagerDesc desc; - desc.m_rm = m_session->GetReplicaMgr(); - m_im->Init(desc); - - m_bitmaskHandler = AZStd::make_unique(); - m_im->RegisterHandler(m_bitmaskHandler.get()); - - m_proximityHandler = AZStd::make_unique(); - m_im->RegisterHandler(m_proximityHandler.get()); - - InterestManagerEventsBus::Broadcast( - &InterestManagerEventsBus::Events::OnInterestManagerActivate, m_im.get()); - } - - void InterestManagerComponent::ShutdownInterestManager() - { - if (m_im) - { - InterestManagerEventsBus::Broadcast( - &InterestManagerEventsBus::Events::OnInterestManagerDeactivate, m_im.get()); - - m_im->UnregisterHandler(m_bitmaskHandler.get()); - m_im->UnregisterHandler(m_proximityHandler.get()); - - m_bitmaskHandler = nullptr; - m_proximityHandler = nullptr; - m_im = nullptr; - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h b/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h deleted file mode 100644 index de45c78d43..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -* 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. -* -*/ -#ifndef AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H -#define AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H - - -#include -#include -#include - -#include - -#include - -namespace GridMate -{ - class InterestManager; - class GridSession; - class BitmaskInterestHandler; - class ProximityInterestHandler; -} - -namespace AzFramework -{ - class InterestManagerSystemRequests - : public AZ::EBusTraits - { - public: - virtual ~InterestManagerSystemRequests() {} - - // Returns interest manager instance - virtual GridMate::InterestManager* GetInterestManager() = 0; - - // Returns interest manager instance - virtual GridMate::BitmaskInterestHandler* GetBitmaskInterest() = 0; - - // Returns interest manager instance - virtual GridMate::ProximityInterestHandler* GetProximityInterest() = 0; - }; - - // Interface Bus - using InterestManagerRequestsBus = AZ::EBus; - - class InterestManagerEvents - : public AZ::EBusTraits - { - public: - virtual ~InterestManagerEvents() {} - - // Called when interest manager is initialized and ready to use - virtual void OnInterestManagerActivate(GridMate::InterestManager* im) { (void)im; } - - // Called when interest manager is deactivated - virtual void OnInterestManagerDeactivate(GridMate::InterestManager* im) { (void)im; } - }; - - // Interface Bus - using InterestManagerEventsBus = AZ::EBus; - - /** - * Interest manager component. - * When component is activated replicas will go through interest filtering before being sent to other peers - */ - class InterestManagerComponent - : public AZ::Component - , public AZ::SystemTickBus::Handler - , public InterestManagerRequestsBus::Handler - , public NetBindingSystemEventsBus::Handler - { - public: - AZ_COMPONENT(InterestManagerComponent, "{55371FA7-2942-4A3C-A3EA-27FF2C7DB6C5}"); - - static void Reflect(AZ::ReflectContext* context); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - InterestManagerComponent(); - - void Activate() override; - void Deactivate() override; - - protected: - - // AZ::SystemTickBus::Listener interface implementation - void OnSystemTick() override; - - // InterestManagerSystemRequests implementation - GridMate::InterestManager* GetInterestManager() override; - GridMate::BitmaskInterestHandler* GetBitmaskInterest() override; - GridMate::ProximityInterestHandler* GetProximityInterest() override; - - // SessionEventBus - void OnNetworkSessionActivated(GridMate::GridSession* session) override; - void OnNetworkSessionDeactivated(GridMate::GridSession* session) override; - - void InitInterestManager(); - void ShutdownInterestManager(); - - // Interest handlers - AZStd::unique_ptr m_im; - AZStd::unique_ptr m_bitmaskHandler; - AZStd::unique_ptr m_proximityHandler; - - GridMate::GridSession* m_session; ///< currently bound session - - private: - InterestManagerComponent(const InterestManagerComponent&) = delete; //Cannot use default due to unique_ptr. - }; -} // namesapce AzFramework - -#endif // AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp deleted file mode 100644 index eb0e6efa47..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* -* 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. -* -*/ - -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - //////////////// - // NetBindable - //////////////// - - NetBindable::NetBindable() - : m_isSyncEnabled(true) - { - } - - NetBindable::~NetBindable() - { - if (m_chunk) - { - // NetBindable is a base class for handlers for replica chunks, so we have to clear the handler since this object is about to go away - m_chunk->SetHandler(nullptr); - m_chunk = nullptr; - } - } - - GridMate::ReplicaChunkPtr NetBindable::GetNetworkBinding() - { - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - m_chunk = netContext->CreateReplicaChunk(azrtti_typeid(this)); - netContext->Bind(this, m_chunk, NetworkContextBindMode::Authoritative); - return m_chunk; - } - - return nullptr; - } - - void NetBindable::SetNetworkBinding (GridMate::ReplicaChunkPtr chunk) - { - m_chunk = chunk; - - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - netContext->Bind(this, m_chunk, NetworkContextBindMode::NonAuthoritative); - } - } - - void NetBindable::UnbindFromNetwork() - { - if (m_chunk) - { - // NetworkContext-reflected chunks need access to the handler when they are being destroyed, so we won't null handler in here - m_chunk = nullptr; - } - } - - void NetBindable::NetInit() - { - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - netContext->Bind(this, nullptr, NetworkContextBindMode::NonAuthoritative); - } - } - - void NetBindable::Reflect(AZ::ReflectContext* reflection) - { - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ->Field("m_isSyncEnabled", &NetBindable::m_isSyncEnabled); - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "Network Bindable", "Network-bindable components are synchronized over the network.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Networking") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->DataElement(AZ::Edit::UIHandlers::Default, &NetBindable::m_isSyncEnabled, "Bind To network", "Enable binding to the network."); - } - } - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h deleted file mode 100644 index 39a05c4fc1..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h +++ /dev/null @@ -1,799 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDABLE_H -#define AZFRAMEWORK_NET_BINDABLE_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * Including common GridMate marshallers. - * Otherwise, users of NetBindable/NetworkContext have to find and include them themselves. - */ -#include -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - class ReflectContext; - namespace Internal - { - template - class AzFrameworkNetBindableFieldContainer; - } -} - -namespace AzFramework -{ - using GridMate::DataSetBase; - using GridMate::DataSet; - using GridMate::Marshaler; - using GridMate::BasicThrottle; - using GridMate::RpcBase; - using GridMate::TimeContext; - using GridMate::RpcContext; - using GridMate::RpcDefaultTraits; - - enum class NetworkContextBindMode - { - Authoritative, - NonAuthoritative - }; - - /** - * Components that want to be synchronized over the network should implement NetBindable. - * The NetBindable interface is obtained via AZ_RTTI so components need to make sure to - * declare NetBindable as a base class in their AZ_RTTI declaration (or AZ_COMPONENT declaration), - * as well as to declare both AZ::Component and NetBindable as base classes in the reflection. - * - * For example, here is how to mark a component for network replication in its class declaration: - * - * class TestFieldComponent - * : public AZ::Component - * , public AzFramework::NetBindable - * { - * public: - * AZ_COMPONENT(TestFieldComponent, "{DD02A926-F6B3-4820-9587-62EED9EEBB3F}", NetBindable); - * - * static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - * { - * required.push_back(AZ_CRC("ReplicaChunkService")); - * } - * - * Note, you should declare a dependency on NetBindingComponent as it is done above with "ReplicaChunkService." - * NetBindingComponent is required for an entity to be considered for network replication and replicate your NetBindable-components. - */ - class NetBindable - : public GridMate::ReplicaChunkInterface - { - public: - AZ_RTTI(NetBindable, "{80206665-D429-4703-B42E-94434F82F381}"); - - NetBindable(); - virtual ~NetBindable(); - - void NetInit(); - - //! Called during network binding on the master. The default implementation will use the - //! NetworkContext to create a chunk. User implementations should create and return a new binding. - virtual GridMate::ReplicaChunkPtr GetNetworkBinding(); - - //! Called during network binding on proxies. - virtual void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk); - - //! Called when network is unbound. Implementations should release their references to the binding, if they held a reference. - virtual void UnbindFromNetwork(); - - static void Reflect(AZ::ReflectContext* reflection); - - template , typename ThrottlerType = BasicThrottle > - class Field; - - template , typename ThrottlerType = BasicThrottle > - class BoundField; - - template - class Rpc; - - inline bool IsSyncEnabled() const { return m_isSyncEnabled; } - //! Can be used to disabled net sync on a per component basis - inline void SetSyncEnabled(bool enabled) { m_isSyncEnabled = enabled; } - protected: - bool m_isSyncEnabled; - GridMate::ReplicaChunkPtr m_chunk = nullptr; - }; - - class NetBindableFieldBase - { - public: - virtual ~NetBindableFieldBase() = default; - virtual void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) = 0; - }; - - /** - * \brief NetBindable provides a simplified network interface to mark a member variable inside AZ::Component - * as a network field that will be replicated by GridMate. - * - * \tparam DataType data type of the field, can be either a common C++ type or a custom type - * \tparam MarshalerType optional, marshaler type that provides custom marshal and unmarshal logic, i.e. how to write @DataType to the network and back, see @GridMate::Marshaler - * \tparam ThrottlerType optional, throttler provides the ability to detect if a value is to be considered changed significantly enough for GridMate to replicate its state, see @GridMate::BasicThrottle - * - * Example: - * - * class TestFieldComponent : public AZ::Component , public AzFramework::NetBindable - * { - * public: - * Field m_testInt; - * - * And it must be reflected to SerializeContext _and_ NetworkContext: - * - * void TestFieldComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt) - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt); - * } - * } - * - * Then you can simply write to it as it was an integer: - * - * m_testInt = 3; - * // or - * m_testInt = *m_testInt + 1; - */ - template - class NetBindable::Field - : public NetBindableFieldBase - { - friend class AZ::Internal::AzFrameworkNetBindableFieldContainer >; - public: - using DataSetType = DataSet; - using ValueType = DataType; - - explicit Field(const DataType& value = DataType()) - : m_dataSet(nullptr) - , m_value(value) - {} - ~Field() override = default; - - /* - * Disabling copy and move constructors in order to allow for a common use of fields, for example: - * m_field = m_field + 1; - */ - Field (const Field& other) = delete; - Field (Field&& other) = delete; - Field& operator= (const Field& other) = delete; - Field& operator= (Field&& other) = delete; - - const DataType& Get() const - { - return m_dataSet ? m_dataSet->Get() : m_value; - } - - virtual operator const DataType&() const - { - return Get(); - } - - virtual const DataType& operator*() const - { - return Get(); - } - - virtual Field& operator=(const DataType& val) - { - if (m_dataSet) - { - m_dataSet->Set(val); - } - else - { - m_value = val; - } - return *this; - } - - virtual Field& operator=(const DataType&& val) - { - if (m_dataSet) - { - m_dataSet->Set(AZStd::forward(val)); - } - else - { - m_value = AZStd::move(val); - } - return *this; - } - - void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) override - { - BindDataSet(static_cast(dataSet), mode); - } - - static void ConstructDataSet(void* mem, const char* name) - { - new (mem) DataSetType(name, DataType(), MarshalerType(), ThrottlerType()); - } - - static void DestructDataSet(void* mem) - { - DataSetType* dataSet = reinterpret_cast(mem); - dataSet->~DataSetType(); - } - - protected: - template - void BindDataSet(DST* dataSet, NetworkContextBindMode mode) - { - if (m_dataSet) - { - m_value = m_dataSet->Get(); - } - m_dataSet = dataSet; - if (m_dataSet) - { - if (mode == NetworkContextBindMode::Authoritative) - { - /* - * If we are binding Field<> or BoundField<> on a component of an authoritative entity, - * then we want to bring over the value of the field in the component. This occurs during GetNetworkBinding(). - * - * Whereas on a client's (non-authoritative entities and their components) dataSet already has the desired value - * and should not be overwritten here. - */ - m_dataSet->Set(AZStd::move(m_value)); - } - m_value = DataType(); - } - } - - DataType* CacheValue() - { - if (m_dataSet) - { - m_value = m_dataSet->Get(); - } - return &m_value; - } - - const DataType& GetCachedValue() const - { - return m_value; - } - - private: - DataSet* m_dataSet; - DataType m_value; - }; - - /** - * \brief An extension of @NetBindable::Field with an ability to invoke a callback whenever the value changes on both authoritative and non-authoritative components. - * Or in other terms, on both the server and clients (when GridMate is setup to run in server-authoritative mode). - * - * \tparam DataType data type, same as @NetBindable::Field - * \tparam InterfaceType Component type class that holds this @BoundField - * \tparam FuncPtr member function pointer to the callback to invoke when this value is updated on non-authoritative components. - * \tparam MarshalerType optional, same as @NetBindable::Field - * \tparam ThrottlerType optional, same as @NetBindable::Field - * - * Example: - * - * BoundField m_testInt; - * - * And it must be reflected to SerializeContext _and_ NetworkContext just like @NetBindable::Field - * - * void TestFieldComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt) - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt); - * } - * } - */ - template - class NetBindable::BoundField - : public NetBindable::Field - { - using BaseClass = NetBindable::Field; - friend class AZ::Internal::AzFrameworkNetBindableFieldContainer >; - public: - AZ_TYPE_INFO_LEGACY(BoundField, "{5151CEAF-6AC0-45D7-AEDF-8B6C46CE07B9}", DataType, InterfaceType, MarshalerType, ThrottlerType); - using DataSetType = typename DataSet::template BindInterface; - - explicit BoundField(const DataType& value = DataType()) - : BaseClass(value) - {} - ~BoundField() override = default; - - /* - * Disabling copy and move constructors in order to allow for a common use of fields, for example: - * m_field = m_field + 1; - */ - BoundField (const BoundField& other) = delete; - BoundField (BoundField&& other) = delete; - BoundField& operator= (const BoundField& other) = delete; - BoundField& operator= (BoundField&& other) = delete; - - operator DataType() const - { - return BaseClass::Get(); - } - - const DataType& operator*() const override - { - return BaseClass::Get(); - } - - BaseClass& operator=(const DataType& val) override - { - BaseClass::operator=(val); - return *this; - } - - BaseClass& operator=(const DataType&& val) override - { - BaseClass::operator=(val); - return *this; - } - - void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) override - { - BaseClass::BindDataSet(static_cast(dataSet), mode); - } - - static void ConstructDataSet(void* mem, const char* name) - { - new (mem) DataSetType(name, DataType(), MarshalerType(), ThrottlerType()); - } - - static void DestructDataSet(void* mem) - { - DataSetType* dataSet = reinterpret_cast(mem); - dataSet->~DataSetType(); - } - }; - - class NetBindableRpcBase - { - public: - virtual ~NetBindableRpcBase() = default; - virtual void Bind(RpcBase* rpc) = 0; - virtual void Bind(NetBindable* handler) = 0; - }; - - /** - * \brief NetBindable::Rpc::Binder should be used for any RPC in a NetBindable that you want - * to be able to call remotely. If the object is not network bound, RPC - * calls will dispatch directly, as if the object was authoritative. - * - * \tparam Args any custom parameters for the remote procedure calls. - * - * Here is an example: - * - * // callback - * bool OnRpc(float value, const GridMate::RpcContext& rc); - * - * // Rpc declaration - * Rpc::Binder m_testRpc; - * - * Rpc needs to be reflected in NetworkContext like this: - * - * void TestRPCComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->RPC("Test RPC", &TestRPCComponent::m_testRpc); - * } - * } - * - * It can be invoked as if it was a method: - * - * m_testRpc(deltaTime); - */ - template - class NetBindable::Rpc - { - public: - /** - * \brief Binds rpc callback to a pointer to member function of AZ::Component derived from AzFramework::NetBindable - * See @NetBindable::Rpc - */ - template - class Binder - : public NetBindableRpcBase - { - friend class NetworkContext; - public: - using BindInterfaceType = typename GridMate::Rpc...>::template BindInterface; - - Binder() - : m_rpc(nullptr) - , m_instance(nullptr) - {} - - void Bind(RpcBase* rpc) override - { - m_rpc = static_cast(rpc); - m_instance = nullptr; - } - - void Bind(NetBindable* bindable) override - { - m_instance = static_cast(bindable); - m_rpc = nullptr; - } - - template - void operator()(CallArgs&& ... args) - { - AZ_Assert(m_instance || m_rpc, "Cannot call an RPC without either a local instance or a network bound handler, did you forget to register with NetworkContext()?"); - if (m_rpc) // connected to network - { - (*m_rpc)(AZStd::forward(args) ...); - } - else if (m_instance) // local dispatch - { - (*m_instance.*FuncPtr)(AZStd::forward(args) ..., RpcContext()); - } - } - - protected: - static void ConstructRpc(void* mem, const char* name) - { - new (mem) BindInterfaceType(name); - } - - static void DestructRpc(void*) { } - - private: - BindInterfaceType* m_rpc; - InterfaceType* m_instance; - }; - - Rpc() = delete; - }; -} // namespace AzFramework - -namespace AZ -{ - AZ_TYPE_INFO_TEMPLATE_WITH_NAME(AzFramework::NetBindable::Field, "Field", "{00D56FA7-F8BD-402B-97FB-0E2599897056}", AZ_TYPE_INFO_CLASS, AZ_TYPE_INFO_TYPENAME, AZ_TYPE_INFO_TYPENAME); - - namespace Internal - { - template - class AzFrameworkNetBindableFieldContainer - : public SerializeContext::IDataContainer - { - using ValueType = typename FieldType::ValueType; - public: - AzFrameworkNetBindableFieldContainer() - { - m_classElement.m_name = GetDefaultElementName(); - m_classElement.m_nameCrc = GetDefaultElementNameCrc(); - m_classElement.m_dataSize = sizeof(ValueType); - m_classElement.m_offset = 0; - m_classElement.m_azRtti = GetRttiHelper(); - m_classElement.m_flags = AZStd::is_pointer::value ? SerializeContext::ClassElement::FLG_POINTER : 0; - m_classElement.m_genericClassInfo = SerializeGenericTypeInfo::GetGenericInfo(); - m_classElement.m_typeId = SerializeGenericTypeInfo::GetClassTypeId(); - m_classElement.m_editData = nullptr; - } - - /// Returns the element generic (offsets are mostly invalid 0xbad0ffe0, there are exceptions). Null if element with this name can't be found. - virtual const SerializeContext::ClassElement* GetElement(AZ::u32 elementNameCrc) const override - { - if (elementNameCrc == m_classElement.m_nameCrc) - { - return &m_classElement; - } - return nullptr; - } - - bool GetElement(SerializeContext::ClassElement& classElement, const SerializeContext::DataElement& dataElement) const override - { - if (dataElement.m_nameCrc == m_classElement.m_nameCrc) - { - classElement = m_classElement; - return true; - } - return false; - } - - /// Enumerate elements in the array - virtual void EnumElements(void* instance, const ElementCB& cb) override - { - FieldType* field = reinterpret_cast(instance); - // We can't mess with the internal storage of the dataset safely, so we copy it into - // the field's local value cache temporarily, then hand that to the callback - // This will modify the local value cache, but that shouldn't matter as it will never - // be used as long as a dataset is bound - // If this turns out to be a perf problem due to copies of complex types, then - // the easy solution is to get DataSets to expose a pointer to their underlying - // data storage, and then we can return a pointer to that and modify it directly - // if the field is bound to the network - ValueType* valPtr = field->CacheValue(); - cb(valPtr, m_classElement.m_typeId, m_classElement.m_genericClassInfo ? m_classElement.m_genericClassInfo->GetClassData() : nullptr, &m_classElement); - // Ensure that the dataset is updated if changes happened - *field = *valPtr; - } - - void EnumTypes(const ElementTypeCB& cb) override - { - cb(m_classElement.m_typeId, &m_classElement); - } - - /// Return number of elements in the container. - virtual size_t Size(void*) const override - { - return 1; - } - - /// Returns the capacity of the container. Returns 0 for objects without fixed capacity. - virtual size_t Capacity(void* instance) const override - { - (void)instance; - return 1; - } - - /// Returns true if elements pointers don't change on add/remove. If false you MUST enumerate all elements. - virtual bool IsStableElements() const override { return true; } - - /// Returns true if the container is fixed size, otherwise false. - virtual bool IsFixedSize() const override { return true; } - - /// Returns if the container is fixed capacity, otherwise false - virtual bool IsFixedCapacity() const override { return true; } - - /// Returns true if the container is a smart pointer. - virtual bool IsSmartPointer() const override { return true; } - - /// Returns true if the container elements can be addressed by index, otherwise false. - virtual bool CanAccessElementsByIndex() const override { return false; } - - /// Reserve element - virtual void* ReserveElement(void* instance, const SerializeContext::ClassElement*) override - { - FieldType* field = reinterpret_cast(instance); - *field = ValueType(); - return field->CacheValue(); // return the local value, should be accurate as the field will be unbound at serialization time - } - - /// Get an element's address by its index (called before the element is loaded). - virtual void* GetElementByIndex(void*, const SerializeContext::ClassElement*, size_t) override - { - return nullptr; - } - - /// Store element - virtual void StoreElement(void* instance, void*) override - { - // force store the value again, just in case the field is bound to a dataset - FieldType* field = reinterpret_cast(instance); - *field = field->GetCachedValue(); - } - - /// Remove element in the container. - virtual bool RemoveElement(void* instance, const void*, SerializeContext*) override - { - FieldType* field = reinterpret_cast(instance); - *field = ValueType(); - return false; // you can't remove element from this container. - } - - /// Remove elements (removed array of elements) regardless if the container is Stable or not (IsStableElements) - virtual size_t RemoveElements(void* instance, const void**, size_t, SerializeContext*) override - { - RemoveElement(instance, nullptr, nullptr); - return 0; // you can't remove elements from this container. - } - - /// Clear elements in the instance. - virtual void ClearElements(void* instance, SerializeContext*) override - { - RemoveElement(instance, nullptr, nullptr); - } - - SerializeContext::ClassElement m_classElement; ///< Generic class element covering as must as possible of the element (offset, and some other fields are invalid) - }; - } - - template - struct SerializeGenericTypeInfo< AzFramework::NetBindable::Field > - { - typedef typename AzFramework::NetBindable::Field ContainerType; - - class GenericClassNetBindableField - : public GenericClassInfo - { - public: - AZ_TYPE_INFO(GenericClassNetBindableField, "{C1D4DD97-5DD7-42ED-969C-7435F27F5D8C}"); - GenericClassNetBindableField() - : m_classData{ SerializeContext::ClassData::Create("AzFramework::NetBindable::Field", GetSpecializedTypeId(), Internal::NullFactory::GetInstance(), nullptr, &m_containerStorage) } - { - } - - SerializeContext::ClassData* GetClassData() override - { - return &m_classData; - } - - size_t GetNumTemplatedArguments() override - { - return 1; - } - - const Uuid& GetTemplatedTypeId(size_t) override - { - return SerializeGenericTypeInfo::GetClassTypeId(); - } - - const Uuid& GetSpecializedTypeId() const override - { - return azrtti_typeid(); - } - - const Uuid& GetGenericTypeId() const override - { - return TYPEINFO_Uuid(); - } - - const Uuid& GetLegacySpecializedTypeId() const override - { - return AZ::AzTypeInfo::template Uuid(); - } - - void Reflect(SerializeContext* serializeContext) - { - if (serializeContext) - { - serializeContext->RegisterGenericClassInfo(GetSpecializedTypeId(), this, &AnyTypeInfoConcept::CreateAny); - if (GenericClassInfo* containerGenericClassInfo = m_containerStorage.m_classElement.m_genericClassInfo) - { - containerGenericClassInfo->Reflect(serializeContext); - } - } - } - - protected: - Internal::AzFrameworkNetBindableFieldContainer m_containerStorage; - SerializeContext::ClassData m_classData; - }; - - using ClassInfoType = GenericClassNetBindableField; - - static ClassInfoType* GetGenericInfo() - { - return GetCurrentSerializeContextModule().CreateGenericClassInfo(); - } - - static const Uuid& GetClassTypeId() - { - return GetGenericInfo()->GetClassData()->m_typeId; - } - }; - - template - struct SerializeGenericTypeInfo< typename AzFramework::NetBindable::BoundField > - { - typedef typename AzFramework::NetBindable::BoundField ContainerType; - - class GenericClassNetBindableBoundField - : public GenericClassInfo - { - public: - AZ_TYPE_INFO(GenericClassNetBindableBoundField, "{EFD64FE7-9432-401A-B7A1-1767F4C5A7F0}"); - GenericClassNetBindableBoundField() - : m_classData{ SerializeContext::ClassData::Create("AzFramework::NetBindable::BoundField", GetSpecializedTypeId(), Internal::NullFactory::GetInstance(), nullptr, &m_containerStorage) } - { - } - - SerializeContext::ClassData* GetClassData() override - { - return &m_classData; - } - - size_t GetNumTemplatedArguments() override - { - return 1; - } - - const Uuid& GetTemplatedTypeId(size_t) override - { - return SerializeGenericTypeInfo::GetClassTypeId(); - } - - const Uuid& GetSpecializedTypeId() const override - { - return azrtti_typeid(); - } - - const Uuid& GetGenericTypeId() const override - { - return TYPEINFO_Uuid(); - } - - const Uuid& GetLegacySpecializedTypeId() const override - { - return AZ::AzTypeInfo::template Uuid(); - } - - void Reflect(SerializeContext* serializeContext) - { - if (serializeContext) - { - serializeContext->RegisterGenericClassInfo(GetSpecializedTypeId(), this, &AnyTypeInfoConcept::CreateAny); - if (GenericClassInfo* containerGenericClassInfo = m_containerStorage.m_classElement.m_genericClassInfo) - { - containerGenericClassInfo->Reflect(serializeContext); - } - } - } - - protected: - Internal::AzFrameworkNetBindableFieldContainer m_containerStorage; - SerializeContext::ClassData m_classData; - }; - - using ClassInfoType = GenericClassNetBindableBoundField; - - static ClassInfoType* GetGenericInfo() - { - return GetCurrentSerializeContextModule().CreateGenericClassInfo(); - } - - static const Uuid& GetClassTypeId() - { - return GetGenericInfo()->GetClassData()->m_typeId; - } - }; -} - -#endif // AZFRAMEWORK_NET_BINDABLE_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp deleted file mode 100644 index 90613daabe..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp +++ /dev/null @@ -1,287 +0,0 @@ -/* -* 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. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - void NetBindingComponent::Reflect(AZ::ReflectContext* reflection) - { - NetBindable::Reflect(reflection); - - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ; - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "Network Binding", "The Network Binding component marks an entity as able to be replicated across the network") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Networking") - ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NetBinding.svg") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/NetBinding.png") - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-network-binding.html") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)); - } - } - - AZ::BehaviorContext* behaviorContext = azrtti_cast(reflection); - - if (behaviorContext) - { - behaviorContext->EBus("NetBindingHandlerBus") - ->Event("IsEntityBoundToNetwork", &NetBindingHandlerBus::Events::IsEntityBoundToNetwork) - ->Event("IsEntityAuthoritative", &NetBindingHandlerBus::Events::IsEntityAuthoritative) - - // Desired, but currently unsupported events. - // Seems to be an unsupported type(AZ::u16) - //->Event("SetReplicaPriority", &NetBindingHandlerBus::Events::SetReplicaPriority) - //->Event("GetReplicaPriority", &NetBindingHandlerBus::Events::GetReplicaPriority) - ; - } - - // We also need to register the chunk type, and this would be a good time to do so. - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(NetBindingComponentChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - - NetBindingComponent::NetBindingComponent() - : m_isLevelSliceEntity(false) - { - } - - void NetBindingComponent::Activate() - { - NetBindingHandlerBus::Handler::BusConnect(GetEntityId()); - - if (!IsEntityBoundToNetwork()) - { - bool shouldBind = false; - NetBindingSystemBus::BroadcastResult( shouldBind, &NetBindingSystemBus::Events::ShouldBindToNetwork); - if (shouldBind) - { - BindToNetwork(nullptr); - } - else - { - /* - * This is the Editor path. We still need to call NetBindable::NetInit() in order - * to initialize NetworkContext Fields and RPCs, so that they behave as - * authoritative in game editor mode. Without this call RPCs callbacks won't invoke inside the Editor. - * For example: - * - * static void Reflect(...) - * { - * NetworkContext->Class()->RPC("my rpc", &MyNetworkComponent::m_myRpc); - * } - * ... - * m_myRpc(); // <--- will not invoke the callback inside the Editor unless NetInit() is called below. - */ - for (Component* component : GetEntity()->GetComponents()) - { - if (NetBindable* netBindable = azrtti_cast(component)) - { - netBindable->NetInit(); - } - } - } - } - } - - void NetBindingComponent::Deactivate() - { - NetBindingHandlerBus::Handler::BusDisconnect(); - if (IsEntityBoundToNetwork()) - { - static_cast(m_chunk.get())->SetBinding(nullptr); - if (m_chunk->IsMaster()) - { - m_chunk->GetReplica()->Destroy(); - } - m_chunk = nullptr; - } - } - - bool NetBindingComponent::IsEntityBoundToNetwork() - { - return m_chunk && m_chunk->GetReplica(); - } - - bool NetBindingComponent::IsEntityAuthoritative() - { - return !m_chunk || m_chunk->IsMaster(); - } - - void NetBindingComponent::BindToNetwork(GridMate::ReplicaPtr bindTo) - { - AZ_Assert(!IsEntityBoundToNetwork(), "We shouldn't be bound to the network if the network is just starting!"); - - if (bindTo) - { - NetBindingComponentChunkPtr bindingChunk = bindTo->FindReplicaChunk(); - AZ_Assert(bindingChunk, "Can't find NetBindingComponentChunk!"); - m_chunk = bindingChunk; - bindingChunk->SetBinding(this); - - GridMate::Replica* replica = bindingChunk->GetReplica(); - size_t nChunks = replica->GetNumChunks(); - size_t nBindings = bindingChunk->m_bindMap.Get().size(); - AZ_Assert(nChunks == nBindings, "Number of chunks received is not the same as the size of the bind map!"); - nBindings = AZ::GetMin(nBindings, nChunks); - for (size_t i = 0; i < nBindings; ++i) - { - AZ::ComponentId bindToId = bindingChunk->m_bindMap.Get()[i]; - if (bindToId != AZ::InvalidComponentId) - { - AZ::Component* component = GetEntity()->FindComponent(bindToId); - NetBindable* netBindable = azrtti_cast(component); - AZ_Assert(netBindable, "Can't find net bindable component with id %llu to be bound to chunk type %s!", bindToId, replica->GetChunkByIndex(i)->GetDescriptor()->GetChunkName()); - if (netBindable && netBindable->IsSyncEnabled()) - { - netBindable->SetNetworkBinding(replica->GetChunkByIndex(i)); - } - } - } - } - else - { - GridMate::ReplicaPtr replica = GridMate::Replica::CreateReplica(GetEntity()->GetName().c_str()); - NetBindingComponentChunk* chunk = GridMate::CreateReplicaChunk(); - m_chunk = chunk; - chunk->SetBinding(this); - replica->AttachReplicaChunk(chunk); - - chunk->m_bindMap.Modify([&](AZStd::vector& bindMap) - { - // Mark the chunks already in the replica as non-components. - bindMap.resize(replica->GetNumChunks(), AZ::InvalidComponentId); - - // Collect the bindings and add the to the replica - AZ::Entity* entity = GetEntity(); - for (Component* component : entity->GetComponents()) - { - NetBindable* netBindable = azrtti_cast(component); - if (netBindable && netBindable->IsSyncEnabled()) - { - GridMate::ReplicaChunkPtr bindingChunk = netBindable->GetNetworkBinding(); - if (bindingChunk) - { - bindMap.push_back(component->GetId()); - replica->AttachReplicaChunk(bindingChunk); - } - } - } - return true; - }); - - // Add replica to session replica manager (may be deferred) - NetBindingSystemBus::Broadcast( &NetBindingSystemBus::Events::AddReplicaMaster, GetEntity(), replica); - } - } - - void NetBindingComponent::UnbindFromNetwork() - { - if (m_chunk) - { - for (Component* component : GetEntity()->GetComponents()) - { - NetBindable* netBindable = azrtti_cast(component); - if (netBindable && netBindable->IsSyncEnabled()) - { - netBindable->UnbindFromNetwork(); - } - } - - NetBindingComponentChunkPtr chunk = static_cast(m_chunk.get()); - chunk->SetBinding(nullptr); - m_chunk = nullptr; - if (chunk->IsProxy()) - { - EntityContextId contextId = EntityContextId::CreateNull(); - EntityIdContextQueryBus::EventResult( contextId, GetEntityId(), &EntityIdContextQueryBus::Events::GetOwningContextId); - if (contextId.IsNull()) - { - delete GetEntity(); - } - else if (!IsLevelSliceEntity()) - { - NetBindingSystemBus::Broadcast( &NetBindingSystemBus::Events::UnbindGameEntity, GetEntityId(), m_sliceInstanceId); - } - } - } - } - - void NetBindingComponent::MarkAsLevelSliceEntity() - { - AZ_Assert(!IsEntityBoundToNetwork(), "MarkAsLevelSliceEntity() has to be called before the entity is bound to the network!"); - m_isLevelSliceEntity = true; - } - - void NetBindingComponent::SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - m_sliceInstanceId = sliceInstanceId; - } - - void NetBindingComponent::RequestEntityChangeOwnership(GridMate::PeerId peerId) - { - if (m_chunk && m_chunk->GetReplica()) - { - m_chunk->GetReplica()->RequestChangeOwnership(peerId); - } - } - - void NetBindingComponent::SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) - { - if (m_chunk) - { - m_chunk->SetPriority(replicaPriority); - } - } - - GridMate::ReplicaPriority NetBindingComponent::GetReplicaPriority() const - { - if (m_chunk && m_chunk->GetReplica()) - { - return m_chunk->GetReplica()->GetPriority(); - } - else - { - AZ_Error("NetBindingComponent",false,"Trying to gather ReplicaPriority without having a Replica."); - return GridMate::k_replicaPriorityLowest; - } - } - - bool NetBindingComponent::IsLevelSliceEntity() const - { - return m_isLevelSliceEntity; - } -} // namespace AzFramework - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h deleted file mode 100644 index 5f4ec1c7f3..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_COMPONENT_H -#define AZFRAMEWORK_NET_BINDING_COMPONENT_H - -#include -#include - -namespace AzFramework -{ - /** - * NetBindingComponent enables network synchronization for the entity. - * It works in conjunction with NetBindingComponentChunk and NetBindingSystemComponent - * to perform network binding and notifies other components on the entity to bind - * their ReplicaChunks via the NetBindable interface. - * - * Entities bound to proxy replicas will be automatically destroyed when they are - * unbound from the network. - */ - class NetBindingComponent - : public AZ::Component - , public NetBindingHandlerBus::Handler - { - friend class NetBindingComponentChunk; - - public: - AZ_COMPONENT(NetBindingComponent, "{E9CA5D63-ED2D-4B59-B3C4-EBCD4A0013E4}", NetBindingHandlerInterface); - - NetBindingComponent(); - - protected: - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8)); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8)); - } - - /////////////////////////////////////////////////////////////////////// - // AZ::Component - static void Reflect(AZ::ReflectContext* reflection); - void Activate() override; - void Deactivate() override; - /////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////// - // NetBindingHandlerBus::Handler - void BindToNetwork(GridMate::ReplicaPtr bindTo) override; - void UnbindFromNetwork() override; - bool IsEntityBoundToNetwork() override; - bool IsEntityAuthoritative() override; - void MarkAsLevelSliceEntity() override; - void SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) override; - void RequestEntityChangeOwnership(GridMate::PeerId peerId = GridMate::InvalidReplicaPeerId) override; - - void SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) override; - GridMate::ReplicaPriority GetReplicaPriority() const override; - /////////////////////////////////////////////////////////////////////// - - //! Returns if the entity belongs to the level slice for binding purposes. - bool IsLevelSliceEntity() const; - - //! Points to the NetBindingComponentChunk counterpart. - GridMate::ReplicaChunkPtr m_chunk; - bool m_isLevelSliceEntity; - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_COMPONENT_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp deleted file mode 100644 index 6ebfe63507..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* -* 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. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - NetBindingComponentChunk::SpawnInfo::SpawnInfo() - : m_runtimeEntityId(AZ::EntityId::InvalidEntityId) - , m_owningContextId(UnspecifiedNetBindingContextSequence) - , m_staticEntityId(AZ::EntityId::InvalidEntityId) - , m_sliceInstanceId(UnspecifiedSliceInstanceId) - , m_sliceAssetId(UnspecifiedSliceInstanceId, 0) - { - } - - bool NetBindingComponentChunk::SpawnInfo::operator==(const SpawnInfo& rhs) - { - return m_owningContextId == rhs.m_owningContextId - && m_runtimeEntityId == rhs.m_runtimeEntityId - && m_staticEntityId == rhs.m_staticEntityId - && m_serializedState == rhs.m_serializedState - && m_sliceAssetId == rhs.m_sliceAssetId; - } - - bool NetBindingComponentChunk::SpawnInfo::ContainsSerializedState() const - { - return !m_serializedState.empty(); - } - - void NetBindingComponentChunk::SpawnInfo::Marshaler::Marshal(GridMate::WriteBuffer& wb, const SpawnInfo& data) - { - wb.Write(data.m_owningContextId, GridMate::VlqU32Marshaler()); - wb.Write(data.m_runtimeEntityId); - - bool useSerializedState = data.ContainsSerializedState(); - wb.Write(useSerializedState); - if (useSerializedState) - { - wb.Write(data.m_serializedState); - } - else - { - wb.Write(data.m_sliceAssetId); - wb.Write(data.m_staticEntityId); - wb.Write(data.m_sliceInstanceId); - } - } - - void NetBindingComponentChunk::SpawnInfo::Marshaler::Unmarshal(SpawnInfo& data, GridMate::ReadBuffer& rb) - { - rb.Read(data.m_owningContextId, GridMate::VlqU32Marshaler()); - rb.Read(data.m_runtimeEntityId); - - bool hasSerializedState = false; - rb.Read(hasSerializedState); - if (hasSerializedState) - { - rb.Read(data.m_serializedState); - } - else - { - rb.Read(data.m_sliceAssetId); - rb.Read(data.m_staticEntityId); - rb.Read(data.m_sliceInstanceId); - } - } - - NetBindingComponentChunk::NetBindingComponentChunk() - : m_bindingComponent(nullptr) - , m_spawnInfo("SpawnInfo") - , m_bindMap("ComponentBindMap") - { - m_spawnInfo.SetMaxIdleTime(0.f); - m_bindMap.SetMaxIdleTime(0.f); - } - - void NetBindingComponentChunk::OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - if (IsMaster()) - { - // Get and store entity spawn data - AZ_Assert(m_bindingComponent, "Entity binding is invalid!"); - - m_spawnInfo.Modify([&](SpawnInfo& spawnInfo) - { - spawnInfo.m_runtimeEntityId = static_cast(m_bindingComponent->GetEntity()->GetId()); - - bool isProceduralEntity = true; - AZ::SliceComponent::SliceInstanceAddress sliceInfo; - - EntityContextId contextId = EntityContextId::CreateNull(); - const AZ::EntityId bindingComponentEntityId = m_bindingComponent->GetEntityId(); - EntityIdContextQueryBus::EventResult(contextId, bindingComponentEntityId, - &EntityIdContextQueryBus::Events::GetOwningContextId); - if (!contextId.IsNull()) - { - EBUS_EVENT_RESULT(spawnInfo.m_owningContextId, NetBindingSystemBus, GetCurrentContextSequence); - SliceEntityRequestBus::EventResult(sliceInfo, bindingComponentEntityId, - &SliceEntityRequestBus::Events::GetOwningSlice); - bool isDynamicSliceEntity = sliceInfo.IsValid(); - - isProceduralEntity = !m_bindingComponent->IsLevelSliceEntity() && !isDynamicSliceEntity; - } - - if (isProceduralEntity) - { - // write cloning info - AZ::SerializeContext* sc = nullptr; - EBUS_EVENT_RESULT(sc, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(sc, "Can't find SerializeContext!"); - AZ::IO::ByteContainerStream> spawnDataStream(&spawnInfo.m_serializedState); - AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&spawnDataStream, *sc, AZ::DataStream::ST_BINARY); - objStream->WriteClass(m_bindingComponent->GetEntity()); - objStream->Finalize(); - } - else - { - // write slice info - if (sliceInfo.IsValid()) - { - AZ::Data::AssetId sliceAssetId = sliceInfo.GetReference()->GetSliceAsset().GetId(); - spawnInfo.m_sliceAssetId = AZStd::make_pair(sliceAssetId.m_guid, sliceAssetId.m_subId); - } - if (sliceInfo.GetInstance()) - { - spawnInfo.m_sliceInstanceId = sliceInfo.GetInstance()->GetId(); - } - - AZ::EntityId staticEntityId; - EBUS_EVENT_RESULT(staticEntityId, NetBindingSystemBus, GetStaticIdFromEntityId, m_bindingComponent->GetEntity()->GetId()); - spawnInfo.m_staticEntityId = static_cast(staticEntityId); - } - - return true; - }); - } - else - { - AZ::EntityId runtimeEntityId(m_spawnInfo.Get().m_runtimeEntityId); - NetBindingContextSequence owningContextId = m_spawnInfo.Get().m_owningContextId; - - //TODO Move to Filter Hook - // Reject and cancel sessions with duplicate MachineIds? - // Reject and cancel sessions with duplicate entity ID creation requests? - //Check MachineId collision - bool collision = AZ::Entity::GetProcessSignature() == (m_spawnInfo.Get().m_runtimeEntityId & 0xFFFFFFFF); - AZ_Error("GridMate", !collision, "Replica received with duplicate Entity Machine IDs. Ignoring"); - - if (!collision) - { - //Check EntityID collision - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, runtimeEntityId); - - /* - * Only false if no machine ID collision and no entity ID collision - * And the entity is already active, it's possible the entity already exists in deactivated state as a cache mechanism - */ - collision = (entity != nullptr) && (entity->GetState() == AZ::Entity::State::Active); - } - - /** - * Special case - static entities should not count as duplicates. - * Static entities are loaded with the level and will be bounded here. - */ - if (collision) - { - AZ::EntityId staticEntityId; - EBUS_EVENT_RESULT(staticEntityId, NetBindingSystemBus, GetStaticIdFromEntityId, runtimeEntityId); - if (staticEntityId == runtimeEntityId) - { - collision = false; - } - } - - if (!collision) //Ignore duplicate runtime entity IDs - { - if (m_spawnInfo.Get().ContainsSerializedState()) - { - // Spawn the entity from stream input data - AZ::IO::MemoryStream spawnData(m_spawnInfo.Get().m_serializedState.data(), m_spawnInfo.Get().m_serializedState.size()); - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromStream, spawnData, runtimeEntityId, GetReplicaId(), owningContextId); - } - else - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = owningContextId; - spawnContext.m_sliceAssetId = AZ::Data::AssetId(m_spawnInfo.Get().m_sliceAssetId.first, m_spawnInfo.Get().m_sliceAssetId.second); - spawnContext.m_runtimeEntityId = runtimeEntityId; - spawnContext.m_staticEntityId = AZ::EntityId(m_spawnInfo.Get().m_staticEntityId); - spawnContext.m_sliceInstanceId = m_spawnInfo.Get().m_sliceInstanceId; - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, GetReplicaId(), spawnContext); - } - } - else //Fail early to prevent unnecessary spawning of duplicate entity IDs - { - //Misconfiguration or potential cheating/DoS? - AZ_Warning("NetBinding", false, "Received duplicate Entity ID %llu. Ignoring.", runtimeEntityId); - } - } - } - - void NetBindingComponentChunk::OnReplicaDeactivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - if (m_bindingComponent) - { - m_bindingComponent->UnbindFromNetwork(); - } - } - - bool NetBindingComponentChunk::AcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) - { - bool result = true; - - if (m_bindingComponent) - { - EBUS_EVENT_ID_RESULT(result, m_bindingComponent->GetEntityId(), NetBindingEventsBus, OnEntityAcceptChangeOwnership, requestor, rc); - } - - return result; - } - - void NetBindingComponentChunk::OnReplicaChangeOwnership(const GridMate::ReplicaContext& rc) - { - if (m_bindingComponent) - { - EBUS_EVENT_ID(m_bindingComponent->GetEntityId(), NetBindingEventsBus, OnEntityChangeOwnership, rc); - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h deleted file mode 100644 index 5a0f023fa2..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H -#define AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H - -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - class NetBindingComponent; - class NetBindingComponentChunkDescriptor; - - /** - * NetBindingComponentChunk is the counterpart of NetBindingComponent on the network side. - * It contains entity spawn data. It is created by NetBindingComponent during network - * binding on the master and initiates entity creation and binding on the proxy side. - */ - class NetBindingComponentChunk - : public GridMate::ReplicaChunk - { - friend NetBindingComponent; - friend NetBindingComponentChunkDescriptor; - - public: - AZ_CLASS_ALLOCATOR(NetBindingComponentChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingComponentChunk"; } - - NetBindingComponentChunk(); - - void SetBinding(NetBindingComponent* bindingComponent) { m_bindingComponent = bindingComponent; } - NetBindingComponent* GetBinding() const { return m_bindingComponent; } - - protected: - /////////////////////////////////////////////////////////////////////// - // ReplicaChunk - bool IsReplicaMigratable() override { return true; } - void OnReplicaActivate(const GridMate::ReplicaContext& rc) override; - void OnReplicaDeactivate(const GridMate::ReplicaContext& rc) override; - bool AcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) override; - void OnReplicaChangeOwnership(const GridMate::ReplicaContext& rc) override; - /////////////////////////////////////////////////////////////////////// - - NetBindingComponent* m_bindingComponent; - - class SpawnInfo - { - public: - class Marshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, const SpawnInfo& data); - void Unmarshal(SpawnInfo& data, GridMate::ReadBuffer& rb); - }; - - class Throttle - { - public: - //! Always return true because SpawnInfo never changes - bool WithinThreshold(const SpawnInfo&) const { return true; } - void UpdateBaseline(const SpawnInfo& baseline) { (void)baseline; } - }; - - SpawnInfo(); - - bool operator==(const SpawnInfo& rhs); - - bool ContainsSerializedState() const; - - /** - * \brief Same as m_staticEntityId on authoritative entity with master replica - */ - AZ::u64 m_runtimeEntityId; - NetBindingContextSequence m_owningContextId; - AZStd::vector m_serializedState; - - /** - * \brief EntityId of authoritative entity with master replica - */ - AZ::u64 m_staticEntityId; - - AZStd::pair m_sliceAssetId; - /** - * \brief uniquely identifies the slice instance that this entity is being replicated from - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; - - GridMate::DataSet m_spawnInfo; - GridMate::DataSet > m_bindMap; - }; - typedef AZStd::intrusive_ptr NetBindingComponentChunkPtr; -} // namespace AZ - -#endif // AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h deleted file mode 100644 index f3089947dc..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H -#define AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H - -#include -#include -#include - -namespace AzFramework -{ - /** - * NetBindingEventsBus - * Throws networking related entity events - */ - class NetBindingEvents - : public AZ::EBusTraits - { - public: - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - typedef AZ::EntityId BusIdType; - - virtual ~NetBindingEvents() {} - - /** - * Called on authoritative(Master) entity when ownership of this entity is about to be transferred to another peer - * Returning false from this call will result in denying request for ownership transfer - */ - virtual bool OnEntityAcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) { (void)requestor; (void)rc; return true; } - - /** - * Called when ownership transfer of an entity is finished. - */ - virtual void OnEntityChangeOwnership(const GridMate::ReplicaContext& rc) { (void)rc; } - }; - - typedef AZ::EBus NetBindingEventsBus; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h deleted file mode 100644 index 55fa4c0217..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H -#define AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H - -#include -#include -#include -#include -#include - -namespace AzFramework -{ - /** - * The NetBindingSystemComponent notifies net binding handlers of binding events on this bus. - * The net binding component implements this interface and listens on the NetBindingHandlerBus. - */ - class NetBindingHandlerInterface - : public AZ::EBusTraits - { - public: - AZ_RTTI(NetBindingHandlerInterface, "{9F84E9FE-81A0-4105-9C51-6C42C83FECAF}"); - - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - typedef AZ::EntityId BusIdType; - - virtual ~NetBindingHandlerInterface() {} - - /** - * Called to let the entity know that it should bind to the network. - * If bindTo is set, it means that the entity is a proxy and the handler - * should bind the entity to the specified - * replica, otherwise it should bind to a new replica and add it via - * NetBindingSystemBus::AddReplicaMaster. - */ - virtual void BindToNetwork(GridMate::ReplicaPtr bindTo) = 0; - - /** - * Called to let the entity know that it should unbind from the network. - */ - virtual void UnbindFromNetwork() = 0; - - /** - * Returns true if the entity is bound to the network. - */ - virtual bool IsEntityBoundToNetwork() = 0; - - /** - * Returns true if the entity is authoritative on the local node. - */ - virtual bool IsEntityAuthoritative() = 0; - - /** - * Flags the entity as part of the level slice. - */ - virtual void MarkAsLevelSliceEntity() = 0; - - /** - * Set the slice instance id that this entity was spawned by and belongs to. - */ - virtual void SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) = 0; - - /** - * Sets the Replica Priority - */ - virtual void SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) = 0; - - /** - * Request entity ownership to a given peer (by default to local peer) - */ - virtual void RequestEntityChangeOwnership(GridMate::PeerId peerId = GridMate::InvalidReplicaPeerId) = 0; - - /** - * Gets the Replica Priority - */ - virtual GridMate::ReplicaPriority GetReplicaPriority() const = 0; - }; - typedef AZ::EBus NetBindingHandlerBus; - - /** - * Set of queries that might want to be made about the networking system - * mainly wraps up EBus calls to keep the implementing code a bit more readable - */ - class NetQuery - { - public: - AZ_RTTI(NetQuery, "{AA4C5699-889D-4A73-9AD2-53EB03D8BB99}"); - - virtual ~NetQuery() = default; - - static AZ_FORCE_INLINE bool IsEntityAuthoritative(AZ::EntityId entityId) - { - bool result = true; - EBUS_EVENT_ID_RESULT(result,entityId,NetBindingHandlerBus,IsEntityAuthoritative); - return result; - } - }; - -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h deleted file mode 100644 index c26c6d6350..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#ifndef AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H -#define AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H - -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - namespace IO - { - class GenericStream; - } -} - -namespace AzFramework -{ - const AZ::SliceComponent::SliceInstanceId UnspecifiedSliceInstanceId = AZ::Uuid::CreateNull(); - - /** - */ - typedef AZ::u32 NetBindingContextSequence; - const NetBindingContextSequence UnspecifiedNetBindingContextSequence = 0; - - /** - */ - struct NetBindingSliceContext - { - NetBindingContextSequence m_contextSequence; - AZ::Data::AssetId m_sliceAssetId; - AZ::EntityId m_staticEntityId; - AZ::EntityId m_runtimeEntityId; - /** - * \brief uniquely identifies the slice instance that this entity is being replicated from - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; - - /** - * The net binding system implements this interface and listens on the NetBindingSystemBus. - * - * Network binding is activated when OnNetworkSessionActivated event is received with the binding session, - * and is deactivated by the OnNetworkSessionDeactivated event. - */ - class NetBindingSystemInterface - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - virtual ~NetBindingSystemInterface() {} - - //! Returns true if a network session is available and entities should bind themselves to the network. - virtual bool ShouldBindToNetwork() = 0; - - //! Returns the current entity context sequence - virtual NetBindingContextSequence GetCurrentContextSequence() = 0; - - //! Get a level entity's static id. - virtual AZ::EntityId GetStaticIdFromEntityId(AZ::EntityId entity) = 0; - - //! Get a level entity's id based on the static id - virtual AZ::EntityId GetEntityIdFromStaticId(AZ::EntityId staticEntityId) = 0; - - //! Adds a bound replica to the network session as master. - virtual void AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) = 0; - - //! Spawn and bind an entity from a slice - virtual void SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) = 0; - - //! Spawn and bind an entity from stream - virtual void SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) = 0; - - //! De-spawn an entity: deactivates or removes the entity. - /** - * /note @sliceInstanceId is the slice instance that the entity belongs to. If it's a level entity, then this should be AZ::Uuid::CreateNull() - */ - virtual void UnbindGameEntity(AZ::EntityId entity, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) = 0; - }; - typedef AZ::EBus NetBindingSystemBus; - - class NetBindingSystemEvents - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - //! Notification that a network session is created - virtual void OnNetworkSessionCreated(GridMate::GridSession* session) { (void)session; } - - //! Notification that a network session is ready - virtual void OnNetworkSessionActivated(GridMate::GridSession* session) { (void)session; } - - //! Notification that a network session is no longer available - virtual void OnNetworkSessionDeactivated(GridMate::GridSession* session) { (void)session; } - }; - typedef AZ::EBus NetBindingSystemEventsBus; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp deleted file mode 100644 index 85081d1637..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* 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. -* -*/ - -#include -#include - -namespace AzFramework -{ - NetBindingSystemComponent::NetBindingSystemComponent() - { - } - - NetBindingSystemComponent::~NetBindingSystemComponent() - { - } - - void NetBindingSystemComponent::Activate() - { - NetBindingSystemImpl::Init(); - } - - void NetBindingSystemComponent::Deactivate() - { - NetBindingSystemImpl::Shutdown(); - } - - void NetBindingSystemComponent::Reflect(AZ::ReflectContext* context) - { - NetBindingSystemImpl::Reflect(context); - - if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ; - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class( - "NetBinding System", "Performs network binding for game entities.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Engine") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) - ; - } - } - } - - void NetBindingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("NetBindingSystemService", 0xa0ad6656)); - } - - void NetBindingSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("NetBindingSystemService", 0xa0ad6656)); - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h deleted file mode 100644 index 03ff6aa86f..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h +++ /dev/null @@ -1,53 +0,0 @@ -/* -* 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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H -#define AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H - -#include -#include - -namespace AZ -{ - class ReflectContext; -} - -namespace AzFramework -{ - /** - * NetBindingSystemComponent exposes NetBindingSystemImpl as a component - */ - class NetBindingSystemComponent - : public AZ::Component - , public NetBindingSystemImpl - { - friend class NetBindingSystemContextData; - public: - AZ_COMPONENT(NetBindingSystemComponent, "{B96548CC-0866-4BB3-A87B-BF0C4F69E8AC}"); - - NetBindingSystemComponent(); - ~NetBindingSystemComponent() override; - - ////////////////////////////////////////////////////////////////////////// - // Component overrides - void Activate() override; - void Deactivate() override; - static void Reflect(AZ::ReflectContext* context); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - ////////////////////////////////////////////////////////////////////////// - }; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H -#pragma once - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp deleted file mode 100644 index bb40432ffb..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp +++ /dev/null @@ -1,957 +0,0 @@ -/* -* 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. -* -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#define Extra_Tracing -#undef Extra_Tracing - -#if defined(Extra_Tracing) -#include -#define AZ_ExtraTracePrintf(window, ...) AZ::Debug::Trace::Instance().Printf(window, __VA_ARGS__); -#else -#define AZ_ExtraTracePrintf(window, ...) -#endif - -namespace AzFramework -{ - const AZStd::chrono::milliseconds NetBindingSystemImpl::s_sliceBindingTimeout = AZStd::chrono::milliseconds(5000); - - namespace - { - NetBindingHandlerInterface* GetNetBindingHandler(AZ::Entity* entity) - { - NetBindingHandlerInterface* handler = nullptr; - for (AZ::Component* component : entity->GetComponents()) - { - handler = azrtti_cast(component); - if (handler) - { - break; - } - } - return handler; - } - } - - NetBindingSliceInstantiationHandler::~NetBindingSliceInstantiationHandler() - { - // m_bindRequests in NetBindingSystemImpl could be cleaned before slice instantiation finished - if (m_state == State::Spawning) - { - AzFramework::SliceInstantiationResultBus::Handler::BusDisconnect(); - SliceGameEntityOwnershipServiceRequestBus::Broadcast( - &SliceGameEntityOwnershipServiceRequests::CancelDynamicSliceInstantiation, m_ticket - ); - } - - for (AZ::Entity* entity : m_boundEntities) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Cleanup - deleting %llu\n", entity->GetId()); - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, entity->GetId()); - } - } - - void NetBindingSliceInstantiationHandler::InstantiateEntities() - { - if (m_sliceAssetId.IsValid()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "InstantiateEntities sliceid %s\n", - m_sliceInstanceId.ToString(false, false).c_str()); - - if (AZ::Data::AssetManager::IsReady()) - { - auto remapFunc = [bindingQueue=m_bindingQueue](AZ::EntityId originalId, bool /*isEntityId*/, const AZStd::function&) -> AZ::EntityId - { - auto iter = bindingQueue.find(originalId); - if (iter != bindingQueue.end()) - { - return iter->second.m_desiredRuntimeEntityId; - } - return AZ::Entity::MakeId(); - }; - - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset(m_sliceAssetId, AZ::Data::AssetLoadBehavior::Default); - - SliceGameEntityOwnershipServiceRequestBus::BroadcastResult(m_ticket, - &SliceGameEntityOwnershipServiceRequests::InstantiateDynamicSlice, asset, AZ::Transform::Identity(), remapFunc); - SliceInstantiationResultBus::Handler::BusConnect(m_ticket); - - m_state = State::Spawning; - } - else - { - AZ_Warning("NetBindingSystemImpl", false, "AssetManager was not ready when attempting to instantiate sliceid %s\n", - m_sliceInstanceId.ToString(false, false).c_str()); - InstantiationFailureCleanup(); - } - } - } - - bool NetBindingSliceInstantiationHandler::IsInstantiated() const - { - return m_state == State::Spawned; - } - - bool NetBindingSliceInstantiationHandler::IsANewSliceRequest() const - { - return m_state == State::NewRequest && m_sliceAssetId.IsValid() && !m_ticket.IsValid(); - } - - bool NetBindingSliceInstantiationHandler::IsBindingComplete() const - { - return !SliceInstantiationResultBus::Handler::BusIsConnected() && m_bindingQueue.empty(); - } - - bool NetBindingSliceInstantiationHandler::HasActiveEntities() const - { - for (const AZ::Entity* entity : m_boundEntities) - { - if (entity->GetState() == AZ::Entity::State::Active) - { - return true; - } - } - - return false; - } - - void NetBindingSliceInstantiationHandler::OnSlicePreInstantiate(const AZ::Data::AssetId& /*sliceAssetId*/, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) - { - const auto& entityMapping = sliceAddress.GetInstance()->GetEntityIdToBaseMap(); - - const AZ::SliceComponent::EntityList& sliceEntities = sliceAddress.GetInstance()->GetInstantiated()->m_entities; - for (AZ::Entity *sliceEntity : sliceEntities) - { - auto it = entityMapping.find(sliceEntity->GetId()); - AZ_Assert(it != entityMapping.end(), "Failed to retrieve static entity id for a slice entity!"); - const AZ::EntityId staticEntityId = it->second; - - auto itBindRecord = m_bindingQueue.find(staticEntityId); - if (itBindRecord != m_bindingQueue.end()) - { - AZ_Assert(GetNetBindingHandler(sliceEntity), "Slice entity matched the static id of replicated entity, but there is no valid NetBindingHandlerInterface on it!"); - - itBindRecord->second.m_actualRuntimeEntityId = sliceEntity->GetId(); - } - else if (GetNetBindingHandler(sliceEntity)) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "OnSlicePreInstantiate late bindRequest, slice %s, staticid %llu, spawned %llu\n", - m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(staticEntityId), - static_cast(sliceEntity->GetId())); - - BindRequest& request = m_bindingQueue[staticEntityId]; - request.m_desiredRuntimeEntityId = staticEntityId; - request.m_actualRuntimeEntityId = sliceEntity->GetId(); - request.m_requestTime = m_bindTime; - request.m_state = BindRequest::State::PlaceholderBind; - } - - sliceEntity->SetRuntimeActiveByDefault(false); - } - } - - void NetBindingSliceInstantiationHandler::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) - { - SliceInstantiationResultBus::Handler::BusDisconnect(); - - CloseEntityMap(sliceAddress.GetInstance()->GetEntityIdMap()); - - const AZ::SliceComponent::EntityList sliceEntities = sliceAddress.GetInstance()->GetInstantiated()->m_entities; - for (AZ::Entity *sliceEntity : sliceEntities) - { - auto it = sliceAddress.GetInstance()->GetEntityIdToBaseMap().find(sliceEntity->GetId()); - AZ_Assert(it != sliceAddress.GetInstance()->GetEntityIdToBaseMap().end(), "Failed to retrieve static entity id for a slice entity!"); - const AZ::EntityId staticEntityId = it->second; - const auto itUnbound = m_bindingQueue.find(staticEntityId); - if (itUnbound == m_bindingQueue.end()) - { - /* - * Remove entities that aren't meant to be net bounded. - */ - if (!GetNetBindingHandler(sliceEntity)) - { - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, sliceEntity->GetId()); - continue; - } - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Adding %llu \n", sliceEntity->GetId()); - m_boundEntities.push_back(sliceEntity); - } - - m_state = State::Spawned; - } - - void NetBindingSliceInstantiationHandler::OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId) - { - SliceInstantiationResultBus::Handler::BusDisconnect(); - - AZ_UNUSED(sliceAssetId); - AZ_TracePrintf("NetBindingSystemImpl", "Failed to instantiate a slice %s!", sliceAssetId.ToString().c_str()); - - InstantiationFailureCleanup(); - } - - void NetBindingSliceInstantiationHandler::InstantiationFailureCleanup() - { - m_boundEntities.clear(); - m_bindingQueue.clear(); - - // With m_bindingQueue empty, this slice instance handler will be removed on the next tick of NetBindingSystemImpl - m_state = State::Failed; - } - - void NetBindingSliceInstantiationHandler::UseCacheFor(BindRequest& request, const AZ::EntityId& staticEntityId) - { - AZ_Warning("NetBindingSystemImpl", !m_staticToRuntimeEntityMap.empty(), "An empty slice, really? static %llu", - static_cast(staticEntityId)); - - const auto actualRuntimeIter = m_staticToRuntimeEntityMap.find(staticEntityId); - if (actualRuntimeIter == m_staticToRuntimeEntityMap.end()) - { - AZ_Warning("NetBindingSystemImpl", false, "Wrong mapping, expected cache to have entity %llu for slice %s \n", - static_cast(staticEntityId), - m_sliceInstanceId.ToString(false, false).c_str()); - -#if defined(Extra_Tracing) - for (auto& item: m_staticToRuntimeEntityMap) - { - AZ_UNUSED(item); - AZ_ExtraTracePrintf("NetBindingSystemImpl", "mapping had %llu to %llu \n", - static_cast(item.first), - static_cast(item.second)); - } -#endif - - return; - } - - const AZ::EntityId actualRuntimeEntityId = actualRuntimeIter->second; - const auto itCache = AZStd::find_if(m_boundEntities.begin(), m_boundEntities.end(), [&actualRuntimeEntityId](AZ::Entity* entity) { - return entity->GetId() == actualRuntimeEntityId; - }); - - if (itCache != m_boundEntities.end()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "OnSlicePreInstantiate late bindRequest, slice %s, staticid %llu, spawned %llu\n", - m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(staticEntityId), - static_cast(actualRuntimeEntityId)); - - request.m_actualRuntimeEntityId = actualRuntimeEntityId; - request.m_desiredRuntimeEntityId = staticEntityId; - } - else - { - AZ_Warning("NetBindingSystemImpl", false, "Expected cache to have entity %llu for slice %s \n", - static_cast(request.m_desiredRuntimeEntityId), - m_sliceInstanceId.ToString(false, false).c_str()); - } - } - - void NetBindingSliceInstantiationHandler::CloseEntityMap( - const AZ::SliceComponent::EntityIdToEntityIdMap& staticToRuntimeMap) - { - m_staticToRuntimeEntityMap.clear(); - for (auto& item : staticToRuntimeMap) - { - m_staticToRuntimeEntityMap[item.first] = item.second; - } - } - - NetBindingSystemContextData::NetBindingSystemContextData() - : m_bindingContextSequence("BindingContextSequence", UnspecifiedNetBindingContextSequence) - { - } - - void NetBindingSystemContextData::OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - NetBindingSystemImpl* system = static_cast(NetBindingSystemBus::FindFirstHandler()); - AZ_Assert(system, "NetBindingSystemContextData requires a valid NetBindingSystemComponent to function!"); - system->OnContextDataActivated(this); - } - - void NetBindingSystemContextData::OnReplicaDeactivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - NetBindingSystemImpl* system = static_cast(NetBindingSystemBus::FindFirstHandler()); - if (system) - { - system->OnContextDataDeactivated(this); - } - } - - - NetBindingSystemImpl::NetBindingSystemImpl() - : m_bindingSession(nullptr) - , m_currentBindingContextSequence(UnspecifiedNetBindingContextSequence) - , m_isAuthoritativeRootSliceLoad(false) - , m_overrideRootSliceLoadAuthoritative(false) - { - } - - NetBindingSystemImpl::~NetBindingSystemImpl() - { - } - - void NetBindingSystemImpl::Init() - { - NetBindingSystemBus::Handler::BusConnect(); - NetBindingSystemEventsBus::Handler::BusConnect(); - - // Start listening for game context events - EntityContextId gameContextId = EntityContextId::CreateNull(); - EBUS_EVENT_RESULT(gameContextId, GameEntityContextRequestBus, GetGameEntityContextId); - if (!gameContextId.IsNull()) - { - EntityContextEventBus::Handler::BusConnect(gameContextId); - } - } - - void NetBindingSystemImpl::Shutdown() - { - EntityContextEventBus::Handler::BusDisconnect(); - NetBindingSystemEventsBus::Handler::BusDisconnect(); - NetBindingSystemBus::Handler::BusDisconnect(); - - m_contextData.reset(); - } - - bool NetBindingSystemImpl::ShouldBindToNetwork() - { - return m_contextData && m_contextData->ShouldBindToNetwork(); - } - - NetBindingContextSequence NetBindingSystemImpl::GetCurrentContextSequence() - { - return m_currentBindingContextSequence; - } - - bool NetBindingSystemImpl::ReadyToAddReplica() const - { - return m_bindingSession && m_bindingSession->GetReplicaMgr(); - } - - void NetBindingSystemImpl::AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) - { - bool addReplica = ShouldBindToNetwork(); - AZ_Assert(addReplica, "Entities shouldn't be binding to the network right now!"); - if (addReplica) - { - if (ReadyToAddReplica()) - { - m_bindingSession->GetReplicaMgr()->AddMaster(replica); - } - else - { - m_addMasterRequests.push_back(AZStd::make_pair(entity->GetId(), replica)); - } - } - } - - - AZ::EntityId NetBindingSystemImpl::GetStaticIdFromEntityId(AZ::EntityId entityId) - { - AZ::EntityId staticId = entityId; // if no static id mapping is found, then the static id is the same as the runtime id - - // If entity came from a slice, try to get the mapping from it - AZ::SliceComponent::SliceInstanceAddress sliceInfo; - SliceEntityRequestBus::EventResult(sliceInfo, entityId, &SliceEntityRequestBus::Events::GetOwningSlice); - AZ::SliceComponent::SliceInstance* sliceInstance = sliceInfo.GetInstance(); - if (sliceInstance) - { - const auto it = sliceInstance->GetEntityIdToBaseMap().find(entityId); - if (it != sliceInstance->GetEntityIdToBaseMap().end()) - { - staticId = it->second; - } - } - - return staticId; - } - - AZ::EntityId NetBindingSystemImpl::GetEntityIdFromStaticId(AZ::EntityId staticEntityId) - { - AZ::EntityId runtimeId = AZ::EntityId(); - - // if we can find an entity with the static id, then the static id is the same as the runtime id. - AZ::Entity* entity = nullptr; - EBUS_EVENT(AZ::ComponentApplicationBus, FindEntity, staticEntityId); - if (entity) - { - runtimeId = staticEntityId; - } - - return runtimeId; - } - - void NetBindingSystemImpl::SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) - { - auto& sliceQueue = m_bindRequests[bindToContext.m_contextSequence]; - - const bool slicePresent = sliceQueue.find(bindToContext.m_sliceInstanceId) != sliceQueue.end(); - - auto iterSliceRequest = sliceQueue.insert_key(bindToContext.m_sliceInstanceId); - NetBindingSliceInstantiationHandler& sliceHandler = iterSliceRequest.first->second; - sliceHandler.m_sliceAssetId = bindToContext.m_sliceAssetId; - sliceHandler.m_sliceInstanceId = bindToContext.m_sliceInstanceId; - - BindRequest& request = sliceHandler.m_bindingQueue[bindToContext.m_staticEntityId]; - - if (!slicePresent) - { - request.m_state = BindRequest::State::FirstBindInSlice; - } - else - { - request.m_state = BindRequest::State::LateBind; - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "SpawnEntityFromSlice late, slice %s, static %llu, desired %llu, state %d \n", - bindToContext.m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(bindToContext.m_staticEntityId), - static_cast(bindToContext.m_runtimeEntityId), - request.m_state); - - sliceHandler.m_bindTime = Now(); - - request.m_bindTo = bindTo; - request.m_desiredRuntimeEntityId = bindToContext.m_runtimeEntityId; - request.m_requestTime = Now(); - - if (sliceHandler.IsInstantiated()) - { - // The slice has been instantiated now, thus we have to use the cache to populated the request with the entity. - sliceHandler.UseCacheFor(request, bindToContext.m_staticEntityId); - } - } - - void NetBindingSystemImpl::SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) - { - auto& requestQueue = m_spawnRequests[addToContext]; - requestQueue.push_back(); - SpawnRequest& request = requestQueue.back(); - request.m_bindTo = bindTo; - request.m_useEntityId = useEntityId; - request.m_spawnDataBuffer.resize_no_construct(spawnData.GetLength()); - spawnData.Read(request.m_spawnDataBuffer.size(), request.m_spawnDataBuffer.data()); - } - - void NetBindingSystemImpl::OnNetworkSessionActivated(GridMate::GridSession* session) - { - AZ_Assert(!m_bindingSession, "We already have an active session! Was the previous session deactivated?"); - if (!m_bindingSession) - { - m_bindingSession = session; - - if (m_bindingSession->IsHost()) - { - GridMate::Replica* replica = CreateSystemReplica(); - session->GetReplicaMgr()->AddMaster(replica); - } - } - } - - void NetBindingSystemImpl::OnNetworkSessionDeactivated(GridMate::GridSession* session) - { - if (session == m_bindingSession) - { - m_bindingSession = nullptr; - } - } - - void NetBindingSystemImpl::UnbindGameEntity(AZ::EntityId entityId, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - if (!m_bindRequests.empty()) - { - const auto itCurrentContextQueue = m_bindRequests.lower_bound(GetCurrentContextSequence()); - - if (itCurrentContextQueue != m_bindRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - const auto itSliceHandler = itCurrentContextQueue->second.find(sliceInstanceId); - if (itSliceHandler != itCurrentContextQueue->second.end()) - { - NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; - for (AZ::Entity* entity : sliceHandler.m_boundEntities) - { - if (entity->GetId() == entityId) - { - entity->Deactivate(); - return; - } - } - - // clean any relevant bind requests as well - const auto bindQueueItem = sliceHandler.m_bindingQueue.find(entityId); - if (bindQueueItem != sliceHandler.m_bindingQueue.end()) - { - sliceHandler.m_bindingQueue.erase(bindQueueItem); - return; - } - } - } - } - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Not in cache - deleting %llu \n", entityId); - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, entityId); - } - - void NetBindingSystemImpl::OnEntityContextReset() - { - const bool isContextOwner = m_contextData && m_contextData->IsMaster() && m_bindingSession && m_bindingSession->IsHost(); - if (isContextOwner) - { - ++m_currentBindingContextSequence; - NetBindingSystemContextData* context = static_cast(m_contextData.get()); - context->m_bindingContextSequence.Set(m_currentBindingContextSequence); - } - } - - bool NetBindingSystemImpl::IsAuthoritateLoad() const - { - if (m_overrideRootSliceLoadAuthoritative) - { - return m_isAuthoritativeRootSliceLoad; - } - - return !m_bindingSession || m_bindingSession->IsHost(); - } - - void NetBindingSystemImpl::UpdateClock(float deltaTime) - { - m_currentTime += AZStd::chrono::milliseconds(aznumeric_cast(deltaTime * AZStd::milli::den)); - } - - AZStd::chrono::system_clock::time_point NetBindingSystemImpl::Now() const - { - return m_currentTime; - } - - void NetBindingSystemImpl::OnEntityContextLoadedFromStream(const AZ::SliceComponent::EntityList& contextEntities) - { - const bool isAuthoritativeLoad = IsAuthoritateLoad(); - - for (AZ::Entity* entity : contextEntities) - { - NetBindingHandlerInterface* netBinder = GetNetBindingHandler(entity); - if (netBinder) - { - netBinder->MarkAsLevelSliceEntity(); - } - - if (!isAuthoritativeLoad && netBinder) - { - entity->SetRuntimeActiveByDefault(false); - - auto& slicesQueue = m_bindRequests[GetCurrentContextSequence()]; - auto& sliceHandler = slicesQueue[UnspecifiedSliceInstanceId]; - BindRequest& request = sliceHandler.m_bindingQueue[entity->GetId()]; - request.m_actualRuntimeEntityId = entity->GetId(); - request.m_requestTime = Now(); - } - } - } - - void NetBindingSystemImpl::OnTick(float deltaTime, AZ::ScriptTimePoint time) - { - AZ_UNUSED(time); - - UpdateClock(deltaTime); - UpdateContextSequence(); - -#if defined(Extra_Tracing) - static AZ::Debug::Timer sTimer; - sTimer.Stamp(); -#endif - ProcessBindRequests(); -#if defined(Extra_Tracing) - const float seconds = sTimer.StampAndGetDeltaTimeInSeconds(); - - static float debugPeriod = 2.f; - static float accumulator = 0; - static float totalTimeTaken = 0; - static AZ::u32 totalTicks = 0; - accumulator += deltaTime; - totalTimeTaken += seconds; - totalTicks++; - - if (accumulator >= debugPeriod) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "ProcessBindRequests() took %f sec \n", totalTicks > 0 ? totalTimeTaken / totalTicks : 0); - - accumulator -= debugPeriod; - totalTimeTaken = 0; - totalTicks = 0; - } -#endif - - ProcessSpawnRequests(); - } - - int NetBindingSystemImpl::GetTickOrder() - { - return AZ::TICK_PLACEMENT + 1; - } - - void NetBindingSystemImpl::UpdateContextSequence() - { - NetBindingSystemContextData* contextChunk = static_cast(m_contextData.get()); - if (m_currentBindingContextSequence != contextChunk->m_bindingContextSequence.Get()) - { - m_currentBindingContextSequence = contextChunk->m_bindingContextSequence.Get(); - } - } - - GridMate::Replica* NetBindingSystemImpl::CreateSystemReplica() - { - AZ_Assert(m_bindingSession->IsHost(), "CreateSystemReplica should only be called on the host!"); - GridMate::Replica* replica = GridMate::Replica::CreateReplica("NetBindingSystem"); - NetBindingSystemContextData* contextChunk = GridMate::CreateReplicaChunk(); - replica->AttachReplicaChunk(contextChunk); - - return replica; - } - - void NetBindingSystemImpl::OnContextDataActivated(GridMate::ReplicaChunkPtr contextData) - { - AZ_Assert(!m_contextData, "We already have our context!"); - m_contextData = contextData; - - // Make sure we always have the unspecified entry. This should also - // be the lower_bound in the map and assuming it is always there - // makes things simpler. - m_spawnRequests.insert(UnspecifiedNetBindingContextSequence); - m_bindRequests.insert(UnspecifiedNetBindingContextSequence); - - if (contextData->IsMaster()) - { - ++m_currentBindingContextSequence; - static_cast(contextData.get())->m_bindingContextSequence.Set(m_currentBindingContextSequence); - } - else - { - UpdateContextSequence(); - } - AZ::TickBus::Handler::BusConnect(); - EBUS_EVENT(AzFramework::NetBindingHandlerBus, BindToNetwork, nullptr); - } - - void NetBindingSystemImpl::OnContextDataDeactivated(GridMate::ReplicaChunkPtr contextData) - { - AZ_Assert(m_contextData == contextData, "This is not our context!"); - m_contextData = nullptr; - - AZ::TickBus::Handler::BusDisconnect(); - m_spawnRequests.clear(); - m_bindRequests.clear(); - m_addMasterRequests.clear(); - m_currentBindingContextSequence = UnspecifiedNetBindingContextSequence; - } - - void NetBindingSystemImpl::ProcessSpawnRequests() - { - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "NetBindingSystemComponent requires a valid SerializeContext in order to spawn entities!"); - const auto spawnFunc = [=](SpawnRequest& spawnData, AZ::EntityId useEntityId, bool addToContext) - { - AZ::Entity* proxyEntity = nullptr; - AZ::ObjectStream::ClassReadyCB readyCB([&](void* classPtr, const AZ::Uuid& classId, AZ::SerializeContext* sc) - { - (void)classId; - (void)sc; - proxyEntity = static_cast(classPtr); - }); - AZ::IO::ByteContainerStream > stream(&spawnData.m_spawnDataBuffer); - AZ::ObjectStream::LoadBlocking(&stream, *serializeContext, readyCB); - - AZ_Warning("NetBindingSystemImpl", proxyEntity, "Could not spawn entity from stream %llu", useEntityId); - if (proxyEntity) - { - proxyEntity->SetId(useEntityId); - if (!BindAndActivate(proxyEntity, spawnData.m_bindTo, addToContext, AZ::Uuid::CreateNull())) - { - AzFramework::EntityContextId contextId = AzFramework::EntityContextId::CreateNull(); - AzFramework::EntityIdContextQueryBus::EventResult( - contextId, proxyEntity->GetId(), &AzFramework::EntityIdContextQueryBus::Events::GetOwningContextId); - - if (contextId.IsNull()) - { - delete proxyEntity; - } - else - { - GameEntityContextRequestBus::Broadcast( - &GameEntityContextRequestBus::Events::DestroyGameEntity, proxyEntity->GetId()); - } - - } - } - }; - - if (!m_spawnRequests.empty()) - { - SpawnRequestContextContainerType::iterator itContextQueue = m_spawnRequests.lower_bound(UnspecifiedNetBindingContextSequence); - AZ_Assert(itContextQueue->first == UnspecifiedNetBindingContextSequence, "We should always have the unspecified (aka global entity) spawn queue!");// - - // Process requests for global entities (not part of any context) - SpawnRequestContainerType& globalQueue = itContextQueue->second; - for (SpawnRequest& request : globalQueue) - { - spawnFunc(request, request.m_useEntityId, false); - } - globalQueue.clear(); - - if (GetCurrentContextSequence() != UnspecifiedNetBindingContextSequence) - { - ++itContextQueue; - - // Clear any obsolete requests (any contexts below the current context sequence) - SpawnRequestContextContainerType::iterator itCurrentContextQueue = m_spawnRequests.lower_bound(GetCurrentContextSequence()); - if (itContextQueue != itCurrentContextQueue) - { - m_spawnRequests.erase(itContextQueue, itCurrentContextQueue); - } - - // Spawn any entities for the current context - if (itCurrentContextQueue != m_spawnRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - for (SpawnRequest& request : itCurrentContextQueue->second) - { - spawnFunc(request, request.m_useEntityId, true); - } - itCurrentContextQueue->second.clear(); - } - } - } - } - } - - void NetBindingSystemImpl::ProcessBindRequests() - { - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "NetBindingSystemComponent requires a valid SerializeContext in order to spawn entities!"); - - if (!m_bindRequests.empty()) - { - BindRequestContextContainerType::iterator itContextQueue = m_bindRequests.lower_bound(UnspecifiedNetBindingContextSequence); - AZ_Assert(itContextQueue->first == UnspecifiedNetBindingContextSequence, "We should always have the unspecified/global spawn queue!"); - - if (GetCurrentContextSequence() != UnspecifiedNetBindingContextSequence) - { - ++itContextQueue; - - // Clear any obsolete requests (any contexts below the current context sequence) - BindRequestContextContainerType::iterator itCurrentContextQueue = m_bindRequests.lower_bound(GetCurrentContextSequence()); - if (itContextQueue != itCurrentContextQueue) - { - m_bindRequests.erase(itContextQueue, itCurrentContextQueue); - } - - // Spawn any proxy entities for the current context - if (itCurrentContextQueue != m_bindRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - for (auto itSliceHandler = itCurrentContextQueue->second.begin(); itSliceHandler != itCurrentContextQueue->second.end(); /*++itSliceHandler*/) - { - NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; - - // If this is a new slice request, instantiate it - if (sliceHandler.IsANewSliceRequest()) - { - sliceHandler.InstantiateEntities(); - } - /* - * A slice instance is kept alive for caching purposes. As we check each bind request for its readiness, - * we are also going to check if the slice instance itself has become inactive and needs to be removed. - */ - bool mightBeInactiveSlice = true; - if (sliceHandler.m_bindingQueue.empty() && sliceHandler.HasActiveEntities()) - { - // The slice instance is spawned and full bound. - mightBeInactiveSlice = false; - } - - // If the entity is ready to be bound to the network, bind it. - // NOTE: It is possible for entities spawned from a slice containing multiple entities with net binding - // to never receive their replica counterpart, either because the replica was destroyed, or was interest - // filtered. We don't have a very good pipeline to prevent these slices from being authored, so if we - // encounter them, we will delete them after a timeout. - for (auto itRequest = sliceHandler.m_bindingQueue.begin(); itRequest != sliceHandler.m_bindingQueue.end(); /*++itRequest*/) - { - BindRequest& request = itRequest->second; - - if (request.m_bindTo != GridMate::InvalidReplicaId && request.m_actualRuntimeEntityId.IsValid()) - { - AZ::Entity* proxyEntity = nullptr; - EBUS_EVENT_RESULT(proxyEntity, AZ::ComponentApplicationBus, FindEntity, request.m_actualRuntimeEntityId); - AZ_Warning("NetBindingSystemImpl", proxyEntity, "Could not find entity for binding %llu", request.m_actualRuntimeEntityId); - if (proxyEntity) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "BindAndActivate desired id %llu, actual %llu, slice %s \n", - static_cast(request.m_desiredRuntimeEntityId), - static_cast(request.m_actualRuntimeEntityId), - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str()); - - BindAndActivate(proxyEntity, request.m_bindTo, false, sliceHandler.m_sliceInstanceId); - } - itRequest = sliceHandler.m_bindingQueue.erase(itRequest); - - // The slice instance is not fully bound. It may remain for a while for caching purposes. - mightBeInactiveSlice = false; - } - else if (AZStd::chrono::milliseconds(Now() - request.m_requestTime) > s_sliceBindingTimeout) - { - // If the real request never showed up, then no need for a trace - if (request.m_state == BindRequest::State::FirstBindInSlice || - request.m_state == BindRequest::State::LateBind) - { - AZ_TracePrintf("NetBindingSystemImpl", "Entity with static id [%llu], slice [%s]\n is still unbound after %llu ms. Discarding unbound entity.\n", - static_cast(request.m_actualRuntimeEntityId), - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str(), - s_sliceBindingTimeout.count()); - } - - switch (sliceHandler.m_state) - { - case NetBindingSliceInstantiationHandler::State::NewRequest: - case NetBindingSliceInstantiationHandler::State::Spawning: - // The slice instance isn't ready yet. We will wait to consider the timing logic until it is ready. - mightBeInactiveSlice = false; - break; - case NetBindingSliceInstantiationHandler::State::Spawned: - case NetBindingSliceInstantiationHandler::State::Failed: - // Now the timing logic for removing the slice instance becomes valid. - mightBeInactiveSlice = true; - break; - default: - break; - } - - ++itRequest; - } - else - { - mightBeInactiveSlice = false; - ++itRequest; - } - } - - if (mightBeInactiveSlice && !sliceHandler.HasActiveEntities()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Removing inactive slice %s \n", - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str()); - - itSliceHandler = itCurrentContextQueue->second.erase(itSliceHandler); - } - else - { - ++itSliceHandler; - } - } - } - } - } - } - - // Spawn replicas for any local entities that are still valid - for (auto& addRequest : m_addMasterRequests) - { - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, addRequest.first); - if (entity) - { - m_bindingSession->GetReplicaMgr()->AddMaster(addRequest.second); - } - } - m_addMasterRequests.clear(); - } - - bool NetBindingSystemImpl::BindAndActivate(AZ::Entity* entity, GridMate::ReplicaId replicaId, bool addToContext, - const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - bool success = false; - - if ( ShouldBindToNetwork() ) - { - const GridMate::ReplicaPtr bindTo = m_contextData->GetReplicaManager()->FindReplica(replicaId); - if (bindTo) - { - if (addToContext) - { - EBUS_EVENT(GameEntityContextRequestBus, AddGameEntity, entity); - } - - if (entity->GetState() == AZ::Entity::State::Constructed) - { - entity->Init(); - } - - NetBindingHandlerInterface* binding = GetNetBindingHandler(entity); - AZ_Warning("NetBindingSystemImpl", binding, "Can't find NetBindingComponent on entity %llu (%s)!", static_cast(entity->GetId()), entity->GetName().c_str()); - if (binding) - { - binding->BindToNetwork(bindTo); - binding->SetSliceInstanceId(sliceInstanceId); - - entity->Activate(); - success = true; - } - } - else - { - // NOTE: It is possible for entities spawned from a slice containing multiple entities with net binding - // to never receive their replica counterpart, either because the replica was destroyed, or was interest - // filtered. - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Failed to bind entity %llu - could not find replica %u", entity->GetId(), replicaId); - } - } - - return success; - } - - void NetBindingSystemImpl::Reflect(AZ::ReflectContext* context) - { - if (context) - { - // We need to register the chunk type, and this would be a good time to do so. - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(NetBindingSystemContextData::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h deleted file mode 100644 index 543d9544ce..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h +++ /dev/null @@ -1,311 +0,0 @@ -/* -* 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. -* -*/ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - /** - * \brief Represents a request to bind a particular replica to an entity - */ - class BindRequest - { - public: - BindRequest() - : m_bindTo(GridMate::InvalidReplicaId) - , m_state(State::None) - { - } - - GridMate::ReplicaId m_bindTo; - AZ::EntityId m_desiredRuntimeEntityId; - AZ::EntityId m_actualRuntimeEntityId; - AZStd::chrono::system_clock::time_point m_requestTime; - - /** - * \brief Represents the state of this bind request and it's relation to the slice instantiation process - */ - enum class State : AZ::u8 - { - None, - /** - * \brief This is the first request that led to instantiating a slice - */ - FirstBindInSlice, - /** - * \brief The request is a placeholder in case a real bind request arrives later. - * Some part of the slice may never be bound (e.g. if a replica is omitted by Interest Manager) - */ - PlaceholderBind, - /** - * \brief The real request did arrive to replace a placeholder request. - */ - LateBind, - }; - - State m_state; - }; - - typedef AZStd::unordered_map BindRequestContainerType; - - /** - * \brief Represents a slice instance being instantiated and bound to replicas - * \note It's possible that only some of the entities are activated and bound to replicas. - */ - class NetBindingSliceInstantiationHandler - : public SliceInstantiationResultBus::Handler - { - public: - ~NetBindingSliceInstantiationHandler() override; - - void InstantiateEntities(); - bool IsInstantiated() const; - bool IsANewSliceRequest() const; - bool IsBindingComplete() const; - - /** - * \note Returns false if there are no entities in the slice or the slice instance isn't ready yet. - * \return true if any of the entities from the slice are active - */ - bool HasActiveEntities() const; - - ////////////////////////////////////////////////////////////////////////// - // SliceInstantiationResultBus - void OnSlicePreInstantiate(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override; - void OnSliceInstantiated(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override; - void OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId) override; - ////////////////////////////////////////////////////////////////////////// - - void InstantiationFailureCleanup(); - void UseCacheFor(BindRequest& request, const AZ::EntityId& staticEntityId); - void CloseEntityMap(const AZ::SliceComponent::EntityIdToEntityIdMap& staticToRuntimeMap); - - AZ::Data::AssetId m_sliceAssetId; - BindRequestContainerType m_bindingQueue; - SliceInstantiationTicket m_ticket; - - /** - * \breif a cache of entities that might be networked at some point - * \note they might be bound and unbound if their replicas leave and come back in the view - */ - AZStd::vector m_boundEntities; - - /** - * \brief identifies which slice instance the instantiation will be performed for - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - /** - * \brief when was the request to spawn a slice and bind it made - */ - AZStd::chrono::system_clock::time_point m_bindTime; - - AZ::SliceComponent::EntityIdToEntityIdMap m_staticToRuntimeEntityMap; - - /** - * \brief The state of the slice instance. - */ - enum class State - { - /** - * \brief Has not started instantiating the slice instance. - */ - NewRequest, - /** - * \brief Waiting on the slice to spawn. - */ - Spawning, - /** - * \brief Successfully spawned the slice assets. - */ - Spawned, - /** - * \brief Failed to spawn the slice. - */ - Failed - }; - - State m_state = State::NewRequest; - }; - - /** - * NetBindingSystemImpl works in conjunction with NetBindingComponent and - * NetBindingComponentChunk to perform network binding for game entities. - * - * It is responsible for adding entity replicas to the network on the master side - * and servicing entity spawn requests from the network on the proxy side, as - * well as detecting network availability and triggering network binding/unbinding. - * - * The system is first activated on the host side when OnNetworkSessionActivated event - * is received, and NetBindingSystemContextData is created. - * The system becomes fully operational when the NetBindingSystemContextData is activated - * and bound to the system, and remains operational as long as the NetBindingSystemContextData - * remains valid. - * - * Level switching is tracked by a monotonically increasing context sequence number controlled - * by the host. Spawn and bind operations are deferred until the correct sequence number - * is reached. Spawning is always performed from the game thread. - */ - class NetBindingSystemImpl - : public NetBindingSystemBus::Handler - , public NetBindingSystemEventsBus::Handler - , public EntityContextEventBus::Handler - , public AZ::TickBus::Handler - { - friend class NetBindingSystemContextData; - - public: - NetBindingSystemImpl(); - ~NetBindingSystemImpl() override; - - static void Reflect(AZ::ReflectContext* context); - - virtual void Init(); - virtual void Shutdown(); - - static const AZStd::chrono::milliseconds s_sliceBindingTimeout; - - ////////////////////////////////////////////////////////////////////////// - // NetBindingSystemBus - bool ShouldBindToNetwork() override; - NetBindingContextSequence GetCurrentContextSequence() override; - void AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) override; - AZ::EntityId GetStaticIdFromEntityId(AZ::EntityId entity) override; - AZ::EntityId GetEntityIdFromStaticId(AZ::EntityId staticEntityId) override; - void SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) override; - void SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) override; - void OnNetworkSessionActivated(GridMate::GridSession* session) override; - void OnNetworkSessionDeactivated(GridMate::GridSession* session) override; - void UnbindGameEntity(AZ::EntityId entity, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // EntityContextEventBus::Handler - void OnEntityContextReset() override; - void OnEntityContextLoadedFromStream(const AZ::SliceComponent::EntityList& contextEntities) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // TickBus::Handler - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - int GetTickOrder() override; - ////////////////////////////////////////////////////////////////////////// - - protected: - //! Called by the NetBindingContext chunk when it is activated - void OnContextDataActivated(GridMate::ReplicaChunkPtr contextData); - - //! Called by the NetBindingContext chunk when it is deactivated - void OnContextDataDeactivated(GridMate::ReplicaChunkPtr contextData); - - //! Update the current binding context sequence - virtual void UpdateContextSequence(); - - //! Process pending spawn requests - virtual void ProcessSpawnRequests(); - - //! Process pending bind requests - virtual void ProcessBindRequests(); - - //! Performs final stage of entity spawning process - virtual bool BindAndActivate(AZ::Entity* entity, GridMate::ReplicaId replicaId, bool addToContext, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId); - - //! Called on the host to spawn the net binding system replica - virtual GridMate::Replica* CreateSystemReplica(); - - AZ_FORCE_INLINE bool ReadyToAddReplica() const; - - class SpawnRequest - { - public: - GridMate::ReplicaId m_bindTo; - AZ::EntityId m_useEntityId; - AZStd::vector m_spawnDataBuffer; - }; - - typedef AZStd::list SpawnRequestContainerType; - typedef AZStd::map SpawnRequestContextContainerType; - - typedef AZStd::unordered_map SliceRequestContainerType; - typedef AZStd::map BindRequestContextContainerType; - - GridMate::GridSession* m_bindingSession; - GridMate::ReplicaChunkPtr m_contextData; - NetBindingContextSequence m_currentBindingContextSequence; - SpawnRequestContextContainerType m_spawnRequests; - BindRequestContextContainerType m_bindRequests; - AZStd::list> m_addMasterRequests; - - /** - * \brief override how root slice entities' replicas should be loaded - * - * We occasionally get GameContextBridge replica (that tells us what level to load) before we get - * a replica that tells us that we are connecting to a network sessions, thus we may not figure out in time if we - * need to load the root slice entities with NetBindingComponent as master replicas or proxy replicas. - * This is a fix until proper order is established. - * - * \param isAuthoritative true if root slice entities with NetBindingComponents to be loaded authoritatively - */ - void OverrideRootSliceLoadMode(bool isAuthoritative) - { - m_isAuthoritativeRootSliceLoad = isAuthoritative; - m_overrideRootSliceLoadAuthoritative = true; - } - - private: - /** - * \brief True if the root slice is to be loaded authoritatively - */ - bool m_isAuthoritativeRootSliceLoad; - /** - * \brief True if root slice loading mode was overriden, otherwise the mode would be determined via m_bindingSession - */ - bool m_overrideRootSliceLoadAuthoritative; - /** - * \brief A helper method to figure the mode of loading root slice entities' replicas - * \return True if the root slice entities is to be loaded authoritatively - */ - bool IsAuthoritateLoad() const; - - void UpdateClock(float deltaTime); - AZStd::chrono::system_clock::time_point Now() const; - - AZStd::chrono::system_clock::time_point m_currentTime; - }; - - class NetBindingSystemContextData - : public GridMate::ReplicaChunk - { - public: - AZ_CLASS_ALLOCATOR(NetBindingSystemContextData, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingSystemContextData"; } - - NetBindingSystemContextData(); - - bool IsReplicaMigratable() override { return true; } - bool IsBroadcast() override { return true; } - - void OnReplicaActivate(const GridMate::ReplicaContext& rc) override; - - void OnReplicaDeactivate(const GridMate::ReplicaContext& rc) override; - - GridMate::DataSet m_bindingContextSequence; - }; -} // namespace AzFramework - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h deleted file mode 100644 index 788eacf8b5..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include - -namespace AzFramework -{ - class NetworkContext; - - /** - * The NetSystemRequestBus services requests for global networking systems in AzFramework - */ - class NetSystemRequests - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - NetSystemRequests() = default; - virtual ~NetSystemRequests() = default; - - virtual NetworkContext* GetNetworkContext() = 0; - }; - - using NetSystemRequestBus = AZ::EBus; -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp deleted file mode 100644 index 98ef897d29..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* -* 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. -* -*/ - -#include -#include -#include - - -namespace AzFramework -{ - NetworkContext::DescBase::DescBase(const char* name, ptrdiff_t offset) - : m_name(name) - , m_offset(offset) - { - } - - NetworkContext::FieldDescBase::FieldDescBase(const char* name, ptrdiff_t offset) - : DescBase(name, offset) - , m_dataSetIdx(static_cast(-1)) - { - } - - NetworkContext::RpcDescBase::RpcDescBase(const char* name, ptrdiff_t offset) - : DescBase(name, offset) - , m_rpcIdx(static_cast(-1)) - { - } - - NetworkContext::CtorDataBase::CtorDataBase(const char* name) - : m_name(name) - { - } - - NetworkContext::ClassBuilder::ClassBuilder(NetworkContext* context, ClassDescPtr binding) - : m_binding(binding) - , m_context(context) - { - } - - NetworkContext::ClassBuilder::~ClassBuilder() - { - if (m_context->IsRemovingReflection()) - { - if (m_binding->UnregisterChunkType) - { - m_binding->UnregisterChunkType(); - } - } - else - { - if (m_binding->RegisterChunkType) - { - m_binding->RegisterChunkType(); - } - } - } - - NetworkContext::ClassDesc::ClassDesc(const char* name, const AZ::Uuid& typeId /* = AZ::Uuid() */) - : m_name(name) - , m_typeId(typeId) - { - } - - /////////////////////////////////////////////////////////////////////////// - /// NetworkContext - /////////////////////////////////////////////////////////////////////////// - NetworkContext::NetworkContext() - { - } - - NetworkContext::~NetworkContext() - { - } - - size_t NetworkContext::GetReflectedChunkSize(const AZ::Uuid& typeId) const - { - size_t totalSize = 0; - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - for (const auto& field : binding->m_chunkDesc.m_fields) - { - totalSize += field->GetDataSetSize(); - } - - for (const auto& rpc : binding->m_chunkDesc.m_rpcs) - { - totalSize += rpc->GetRpcSize(); - } - } - - return totalSize; - } - - bool NetworkContext::UsesSelfAsChunk(const AZ::Uuid& typeId) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - return !binding->m_chunkDesc.m_external && binding->m_chunkDesc.m_fields.size() > 0; - } - return false; - } - - bool NetworkContext::UsesExternalChunk(const AZ::Uuid& typeId) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - return binding->m_chunkDesc.m_external && (AZ::u32(binding->m_chunkDesc.m_chunkId) != 0); - } - return false; - } - - ReplicaChunkBase* NetworkContext::CreateReplicaChunk(const AZ::Uuid& typeId) - { - const auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ClassDescPtr binding = it->second; - if (binding->CreateReplicaChunk) - { - ReplicaChunkDescriptor* descriptor = ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(binding->m_chunkDesc.m_chunkId); - AZ_Assert(descriptor, "NetworkContext cannot find replica chunk descriptor for %s. Did you remember to register the chunk type?", binding->m_name); - ReplicaChunkDescriptorTable::Get().BeginConstructReplicaChunk(descriptor); - ReplicaChunkBase* chunk = binding->CreateReplicaChunk(); - ReplicaChunkDescriptorTable::Get().EndConstructReplicaChunk(); - chunk->Init(descriptor); - return chunk; - } - } - - /* - * Special case: empty declarations such as: - * - * static void Reflect() { - * .... - * NetworkContext->Class(); - * } - * - * Result in no ReplicaChunks being created. It's treated as a no-op. No replication will be performed. - */ - return nullptr; - } - - void NetworkContext::DestroyReplicaChunk(ReplicaChunkBase* chunk) - { - ReplicaChunkClassId chunkId = chunk->GetDescriptor()->GetChunkTypeId(); - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - ClassDescPtr binding = it->second; - binding->DestroyReplicaChunk(chunk); - return; - } - - AZ_Warning("NetworkContext", false, "DestroyReplicaChunk could not find a binding for %s", chunk->GetDescriptor()->GetChunkName()); - } - - void NetworkContext::Bind(NetBindable* instance, ReplicaChunkPtr chunk, NetworkContextBindMode mode) - { - const AZ::Uuid& typeId = instance->RTTI_GetType(); - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - if (chunk) - { - ReplicaChunkClassId chunkId = chunk->GetDescriptor()->GetChunkTypeId(); - AZ_Assert(binding->m_chunkDesc.m_chunkId == chunkId, "NetworkContext detected a type mismatch while trying to bind an instance to a ReplicaChunk"); - if (binding->m_chunkDesc.m_chunkId == chunkId) - { - if (!binding->m_chunkDesc.m_external) - { - ReflectedReplicaChunkBase* refChunk = static_cast(chunk.get()); - refChunk->Bind(instance, mode); - } - } - } - else - { - if (binding->BindRpcs) - { - binding->BindRpcs(instance); - } - } - } - } - - void NetworkContext::EnumerateFields(const ReplicaChunkClassId& chunkId, FieldVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& field : chunkDesc.m_fields) - { - visitor(field.get()); - } - } - } - - void NetworkContext::EnumerateFields(const AZ::Uuid& typeId, FieldVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& field : chunkDesc.m_fields) - { - visitor(field.get()); - } - } - } - - void NetworkContext::EnumerateRpcs(const ReplicaChunkClassId& chunkId, RpcVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& rpc : chunkDesc.m_rpcs) - { - visitor(rpc.get()); - } - } - } - - void NetworkContext::EnumerateRpcs(const AZ::Uuid& typeId, RpcVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& rpc : chunkDesc.m_rpcs) - { - visitor(rpc.get()); - } - } - } - - void NetworkContext::EnumerateCtorData(const ReplicaChunkClassId& chunkId, CtorVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& ctor : chunkDesc.m_ctors) - { - visitor(ctor.get()); - } - } - } - - void NetworkContext::EnumerateCtorData(const AZ::Uuid& typeId, CtorVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& ctor : chunkDesc.m_ctors) - { - visitor(ctor.get()); - } - } - } - - /////////////////////////////////////////////////////////////////////////// - ReflectedReplicaChunkBase::ReflectedReplicaChunkBase() - : m_ctorBuffer(GridMate::EndianType::IgnoreEndian, 0) - { - } - - /////////////////////////////////////////////////////////////////////////// - NetworkContextChunkDescriptor::NetworkContextChunkDescriptor(const char* name, size_t size, const AZ::Uuid& typeId) - : ReplicaChunkDescriptor(name, size) - , m_typeId(typeId) - { - } - - ReplicaChunkBase* NetworkContextChunkDescriptor::CreateFromStream(UnmarshalContext& ctx) - { - AZ_Assert(!m_typeId.IsNull(), "No typeid associated with NetworkContextChunkDescriptor, cannot spawn Chunk"); - if (!m_typeId.IsNull()) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to construct ReflectedReplicaChunk"); - - ReplicaChunkBase* replicaChunk = netContext->CreateReplicaChunk(m_typeId); - if (ctx.m_hasCtorData && ctx.m_iBuf) - { - NetworkContextChunkDescriptor* netChunkDesc = static_cast(replicaChunk->GetDescriptor()); - if (netChunkDesc->IsAuto()) - { - // copy each ctor data field into the ctor buffer - ReflectedReplicaChunkBase* refChunk = static_cast(replicaChunk); - netContext->EnumerateCtorData(m_typeId, - [&ctx, refChunk](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Copy(*ctx.m_iBuf, refChunk->m_ctorBuffer); - }); - } - } - return replicaChunk; - } - return nullptr; - } - - void NetworkContextChunkDescriptor::DeleteReplicaChunk(ReplicaChunkBase* chunk) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to destroy ReflectedReplicaChunk"); - netContext->DestroyReplicaChunk(chunk); - } - - void NetworkContextChunkDescriptor::MarshalCtorData(ReplicaChunkBase* chunk, WriteBuffer& buffer) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to collect ctor data for ReflectedReplicaChunk"); - NetBindable* netBindable = static_cast(chunk->GetHandler()); - NetworkContextChunkDescriptor* netChunkDesc = static_cast(chunk->GetDescriptor()); - if (!netChunkDesc->IsAuto()) - { - return; - } - - if (netBindable) // chunk is bound, get source data from the netBindable - { - netContext->EnumerateCtorData(m_typeId, - [netBindable, &buffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Marshal(netBindable, buffer); - }); - } - else // chunk is not bound yet, copy the ctor data for forwarding - { - ReflectedReplicaChunkBase* refChunk = static_cast(chunk); - ReadBuffer src(refChunk->m_ctorBuffer.GetEndianType(), refChunk->m_ctorBuffer.Get(), refChunk->m_ctorBuffer.Size()); - netContext->EnumerateCtorData(m_typeId, - [&src, &buffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Copy(src, buffer); - }); - } - } - - void NetworkContextChunkDescriptor::DiscardCtorStream(UnmarshalContext& ctx) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to skip ctor data for ReflectedReplicaChunk"); - if (ctx.m_hasCtorData) - { - // Iterate over all of the ctor data and unmarshal it with no destination, - // which will advance the buffer past the ctor data for this object - netContext->EnumerateCtorData(m_typeId, - [&ctx](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Unmarshal(*ctx.m_iBuf, nullptr); - }); - } - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h b/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h deleted file mode 100644 index 5b6d420a79..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h +++ /dev/null @@ -1,969 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace AzFramework -{ - class NetBindable; - - using GridMate::ReplicaChunkInterface; - using GridMate::ReplicaChunkBase; - using GridMate::ReplicaChunk; - using GridMate::ReplicaChunkDescriptor; - using GridMate::DefaultReplicaChunkDescriptor; - using GridMate::ReplicaChunkDescriptorTable; - using GridMate::ReplicaChunkClassId; - using GridMate::ReplicaChunkPtr; - using GridMate::Rpc; - using GridMate::ZoneMask; - using GridMate::ZoneMask_All; - using GridMate::UnmarshalContext; - using GridMate::ReadBuffer; - using GridMate::WriteBuffer; - using GridMate::WriteBufferDynamic; - - /////////////////////////////////////////////////////////////////////////// - // GridMate ReplicaChunk/ReplicaChunkDescriptors - /////////////////////////////////////////////////////////////////////////// - class ReflectedReplicaChunkBase - : public ReplicaChunkBase - , public ReplicaChunkInterface - { - friend NetworkContext; - public: - ReflectedReplicaChunkBase(); - bool IsReplicaMigratable() override { return true; } - - /// Returns the chunk type name, e.g. "ReflectedReplicaChunk" - virtual const char* GetName() const = 0; - /// Returns the linear size of the chunk including DataSets and RPCs - virtual size_t GetSize() const = 0; - /// Returns a pointer to the start of the DataSet/RPC storage allocated with the chunk - virtual AZ::u8* GetDataStart() const = 0; - /// Binds an instance of the reflected class to this chunk - virtual void Bind(NetBindable* instance, NetworkContextBindMode mode) = 0; - /// Removes network bindings from the bound NetBindable - virtual void Unbind() = 0; - - WriteBufferDynamic m_ctorBuffer; ///< Buffer to hold ctor data before the chunk is bound - }; - - /// This will be the header for a blob in memory: - /// The layout looks like: - /// * ReflectedReplicaChunk - /// * DataSets - /// * RPCs - template - class ReflectedReplicaChunk - : public ReflectedReplicaChunkBase - { - friend NetworkContext; - public: - static const char* GetChunkName(); - static size_t GetChunkSize(); - - public: - AZ_CLASS_ALLOCATOR(ReflectedReplicaChunk, AZ::SystemAllocator, 0); - ReflectedReplicaChunk() - : m_dataSets(reinterpret_cast(this) + sizeof(*this)) - { - } - - const char* GetName() const override { return GetChunkName(); } - size_t GetSize() const override { return GetChunkSize(); } - AZ::u8* GetDataStart() const override { return const_cast(m_dataSets); } - void Bind(NetBindable* instance, NetworkContextBindMode mode) override; - void Unbind() override; - - private: - const AZ::u8* m_dataSets; ///< Points to the beginning of the datasets for this chunk - }; - - class NetworkContextChunkDescriptor - : public ReplicaChunkDescriptor - { - public: - NetworkContextChunkDescriptor(const char* name, size_t size, const AZ::Uuid& typeId = AZ::Uuid()); - - ReplicaChunkBase* CreateFromStream(UnmarshalContext& ctx) override; - void DeleteReplicaChunk(ReplicaChunkBase* chunkInstance) override; - void DiscardCtorStream(UnmarshalContext&) override; - void MarshalCtorData(ReplicaChunkBase*, WriteBuffer&) override; - - void Bind(const AZ::Uuid& typeId) { m_typeId = typeId; } - virtual bool IsAuto() const { return false; } - - private: - AZ::Uuid m_typeId; ///< TypeId of the class this descriptor represents (not the chunk type) - }; - - template - class AutoChunkDescriptor - : public NetworkContextChunkDescriptor - { - public: - AutoChunkDescriptor() - : NetworkContextChunkDescriptor(ReflectedReplicaChunk::GetChunkName(), ReflectedReplicaChunk::GetChunkSize(), AZ::RttiTypeId()) - { - } - - ZoneMask GetZoneMask() const override { return mask; } - - bool IsAuto() const override { return true; } - }; - - template - class ExternalChunkDescriptor - : public NetworkContextChunkDescriptor - { - public: - ExternalChunkDescriptor() - : NetworkContextChunkDescriptor(ChunkType::GetChunkName(), sizeof(ChunkType)) - {} - - ZoneMask GetZoneMask() const override { return mask; } - }; - - /////////////////////////////////////////////////////////////////////////// - /// NetworkContext can be used to reflect classes for network serialization - /// It will automatically generate ReplicaChunks and bind them to instances - /// when requested. It also serves as a binding registry for binding a class - /// to the ReplicaChunk that should be used to replicate it. - /////////////////////////////////////////////////////////////////////////// - class NetworkContext - : public AZ::ReflectContext - { - public: - /// @cond EXCLUDE_DOCS - class ClassBuilder; - class ClassDesc; - using ClassDescPtr = AZStd::intrusive_ptr; - using ClassBuilderPtr = AZStd::intrusive_ptr; - using ClassBindings = AZStd::unordered_map; - using ChunkBindings = AZStd::unordered_map; - using ClassInfo = ClassBuilder; ///< @deprecated Use NetworkContext::ClassBuilder - using ClassInfoPtr = ClassBuilderPtr; ///< @deprecated Use NetworkContext::ClassBuilderPtr - /// @endcond - - class IntrusiveRefCounted - { - public: - virtual ~IntrusiveRefCounted() {} - private: - // refcount - template - friend struct AZStd::IntrusivePtrCountPolicy; - mutable unsigned int m_refCount = 0; - AZ_FORCE_INLINE void add_ref() { ++m_refCount; } - AZ_FORCE_INLINE void release() - { - AZ_Assert(m_refCount > 0, "Reference count logic error, trying to remove reference when refcount is 0"); - if (--m_refCount == 0) - { - delete this; - } - } - }; - - /** - * Interface for recording classes, chunks, and datasets - * When destructed at the end of reflection, it will register/unregister the ChunkDescriptor - */ - class ClassBuilder - : public IntrusiveRefCounted - { - friend class NetworkContext; - - protected: - AZ_CLASS_ALLOCATOR(ClassBuilder, AZ::SystemAllocator, 0); - ClassBuilder(NetworkContext* context, ClassDescPtr binding); - - public: - ~ClassBuilder(); - ClassBuilderPtr operator->() { return this; } - - /// Bind a ReplicaChunk type to this class for network serialization - template > - ClassBuilderPtr Chunk(); - - /// Bind a NetBindable's Field - template - typename AZStd::enable_if::value, ClassBuilderPtr>::type - Field(const char* name, FieldType ClassType::* address); - - /// Declare an external chunk's DataSet - template - typename AZStd::enable_if::value, ClassBuilderPtr>::type - Field(const char* name, DataSetType ClassType::* address); - - /// Bind an Rpc::BindInterface for this chunk - template ::template BindInterface > - typename AZStd::enable_if::value, ClassBuilderPtr>::type - RPC(const char* name, RpcBindType ClassType::* rpc); - - /// Bind a NetBindable::Rpc for this NetBindable - template ::template Bind > - typename AZStd::enable_if::value, ClassBuilderPtr>::type - RPC(const char* name, RpcBindType ClassType::* rpc); - -#define CTOR_DATA_OVERLOAD(_getsig, _setsig) \ - template > \ - ClassBuilderPtr CtorData(const char* name, _getsig, _setsig, const MarshalerType&marshaler = MarshalerType()) \ - { \ - return CtorDataImpl(name, getter, setter, marshaler); \ - } - - /// Bind a getter/setter pair for data required during object construction - // this has to be done via overload so that the user does not have to explicitly provide - // the template arguments, they can be divined from the function call - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)() const, void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)() const, void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)() const, void (ClassType::* setter)(DataType)); -#undef CTOR_DATA_OVERLOAD - - private: - template > - ClassBuilderPtr CtorDataImpl(const char* name, GetterFunction getter, SetterFunction setter, const MarshalerType& marshaler = MarshalerType()); - - private: - ClassDescPtr m_binding; - NetworkContext* m_context; - }; - - class DescBase - : public IntrusiveRefCounted - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(DescBase, AZ::SystemAllocator, 0); - DescBase(const char* name, ptrdiff_t offset); - virtual ~DescBase() {} - - const char* GetName() const { return m_name; } - ptrdiff_t GetOffset() const { return m_offset; } - protected: - const char* m_name; ///< Field name, will be used as DataSet debug name - ptrdiff_t m_offset; ///< Offset from an instance pointer (a ReplicaChunk or the actual class instance) - }; - - class FieldDescBase - : public DescBase - { - friend class NetworkContext; - - public: - AZ_CLASS_ALLOCATOR(FieldDescBase, AZ::SystemAllocator, 0); - FieldDescBase(const char* name, ptrdiff_t offset); - virtual ~FieldDescBase() {} - - virtual void ConstructDataSet(void*) const = 0; - virtual void DestructDataSet(void*) const = 0; - virtual size_t GetDataSetSize() const = 0; - - size_t GetDataSetIndex() const { return m_dataSetIdx; } - - protected: - size_t m_dataSetIdx; - }; - - /** - * Represents a DataSet in a chunk or class - * NOTE: m_offset in this class is the offset from ReplicaChunk* -> DataSet - */ - template - class DataSetDesc - : public FieldDescBase - { - public: - AZ_CLASS_ALLOCATOR(DataSetDesc, AZ::SystemAllocator, 0); - DataSetDesc(const char* name, ptrdiff_t offset); - - void ConstructDataSet(void*) const override {} - void DestructDataSet(void*) const override {} - size_t GetDataSetSize() const override { return sizeof(DataSetType); } - }; - - /** - * Represents a field in a chunk, responsible for creating a DataSet - * that represents the field - * NOTE: m_offset in this class is the offset from NetBindable* -> NetBindable::Field - */ - template - class NetBindableFieldDesc - : public FieldDescBase - { - public: - using DataSetType = typename FieldType::DataSetType; - - public: - AZ_CLASS_ALLOCATOR(NetBindableFieldDesc, AZ::SystemAllocator, 0); - NetBindableFieldDesc(const char* name, ptrdiff_t offset); - - void ConstructDataSet(void* mem) const override { FieldType::ConstructDataSet(mem, m_name); } - void DestructDataSet(void* mem) const override { FieldType::DestructDataSet(mem); } - size_t GetDataSetSize() const override { return sizeof(DataSetType); } - }; - - class RpcDescBase - : public DescBase - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(RpcDescBase, AZ::SystemAllocator, 0); - RpcDescBase(const char* name, ptrdiff_t offset); - virtual ~RpcDescBase() {} - - virtual void ConstructRpc(void*) const {} - virtual void DestructRpc(void*) const {} - virtual size_t GetRpcSize() const { return 0; } - - size_t GetRpcIndex() const { return m_rpcIdx; } - - protected: - size_t m_rpcIdx; - }; - - template - class NetBindableRpcDesc - : public RpcDescBase - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(NetBindableRpcDesc, AZ::SystemAllocator, 0); - NetBindableRpcDesc(const char* name, ptrdiff_t offset) - : RpcDescBase(name, offset) - { - static_assert((AZStd::is_base_of::value), "NetBindableRpcDesc is intended for use only with NetBindableRpcs"); - } - - void ConstructRpc(void* mem) const override { RpcBindType::ConstructRpc(mem, m_name); } - void DestructRpc(void* mem) const override { RpcBindType::DestructRpc(mem); } - size_t GetRpcSize() const override { return sizeof(typename RpcBindType::BindInterfaceType); } - }; - - class CtorDataBase - : public IntrusiveRefCounted - { - public: - AZ_CLASS_ALLOCATOR(CtorDataBase, AZ::SystemAllocator, 0); - CtorDataBase(const char* name); - virtual ~CtorDataBase() {} - - virtual void Marshal(NetBindable* netBindable, WriteBuffer& buffer) const = 0; - virtual void Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const = 0; - virtual void Copy(ReadBuffer& src, WriteBuffer& dest) const = 0; - - protected: - const char* m_name; - }; - - template - class CtorDataDesc - : public CtorDataBase - { - using GetterFunction = AZStd::function; - using SetterFunction = AZStd::function; - public: - AZ_CLASS_ALLOCATOR(CtorDataDesc, AZ::SystemAllocator, 0); - CtorDataDesc(const char* name, GetterFunction get, SetterFunction set) - : CtorDataBase(name) - , m_get(get) - , m_set(set) - {} - - CtorDataDesc(const char* name, DataType(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)) - : CtorDataBase(name) - , m_get(AZStd::bind(getter, AZStd::placeholders::_1)) - , m_set(AZStd::bind(setter, AZStd::placeholders::_1, AZStd::placeholders::_2)) - {} - - void Marshal(NetBindable* netBindable, WriteBuffer& buffer) const override; - void Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const override; - virtual void Copy(ReadBuffer& src, WriteBuffer& dest) const override; - - GetterFunction m_get; - SetterFunction m_set; - MarshalerType m_marshaler; - }; - - struct ChunkDesc - { - public: - using Fields = AZStd::vector >; - using Rpcs = AZStd::vector >; - using Ctors = AZStd::vector >; - - const char* m_name = nullptr; ///< The name of the chunk - ReplicaChunkClassId m_chunkId; ///< The registered id of the ReplicaChunk this class will use - Fields m_fields; ///< list of data fields in the ReplicaChunk - Rpcs m_rpcs; ///< list of RPCs in the ReplicaChunk - Ctors m_ctors; ///< list of ctor callbacks to gather/apply ctor data - bool m_external = false; ///< If true, this chunk is separate from the class bound to it - }; - - /** - * Contains the chunk factory and field descriptions for a given class - */ - class ClassDesc - : public IntrusiveRefCounted - { - public: - - AZ_CLASS_ALLOCATOR(ClassDesc, AZ::SystemAllocator, 0); - ClassDesc(const char* name = nullptr, const AZ::Uuid& typeId = AZ::Uuid()); - - public: - const char* m_name; ///< The name of the class that is bound - AZ::Uuid m_typeId; ///< The type that this binding represents (null for chunks) - ChunkDesc m_chunkDesc; ///< Descriptor for the chunk for this type - - /// Functor which will register the ReplicaChunkDescriptor with the global registry - AZStd::function RegisterChunkType; - /// Functor to unregister the ReplicaChunkDescriptor (during reflection removal) - AZStd::function UnregisterChunkType; - /// Functor which will create a ReplicaChunk and bind it to the given instance - AZStd::function CreateReplicaChunk; - /// Functor which can destroy a ReplicaChunk and free its memory - AZStd::function DestroyReplicaChunk; - /// Functor which binds an instance of this class to its RPCs for local dispatch - AZStd::function BindRpcs; - }; - - AZ_CLASS_ALLOCATOR(NetworkContext, AZ::SystemAllocator, 0); - AZ_RTTI(NetworkContext, "{B1172D4A-EA1B-441D-AAE6-A9933DAECA8A}", AZ::ReflectContext); - - NetworkContext(); - virtual ~NetworkContext(); - - /// Register a class with the NetworkContext for replication - template - ClassBuilderPtr Class(); - - /// Create a replica chunk for a given class - ReplicaChunkBase* CreateReplicaChunk(const AZ::Uuid& typeId); - - /// Create a replica chunk for a given class, template version - template - ReplicaChunkBase* CreateReplicaChunk(); - - /// Destroy a replica chunk for a given class - void DestroyReplicaChunk(ReplicaChunkBase * chunk); - - /// Bind an instance and a chunk to each other - void Bind(NetBindable * instance, ReplicaChunkPtr chunk, NetworkContextBindMode mode); - - /// Returns whether or not a given type uses a reflected (automatic) ReplicaChunk - bool UsesSelfAsChunk(const AZ::Uuid & typeId) const; - - /// Returns whether or not a given type uses a custom ReplicaChunk - bool UsesExternalChunk(const AZ::Uuid & typeId) const; - - /// Return the size of the the chunk which will represent the given type - size_t GetReflectedChunkSize(const AZ::Uuid & typeId) const; - - using FieldVisitor = AZStd::function; - void EnumerateFields(const ReplicaChunkClassId&chunkId, FieldVisitor visitor) const; - void EnumerateFields(const AZ::Uuid & typeId, FieldVisitor visitor) const; - - using RpcVisitor = AZStd::function; - void EnumerateRpcs(const ReplicaChunkClassId&chunkId, RpcVisitor visitor) const; - void EnumerateRpcs(const AZ::Uuid & typeId, RpcVisitor visitor) const; - - using CtorVisitor = AZStd::function; - void EnumerateCtorData(const ReplicaChunkClassId&chunkId, CtorVisitor visitor) const; - void EnumerateCtorData(const AZ::Uuid & typeId, CtorVisitor visitor) const; - - private: - template - void InitReflectedChunkBinding(ClassDescPtr binding); - - template > - void InitExternalChunkBinding(ClassDescPtr binding); - - private: - ClassBindings m_classBindings; - ChunkBindings m_chunkBindings; - }; - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::ClassBuilderPtr NetworkContext::Class() - { - static_assert((AZStd::is_base_of::value), "Classes reflected through NetworkContext must be derived from NetBindable"); - const AZ::Uuid& typeId = AZ::AzTypeInfo::Uuid(); - ClassDescPtr binding = nullptr; - if (IsRemovingReflection()) // Just remove the entire class definition - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - binding = it->second; - m_chunkBindings.erase(binding->m_chunkDesc.m_chunkId); - m_classBindings.erase(it); - } - } - else - { - auto ret = m_classBindings.insert_key(typeId); - AZ_Assert(ret.second, "Cannot register more than one type with the same Uuid in the NetworkContext"); - binding = ret.first->second = aznew ClassDesc(AZ::AzTypeInfo::Name(), AZ::AzTypeInfo::Uuid()); - } - - return aznew ClassBuilder(this, binding); - } - - template - void NetworkContext::InitReflectedChunkBinding(ClassDescPtr binding) - { - if (!binding->RegisterChunkType) - { - binding->m_chunkDesc.m_name = ReflectedReplicaChunk::GetChunkName(); - ReplicaChunkClassId chunkClassId = ReplicaChunkClassId(binding->m_chunkDesc.m_name); - m_chunkBindings[chunkClassId] = binding; - NetworkContext* netContext = this; - - binding->RegisterChunkType = [chunkClassId, netContext]() - { - bool result = ReplicaChunkDescriptorTable::Get().RegisterChunkType, AutoChunkDescriptor >(); - ReplicaChunkDescriptor* desc = ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(chunkClassId); - ReplicaChunkDescriptorTable::Get().BeginConstructReplicaChunk(desc); - // The offset recorded in NetBindableFields is the offset in the NetBindable - // We must compute the offset of the generated DataSets here and record the - // index from the descriptor - ptrdiff_t offset = sizeof(ReflectedReplicaChunk); // data sets are right after the ReflectedReplicaChunk<> in memory - netContext->EnumerateFields(chunkClassId, - [desc, &offset](FieldDescBase* field) - { - desc->RegisterDataSet(field->m_name, offset); - field->m_dataSetIdx = desc->GetDataSetIndex(offset); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [desc, &offset](RpcDescBase* rpc) - { - desc->RegisterRPC(rpc->m_name, offset); - rpc->m_rpcIdx = desc->GetRpcIndex(offset); - offset += rpc->GetRpcSize(); - }); - AZ_Assert(offset == static_cast(ReflectedReplicaChunk::GetChunkSize()), "Overflow/underflow while registering DataSets for %s", ReflectedReplicaChunk::GetChunkName()); - ReplicaChunkDescriptorTable::Get().EndConstructReplicaChunk(); - return result; - }; - - binding->UnregisterChunkType = [chunkClassId]() - { - ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(chunkClassId); - }; - - binding->CreateReplicaChunk = [netContext, chunkClassId]() - { - ReflectedReplicaChunkBase* chunk = new(azmalloc(ReflectedReplicaChunk::GetChunkSize(), AZStd::alignment_of >::value, AZ::SystemAllocator, ReflectedReplicaChunk::GetChunkName()))ReflectedReplicaChunk(); - AZ::u8* dataStart = chunk->GetDataStart(); - AZ::u8* dataEnd = reinterpret_cast(chunk) + chunk->GetSize(); - ptrdiff_t offset = 0; - netContext->EnumerateFields(chunkClassId, - [&offset, dataStart, dataEnd](FieldDescBase* field) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* dataSetMem = reinterpret_cast(dataStart + offset); - field->ConstructDataSet(dataSetMem); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [&offset, dataStart, dataEnd](RpcDescBase* rpc) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* rpcMem = reinterpret_cast(dataStart + offset); - rpc->ConstructRpc(rpcMem); - offset += rpc->GetRpcSize(); - }); - AZ_Assert((dataStart + offset) == dataEnd, "Overflow/underflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - return chunk; - }; - - binding->DestroyReplicaChunk = [netContext, chunkClassId](ReplicaChunkBase* chunkBase) - { - AZ_Assert(chunkBase->GetDescriptor()->GetChunkTypeId() == chunkClassId, "Mismatched chunk type id for %s (0x%p)", ReflectedReplicaChunk::GetChunkName(), chunkBase); - ReflectedReplicaChunkBase* chunk = static_cast(chunkBase); - chunk->Unbind(); - - AZ::u8* dataStart = chunk->GetDataStart(); - AZ::u8* dataEnd = reinterpret_cast(chunk) + chunk->GetSize(); - ptrdiff_t offset = 0; - netContext->EnumerateFields(chunkClassId, - [&offset, dataStart, dataEnd](FieldDescBase* field) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in dtor while destroying %s", ReflectedReplicaChunk::GetChunkName()); - void* dataSetMem = reinterpret_cast(dataStart + offset); - field->DestructDataSet(dataSetMem); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [&offset, dataStart, dataEnd](RpcDescBase* rpc) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* rpcMem = reinterpret_cast(dataStart + offset); - rpc->DestructRpc(rpcMem); - offset += rpc->GetRpcSize(); - }); - AZ_Assert((dataStart + offset) == dataEnd, "Overflow/underflow in dtor while destroying %s", ReflectedReplicaChunk::GetChunkName()); - chunk->~ReflectedReplicaChunkBase(); - azfree(chunk, AZ::SystemAllocator, ReflectedReplicaChunk::GetChunkSize(), AZStd::alignment_of >::value); - }; - - binding->BindRpcs = [netContext, chunkClassId](NetBindable* bindable) - { - ClassType* derivedInstance = static_cast(bindable); - netContext->EnumerateRpcs(chunkClassId, - [derivedInstance](const RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - bindableRpc->Bind(derivedInstance); - }); - }; - - binding->m_chunkDesc.m_chunkId = chunkClassId; - } - } - - template - void NetworkContext::InitExternalChunkBinding(ClassDescPtr binding) - { - if (!binding->RegisterChunkType) - { - binding->m_chunkDesc.m_name = ChunkType::GetChunkName(); - ReplicaChunkClassId chunkClassId = ReplicaChunkClassId(binding->m_chunkDesc.m_name); - m_chunkBindings[chunkClassId] = binding; - const AZ::Uuid& typeId = binding->m_typeId; - NetworkContext* netContext = this; - binding->RegisterChunkType = [chunkClassId, typeId, netContext]() - { - bool result = ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - NetworkContextChunkDescriptor* desc = static_cast(ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(chunkClassId)); - desc->Bind(typeId); - netContext->EnumerateFields(chunkClassId, - [desc](FieldDescBase* field) - { - desc->RegisterDataSet(field->m_name, field->m_offset); - field->m_dataSetIdx = desc->GetDataSetIndex(field->m_offset); - }); - netContext->EnumerateRpcs(chunkClassId, - [desc](RpcDescBase* rpc) - { - desc->RegisterRPC(rpc->m_name, rpc->m_offset); - }); - return result; - }; - - binding->UnregisterChunkType = [chunkClassId]() - { - return ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(chunkClassId); - }; - - binding->CreateReplicaChunk = []() - { - return aznew ChunkType(); - }; - - binding->DestroyReplicaChunk = [](ReplicaChunkBase* chunk) - { - delete chunk; - }; - - binding->m_chunkDesc.m_chunkId = chunkClassId; - } - } - - template - ReplicaChunkBase* NetworkContext::CreateReplicaChunk() - { - return CreateReplicaChunk(AZ::AzTypeInfo::Uuid()); - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::DataSetDesc::DataSetDesc(const char* name, ptrdiff_t offset) - : NetworkContext::FieldDescBase(name, offset) - { - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::NetBindableFieldDesc::NetBindableFieldDesc(const char* name, ptrdiff_t offset) - : NetworkContext::FieldDescBase(name, offset) - { - } - - /////////////////////////////////////////////////////////////////////////// - template - void NetworkContext::CtorDataDesc::Marshal(NetBindable* netBindable, WriteBuffer& buffer) const - { - ClassType* instance = static_cast(netBindable); - DataType data = m_get(instance); - buffer.Write(data, m_marshaler); - } - - template - void NetworkContext::CtorDataDesc::Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const - { - ClassType* instance = static_cast(netBindable); - DataType data; - buffer.Read(data, m_marshaler); - if (instance) - { - m_set(instance, data); - } - } - - template - void NetworkContext::CtorDataDesc::Copy(ReadBuffer& src, WriteBuffer& dest) const - { - DataType data; - src.Read(data, m_marshaler); - dest.Write(data, m_marshaler); - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::ClassBuilderPtr NetworkContext::ClassBuilder::Chunk() - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "ReplicaChunks being registered with the NetworkContext must derive from ReplicaChunk"); - static_assert((AZStd::is_base_of::value), "Chunk bindings via NetworkContext must use a NetworkContextChunkDescriptor derived descriptor"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a ReplicaChunk for a class which has not been declared to the NetworkContext"); - AZ_Assert(!m_binding->m_chunkDesc.m_chunkId, "Cannot register more than one ReplicaChunk binding for a class in the NetworkContext"); - - m_context->InitExternalChunkBinding(m_binding); - m_binding->m_chunkDesc.m_external = true; - } - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::Field(const char* name, FieldType ClassType::* address) - { - if (!m_context->IsRemovingReflection()) - { - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a field for a class which has not been declared to the NetworkContext"); - AZ_Assert(!m_binding->m_chunkDesc.m_external, "Cannot register a NetBindable::Field from within an external chunk"); - - m_context->InitReflectedChunkBinding(m_binding); - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*address)); - m_binding->m_chunkDesc.m_fields.push_back(aznew NetBindableFieldDesc(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::Field(const char* name, DataSetType ClassType::* address) - { - if (!m_context->IsRemovingReflection()) - { - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a field for a class which has not been declared to the NetworkContext"); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*address)); - m_binding->m_chunkDesc.m_fields.push_back(aznew DataSetDesc(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::RPC(const char* name, RpcBindType ClassType::* rpc) - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "Cannot bind an RPC call to an object which is not a ReplicaChunkInterface"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register an RPC for a class which has not been declared to the NetworkContext"); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*rpc)); - m_binding->m_chunkDesc.m_rpcs.push_back(aznew RpcDescBase(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::RPC(const char* name, RpcBindType ClassType::* rpc) - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "Cannot bind an RPC call to an object which is not a ReplicaChunkInterface"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register an RPC for a class which has not been declared to the NetworkContext"); - - m_context->InitReflectedChunkBinding(m_binding); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*rpc)); - m_binding->m_chunkDesc.m_rpcs.push_back(aznew NetBindableRpcDesc(name, offset)); - } - - return this; - } - - template - NetworkContext::ClassBuilderPtr NetworkContext::ClassBuilder::CtorDataImpl(const char* name, GetterFunction getter, SetterFunction setter, const MarshalerType&) - { - if (!m_context->IsRemovingReflection()) - { - m_context->InitReflectedChunkBinding(m_binding); - - auto get = [getter](NetBindable* nb) -> DataType { return (*static_cast(nb).*getter)(); }; - auto set = [setter](NetBindable* nb, const DataType& data) { (*static_cast(nb).*setter)(data); }; - m_binding->m_chunkDesc.m_ctors.push_back(aznew CtorDataDesc(name, get, set)); - } - - return this; - } - - /////////////////////////////////////////////////////////////////////////// - template - const char* ReflectedReplicaChunk::GetChunkName() - { - static char name[128] = { 0 }; - if (!name[0]) - { - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), "ReflectedReplicaChunk<"); - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), AZ::AzTypeInfo::Name()); - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), ">"); - } - return name; - } - - template - size_t ReflectedReplicaChunk::GetChunkSize() - { - static size_t chunkSize = 0; - if (chunkSize == 0) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to compute chunk size"); - if (!netContext) - { - return 0; - } - chunkSize = sizeof(ReflectedReplicaChunk) + netContext->GetReflectedChunkSize(AZ::AzTypeInfo::Uuid()); - } - - return chunkSize; - } - - template - void ReflectedReplicaChunk::Bind(NetBindable* instance, NetworkContextBindMode mode) - { - SetHandler(instance); - ClassType* derivedInstance = azrtti_cast(instance); - AZ_Assert(derivedInstance, "Unable to convert NetBindable to %s", AZ::AzTypeInfo::Name()); - ReplicaChunkDescriptor* desc = GetDescriptor(); - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - netContext->EnumerateFields(desc->GetChunkTypeId(), - [this, derivedInstance, desc, mode](NetworkContext::FieldDescBase* field) - { - NetBindableFieldBase* bindableField = reinterpret_cast(reinterpret_cast(derivedInstance) + field->GetOffset()); - DataSetBase* dataSet = desc->GetDataSet(this, field->GetDataSetIndex()); - bindableField->Bind(dataSet, mode); - }); - netContext->EnumerateRpcs(desc->GetChunkTypeId(), - [this, derivedInstance, desc](NetworkContext::RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - RpcBase* rpcBase = desc->GetRpc(this, rpc->GetRpcIndex()); - bindableRpc->Bind(rpcBase); - }); - - // Transfer any stored ctor data from the buffer -> NetBindable instance - if (m_ctorBuffer.Size() > 0) - { - ReadBuffer ctorBuffer(m_ctorBuffer.GetEndianType(), m_ctorBuffer.Get(), m_ctorBuffer.Size()); - netContext->EnumerateCtorData(desc->GetChunkTypeId(), - [instance, &ctorBuffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Unmarshal(ctorBuffer, instance); - }); - } - } - - template - void ReflectedReplicaChunk::Unbind() - { - ReplicaChunkInterface* handler = GetHandler(); - if (!handler || handler == this) - { - return; - } - - NetBindable* netBindable = static_cast(handler); - ClassType* derivedInstance = azrtti_cast(netBindable); - AZ_Assert(derivedInstance, "Unable to convert NetBindable to %s. Have you forgotten to derive your component from AzFramework::NetBindable?", AZ::AzTypeInfo::Name()); - if (derivedInstance) - { - ReplicaChunkDescriptor* desc = GetDescriptor(); - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - netContext->EnumerateFields(desc->GetChunkTypeId(), - [derivedInstance](NetworkContext::FieldDescBase* field) - { - NetBindableFieldBase* bindableField = reinterpret_cast(reinterpret_cast(derivedInstance) + field->GetOffset()); - bindableField->Bind(nullptr, NetworkContextBindMode::NonAuthoritative); - }); - netContext->EnumerateRpcs(desc->GetChunkTypeId(), - [derivedInstance](NetworkContext::RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - bindableRpc->Bind(derivedInstance); - }); - } - - // We have disconnected from the handler and erased any connections from DataFields or Rpcs - SetHandler(nullptr); - } -} // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Character.h b/Code/Framework/AzFramework/AzFramework/Physics/Character.h index 19a6cbfe03..2401c9c5b9 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Character.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Character.h @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -36,7 +37,7 @@ namespace Physics static void Reflect(AZ::ReflectContext* context); AZStd::string m_name; - ShapeConfigurationList m_shapes; + AzPhysics::ShapeColliderPairList m_shapes; }; class CharacterColliderConfiguration diff --git a/Code/Framework/AzFramework/AzFramework/Physics/ClassConverters.cpp b/Code/Framework/AzFramework/AzFramework/Physics/ClassConverters.cpp index eb74390638..4f206858af 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/ClassConverters.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/ClassConverters.cpp @@ -57,7 +57,7 @@ namespace Physics classElement.RemoveElement(shapesIndex); // add a new vector in the new format - const int newShapesIndex = classElement.AddElement(context, "shapes"); + const int newShapesIndex = classElement.AddElement(context, "shapes"); if (newShapesIndex != -1) { AZ::SerializeContext::DataElementNode& newShapesElement = classElement.GetSubElement(newShapesIndex); @@ -65,7 +65,9 @@ namespace Physics // convert the old shapes into the new format and add to the vector for (AZ::SerializeContext::DataElementNode shape : shapesCopy) { - const int pairIndex = newShapesElement.AddElementWithData(context, "element", ShapeConfigurationPair()); + const int pairIndex = newShapesElement.AddElementWithData( + context, "element", AzPhysics::ShapeColliderPair()); + AZ::SerializeContext::DataElementNode& pairElement = newShapesElement.GetSubElement(pairIndex); ColliderConfiguration colliderConfig; @@ -131,8 +133,8 @@ namespace Physics AZ::SerializeContext::DataElementNode* baseBaseClass1 = baseClass1->FindSubElement(AZ_CRC("BaseClass1", 0xd4925735)); if (baseBaseClass1 && baseBaseClass1->FindSubElementAndGetData(AZ_CRC("name", 0x5e237e06), name)) { - ShapeConfigurationList shapes; - if (nodeElement.FindSubElementAndGetData(AZ_CRC("shapes", 0x93dba512), shapes)) + AzPhysics::ShapeColliderPairList shapes; + if (nodeElement.FindSubElementAndGetData(AZ_CRC("shapes", 0x93dba512), shapes)) { CharacterColliderNodeConfiguration newColliderNodeConfig; newColliderNodeConfig.m_name = name; @@ -257,11 +259,18 @@ namespace Physics if (success) { - success = success && dataElement.RemoveElementByName(AZ_CRC("MaterialId", 0x9360e002)); + dataElement.RemoveElementByName(AZ_CRC("MaterialId", 0x9360e002)); + success = success && (dataElement.FindElement(AZ_CRC("MaterialId", 0x9360e002)) < 0); success = success && dataElement.AddElementWithData(context, "MaterialIds", AZStd::vector { materialId }); } } + if (success && dataElement.GetVersion() <= 2) + { + dataElement.RemoveElementByName(AZ_CRC_CE("Material")); + success = success && (dataElement.FindElement(AZ_CRC_CE("Material")) < 0); + } + return success; } } // namespace ClassConverters diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h index d5a82c0367..a3a34dc1df 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsEvents.h @@ -58,9 +58,18 @@ namespace AzPhysics //! When triggered will send the handle to the old Scene (after this call, the Handle will be invalid). using OnSceneRemovedEvent = AZ::Event; - //! Event that triggers when the default material library changes. + //! Event that triggers when the material library changes. //! When triggered the event will send the Asset Id of the new material library. - using OnDefaultMaterialLibraryChangedEvent = AZ::Event; + using OnMaterialLibraryChangedEvent = AZ::Event; + + enum class MaterialLibraryLoadErrorType : uint8_t + { + InvalidId, + ErrorLoading + }; + + //! Event that triggers when the default material library has loaded with errors. + using OnMaterialLibraryLoadErrorEvent = AZ::Event; //! Event that triggers when the default scene configuration changes. //! When triggered the event will send the new default scene configuration. diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSimulatedBody.h b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSimulatedBody.h index ed8a68dc24..9d45a17edc 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSimulatedBody.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsSimulatedBody.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,22 @@ namespace AzPhysics return m_customUserData; } + //! Helper functions for setting frame ID. + //! @param frameId Optionally set frame ID for the systems moving the actors back in time. + void SetFrameId(uint32_t frameId) + { + m_frameId = frameId; + } + + //! Helper functions for getting the set frame ID. + //! @return Will return the frame ID. + uint32_t GetFrameId() const + { + return m_frameId; + } + + static constexpr uint32_t UndefinedFrameId = AZStd::numeric_limits::max(); + //! Perform a ray cast on this Simulated Body. //! @param request The request to make. //! @return Returns the closest hit, if any, against this simulated body. @@ -126,6 +143,7 @@ namespace AzPhysics SimulatedBodyEvents::OnTriggerExit m_triggerExitEvent; void* m_customUserData = nullptr; + uint32_t m_frameId = UndefinedFrameId; // helpers for reflecting to behavior context SimulatedBodyEvents::OnCollisionBegin* GetOnCollisionBeginEvent(); diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsTypes.h b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsTypes.h index 5158da275e..b2b5fd1511 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsTypes.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Common/PhysicsTypes.h @@ -70,7 +70,10 @@ namespace AzPhysics using SimulatedBodyHandleList = AZStd::vector; //! Helper used for pairing the ShapeConfiguration and ColliderConfiguration together which is used when creating a Simulated Body. - using ShapeColliderPair = AZStd::pair; + using ShapeColliderPair = AZStd::pair< + AZStd::shared_ptr, + AZStd::shared_ptr>; + using ShapeColliderPairList = AZStd::vector; //! Flags used to specifying which properties of a body to compute. enum class MassComputeFlags : AZ::u8 diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Components/SimulatedBodyComponentBus.h b/Code/Framework/AzFramework/AzFramework/Physics/Components/SimulatedBodyComponentBus.h new file mode 100644 index 0000000000..ac6d44af8b --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Physics/Components/SimulatedBodyComponentBus.h @@ -0,0 +1,47 @@ +/* +* 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. +* +*/ + +#pragma once + +#include +#include +#include +#include + +namespace AzPhysics +{ + //! Requests for physics simulated body components. + class SimulatedBodyComponentRequests + : public AZ::ComponentBus + { + public: + using MutexType = AZStd::recursive_mutex; + + //! Enable physics for this body. + virtual void EnablePhysics() = 0; + //! Disable physics for this body. + virtual void DisablePhysics() = 0; + //! Retrieve whether physics is enabled for this body. + virtual bool IsPhysicsEnabled() const = 0; + + //! Retrieves the AABB(aligned-axis bounding box) for this body. + virtual AZ::Aabb GetAabb() const = 0; + //! Get the Simulated Body Handle for this body. + virtual AzPhysics::SimulatedBodyHandle GetSimulatedBodyHandle() const = 0; + //! Retrieves current WorldBody* for this body. + //! @note Do not hold a reference to AzPhysics::SimulatedBody* as it could be deleted or moved. + virtual AzPhysics::SimulatedBody* GetSimulatedBody() = 0; + //! Perform a single-object raycast against this body. + virtual AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) = 0; + }; + using SimulatedBodyComponentRequestsBus = AZ::EBus; +} diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp index 80434e5dee..0d5d5ca841 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp @@ -99,6 +99,11 @@ namespace AzPhysics classElement.RemoveElementByName(AZ_CRC_CE("Property Visibility Flags")); } + if (classElement.GetVersion() <= 4) + { + classElement.RemoveElementByName(AZ_CRC_CE("Simulated")); + } + return true; } } @@ -110,7 +115,7 @@ namespace AzPhysics if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(4, &Internal::RigidBodyVersionConverter) + ->Version(5, &Internal::RigidBodyVersionConverter) ->Field("Initial linear velocity", &RigidBodyConfiguration::m_initialLinearVelocity) ->Field("Initial angular velocity", &RigidBodyConfiguration::m_initialAngularVelocity) ->Field("Linear damping", &RigidBodyConfiguration::m_linearDamping) @@ -119,7 +124,6 @@ namespace AzPhysics ->Field("Start Asleep", &RigidBodyConfiguration::m_startAsleep) ->Field("Interpolate Motion", &RigidBodyConfiguration::m_interpolateMotion) ->Field("Gravity Enabled", &RigidBodyConfiguration::m_gravityEnabled) - ->Field("Simulated", &RigidBodyConfiguration::m_simulated) ->Field("Kinematic", &RigidBodyConfiguration::m_kinematic) ->Field("CCD Enabled", &RigidBodyConfiguration::m_ccdEnabled) ->Field("Compute Mass", &RigidBodyConfiguration::m_computeMass) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h index 5c43118f3d..ecf7e023c5 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h @@ -57,7 +57,6 @@ namespace AzPhysics bool m_startAsleep = false; bool m_interpolateMotion = false; bool m_gravityEnabled = true; - bool m_simulated = true; bool m_kinematic = false; bool m_ccdEnabled = false; //!< Whether continuous collision detection is enabled. float m_ccdMinAdvanceCoefficient = 0.15f; //!< Coefficient affecting how granularly time is subdivided in CCD. diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.cpp index 01bff3ccbb..4aea643c6c 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.cpp @@ -30,6 +30,16 @@ namespace AzPhysics classElement.AddElementWithData(context, "name", name); return true; } + + bool SimulatedBodyVersionConverter([[maybe_unused]] AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) + { + if (classElement.GetVersion() <= 1) + { + classElement.RemoveElementByName(AZ_CRC_CE("scale")); + } + + return true; + } } AZ_CLASS_ALLOCATOR_IMPL(SimulatedBodyConfiguration, AZ::SystemAllocator, 0); @@ -40,11 +50,10 @@ namespace AzPhysics { serializeContext->ClassDeprecate("WorldBodyConfiguration", "{6EEB377C-DC60-4E10-AF12-9626C0763B2D}", &Internal::DeprecateWorldBodyConfiguration); serializeContext->Class() - ->Version(1) + ->Version(2, &Internal::SimulatedBodyVersionConverter) ->Field("name", &SimulatedBodyConfiguration::m_debugName) ->Field("position", &SimulatedBodyConfiguration::m_position) ->Field("orientation", &SimulatedBodyConfiguration::m_orientation) - ->Field("scale", &SimulatedBodyConfiguration::m_scale) ->Field("entityId", &SimulatedBodyConfiguration::m_entityId) ->Field("startSimulationEnabled", &SimulatedBodyConfiguration::m_startSimulationEnabled) ; diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.h index 6862bfccb8..5ac920ab9d 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SimulatedBodyConfiguration.h @@ -38,7 +38,6 @@ namespace AzPhysics // Basic initial settings. AZ::Vector3 m_position = AZ::Vector3::CreateZero(); AZ::Quaternion m_orientation = AZ::Quaternion::CreateIdentity(); - AZ::Vector3 m_scale = AZ::Vector3::CreateOne(); bool m_startSimulationEnabled = true; // Entity/object association. diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp index 497d67bef1..d7532cbfea 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.cpp @@ -21,7 +21,7 @@ namespace AzPhysics namespace { const float TimestepMin = 0.001f; //1000fps - const float TimestepMax = 0.05f; //20fps + const float TimestepMax = 0.1f; //10fps } AZ_CLASS_ALLOCATOR_IMPL(SystemConfiguration, AZ::SystemAllocator, 0); @@ -39,6 +39,8 @@ namespace AzPhysics ->Field("ShapecastBufferSize", &SystemConfiguration::m_shapecastBufferSize) ->Field("OverlapBufferSize", &SystemConfiguration::m_overlapBufferSize) ->Field("CollisionConfig", &SystemConfiguration::m_collisionConfig) + ->Field("DefaultMaterial", &SystemConfiguration::m_defaultMaterialConfiguration) + ->Field("MaterialLibrary", &SystemConfiguration::m_materialLibraryAsset) ; if (AZ::EditContext* editContext = serializeContext->GetEditContext()) @@ -79,7 +81,9 @@ namespace AzPhysics m_overlapBufferSize == other.m_overlapBufferSize && AZ::IsClose(m_maxTimestep, other.m_maxTimestep) && AZ::IsClose(m_fixedTimestep, other.m_fixedTimestep) && - m_collisionConfig == other.m_collisionConfig + m_collisionConfig == other.m_collisionConfig && + m_defaultMaterialConfiguration == other.m_defaultMaterialConfiguration && + m_materialLibraryAsset == other.m_materialLibraryAsset ; } diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h index 3de4dafd8c..56fe9a68c4 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/SystemConfiguration.h @@ -13,6 +13,7 @@ #include #include +#include namespace AZ { @@ -34,7 +35,7 @@ namespace AzPhysics static constexpr float DefaultFixedTimestep = 0.0166667f; //! Value represents 1/60th or 60 FPS. - float m_maxTimestep = 1.f / 20.f; //!< Maximum fixed timestep in seconds to run the physics update. + float m_maxTimestep = 0.1f; //!< Maximum fixed timestep in seconds to run the physics update (10FPS). float m_fixedTimestep = DefaultFixedTimestep; //!< Timestep in seconds to run the physics update. See DefaultFixedTimestep. AZ::u64 m_raycastBufferSize = 32; //!< Maximum number of hits that will be returned from a raycast. @@ -45,6 +46,9 @@ namespace AzPhysics //! Each Physics Scene uses this as a base and will override as needed. CollisionConfiguration m_collisionConfig; + Physics::MaterialConfiguration m_defaultMaterialConfiguration; //!< Default material parameters for the project. + AZ::Data::Asset m_materialLibraryAsset = AZ::Data::AssetLoadBehavior::NoLoad; //!< Material Library exposed by the system component SystemBus API. + //! Controls whether the Physics System will self register to the TickBus and call StartSimulation / FinishSimulation on each Scene. //! Disable this to manually control Physics Scene simulation logic. bool m_autoManageSimulationUpdate = true; diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp index 5552cef448..78e0431753 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Material.cpp @@ -49,10 +49,7 @@ namespace Physics { materialSelection->SetMaterialSlots(Physics::MaterialSelection::SlotsArray()); } - if (materialSelection->IsDefaultMaterialLibraryAsset()) - { - materialSelection->SyncSelectionToMaterialLibrary(); - } + materialSelection->SyncSelectionToMaterialLibrary(); } }; @@ -122,6 +119,24 @@ namespace Physics } } + bool MaterialConfiguration::operator==(const MaterialConfiguration& other) const + { + return m_surfaceType == other.m_surfaceType && + AZ::IsClose(m_dynamicFriction, other.m_dynamicFriction) && + AZ::IsClose(m_staticFriction, other.m_staticFriction) && + AZ::IsClose(m_restitution, other.m_restitution) && + AZ::IsClose(m_density, other.m_density) && + m_restitutionCombine == other.m_restitutionCombine && + m_frictionCombine == other.m_frictionCombine && + m_debugColor == other.m_debugColor + ; + } + + bool MaterialConfiguration::operator!=(const MaterialConfiguration& other) const + { + return !(*this == other); + } + AZ::Color MaterialConfiguration::GenerateDebugColor(const char* materialName) { static const AZ::Color colors[] = @@ -191,51 +206,25 @@ namespace Physics ////////////////////////////////////////////////////////////////////////// - void MaterialLibraryAssetReflectionWrapper::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("Asset", &MaterialLibraryAssetReflectionWrapper::m_asset) - ; - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - if (editContext) - { - editContext->Class("", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialLibraryAssetReflectionWrapper::m_asset, "Physics Material Library", "Physics Material Library") - ->Attribute("EditButton", "") - ; - } - } - } - - ////////////////////////////////////////////////////////////////////////// - - - void DefaultMaterialLibraryAssetReflectionWrapper::Reflect(AZ::ReflectContext* context) + void MaterialInfoReflectionWrapper::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) { - serializeContext->Class() + serializeContext->Class() ->Version(1) - ->Field("Asset", &DefaultMaterialLibraryAssetReflectionWrapper::m_asset) + ->Field("DefaultMaterial", &MaterialInfoReflectionWrapper::m_defaultMaterialConfiguration) + ->Field("Asset", &MaterialInfoReflectionWrapper::m_materialLibraryAsset) ; AZ::EditContext* editContext = serializeContext->GetEditContext(); if (editContext) { - editContext->Class("", "") + editContext->Class("Physics Materials", "") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->DataElement(AZ::Edit::UIHandlers::Default, &DefaultMaterialLibraryAssetReflectionWrapper::m_asset, "Default Physics Material Library", "Library to use by default") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialInfoReflectionWrapper::m_defaultMaterialConfiguration, "Default Physics Material", "Material used by default") + ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialInfoReflectionWrapper::m_materialLibraryAsset, "Physics Material Library", "Library to use for the project") ->Attribute(AZ::Edit::Attributes::AllowClearAsset, false) ->Attribute("EditButton", "") ; @@ -269,6 +258,17 @@ namespace Physics } } + bool MaterialFromAssetConfiguration::operator==(const MaterialFromAssetConfiguration& other) const + { + return m_configuration == other.m_configuration && + m_id == other.m_id; + } + + bool MaterialFromAssetConfiguration::operator!=(const MaterialFromAssetConfiguration& other) const + { + return !(*this == other); + } + ////////////////////////////////////////////////////////////////////////// bool MaterialLibraryAsset::GetDataForMaterialId(const MaterialId& materialId, MaterialFromAssetConfiguration& configuration) const @@ -370,9 +370,8 @@ namespace Physics if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(2, &ClassConverters::MaterialSelectionConverter) + ->Version(3, &ClassConverters::MaterialSelectionConverter) ->EventHandler() - ->Field("Material", &MaterialSelection::m_materialLibrary) ->Field("MaterialIds", &MaterialSelection::m_materialIdsAssignedToSlots) ; @@ -381,14 +380,8 @@ namespace Physics editContext->Class("Physics Material", "Select physics material library and which materials to use for the object") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialLibrary, "Library", "Physics material library to use for this object") - ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, true) - ->Attribute("EditButton", "") - ->Attribute("EditDescription", "Open in Asset Editor") - ->Attribute(AZ::Edit::Attributes::DefaultAsset, &MaterialSelection::GetDefaultMaterialLibraryId) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &MaterialSelection::OnMaterialLibraryChanged) ->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialIdsAssignedToSlots, "Mesh Surfaces", "Specify which Physics Material to use for each element of this object") - ->ElementAttribute(Attributes::MaterialLibraryAssetId, &MaterialSelection::GetMaterialLibraryAssetId) + ->ElementAttribute(Attributes::MaterialLibraryAssetId, &MaterialSelection::GetMaterialLibraryId) ->Attribute(AZ::Edit::Attributes::IndexedChildNameLabelOverride, &MaterialSelection::GetMaterialSlotLabel) ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->ElementAttribute(AZ::Edit::Attributes::ReadOnly, &MaterialSelection::AreMaterialSlotsReadOnly) @@ -398,12 +391,6 @@ namespace Physics } } - AZ::u32 MaterialSelection::OnMaterialLibraryChanged() - { - SyncSelectionToMaterialLibrary(); - return AZ::Edit::PropertyRefreshLevels::EntireTree; - } - AZStd::string MaterialSelection::GetMaterialSlotLabel(int index) { if (index < m_materialSlots.size()) @@ -425,28 +412,9 @@ namespace Physics } } - AZ::Data::AssetId MaterialSelection::GetMaterialLibraryAssetId() const + void MaterialSelection::OnMaterialLibraryChanged([[maybe_unused]] const AZ::Data::AssetId& defaultMaterialLibraryId) { - return GetMaterialLibraryAsset().GetId(); - } - - const Physics::MaterialLibraryAsset* MaterialSelection::GetMaterialLibraryAssetData() const - { - return GetMaterialLibraryAsset().Get(); - } - - const AZStd::string& MaterialSelection::GetMaterialLibraryAssetHint() const - { - return m_materialLibrary.GetHint(); - } - - void MaterialSelection::OnDefaultMaterialLibraryChanged(const AZ::Data::AssetId& defaultMaterialLibraryId) - { - AZ_UNUSED(defaultMaterialLibraryId); - if (IsDefaultMaterialLibraryAsset()) - { - OnMaterialLibraryChanged(); - } + SyncSelectionToMaterialLibrary(); } void MaterialSelection::SetSlotsReadOnly(bool readOnly) @@ -454,45 +422,6 @@ namespace Physics m_slotsReadOnly = readOnly; } - bool MaterialSelection::IsMaterialLibraryValid() const - { - if (GetMaterialLibraryAssetId().IsValid()) - { - auto materialAsset = LoadAsset(); - const auto& materialsData = materialAsset.Get()->GetMaterialsData(); - - if (materialsData.size() != 0) - { - return true; - } - } - return false; - } - - bool MaterialSelection::GetMaterialConfiguration(Physics::MaterialFromAssetConfiguration& configuration, const Physics::MaterialId& materialId) const - { - if (IsMaterialLibraryValid()) - { - auto materialAsset = LoadAsset(); - if (materialAsset.Get()) - { - return materialAsset.Get()->GetDataForMaterialId(materialId, configuration); - } - } - return false; - } - - void MaterialSelection::SetMaterialLibrary(const AZ::Data::AssetId& assetId) - { - m_materialLibrary = AZ::Data::AssetManager::Instance().GetAsset(assetId, m_materialLibrary.GetAutoLoadBehavior()); - m_materialLibrary.BlockUntilLoadComplete(); - } - - void MaterialSelection::ResetToDefaultMaterialLibrary() - { - m_materialLibrary = {}; - } - void MaterialSelection::SetMaterialSlots(const SlotsArray& slots) { if (slots.empty()) @@ -533,74 +462,45 @@ namespace Physics m_materialIdsAssignedToSlots[slotIndex] = materialId; } - AZ::Data::Asset MaterialSelection::LoadAsset() const - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance() - .GetAsset(GetMaterialLibraryAssetId(), AZ::Data::AssetLoadBehavior::Default); - - asset.BlockUntilLoadComplete(); - - return asset; - } - void MaterialSelection::SyncSelectionToMaterialLibrary() { - if (GetMaterialLibraryAssetId().IsValid()) + auto* materialLibrary = GetMaterialLibrary().Get(); + if (!materialLibrary) { - auto materialLibraryAsset = AZ::Data::AssetManager::Instance().GetAsset(GetMaterialLibraryAssetId(), AZ::Data::AssetLoadBehavior::Default); + return; + } - materialLibraryAsset.BlockUntilLoadComplete(); - - // We try to check whether existing selection matches any materials in the newly assigned library and do one of the following: - // 1. If previous MaterialId is invalid for this material library, and it is not the Default material, we set it to the Default material from the library. - // 2. If it's valid, or it is the Default material, we don't change it (useful when user accidentally re-assigns the same library: previous selection won't go away). - - if (materialLibraryAsset.Get()) + for (Physics::MaterialId& materialId : m_materialIdsAssignedToSlots) + { + // Leave nulls (default) unchanged. + if (materialId.IsNull()) { - for (Physics::MaterialId& materialId : m_materialIdsAssignedToSlots) - { - if (!materialLibraryAsset.Get()->HasDataForMaterialId(materialId) - && !materialId.IsNull()) // Null materialId is the Default material. - { - materialId = MaterialId(); - } - } + continue; } - else + + // If the material id is not present in the library anymore, set it to default + if (!materialLibrary->HasDataForMaterialId(materialId)) { - AZ_Warning("PhysX", false, "MaterialSelection: invalid material library"); + materialId = MaterialId(); } } } - const AZ::Data::Asset& MaterialSelection::GetMaterialLibraryAsset() const - { - if (IsDefaultMaterialLibraryAsset()) - { - const AZ::Data::Asset& defaultMaterialLibrary = GetDefaultMaterialLibrary(); - return defaultMaterialLibrary; - } - - return m_materialLibrary; - } - - bool MaterialSelection::IsDefaultMaterialLibraryAsset() const - { - return !m_materialLibrary.GetId().IsValid(); - } - - const AZ::Data::Asset& MaterialSelection::GetDefaultMaterialLibrary() + const AZ::Data::Asset& MaterialSelection::GetMaterialLibrary() { if (auto* physicsSystem = AZ::Interface::Get()) { - return physicsSystem->GetDefaultMaterialLibrary(); + if (const auto* physicsConfiguration = physicsSystem->GetConfiguration()) + { + return physicsConfiguration->m_materialLibraryAsset; + } } return s_invalidMaterialLibrary; } - const AZ::Data::AssetId& MaterialSelection::GetDefaultMaterialLibraryId() + const AZ::Data::AssetId& MaterialSelection::GetMaterialLibraryId() { - return GetDefaultMaterialLibrary().GetId(); + return GetMaterialLibrary().GetId(); } bool MaterialSelection::AreMaterialSlotsReadOnly() const diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Material.h b/Code/Framework/AzFramework/AzFramework/Physics/Material.h index e9eaae929f..69edf3ed25 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Material.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Material.h @@ -29,7 +29,6 @@ namespace Physics /// ========================= /// This is the interface to the wrapper around native material type (such as PxMaterial in PhysX gem) /// that stores extra metadata, like Surface Type name. - /// To see more details about PhysX implementation please refer to PhysX::Material class /// /// Usage example /// ------------------------- @@ -37,14 +36,7 @@ namespace Physics /// /// Physics::MaterialConfiguration materialProperties; /// AZStd::shared_ptr newMaterial = AZ::Interface::Get()->CreateMaterial(materialProperties); - /// - /// To get PxMaterial use GetNativePointer function - /// - /// physx::PxMaterial* material = static_cast(newMaterial->GetNativePointer()); - /// - /// You can use retrieved PxMaterial pointer on its own, provided you increment its reference count. - /// If this class goes out of scope, the PxMaterial pointer will be valid, but its userData - /// will be cleaned up to point to nullptr. + /// class Material { public: @@ -63,9 +55,9 @@ namespace Physics /// Returns AZ::Crc32 of the surface name. virtual AZ::Crc32 GetSurfaceType() const = 0; - virtual void SetSurfaceType(AZ::Crc32 surfaceType) = 0; virtual const AZStd::string& GetSurfaceTypeName() const = 0; + virtual void SetSurfaceTypeName(const AZStd::string& surfaceTypeName) = 0; virtual float GetDynamicFriction() const = 0; virtual void SetDynamicFriction(float dynamicFriction) = 0; @@ -85,6 +77,9 @@ namespace Physics virtual float GetDensity() const = 0; virtual void SetDensity(float density) = 0; + virtual AZ::Color GetDebugColor() const = 0; + virtual void SetDebugColor(const AZ::Color& debugColor) = 0; + /// If the name of this material matches the name of one of the CrySurface types, it will return its CrySurface Id.\n /// If there's no match it will return default CrySurface Id.\n /// CrySurface types are defined in libs/materialeffects/surfacetypes.xml @@ -122,6 +117,10 @@ namespace Physics Material::CombineMode m_frictionCombine = Material::CombineMode::Average; AZ::Color m_debugColor = AZ::Colors::White; + + bool operator==(const MaterialConfiguration& other) const; + bool operator!=(const MaterialConfiguration& other) const; + private: static bool VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); static AZ::Color GenerateDebugColor(const char* materialName); @@ -147,6 +146,7 @@ namespace Physics static MaterialId FromUUID(const AZ::Uuid& uuid); bool IsNull() const { return m_id.IsNull(); } bool operator==(const MaterialId& other) const { return m_id == other.m_id; } + bool operator!=(const MaterialId& other) const { return !(*this == other); } const AZ::Uuid& GetUuid() const { return m_id; } private: @@ -166,6 +166,9 @@ namespace Physics MaterialConfiguration m_configuration; MaterialId m_id; + + bool operator==(const MaterialFromAssetConfiguration& other) const; + bool operator!=(const MaterialFromAssetConfiguration& other) const; }; /// An asset that holds a list of materials to be edited and assigned in Open 3D Engine Editor @@ -222,40 +225,27 @@ namespace Physics AZStd::vector m_materialLibrary; }; - /// The class is used to expose a MaterialLibraryAsset to Edit Context + /// The class is used to expose a default material and material library asset to Edit Context /// ======================================================================= /// /// Since AZ::Data::Asset doesn't reflect the data to EditContext /// we have to have a wrapper doing it. - class MaterialLibraryAssetReflectionWrapper + class MaterialInfoReflectionWrapper { public: - AZ_CLASS_ALLOCATOR(MaterialLibraryAssetReflectionWrapper, AZ::SystemAllocator, 0); - AZ_TYPE_INFO(Physics::MaterialLibraryAssetReflectionWrapper, "{3D2EF5DF-EFD0-47EB-B88F-3E6FE1FEE5B0}"); + AZ_CLASS_ALLOCATOR(MaterialInfoReflectionWrapper, AZ::SystemAllocator, 0); + AZ_TYPE_INFO(Physics::MaterialInfoReflectionWrapper, "{02AB8CBC-D35B-4E0F-89BA-A96D94DAD4F9}"); static void Reflect(AZ::ReflectContext* context); - AZ::Data::Asset m_asset = + Physics::MaterialConfiguration m_defaultMaterialConfiguration; + AZ::Data::Asset m_materialLibraryAsset = AZ::Data::AssetLoadBehavior::NoLoad; }; - /// Customized material library for use as default material library - class DefaultMaterialLibraryAssetReflectionWrapper : public Physics::MaterialLibraryAssetReflectionWrapper - { - public: - AZ_CLASS_ALLOCATOR(MaterialLibraryAssetReflectionWrapper, AZ::SystemAllocator, 0); - AZ_TYPE_INFO(Physics::DefaultMaterialLibraryAssetReflectionWrapper, "{02AB8CBC-D35B-4E0F-89BA-A96D94DAD4F9}"); - static void Reflect(AZ::ReflectContext* context); - - AZ::Data::Asset m_asset = - AZ::Data::AssetLoadBehavior::NoLoad; - }; - - /// The class is used to store a MaterialLibraryAsset and a vector of MaterialIds selected from the library + /// The class is used to store a vector of MaterialIds selected from the library /// ======================================================================= /// - /// This class is used to store a reference to the library asset and user's - /// selection of the materials from this library.\n - /// It also reflects UI controls for assigning MaterialLibraryAsset and selecting a material from it. + /// This class is used to store the user's selection of the materials from this library. /// You can reflect this class in EditorContext to provide UI for selecting materials /// on any custom component or QWidget. class MaterialSelection @@ -269,27 +259,6 @@ namespace Physics static void Reflect(AZ::ReflectContext* context); - /// Returns whether MaterialLibraryAsset assigned to this selection exists and valid. Attempts to load - /// the library if it's not loaded yet. - /// @return true if MaterialLibraryAsset has a valid AssetId, loaded and isn't empty - bool IsMaterialLibraryValid() const; - - /// Looks up MaterialLibraryAsset for MaterialFromAssetConfiguration with MaterialId that is stored intrenally. - /// @param configuration contains material data if there is a material selected by user - /// and if it exists in the MaterialLibraryAsset - /// @param materialId MaterialId to retrieve MaterialFromAssetConfiguration for - /// @return true if lookup was successful. - bool GetMaterialConfiguration(Physics::MaterialFromAssetConfiguration& configuration, const Physics::MaterialId& materialId) const; - - /// Sets and loads MaterialLibraryAsset with specified AssetId. - /// It is used to construct MaterialSelection at runtime. - /// It is not a typical use case and mostly needed to convert legacy entities and auto-generate material libraries - /// @param assetId AssetId to create MaterialLibraryAsset with - void SetMaterialLibrary(const AZ::Data::AssetId& assetId); - - /// Sets the material library to none, this will cause to use the project-wide default material library - void ResetToDefaultMaterialLibrary(); - /// Sets an array of material slots to pick MaterialIds for. Having multiple slots is required for assigning multiple materials on a mesh /// or heightfield object. SlotsArray can be empty and in this case Default slot will be created. /// @param slots Array of names for slots. Can be empty, in this case Default slot will be created @@ -298,48 +267,34 @@ namespace Physics /// Returns a list of MaterialId that were assigned for each corresponding slot. const AZStd::vector& GetMaterialIdsAssignedToSlots() const; - /// Sets the MaterialId from MaterialLibraryAsset as the selected material at a specific slotIndex. - /// @param materialId MaterialId that user selected from the MaterialLibraryAsset - /// @param slotIndex index of the slot to set MaterialId for + /// Sets the MaterialId as the selected material at a specific slotIndex. + /// @param materialId MaterialId that user selected + /// @param slotIndex Index of the slot to set the MaterialId void SetMaterialId(const Physics::MaterialId& materialId, int slotIndex = 0); - /// Returns the material library asset id. - AZ::Data::AssetId GetMaterialLibraryAssetId() const; - /// Returns the material id assigned to this selection at a specific slotIndex. - /// @param slotIndex index of the slot to retrieve MaterialId for + /// @param slotIndex Index of the slot to retrieve the MaterialId Physics::MaterialId GetMaterialId(int slotIndex = 0) const; - /// Returns the material library asset. - const Physics::MaterialLibraryAsset* GetMaterialLibraryAssetData() const; - - /// Returns the material library asset hint(UI display string) - const AZStd::string& GetMaterialLibraryAssetHint() const; - /// Called when the material library has changed - void OnDefaultMaterialLibraryChanged(const AZ::Data::AssetId& defaultMaterialLibraryId); + void OnMaterialLibraryChanged(const AZ::Data::AssetId& defaultMaterialLibraryId); /// Set if the material slots are editable in the edit context void SetSlotsReadOnly(bool readOnly); private: - AZ::Data::Asset m_materialLibrary { AZ::Data::AssetLoadBehavior::NoLoad }; AZStd::vector m_materialIdsAssignedToSlots; SlotsArray m_materialSlots; bool m_slotsReadOnly = false; - const AZ::Data::Asset& GetMaterialLibraryAsset() const; - AZ::Data::Asset LoadAsset() const; - bool IsDefaultMaterialLibraryAsset() const; void SyncSelectionToMaterialLibrary(); - static const AZ::Data::Asset& GetDefaultMaterialLibrary(); - static const AZ::Data::AssetId& GetDefaultMaterialLibraryId(); + static const AZ::Data::Asset& GetMaterialLibrary(); + static const AZ::Data::AssetId& GetMaterialLibraryId(); bool AreMaterialSlotsReadOnly() const; // EditorContext callbacks - AZ::u32 OnMaterialLibraryChanged(); AZStd::string GetMaterialSlotLabel(int index); }; diff --git a/Code/Framework/AzFramework/AzFramework/Physics/MaterialBus.h b/Code/Framework/AzFramework/AzFramework/Physics/MaterialBus.h index edfa3096d3..a7e4869df1 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/MaterialBus.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/MaterialBus.h @@ -25,21 +25,26 @@ namespace Physics static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; // Implemented by sole owner of materials, e.g. class MaterialManager in PhysX gem. - /// Get default material + /// Get default material. virtual AZStd::shared_ptr GetGenericDefaultMaterial() = 0; /// Returns weak pointers to physics materials. /// Connect to PhysicsMaterialNotifications::MaterialsReleased to be informed when material pointers are deleted by owner. virtual void GetMaterials(const MaterialSelection& materialSelection - , AZStd::vector>& outMaterials) = 0; + , AZStd::vector>& outMaterials) = 0; + + /// Returns a weak pointer to physics material with the given id. + virtual AZStd::shared_ptr GetMaterialById(Physics::MaterialId id) = 0; /// Returns a weak pointer to physics material with the given name. - virtual AZStd::weak_ptr GetMaterialByName(const AZStd::string& name) = 0; + virtual AZStd::shared_ptr GetMaterialByName(const AZStd::string& name) = 0; - /// Returns index of the first selected material in MaterialSelection's material library. - /// A MaterialSelection can contain multiple material selections. - /// Returned index is 0-based where 0 is the Default material, and materials from the material library are 1 and onwards. - virtual AZ::u32 GetFirstSelectedMaterialIndex(const MaterialSelection& materialSelection) = 0; + /// Updates the material selection from the physics asset or sets it to default if there's no asset provided. + /// @param shapeConfiguration The shape information that contains the physics asset. + /// @param materialSelection The material selection to update. + virtual void UpdateMaterialSelectionFromPhysicsAsset( + const ShapeConfiguration& shapeConfiguration, + MaterialSelection& materialSelection) = 0; }; using PhysicsMaterialRequestBus = AZ::EBus; diff --git a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h index db3ec15c83..58e53b0b0d 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsScene.h @@ -88,13 +88,13 @@ namespace AzPhysics //! Remove a simulated body from the Scene.z //! @param sceneHandle A handle to the scene to remove the requested simulated body. - //! @param bodyHandle A handle to the simulated body being removed. - virtual void RemoveSimulatedBody(SceneHandle sceneHandle, SimulatedBodyHandle bodyHandle) = 0; + //! @param bodyHandle A handle to the simulated body being removed. This will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBody(SceneHandle sceneHandle, SimulatedBodyHandle& bodyHandle) = 0; //! Remove a list of simulated bodies from the Scene. //! @param sceneHandle A handle to the scene to remove the simulated bodies from. - //! @param bodyHandles A list of simulated body handles to be removed. - virtual void RemoveSimulatedBodies(SceneHandle sceneHandle, const SimulatedBodyHandleList& bodyHandles) = 0; + //! @param bodyHandles A list of simulated body handles to be removed. All handles will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBodies(SceneHandle sceneHandle, SimulatedBodyHandleList& bodyHandles) = 0; //! Enable / Disable simulation of the requested body. By default all bodies added are enabled. //! Disabling simulation the body will no longer be affected by any forces, collisions, or found with scene queries. @@ -286,12 +286,12 @@ namespace AzPhysics virtual SimulatedBodyList GetSimulatedBodiesFromHandle(const SimulatedBodyHandleList& bodyHandles) = 0; //! Remove a simulated body from the Scene. - //! @param bodyHandle A handle to the simulated body being removed. - virtual void RemoveSimulatedBody(SimulatedBodyHandle bodyHandle) = 0; + //! @param bodyHandle A handle to the simulated body being removed. This will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBody(SimulatedBodyHandle& bodyHandle) = 0; //! Remove a list of simulated bodies from the Scene. - //! @param bodyHandles A list of simulated body handles to be removed. - virtual void RemoveSimulatedBodies(const SimulatedBodyHandleList& bodyHandles) = 0; + //! @param bodyHandles A list of simulated body handles to be removed. All handles will be set to AzPhysics::InvalidSimulatedBodyHandle as they're no longer valid. + virtual void RemoveSimulatedBodies(SimulatedBodyHandleList& bodyHandles) = 0; //! Enable / Disable simulation of the requested body. By default all bodies added are enabled. //! Disabling simulation the body will no longer be affected by any forces, collisions, or found with scene queries. diff --git a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.h b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.h index e3ed449046..36ae4dbecb 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/PhysicsSystem.h @@ -130,13 +130,6 @@ namespace AzPhysics //! @param forceReinitialization Flag to force a reinitialization of the physics system. Default false. virtual void UpdateConfiguration(const SystemConfiguration* newConfig, bool forceReinitialization = false) = 0; - //! Update the default material library. - //! @param materialLibrary The new material library asset to use. - virtual void UpdateDefaultMaterialLibrary(const AZ::Data::Asset& materialLibrary) = 0; - - //! Accessor to get the current Material Library. This is also available in the PhysXSystemConfiguration. - virtual const AZ::Data::Asset& GetDefaultMaterialLibrary() const = 0; - //! Update the current default scene configuration. //! This is the configuration used to to create scenes without a custom configuration. //! @param sceneConfiguration The new configuration to apply. @@ -169,9 +162,12 @@ namespace AzPhysics //! Register to receive notifications when the SystemConfiguration changes. //! @param handler The handler to receive the event. void RegisterSystemConfigurationChangedEvent(SystemEvents::OnConfigurationChangedEvent::Handler& handler) { handler.Connect(m_configChangeEvent); } - //! Register a handler to receive an event when the default material library changes. + //! Register a handler to receive an event when the material library changes. //! @param handler The handler to receive the event. - void RegisterOnDefaultMaterialLibraryChangedEventHandler(SystemEvents::OnDefaultMaterialLibraryChangedEvent::Handler& handler) { handler.Connect(m_onDefaultMaterialLibraryChangedEvent); } + void RegisterOnMaterialLibraryChangedEventHandler(SystemEvents::OnMaterialLibraryChangedEvent::Handler& handler) { handler.Connect(m_onMaterialLibraryChangedEvent); } + //! Register a handler to receive an event when the material library fails to load on startup. + //! @param handler The handler to receive the event. + void RegisterOnMaterialLibraryLoadErrorEventHandler(SystemEvents::OnMaterialLibraryLoadErrorEvent::Handler& handler) { handler.Connect(m_onMaterialLibraryLoadErrorEvent); } //! Register a handler to receive an event when the default SceneConfiguration changes. //! @param handler The handler to receive the event. void RegisterOnDefaultSceneConfigurationChangedEventHandler(SystemEvents::OnDefaultSceneConfigurationChangedEvent::Handler& handler) { handler.Connect(m_onDefaultSceneConfigurationChangedEvent); } @@ -185,7 +181,8 @@ namespace AzPhysics SystemEvents::OnSceneAddedEvent m_sceneAddedEvent; SystemEvents::OnSceneRemovedEvent m_sceneRemovedEvent; SystemEvents::OnConfigurationChangedEvent m_configChangeEvent; - SystemEvents::OnDefaultMaterialLibraryChangedEvent m_onDefaultMaterialLibraryChangedEvent; + SystemEvents::OnMaterialLibraryChangedEvent m_onMaterialLibraryChangedEvent; + SystemEvents::OnMaterialLibraryLoadErrorEvent m_onMaterialLibraryLoadErrorEvent; SystemEvents::OnDefaultSceneConfigurationChangedEvent m_onDefaultSceneConfigurationChangedEvent; }; } // namespace AzPhysics diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Ragdoll.h b/Code/Framework/AzFramework/AzFramework/Physics/Ragdoll.h index 239d93cf32..97c841e8f8 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Ragdoll.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Ragdoll.h @@ -102,7 +102,7 @@ namespace Physics /// Is the ragdoll currently simulated? /// @result True in case the ragdoll is simulated, false if not. - virtual bool IsSimulated() = 0; + virtual bool IsSimulated() const = 0; /// Writes the state for all of the bodies in the ragdoll to the provided output. /// The caller owns the output state and can safely manipulate it without affecting the physics simulation. diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Shape.h b/Code/Framework/AzFramework/AzFramework/Physics/Shape.h index 115503c536..2ac38690ff 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Shape.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Shape.h @@ -80,9 +80,6 @@ namespace Physics void OnContactOffsetChanged(); }; - using ShapeConfigurationPair = AZStd::pair, AZStd::shared_ptr>; - using ShapeConfigurationList = AZStd::vector; - struct RayCastRequest; class Shape diff --git a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp index 52eae22fee..275103bc28 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.cpp @@ -17,6 +17,21 @@ namespace Physics { + namespace Internal + { + bool ShapeConfigurationVersionConverter( + [[maybe_unused]] AZ::SerializeContext& context, + AZ::SerializeContext::DataElementNode& classElement) + { + if (classElement.GetVersion() <= 1) + { + classElement.RemoveElementByName(AZ_CRC_CE("UseMaterialsFromAsset")); + } + + return true; + } + } + void ShapeConfiguration::Reflect(AZ::ReflectContext* context) { if (auto serializeContext = azrtti_cast(context)) @@ -48,6 +63,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Radius", &SphereShapeConfiguration::m_radius) @@ -76,6 +94,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Configuration", &BoxShapeConfiguration::m_dimensions) @@ -104,6 +125,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Height", &CapsuleShapeConfiguration::m_height) @@ -153,11 +177,13 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() - ->Version(1) + ->Version(2, &Internal::ShapeConfigurationVersionConverter) ->Field("PhysicsAsset", &PhysicsAssetShapeConfiguration::m_asset) ->Field("AssetScale", &PhysicsAssetShapeConfiguration::m_assetScale) - ->Field("UseMaterialsFromAsset", &PhysicsAssetShapeConfiguration::m_useMaterialsFromAsset) ->Field("SubdivisionLevel", &PhysicsAssetShapeConfiguration::m_subdivisionLevel) ; @@ -170,7 +196,6 @@ namespace Physics ->DataElement(AZ::Edit::UIHandlers::Default, &PhysicsAssetShapeConfiguration::m_assetScale, "Asset Scale", "The scale of the asset shape") ->Attribute(AZ::Edit::Attributes::Min, 0.0f) ->Attribute(AZ::Edit::Attributes::Step, 0.01f) - ->DataElement(AZ::Edit::UIHandlers::Default, &PhysicsAssetShapeConfiguration::m_useMaterialsFromAsset, "Physics Materials from Mesh", "Auto-set physics materials using Mesh's material surfaces names") ; } } @@ -185,6 +210,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("Scale", &NativeShapeConfiguration::m_nativeShapeScale) @@ -208,6 +236,9 @@ namespace Physics { if (auto serializeContext = azrtti_cast(context)) { + serializeContext + ->RegisterGenericType>(); + serializeContext->Class() ->Version(1) ->Field("CookedData", &CookedMeshShapeConfiguration::m_cookedData) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h index b3d04a10c9..8234ef9173 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/ShapeConfiguration.h @@ -140,7 +140,7 @@ namespace Physics AZ::Data::Asset m_asset{ AZ::Data::AssetLoadBehavior::PreLoad }; AZ::Vector3 m_assetScale = AZ::Vector3::CreateOne(); - bool m_useMaterialsFromAsset = true; + bool m_useMaterialsFromAsset = false; // Not reflected or exposed to the user until there is a way to auto-match mesh's materials with physics materials AZ::u8 m_subdivisionLevel = 4; ///< The level of subdivision if a primitive shape is replaced with a convex mesh due to scaling. }; diff --git a/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h b/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h index 5b18887d43..0f43aaaf4a 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/SimulatedBodies/RigidBody.h @@ -62,7 +62,7 @@ namespace AzPhysics virtual void SetLinearVelocity(const AZ::Vector3& velocity) = 0; virtual AZ::Vector3 GetAngularVelocity() const = 0; virtual void SetAngularVelocity(const AZ::Vector3& angularVelocity) = 0; - virtual AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) = 0; + virtual AZ::Vector3 GetLinearVelocityAtWorldPoint(const AZ::Vector3& worldPoint) const = 0; virtual void ApplyLinearImpulse(const AZ::Vector3& impulse) = 0; virtual void ApplyLinearImpulseAtWorldPoint(const AZ::Vector3& impulse, const AZ::Vector3& worldPoint) = 0; virtual void ApplyAngularImpulse(const AZ::Vector3& angularImpulse) = 0; diff --git a/Code/Framework/AzFramework/AzFramework/Physics/SystemBus.h b/Code/Framework/AzFramework/AzFramework/Physics/SystemBus.h index f198551148..8cdd0e0cf0 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/SystemBus.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/SystemBus.h @@ -142,24 +142,12 @@ namespace Physics virtual AZStd::shared_ptr CreateShape(const ColliderConfiguration& colliderConfiguration, const ShapeConfiguration& configuration) = 0; + virtual AZStd::shared_ptr CreateMaterial(const Physics::MaterialConfiguration& materialConfiguration) = 0; + /// Releases the mesh object created by the physics backend. /// @param nativeMeshObject Pointer to the mesh object. virtual void ReleaseNativeMeshObject(void* nativeMeshObject) = 0; - ////////////////////////////////////////////////////////////////////////// - //// Physics Materials - - virtual AZStd::shared_ptr CreateMaterial(const Physics::MaterialConfiguration& materialConfiguration) = 0; - virtual AZStd::shared_ptr GetDefaultMaterial() = 0; - virtual AZStd::vector> CreateMaterialsFromLibrary(const Physics::MaterialSelection& materialSelection) = 0; - - - /// Updates the collider material selection from the physics asset or sets it to default if there's no asset provided. - /// @param shapeConfiguration The shape information - /// @param colliderConfiguration The collider information - virtual bool UpdateMaterialSelection(const Physics::ShapeConfiguration& shapeConfiguration, - Physics::ColliderConfiguration& colliderConfiguration) = 0; - ////////////////////////////////////////////////////////////////////////// //// Joints diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp index ae8f4308df..2c3b62bb88 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Utils.cpp @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -39,19 +39,19 @@ namespace Physics { namespace ReflectionUtils { - void ReflectWorldBodyBus(AZ::ReflectContext* context) + void ReflectSimulatedBodyComponentRequestsBus(AZ::ReflectContext* context) { if (auto* behaviorContext = azrtti_cast(context)) { - behaviorContext->EBus("WorldBodyRequestBus") + behaviorContext->EBus("SimulatedBodyComponentRequestBus") ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Script::Attributes::Module, "physics") ->Attribute(AZ::Script::Attributes::Category, "PhysX") - ->Event("EnablePhysics", &WorldBodyRequests::EnablePhysics) - ->Event("DisablePhysics", &WorldBodyRequests::DisablePhysics) - ->Event("IsPhysicsEnabled", &WorldBodyRequests::IsPhysicsEnabled) - ->Event("GetAabb", &WorldBodyRequests::GetAabb) - ->Event("RayCast", &WorldBodyRequests::RayCast) + ->Event("EnablePhysics", &AzPhysics::SimulatedBodyComponentRequests::EnablePhysics) + ->Event("DisablePhysics", &AzPhysics::SimulatedBodyComponentRequests::DisablePhysics) + ->Event("IsPhysicsEnabled", &AzPhysics::SimulatedBodyComponentRequests::IsPhysicsEnabled) + ->Event("GetAabb", &AzPhysics::SimulatedBodyComponentRequests::GetAabb) + ->Event("RayCast", &AzPhysics::SimulatedBodyComponentRequests::RayCast) ; } } @@ -119,8 +119,7 @@ namespace Physics AzPhysics::SceneConfiguration::Reflect(context); MaterialConfiguration::Reflect(context); MaterialLibraryAsset::Reflect(context); - MaterialLibraryAssetReflectionWrapper::Reflect(context); - DefaultMaterialLibraryAssetReflectionWrapper::Reflect(context); + MaterialInfoReflectionWrapper::Reflect(context); JointLimitConfiguration::Reflect(context); AzPhysics::SimulatedBodyConfiguration::Reflect(context); AzPhysics::RigidBodyConfiguration::Reflect(context); @@ -131,7 +130,7 @@ namespace Physics AnimationConfiguration::Reflect(context); CharacterConfiguration::Reflect(context); AzPhysics::SimulatedBody::Reflect(context); - ReflectWorldBodyBus(context); + ReflectSimulatedBodyComponentRequestsBus(context); CollisionFilteringRequests::Reflect(context); AzPhysics::SceneQuery::ReflectSceneQueryObjects(context); ReflectWindBus(context); diff --git a/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h b/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h index 60da2c3607..f96af2bcf9 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h @@ -13,6 +13,7 @@ #include #include +#include #include namespace Physics diff --git a/Code/Framework/AzFramework/AzFramework/Physics/WorldBodyBus.h b/Code/Framework/AzFramework/AzFramework/Physics/WorldBodyBus.h deleted file mode 100644 index 943e03d0f3..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Physics/WorldBodyBus.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* 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. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace AzPhysics -{ - struct SimulatedBody; -} - -namespace Physics -{ - //! Requests for generic physical world bodies - class WorldBodyRequests - : public AZ::ComponentBus - { - public: - using MutexType = AZStd::recursive_mutex; - - //! Enable physics for this body - virtual void EnablePhysics() = 0; - //! Disable physics for this body - virtual void DisablePhysics() = 0; - //! Retrieve whether physics is enabled for this body - virtual bool IsPhysicsEnabled() const = 0; - - //! Retrieves the AABB(aligned-axis bounding box) for this body - virtual AZ::Aabb GetAabb() const = 0; - //! Retrieves current WorldBody* for this body. Note: Do not hold a reference to AzPhysics::SimulatedBody* as could be deleted - virtual AzPhysics::SimulatedBody* GetWorldBody() = 0; - - //! Perform a single-object raycast against this body - virtual AzPhysics::SceneQueryHit RayCast(const AzPhysics::RayCastRequest& request) = 0; - }; - using WorldBodyRequestBus = AZ::EBus; - - //! Notifications for generic physical world bodies - class WorldBodyNotifications - : public AZ::ComponentBus - { - public: - //! Notification for physics enabled - virtual void OnPhysicsEnabled() = 0; - //! Notification for physics disabled - virtual void OnPhysicsDisabled() = 0; - }; - using WorldBodyNotificationBus = AZ::EBus; -} diff --git a/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp b/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp index 985bc4665d..22598595fc 100644 --- a/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp +++ b/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp @@ -46,7 +46,6 @@ namespace AzFramework::ProjectManager // Store the Command line to the Setting Registry AZ::SettingsRegistryImpl settingsRegistry; AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine); - AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {}); // Retrieve Command Line from Settings Registry, it may have been updated by the call to FindEngineRoot() // in MergeSettingstoRegistry_ConfigFile @@ -79,7 +78,7 @@ namespace AzFramework::ProjectManager projectJsonPath.c_str()); } - if (LaunchProjectManager(engineRootPath)) + if (LaunchProjectManager()) { AZ_TracePrintf("ProjectManager", "Project Manager launched successfully, requesting exit."); return ProjectPathCheckResult::ProjectManagerLaunched; @@ -88,7 +87,7 @@ namespace AzFramework::ProjectManager return ProjectPathCheckResult::ProjectManagerLaunchFailed; } - bool LaunchProjectManager([[maybe_unused]] const AZ::IO::FixedMaxPath& engineRootPath) + bool LaunchProjectManager(const AZStd::string& commandLineArgs) { bool launchSuccess = false; #if (AZ_TRAIT_AZFRAMEWORK_USE_PROJECT_MANAGER) @@ -99,51 +98,18 @@ namespace AzFramework::ProjectManager AZ::AllocatorInstance::Create(); } { - const char projectsScript[] = "projects.py"; + AZStd::string filename = "o3de"; + AZ::IO::FixedMaxPath executablePath = AZ::Utils::GetExecutableDirectory(); + executablePath /= filename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION; - AZ_Warning("ProjectManager", false, "No project provided - launching project selector."); - - if (engineRootPath.empty()) + if (!AZ::IO::SystemFile::Exists(executablePath.c_str())) { - AZ_Error("ProjectManager", false, "Couldn't find engine root"); + AZ_Error("ProjectManager", false, "%s not found", executablePath.c_str()); return false; } - auto projectManagerPath = engineRootPath / "scripts" / "project_manager"; - - if (!AZ::IO::SystemFile::Exists((projectManagerPath / projectsScript).c_str())) - { - AZ_Error("ProjectManager", false, "%s not found at %s!", projectsScript, projectManagerPath.c_str()); - return false; - } - AZ::IO::FixedMaxPathString executablePath; - AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath.data(), executablePath.capacity()); - if (result.m_pathStored != AZ::Utils::ExecutablePathResult::Success) - { - AZ_Error("ProjectManager", false, "Could not determine executable path!"); - return false; - } - AZ::IO::FixedMaxPath parentPath(executablePath.c_str()); - auto exeFolder = parentPath.ParentPath(); - AZStd::fixed_string<8> debugOption; - auto lastSep = exeFolder.Native().find_last_of(AZ_CORRECT_FILESYSTEM_SEPARATOR); - if (lastSep != AZStd::string_view::npos) - { - exeFolder = exeFolder.Native().substr(lastSep + 1); - } - if (exeFolder == "debug") - { - // We need to use the debug version of the python interpreter to load up our debug version of our libraries which work with the debug version of QT living in this folder - debugOption = "debug "; - } - AZ::IO::FixedMaxPath pythonPath = engineRootPath / "python"; - pythonPath /= AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL; - auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRIu32, pythonPath.Native().c_str(), - debugOption.c_str(), (projectManagerPath / projectsScript).c_str(), executablePath.c_str(), AZ::Platform::GetCurrentProcessId()); AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo; - - processLaunchInfo.m_commandlineParameters = cmdPath; - processLaunchInfo.m_showWindow = false; + processLaunchInfo.m_commandlineParameters = executablePath.String() + commandLineArgs; launchSuccess = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo); } if (ownsSystemAllocator) diff --git a/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.h b/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.h index cc79bd4184..d0ef7172b0 100644 --- a/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.h +++ b/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.h @@ -12,6 +12,7 @@ #pragma once #include +#include namespace AzFramework::ProjectManager { @@ -21,8 +22,16 @@ namespace AzFramework::ProjectManager ProjectManagerLaunched = 0, ProjectPathFound = 1 }; - // Check for a project name, if not found, attempts to launch project manager and returns false + + //! Check for a project name, if not found, attempts to launch project manager and returns false + //! @param argc the number of arguments in argv + //! @param argv arguments provided to this executable + //! @return a ProjectPathCheckResult ProjectPathCheckResult CheckProjectPathProvided(const int argc, char* argv[]); - // Attempt to Launch the project manager. Requires locating the engine root, project manager script, and python. - bool LaunchProjectManager(const AZ::IO::FixedMaxPath& engineRootPath); + + //! Attempt to Launch the project manager, assuming the o3de executable exists in same folder as + //! current executable. Requires the o3de cli and python. + //! @param commandLineArgs additional command line arguments to provide to the project manager + //! @return true on success, false if failed to find or launch the executable + bool LaunchProjectManager(const AZStd::string& commandLineArgs = ""); } // AzFramework::ProjectManager diff --git a/Code/Framework/AzFramework/AzFramework/Render/GeometryIntersectionBus.h b/Code/Framework/AzFramework/AzFramework/Render/GeometryIntersectionBus.h index ba1d2d1e06..749f457286 100644 --- a/Code/Framework/AzFramework/AzFramework/Render/GeometryIntersectionBus.h +++ b/Code/Framework/AzFramework/AzFramework/Render/GeometryIntersectionBus.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include namespace AzFramework @@ -35,12 +36,12 @@ namespace AzFramework AzFramework::EntityContextId m_contextId; }; - //! Interface for intersection requests, implement this interface for making your component - //! render geometry intersectable. + //! Interface for intersection requests. + //! Implement this interface to make your component 'intersectable'. class IntersectionRequests : public AZ::EBusTraits { - //! Policy for notifying the Intersector bus of entities connected/disconnected to this ebus + //! Policy for notifying the Intersector bus of entities connected/disconnected to this EBus //! so it updates the internal data of the entities template struct IntersectionRequestsConnectionPolicy diff --git a/Code/Framework/AzFramework/AzFramework/Render/Intersector.cpp b/Code/Framework/AzFramework/AzFramework/Render/Intersector.cpp index 23d74f7578..143c1f7916 100644 --- a/Code/Framework/AzFramework/AzFramework/Render/Intersector.cpp +++ b/Code/Framework/AzFramework/AzFramework/Render/Intersector.cpp @@ -139,7 +139,8 @@ namespace AzFramework "Implementers of IntersectionRequestBus must also implement BoundsRequestBus to ensure valid " "bounds are returned"); - m_registeredEntities.Update({ entityId, CalculateEntityWorldBoundsUnion(entityId) }); + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(entityId); + m_registeredEntities.Update({ entityId, CalculateEntityWorldBoundsUnion(entity) }); } m_dirtyEntities.clear(); diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp index 838ab0b6e2..4f8da821c1 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp @@ -26,12 +26,9 @@ #include #include -#include -#include #include -#include #include @@ -267,12 +264,12 @@ namespace AzFramework // SampleRPC = // { // // Two callbacks can be registered to the NetRPC - // // A function to be invoked on the Master - OnMaster + // // A function to be invoked on the main server - OnServer // // and a function to be invoked on the Proxy - OnProxy // // - // // Every NetRPC needs to have a valid OnMaster function, while OnProxy is optional. - // OnMaster = function() - // Debug.Log("Function to be invoked on the Master."); + // // Every NetRPC needs to have a valid OnServer function, while OnProxy is optional. + // OnServer = function() + // Debug.Log("Function to be invoked on the server."); // end // // OnProxy = function() @@ -429,83 +426,60 @@ namespace AzFramework { LSV_BEGIN(lua, 1); - // calling format __index(table,key) - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua, lua_upvalueindex(1))); + AZ::ScriptContext::FromNativeContext(lua)->Error(AZ::ScriptContext::ErrorType::Warning, true, + "Property %s not found in entity table. Please push this property to your slice to avoid decrease in performance.", lua_tostring(lua, -1)); + int lookupKey = lua_gettop(lua); - bool readValue = false; - - if (netBindingTable != nullptr) + int lookupTable = lookupKey - 1; + // This is a slow function and it's made slow so we don't cache any extra data. + // This is done because this function will be called only the exported components + // and script are not in sync and we added new properties. + lua_getmetatable(lua, -2); // get the metatable which will be the top property table + int entityProperties = lua_gettop(lua); + if (lua_getmetatable(lua, -1) == 0) // get the metatable of the property which will be the original table { - AZ_Error("ScriptComponent",netBindingTable->GetScriptContext() != nullptr,"ScriptNetBindingTable is missing ScriptContext."); - AZ_Error("ScriptComponent",netBindingTable->GetScriptContext() == nullptr || netBindingTable->GetScriptContext()->NativeContext() == lua,"Trying to use a NetBindingTable in wrong lua context"); - - AZ::ScriptContext* scriptContext = netBindingTable->GetScriptContext(); - - if (scriptContext) - { - AZ::ScriptDataContext stackContext; - scriptContext->ReadStack(stackContext); - - readValue = netBindingTable->InspectTableValue(stackContext); - } + // we are looking at top level properties + lua_pushvalue(lua, -2); // copy the key + lua_rawget(lua, -2); // read the value } - - if (!readValue) + else { - AZ::ScriptContext::FromNativeContext(lua)->Error(AZ::ScriptContext::ErrorType::Warning, true, - "Property %s not found in entity table. Please push this property to your slice to avoid decrease in performance.", lua_tostring(lua, -1)); - int lookupKey = lua_gettop(lua); - - int lookupTable = lookupKey - 1; - // This is a slow function and it's made slow so we don't cache any extra data. - // This is done because this function will be called only the exported components - // and script are not in sync and we added new properties. - lua_getmetatable(lua, -2); // get the metatable which will be the top property table - int entityProperties = lua_gettop(lua); - if (lua_getmetatable(lua, -1) == 0) // get the metatable of the property which will be the original table + // we are looking into the sub table, so do a slow traversal + int scriptProperties = lua_gettop(lua); + if (!Properties__IndexFindSubtable(lua, lookupTable, entityProperties, scriptProperties)) { - // we are looking at top level properties - lua_pushvalue(lua, -2); // copy the key - lua_rawget(lua, -2); // read the value + lua_pushnil(lua); + return 1; // we did not find the table } else { - // we are looking into the sub table, so do a slow traversal - int scriptProperties = lua_gettop(lua); - if (!Properties__IndexFindSubtable(lua, lookupTable, entityProperties, scriptProperties)) - { - lua_pushnil(lua); - return 1; // we did not find the table - } - else - { - lua_pushvalue(lua, lookupKey); - lua_rawget(lua, -2); - } - } - - if (lua_istable(lua, -1)) - { - // if we are here the target table is on the top if the stack - lua_pushstring(lua, ScriptComponent::DefaultFieldName); + lua_pushvalue(lua, lookupKey); lua_rawget(lua, -2); - if (lua_isnil(lua, -1)) - { - // parent table is a group, pop the value and return the table - lua_pop(lua, 1); - } } - - // Duplicate the value, so once the storage is done its on top of the stack, and returned - lua_pushvalue(lua, -1); - - // Push key, and then move it below the value - lua_pushvalue(lua, lookupKey); - lua_insert(lua, -2); - - // Cache the value so that subsequent accesses to this property don't result in warnings - lua_rawset(lua, lookupTable); } + + if (lua_istable(lua, -1)) + { + // if we are here the target table is on the top if the stack + lua_pushstring(lua, ScriptComponent::DefaultFieldName); + lua_rawget(lua, -2); + if (lua_isnil(lua, -1)) + { + // parent table is a group, pop the value and return the table + lua_pop(lua, 1); + } + } + + // Duplicate the value, so once the storage is done its on top of the stack, and returned + lua_pushvalue(lua, -1); + + // Push key, and then move it below the value + lua_pushvalue(lua, lookupKey); + lua_insert(lua, -2); + + // Cache the value so that subsequent accesses to this property don't result in warnings + lua_rawset(lua, lookupTable); + return 1; } //========================================================================= @@ -515,30 +489,7 @@ namespace AzFramework { LSV_BEGIN_VARIABLE(lua); - // calling format __newindex(table,key,value) - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua, lua_upvalueindex(1))); - if (netBindingTable != nullptr) - { - AZ_Error("ScriptContext",netBindingTable->GetScriptContext() != nullptr,"ScriptNetBindingTable is missing ScriptContext."); - AZ_Error("ScriptContext",netBindingTable->GetScriptContext() == nullptr || netBindingTable->GetScriptContext()->NativeContext() == lua,"Trying to use a NetBindingTable in wrong lua context"); - - AZ::ScriptContext* scriptContext = netBindingTable->GetScriptContext(); - if (scriptContext) - { - AZ::ScriptDataContext stackContext; - scriptContext->ReadStack(stackContext); - - const bool assignedValue = netBindingTable->AssignTableValue(stackContext); - if (assignedValue) - { - LSV_END_VARIABLE(0); - return 0; - } - } - } - - // If we didn't assign the value above, we want - // to raw set the value to avoid coming back in here. + // We want to raw set the value to avoid coming back in here. lua_rawset(lua, 1); LSV_END_VARIABLE(-2); return 0; @@ -553,7 +504,6 @@ namespace AzFramework // [8/9/2013] //========================================================================= - const char* ScriptComponent::NetRPCFieldName = "NetRPCs"; const char* ScriptComponent::DefaultFieldName = "default"; ScriptComponent::ScriptComponent() @@ -561,7 +511,6 @@ namespace AzFramework , m_contextId(AZ::ScriptContextIds::DefaultScriptContextId) , m_script(AZ::Data::AssetLoadBehavior::PreLoad) , m_table(LUA_NOREF) - , m_netBindingTable(nullptr) { m_properties.m_name = "Properties"; } @@ -573,8 +522,6 @@ namespace AzFramework ScriptComponent::~ScriptComponent() { m_properties.Clear(); - - delete m_netBindingTable; } //========================================================================= @@ -604,11 +551,6 @@ namespace AzFramework return m_properties.GetProperty(propertyName); } - const AZ::ScriptProperty* ScriptComponent::GetNetworkedScriptProperty(const char* propertyName) const - { - return m_netBindingTable->FindScriptProperty(propertyName); - } - void ScriptComponent::Init() { // Grab the script context @@ -622,11 +564,6 @@ namespace AzFramework //========================================================================= void ScriptComponent::Activate() { - if (m_isSyncEnabled && m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - // if we have valid asset listen for script asset events, like reload if (m_script.GetId().IsValid()) { @@ -681,43 +618,6 @@ namespace AzFramework LoadScript(); } - //========================================================================= - // ScriptComponent::GetNetworkBinding - //========================================================================= - GridMate::ReplicaChunkPtr ScriptComponent::GetNetworkBinding() - { - if (m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - - return m_netBindingTable->GetNetworkBinding(); - } - - //========================================================================= - // ScriptComponent::SetNetworkBinding - //========================================================================= - void ScriptComponent::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - if (m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - - m_netBindingTable->SetNetworkBinding(chunk); - } - - //========================================================================= - // ScriptComponent::UnbindFromNetwork - //========================================================================= - void ScriptComponent::UnbindFromNetwork() - { - if (m_netBindingTable) - { - m_netBindingTable->UnbindFromNetwork(); - } - } - //========================================================================= // LoadScript //========================================================================= @@ -741,11 +641,6 @@ namespace AzFramework AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Script, "Unload: %s", m_script.GetHint().c_str()); DestroyEntityTable(); - - if (m_netBindingTable) - { - m_netBindingTable->Unload(); - } } //========================================================================= @@ -798,12 +693,10 @@ namespace AzFramework // set the __index so we can read values in case we change the script // after we export the component lua_pushliteral(lua, "__index"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__Index, 1); lua_rawset(lua, -3); lua_pushliteral(lua, "__newindex"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1); lua_rawset(lua, -3); } @@ -835,8 +728,7 @@ namespace AzFramework { const char* tableName = lua_tolstring(lua, -2, nullptr); if (strncmp(tableName, "__", 2) == 0 || // skip metatables - strcmp(tableName, propertyTableName) == 0 || // Skip the Properties table - strcmp(tableName, ScriptComponent::NetRPCFieldName) == 0) // Want to skip the RPC table as well + strcmp(tableName, propertyTableName) == 0) // Skip the Properties table { break; } @@ -904,13 +796,10 @@ namespace AzFramework } lua_createtable(lua, 0, 1); // Create entity table; - int entityStackIndex = lua_gettop(lua); + [[maybe_unused]] int entityStackIndex = lua_gettop(lua); // Stack: ScriptRootTable PropertiesTable EntityTable - // Create our network binding. - CreateNetworkBindingTable(baseStackIndex, entityStackIndex); - if (basePropertyTable > -1) // if property table exists { CreatePropertyGroup(m_properties, basePropertyTable, lua_gettop(lua), basePropertyTable, true); @@ -932,11 +821,6 @@ namespace AzFramework // Keep the entity table in the registry m_table = luaL_ref(lua, LUA_REGISTRYINDEX); - if (m_netBindingTable) - { - m_netBindingTable->FinalizeNetworkTable(m_context, m_table); - } - // call OnActivate lua_pushliteral(lua, "OnActivate"); lua_rawget(lua, baseStackIndex); // ScriptTable[OnActivate] @@ -993,18 +877,6 @@ namespace AzFramework } } - //========================================================================= - // CreateNetworkBindingTable - // [6/27/2016] - //========================================================================= - void ScriptComponent::CreateNetworkBindingTable(int baseStackIndex, int entityStackIndex) - { - if (m_netBindingTable) - { - m_netBindingTable->CreateNetworkBindingTable(m_context, baseStackIndex, entityStackIndex); - } - } - //========================================================================= // CreatePropertyGroup // [3/3/2014] @@ -1028,12 +900,10 @@ namespace AzFramework // Ensure that this instance of Properties table has the proper __index and __newIndex metamethods. lua_newtable(lua); // This new table will become the Properties instance metatable. Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} lua_pushliteral(lua, "__index"); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index - lua_pushlightuserdata(lua, m_netBindingTable); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index m_netBinding lua_pushcclosure(lua, &Internal::Properties__Index, 1); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index function lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index} lua_pushliteral(lua, "__newindex"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1); lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex} lua_setmetatable(lua, -2); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {Meta{__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex} } @@ -1050,55 +920,6 @@ namespace AzFramework { AZ::ScriptProperty* prop = group.m_properties[i]; - if (m_netBindingTable != nullptr) - { - lua_pushlstring(lua, prop->m_name.c_str(), prop->m_name.length()); - lua_rawget(lua, propertyGroupTableIndex); - - // Stack: ... SomePropertyInThePropertiesTable. This may be any basic lua type (number, string, table etc) - if (lua_istable(lua, -1)) - { - bool isNetworkedProperty = false; - - AZ::ScriptDataContext stackContext; - - // If we find a table value. We want to inspect it for information. - if (m_context->ReadStack(stackContext)) - { - // check if the current property, which is a table, has a sub-table called "netSynched" - lua_pushliteral(lua, "netSynched"); // Stack: ... SomePropertyInThePropertiesTable netSynched - lua_rawget(lua, -2); // Stack: ... SomePropertyInThePropertiesTable NetSynchedSubTable/nil - if (stackContext.IsTable(-1)) - { - AZ::ScriptDataContext networkTableContext; - if (stackContext.InspectTable(-1, networkTableContext)) // Stack: ... SomePropertyInThePropertiesTable NetSynchedSubTable NetSynchedSubTable nil nil - { - // RegisterDataSet will make sure our __NewIndex function callback will be triggered whenever modifying netSynched Properties. - //isNetworkedProperty = true; - isNetworkedProperty = m_netBindingTable->RegisterDataSet(networkTableContext, prop); - } - } - - // Network binding table - lua_pop(lua, 1); // Stack: ... SomePropertyInThePropertiesTable - } - - // Pop this PropertiesTable's property - lua_pop(lua, 1); - - // If the property is networked, we don't want to copy it over into the table. - if (isNetworkedProperty) - { - continue; - } - } - else - { - // Remove the value we just pushed onto the stack - lua_pop(lua, 1); - } - } - lua_pushlstring(lua, prop->m_name.c_str(), prop->m_name.length()); if (prop->Write(*m_context)) { @@ -1157,8 +978,8 @@ namespace AzFramework return true; }; - serializeContext->Class() - ->Version(3, converter) + serializeContext->Class() + ->Version(4, converter) ->Field("ContextID", &ScriptComponent::m_contextId) ->Field("Properties", &ScriptComponent::m_properties) ->Field("Script", &ScriptComponent::m_script) @@ -1174,8 +995,6 @@ namespace AzFramework AZ::ScriptProperties::Reflect(reflection); } } - - ScriptNetBindingTable::Reflect(reflection); } //========================================================================= diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h index 4d15bc527d..8294f3849c 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h @@ -20,8 +20,6 @@ #include #include -#include - namespace AZ { class ScriptProperty; @@ -37,8 +35,6 @@ namespace AzToolsFramework namespace AzFramework { - class ScriptNetBindingTable; - struct ScriptCompileRequest; using WriteFunction = AZStd::function< AZ::Outcome(const ScriptCompileRequest&, AZ::IO::GenericStream& in, AZ::IO::GenericStream& out) >; @@ -92,15 +88,13 @@ namespace AzFramework class ScriptComponent : public AZ::Component , private AZ::Data::AssetBus::Handler - , public AzFramework::NetBindable { friend class AzToolsFramework::Components::ScriptEditorComponent; public: - static const char* NetRPCFieldName; static const char* DefaultFieldName; - AZ_COMPONENT(AzFramework::ScriptComponent, "{8D1BC97E-C55D-4D34-A460-E63C57CD0D4B}", NetBindable); + AZ_COMPONENT(AzFramework::ScriptComponent, "{8D1BC97E-C55D-4D34-A460-E63C57CD0D4B}", AZ::Component); /// \red ComponentDescriptor::Reflect static void Reflect(AZ::ReflectContext* reflection); @@ -116,7 +110,6 @@ namespace AzFramework // Methods used for unit tests AZ::ScriptProperty* GetScriptProperty(const char* propertyName); - const AZ::ScriptProperty* GetNetworkedScriptProperty(const char* propertyName) const; protected: ScriptComponent(const ScriptComponent&) = delete; @@ -133,13 +126,6 @@ namespace AzFramework void OnAssetReloaded(AZ::Data::Asset asset) override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // NetBindable - GridMate::ReplicaChunkPtr GetNetworkBinding() override; - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) override; - void UnbindFromNetwork() override; - ////////////////////////////////////////////////////////////////////////// - /// Load script (unless already by other instances) and creates the script instance into the VM void LoadScript(); /// Removes the script instance and unloads the script (unless needed by other instances) @@ -152,8 +138,6 @@ namespace AzFramework void CreateEntityTable(); void DestroyEntityTable(); - void CreateNetworkBindingTable(int baseStackIndex, int entityStackIndex); - void CreatePropertyGroup(const ScriptPropertyGroup& group, int propertyGroupTableIndex, int parentIndex, int metatableIndex, bool isRoot); AZ::ScriptContext* m_context; ///< Context in which the script will be running @@ -161,7 +145,6 @@ namespace AzFramework AZ::Data::Asset m_script; ///< Reference to the script asset used for this component. int m_table; ///< Cached table index ScriptPropertyGroup m_properties; ///< List with all properties that were tweaked in the editor and should override values in the m_sourceScriptName class inside m_script. - ScriptNetBindingTable* m_netBindingTable; ///< Table that will hold our networked script values, and manage callbacks }; } // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp deleted file mode 100644 index f02e050e74..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp +++ /dev/null @@ -1,573 +0,0 @@ -/* -* 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. -* -*/ -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "AzFramework/Script/ScriptMarshal.h" - -namespace AzFramework -{ - //////////////////////////// - // ScriptPropertyMarshaler - //////////////////////////// - - template - bool UnmarshalGenericType(AZ::DynamicSerializableField& serializableField, GridMate::ReadBuffer& rb) - { - bool valueChanged = true; - - GridMate::Marshaler serializableFieldMarshaler; - - // Store the old value, to compare with the unmarshaled value, to signal - T oldValue = (*serializableField.Get()); - - serializableFieldMarshaler.Unmarshal(serializableField,rb); - - // If our type hasn't changed, compare the values. - if (serializableField.m_typeId == T::TYPEINFO_Uuid()) - { - valueChanged = !(oldValue == (*serializableField.Get())); - } - - return valueChanged; - } - - class ScriptPropertyTableMarshalerHelper - { - public: - template - static void MarshalScriptPropertyGenericMap(const ScriptPropertyMarshaler& scriptPropertyMarshaler, GridMate::WriteBuffer& wb, const AZ::ScriptPropertyTable* scriptPropertyTable) - { - GridMate::Marshaler sizeMarshaler; - - auto mapIter = scriptPropertyTable->m_genericMapping.find(T::TYPEINFO_Uuid()); - - if (mapIter != scriptPropertyTable->m_genericMapping.end()) - { - AZ::ScriptPropertyGenericClassMapImpl* genericClassKeyMap = static_cast*>(mapIter->second); - - auto& valueMap = genericClassKeyMap->GetPairMapping(); - - // We will write out all of our keys. Since it is easier to write out nil values for the properties. - sizeMarshaler.Marshal(wb,static_cast(valueMap.size())); - - GridMate::Marshaler keyMarshaler; - - for (auto& mapPair : valueMap) - { - keyMarshaler.Marshal(wb,mapPair.first); - scriptPropertyMarshaler.Marshal(wb,mapPair.second.m_valueProperty); - } - } - else - { - sizeMarshaler.Marshal(wb,0); - } - } - - template - static bool UnmarshalScriptPropertyGenericMap(const ScriptPropertyMarshaler& scriptPropertyMarshaler, AZ::ScriptPropertyTable* scriptPropertyTable, GridMate::ReadBuffer& rb) - { - bool valueChanged = false; - - AZ::SerializeContext* useContext = nullptr; - EBUS_EVENT_RESULT(useContext, AZ::ComponentApplicationBus, GetSerializeContext); - - if (useContext) - { - const AZ::SerializeContext::ClassData* classData = useContext->FindClassData(T::TYPEINFO_Uuid()); - - if (classData && classData->m_factory) - { - auto mapIter = scriptPropertyTable->m_genericMapping.find(T::TYPEINFO_Uuid()); - - if (mapIter != scriptPropertyTable->m_genericMapping.end()) - { - // This whole thing is an in-place map update. - // to try to minimize the number of allocations. We try to re-use objects as much as possible. - // - // Two phase approach: Step one, update all of the existing properties, while keeping track of all of the used keys. - // Step two, go through and delete any unupdated keys from the mapping. - AZ::ScriptPropertyGenericClassMapImpl* genericClassKeyMap = static_cast*>(mapIter->second); - - AZStd::unordered_set newKeys; - - GridMate::Marshaler sizeMarshaler; - - AZ::u32 mapSize; - sizeMarshaler.Unmarshal(mapSize,rb); - - auto& valueMap = genericClassKeyMap->GetPairMapping(); - - GridMate::Marshaler keyMarshaler; - - for (unsigned int i=0; i < mapSize; ++i) - { - T propertyKey; - keyMarshaler.Unmarshal(propertyKey,rb); - - newKeys.insert(propertyKey); - - auto valueIter = valueMap.find(propertyKey); - - if (valueIter != valueMap.end()) - { - if (scriptPropertyMarshaler.UnmarshalToPointer(valueIter->second.m_valueProperty,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* newValueProperty = nullptr; - scriptPropertyMarshaler.UnmarshalToPointer(newValueProperty,rb); - - AZ::ScriptPropertyGenericClassMap::MapValuePair newPair; - - newPair.m_valueProperty = newValueProperty; - - T* serializableData = nullptr; - serializableData = static_cast(classData->m_factory->Create("ScriptProperty")); - (*serializableData) = propertyKey; - - AZ::ScriptPropertyGenericClass* genericPropertyClass = aznew AZ::ScriptPropertyGenericClass(); - - genericPropertyClass->Set(serializableData); - - newPair.m_keyProperty = genericPropertyClass; - - valueMap.emplace(propertyKey,newPair); - } - } - - // Delete all of the unused keyes from the map - auto valueIter = valueMap.begin(); - - while (valueIter != valueMap.end()) - { - if (newKeys.find(valueIter->first) == newKeys.end()) - { - valueChanged = true; - valueIter->second.Destroy(); - valueIter = valueMap.erase(valueIter); - } - else - { - ++valueIter; - } - } - } - } - } - - return valueChanged; - } - }; - - - - void ScriptPropertyMarshaler::Marshal(GridMate::WriteBuffer& wb, AZ::ScriptProperty*const& property) const - { - GridMate::Marshaler typeMarshaler; - GridMate::Marshaler idMarshaler; - GridMate::Marshaler nameMarshaler; - - if (property == nullptr) - { - // Write out a nil property if we have a nullptr property - nameMarshaler.Marshal(wb,""); - idMarshaler.Marshal(wb,0); - typeMarshaler.Marshal(wb,AZ::ScriptPropertyNil::RTTI_Type()); - return; - } - - // Common points: - // Always going to marshal the uuid of the type(or something similar) - // so we know what type we have on the other side. - // - // Next need to pass along the name field. - const AZ::Uuid& typeId = azrtti_typeid(property); - - nameMarshaler.Marshal(wb,property->m_name); - idMarshaler.Marshal(wb,property->m_id); - - // Method 1: - // - Allow each ScriptProperty to marshal itself. - // - Currently unavailable since the ScriptProperties live in AZCore - // and the WriteBuffer is in GridMate. - // cont.Marshal(wb); - - // Method 2: - // - Process all of our known marshallable types and use the appropriate marshaler - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler boolMarshaler; - boolMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler doubleMarshaler; - doubleMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler stringMarshaler; - stringMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - const AZ::DynamicSerializableField& serializableField = static_cast(property)->GetSerializableField(); - - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler serializableFieldMarshaler; - serializableFieldMarshaler.Marshal(wb,serializableField); - } - else if (typeId == AZ::ScriptPropertyTable::TYPEINFO_Uuid()) - { - const AZ::ScriptPropertyTable* scriptPropertyTable = static_cast(property); - - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler mapSizeMarshaler; - mapSizeMarshaler.Marshal(wb,static_cast(scriptPropertyTable->m_indexMapping.size())); - - GridMate::Marshaler indexMarshaler; - - // Currently only support integers as keys inside of the table. - for (auto& mapPair : scriptPropertyTable->m_indexMapping) - { - indexMarshaler.Marshal(wb,mapPair.first); - this->Marshal(wb,mapPair.second); - } - - mapSizeMarshaler.Marshal(wb, static_cast(scriptPropertyTable->m_keyMapping.size())); - - GridMate::Marshaler hashMarshaler; - - for (auto& mapPair : scriptPropertyTable->m_keyMapping) - { - // For hashed values. The name of the script property is the same as the hash it should be using. - // We still synchronize the Crc so we can unmarshal in place on the other side. - hashMarshaler.Marshal(wb,mapPair.first); - Marshal(wb,mapPair.second); - } - - // EntityId's - ScriptPropertyTableMarshalerHelper::MarshalScriptPropertyGenericMap((*this), wb, scriptPropertyTable); - } - else - { - typeMarshaler.Marshal(wb,AZ::ScriptPropertyNil::RTTI_Type()); - } - } - - bool ScriptPropertyMarshaler::UnmarshalToPointer(AZ::ScriptProperty*& target, GridMate::ReadBuffer& rb) const - { - bool typeChanged = false; - AZ::Uuid typeId; - AZ::u64 id; - AZStd::string name; - - GridMate::Marshaler typeMarshaler; - GridMate::Marshaler idMarshaler; - GridMate::Marshaler nameMarshaler; - - nameMarshaler.Unmarshal(name,rb); - idMarshaler.Unmarshal(id,rb); - typeMarshaler.Unmarshal(typeId,rb); - - if (target == nullptr || typeId != azrtti_typeid(target)) - { - typeChanged = true; - - AZ::ScriptProperty* actualScriptProperty = nullptr; - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyBoolean(); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyNumber(); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyString(); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyGenericClass(); - } - else if (typeId == AZ::ScriptPropertyTable::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyTable(); - } - else - { - actualScriptProperty = aznew AZ::ScriptPropertyNil(); - } - - actualScriptProperty->m_name = name; - delete target; - - target = actualScriptProperty; - } - - // Update our ID - target->m_id = id; - - // Method 1: - // - Allow each ScriptProperty to unmarshal itself - // - Currently unavailable since the ScriptProperties live in AZCore - // and the WriteBuffer is in GridMate - // actualScriptProperty->Unmarshal(rb); - // - // Method 2: - // - Process all of our known marshallable types and use the appropriate marshaler - - bool valueChanged = false; - - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - AZ::ScriptPropertyBoolean* booleanProperty = static_cast(target); - bool oldValue = booleanProperty->m_value; - - GridMate::Marshaler boolMarshaler; - boolMarshaler.Unmarshal(booleanProperty->m_value,rb); - - valueChanged = !(oldValue == booleanProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - AZ::ScriptPropertyString* stringProperty = static_cast(target); - AZStd::string oldValue = stringProperty->m_value; - - GridMate::Marshaler stringMarshaler; - stringMarshaler.Unmarshal(stringProperty->m_value,rb); - - valueChanged = !(oldValue == stringProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - AZ::ScriptPropertyNumber* numberProperty = static_cast(target); - double oldValue = numberProperty->m_value; - - GridMate::Marshaler numberMarshaler; - numberMarshaler.Unmarshal(numberProperty->m_value,rb); - - valueChanged = !(oldValue == numberProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - AZ::ScriptPropertyGenericClass* genericProperty = static_cast(target); - - AZ::DynamicSerializableField& serializableField = genericProperty->m_value; - - AZ::DynamicSerializableField oldField; - - oldField.CopyDataFrom(serializableField); - - GridMate::Marshaler serializableFieldMarshaler; - serializableFieldMarshaler.Unmarshal(serializableField,rb); - - // If our type hasn't changed, compare the values. - valueChanged = !oldField.IsEqualTo(serializableField); - } - else if (typeId == AZ::ScriptPropertyTable::RTTI_Type()) - { - AZ::ScriptPropertyTable* scriptPropertyTable = static_cast(target); - GridMate::Marshaler mapSizeMarshaler; - - // Unmarshal all of the indexes properties - { - AZ::u32 mapSize = 0; - mapSizeMarshaler.Unmarshal(mapSize, rb); - - AZStd::unordered_set newIndexes; - GridMate::Marshaler indexMarshaler; - - for (AZ::u32 i=0; i < mapSize; ++i) - { - int index = 0; - indexMarshaler.Unmarshal(index,rb); - - auto mapIter = scriptPropertyTable->m_indexMapping.find(index); - - if (mapIter != scriptPropertyTable->m_indexMapping.end()) - { - if (UnmarshalToPointer(mapIter->second,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* scriptProperty = nullptr; - UnmarshalToPointer(scriptProperty,rb); - auto insertResult = scriptPropertyTable->m_indexMapping.emplace(index,scriptProperty); - mapIter = insertResult.first; - } - - if (mapIter->second == nullptr || azrtti_istypeof(mapIter->second)) - { - valueChanged = true; - - delete mapIter->second; - scriptPropertyTable->m_indexMapping.erase(mapIter); - } - else - { - newIndexes.insert(index); - } - } - - auto mapIter = scriptPropertyTable->m_indexMapping.begin(); - - while (mapIter != scriptPropertyTable->m_indexMapping.end()) - { - if (newIndexes.find(mapIter->first) == newIndexes.end()) - { - valueChanged = true; - - delete mapIter->second; - mapIter = scriptPropertyTable->m_indexMapping.erase(mapIter); - } - else - { - ++mapIter; - } - } - } - - // Unmarshal all of the hashed values - { - AZ::u32 mapSize = 0; - mapSizeMarshaler.Unmarshal(mapSize, rb); - - AZStd::unordered_set newHashes; - GridMate::Marshaler hashMarshaler; - - for (AZ::u32 i=0; i < mapSize; ++i) - { - AZ::u32 newHash; - hashMarshaler.Unmarshal(newHash, rb); - - auto mapIter = scriptPropertyTable->m_keyMapping.find(newHash); - - if (mapIter != scriptPropertyTable->m_keyMapping.end()) - { - if (UnmarshalToPointer(mapIter->second,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* scriptProperty = nullptr; - UnmarshalToPointer(scriptProperty,rb); - auto emplaceResult = scriptPropertyTable->m_keyMapping.emplace(newHash,scriptProperty); - mapIter = emplaceResult.first; - } - - if (mapIter->second == nullptr || azrtti_istypeof(mapIter->second)) - { - valueChanged = true; - - delete mapIter->second; - scriptPropertyTable->m_keyMapping.erase(mapIter); - } - else - { - newHashes.insert(newHash); - } - } - - auto mapIter = scriptPropertyTable->m_keyMapping.begin(); - - while (mapIter != scriptPropertyTable->m_keyMapping.end()) - { - if (newHashes.find(mapIter->first) == newHashes.end()) - { - valueChanged = true; - - delete mapIter->second; - mapIter = scriptPropertyTable->m_keyMapping.erase(mapIter); - } - else - { - ++mapIter; - } - } - } - - // Unmarshal all of the generic properties - - // EntityId's - if (ScriptPropertyTableMarshalerHelper::UnmarshalScriptPropertyGenericMap((*this), scriptPropertyTable, rb)) - { - valueChanged = true; - } - } - - return typeChanged || valueChanged; - } - - //////////////////////////// - // ScriptPropertyThrottler - //////////////////////////// - - ScriptPropertyThrottler::ScriptPropertyThrottler() - : m_isDirty(true) - { - - } - - void ScriptPropertyThrottler::SignalDirty() - { - m_isDirty = true; - } - - bool ScriptPropertyThrottler::WithinThreshold(AZ::ScriptProperty* newValue) const - { - return newValue == nullptr || !m_isDirty; - } - - void ScriptPropertyThrottler::UpdateBaseline(AZ::ScriptProperty* baseline) - { - (void)baseline; - - m_isDirty = false; - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h deleted file mode 100644 index c13749d46b..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -* 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. -* -*/ -#ifndef AZFRAMEWORK_SCRIPT_SCRIPTMARSHAL_H -#define AZFRAMEWORK_SCRIPT_SCRIPTMARSHAL_H - -#include - -#include - -namespace AZ -{ - class ScriptProperty; -} - -namespace AzFramework -{ - /** - * Specalized helper marshaler for ScriptProperty class - */ - class ScriptPropertyMarshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, AZ::ScriptProperty*const& cont) const; - bool UnmarshalToPointer(AZ::ScriptProperty*& target, GridMate::ReadBuffer& rb) const; - }; - - class ScriptPropertyThrottler - { - public: - ScriptPropertyThrottler(); - - void SignalDirty(); - bool WithinThreshold(AZ::ScriptProperty* newValue) const; - void UpdateBaseline(AZ::ScriptProperty* baseline); - - private: - bool m_isDirty; - }; - - /** - * Specialized helper marshaler to help with the vector creation/destruction - */ - class ScriptRPCMarshaler - { - public: - - typedef AZStd::vector< AZ::ScriptProperty* > Container; - - ScriptRPCMarshaler() - { - } - - AZ_FORCE_INLINE void Marshal(GridMate::WriteBuffer& wb, const Container& container) const - { - AZ_Assert(container.size() < USHRT_MAX, "Container has too many elements for marshaling!"); - AZ::u16 size = static_cast(container.size()); - wb.Write(size); - for (const auto& i : container) - { - m_marshaler.Marshal(wb, i); - } - } - - AZ_FORCE_INLINE void Unmarshal(Container& container, GridMate::ReadBuffer& rb) const - { - container.clear(); - - AZ::u16 size; - rb.Read(size); - container.reserve(size); - - for (AZ::u16 i = 0; i < size; ++i) - { - AZ::ScriptProperty* readProperty = nullptr; - m_marshaler.UnmarshalToPointer(readProperty, rb); - container.insert(container.end(), readProperty); - } - } - - protected: - ScriptPropertyMarshaler m_marshaler; - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp deleted file mode 100644 index 45690eac01..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp +++ /dev/null @@ -1,1427 +0,0 @@ -/* -* 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. -* -*/ -#include - -#include -#include - -#include - -extern "C" { -# include -# include -} - -namespace AzFramework -{ - namespace Internal - { - static int NetBinding__IsAuthoritative(lua_State* lua) - { - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua,lua_upvalueindex(1))); - - //AZ_Assert(netBindingTable != nullptr && netBindingTable->GetScriptContext(),"Missing or misconfigured ScriptNetBindingTable as upvalue in lua_cclosure"); - if (netBindingTable && netBindingTable->GetScriptContext()) - { - lua_pushboolean(lua,netBindingTable->IsMaster()); - } - else - { - // If we don't have a net binding table, or a a script context, return true - // since we likely are the master. - lua_pushboolean(lua,true); - } - - return 1; - } - - static int NetBinding__IsMaster(lua_State* lua) - { - AZ_Warning("ScriptNetBindings", false, "IsMaster deprecated for the more lexical consistent IsAuthoritative"); - return NetBinding__IsAuthoritative(lua); - } - - static int NetBinding__CallRPC(lua_State* lua) - { - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua,lua_upvalueindex(1))); - - AZ_Error("ScriptComponent", netBindingTable != nullptr,"Missing ScriptNetBindingTable as upvalue in lua_cclosure"); - AZ_Error("ScriptComponent", netBindingTable == nullptr || netBindingTable->GetScriptContext(),"Missing ScriptNetBindingTable as upvalue in lua_cclosure"); - if (netBindingTable && netBindingTable->GetScriptContext()) - { - AZ::ScriptContext* context = netBindingTable->GetScriptContext(); - - AZ::ScriptDataContext stackContext; - bool validIndex = context->ReadStack(stackContext); - - if (validIndex) - { - netBindingTable->InvokeRPC(stackContext); - } - } - - return 0; - } - } - - ////////////////////////// - // ScriptPropertyDataSet - ////////////////////////// - - // Necessary since the field doesn't make a copy, but keeps the actual literal. - // But overall :( - - const char* ScriptPropertyDataSet::GetDataSetName() - { - static size_t s_chunkIndex = 0; - static const char* s_nameArray[] = { - "DataSet1","DataSet2","DataSet3","DataSet4","DataSet5", - "DataSet6","DataSet7","DataSet8","DataSet9","DataSet10", - "DataSet11","DataSet12","DataSet13","DataSet14","DataSet15", - "DataSet16","DataSet17","DataSet18","DataSet19","DataSet20", - "DataSet21","DataSet22","DataSet23","DataSet24","DataSet25", - "DataSet26","DataSet27","DataSet28","DataSet29","DataSet30", - "DataSet31","DataSet32" - }; - - if ((s_chunkIndex >= AZ_ARRAY_SIZE(s_nameArray)) && (AZ_ARRAY_SIZE(s_nameArray) >= 0)) - { - s_chunkIndex = s_chunkIndex % AZ_ARRAY_SIZE(s_nameArray); - } - - return s_nameArray[s_chunkIndex++]; - } - - ScriptPropertyDataSet::ScriptPropertyDataSet() - : ScriptPropertyDataSetType(GetDataSetName()) - , m_reserver(nullptr) - { - } - - ScriptPropertyDataSet::~ScriptPropertyDataSet() - { - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(Get()); - - if (functionalScriptProperty) - { - functionalScriptProperty->DisableInPlaceControls(); - functionalScriptProperty->RemoveWatcher(this); - } - } - - void ScriptPropertyDataSet::Reserve(ScriptNetBindingTable::NetworkedTableValue* reserver) - { - AZ_Error("ScriptComponent",m_reserver == nullptr || reserver == m_reserver, "Trying to reserve the same DataSet for two NetworkedTableVaules."); - - if (m_reserver == nullptr) - { - m_reserver = reserver; - AZ::ScriptPropertyWatcherBus::Handler::BusConnect(this); - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(Get()); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - } - } - - void ScriptPropertyDataSet::Release(ScriptNetBindingTable::NetworkedTableValue* reserver) - { - AZ_Error("ScriptComponent",m_reserver == nullptr || m_reserver == reserver, "Incorrect NetworkedTableValue trying to release a reserver DataSet."); - if (m_reserver == reserver) - { - m_reserver = nullptr; - AZ::ScriptPropertyWatcherBus::Handler::BusDisconnect(this); - } - } - - bool ScriptPropertyDataSet::IsReserved() const - { - return m_reserver != nullptr; - } - - bool ScriptPropertyDataSet::UpdateScriptProperty(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName) - { - bool wroteValue = false; - - Modify([&](AZ::ScriptProperty*& scriptProperty) - { - wroteValue = true; - if (scriptProperty == nullptr || !scriptProperty->TryRead(scriptDataContext,-1)) - { - AZ::ScriptProperty* newPropertyType = scriptDataContext.ConstructScriptProperty(-1,propertyName.c_str()); - - delete scriptProperty; - - if (newPropertyType == nullptr) - { - scriptProperty = aznew AZ::ScriptPropertyNil(); - } - else - { - scriptProperty = newPropertyType; - } - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(newPropertyType); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - } - - m_throttler.SignalDirty(); - - return wroteValue; - }); - - return wroteValue; - } - - void ScriptPropertyDataSet::SetScriptProperty(AZ::ScriptProperty* scriptProperty) - { - Modify([&](AZ::ScriptProperty*& dataSetProperty) - { - AZ::ScriptProperty* tempProperty = dataSetProperty; - - if (scriptProperty == nullptr) - { - if (tempProperty) - { - dataSetProperty = aznew AZ::ScriptPropertyNil(tempProperty->m_name.c_str()); - } - else - { - dataSetProperty = aznew AZ::ScriptPropertyNil(); - } - } - else - { - dataSetProperty = scriptProperty; - } - - if (tempProperty) - { - delete tempProperty; - } - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(dataSetProperty); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - - m_throttler.SignalDirty(); - - return true; - }); - } - - void ScriptPropertyDataSet::OnObjectModified() - { - m_throttler.SignalDirty(); - SetDirty(); - } - - //////////////////////// - // EntityScriptContext - //////////////////////// - - ScriptNetBindingTable::EntityScriptContext::EntityScriptContext() - : m_scriptContext(nullptr) - , m_entityTableRegistryIndex(LUA_REFNIL) - { - } - - void ScriptNetBindingTable::EntityScriptContext::Unload() - { - m_scriptContext = nullptr; - m_entityTableRegistryIndex = LUA_REFNIL; - } - - bool ScriptNetBindingTable::EntityScriptContext::HasEntityTableRegistryIndex() const - { - return m_entityTableRegistryIndex != LUA_REFNIL; - } - - int ScriptNetBindingTable::EntityScriptContext::GetEntityTableRegistryIndex() const - { - return m_entityTableRegistryIndex; - } - - bool ScriptNetBindingTable::EntityScriptContext::HasScriptContext() const - { - return m_scriptContext != nullptr; - } - - AZ::ScriptContext* ScriptNetBindingTable::EntityScriptContext::GetScriptContext() const - { - return m_scriptContext; - } - - void ScriptNetBindingTable::EntityScriptContext::ConfigureContext(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex) - { - m_scriptContext = scriptContext; - m_entityTableRegistryIndex = entityTableRegistryIndex; - - AZ_Error("ScriptComponent",SanityCheckContext(),"Invalid configuration given to ScriptNetBindingTable"); - } - - bool ScriptNetBindingTable::EntityScriptContext::SanityCheckContext() const - { - bool isSane = HasScriptContext(); - - if (isSane) - { - // We want to check if our reference is actually pointing to a table - // which we will assume is our entity table - lua_State* nativeContext = m_scriptContext->NativeContext(); - - lua_rawgeti(nativeContext,LUA_REGISTRYINDEX,m_entityTableRegistryIndex); - isSane = lua_istable(nativeContext,-1); - lua_pop(nativeContext,1); - } - - return isSane; - } - - //////////////////////// - // NetworkedTableValue - //////////////////////// - - ScriptNetBindingTable::NetworkedTableValue::NetworkedTableValue(AZ::ScriptProperty* initialValue) - : m_shimmedScriptProperty(initialValue) - , m_dataSet(nullptr) - , m_forcedDataSetIndex(-1) - , m_functionReference(LUA_REFNIL) - { - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(initialValue); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - } - } - - ScriptNetBindingTable::NetworkedTableValue::~NetworkedTableValue() - { - // Always want to release our dataset if we have one when we are destroyed. - // - // We do not want to delete our proeprty thought, since we might have been copied over. - if (m_dataSet) - { - m_dataSet->Release(this); - } - } - - void ScriptNetBindingTable::NetworkedTableValue::Destroy() - { - if (m_shimmedScriptProperty) - { - delete m_shimmedScriptProperty; - m_shimmedScriptProperty = nullptr; - } - - if (m_dataSet) - { - m_dataSet->Release(this); - } - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasDataSet() const - { - return m_dataSet != nullptr; - } - - void ScriptNetBindingTable::NetworkedTableValue::RegisterDataSet(ScriptPropertyDataSet* dataSet) - { - m_dataSet = dataSet; - - if (m_dataSet) - { - if (m_shimmedScriptProperty) - { - m_dataSet->SetScriptProperty(m_shimmedScriptProperty); - m_shimmedScriptProperty = nullptr; - } - - m_dataSet->Reserve(this); - } - } - - void ScriptNetBindingTable::NetworkedTableValue::UnbindFromDataSet() - { - if (m_dataSet) - { - // Take ownership of the DataSet script property into our shimmed value - // - // If we are the master, we can take ownership and set the data set value to null - if (m_dataSet->CanSet()) - { - m_shimmedScriptProperty = m_dataSet->Get(); - m_dataSet->Set(nullptr); - } - // Otherwise, we need to clone the data in the data set since we can't modify it and we need to avoid a double deletion. - else - { - AZ::ScriptProperty* scriptProperty = m_dataSet->Get(); - m_shimmedScriptProperty = scriptProperty->Clone(); - } - - m_dataSet->Release(this); - m_dataSet = nullptr; - } - } - - ScriptPropertyDataSet* ScriptNetBindingTable::NetworkedTableValue::GetDataSet() const - { - return m_dataSet; - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasForcedDataSetIndex() const - { - return m_forcedDataSetIndex >= 1; - } - - void ScriptNetBindingTable::NetworkedTableValue::SetForcedDataSetIndex(int index) - { - m_forcedDataSetIndex = index; - } - - int ScriptNetBindingTable::NetworkedTableValue::GetForcedDataSetIndex() const - { - return m_forcedDataSetIndex; - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasCallback() const - { - return m_functionReference != LUA_REFNIL; - } - - void ScriptNetBindingTable::NetworkedTableValue::RegisterCallback(int functionReference) - { - AZ_Warning("ScriptComponent",!HasCallback() || functionReference == LUA_REFNIL,"Overriding an already registered callback for a DataSet."); - - m_functionReference = functionReference; - } - - void ScriptNetBindingTable::NetworkedTableValue::ReleaseCallback(AZ::ScriptContext& scriptContext) - { - if (HasCallback()) - { - scriptContext.ReleaseCached(m_functionReference); - m_functionReference = LUA_REFNIL; - } - } - - void ScriptNetBindingTable::NetworkedTableValue::InvokeCallback(EntityScriptContext& entityContext, const GridMate::TimeContext& timeContext) - { - (void)timeContext; - - AZ::ScriptContext* scriptContext = entityContext.GetScriptContext(); - - AZ_Warning("ScriptComponent",scriptContext,"DataSetCallback given null ScriptContext."); - AZ_Warning("ScriptComponent",entityContext.HasEntityTableRegistryIndex(),"DataSetCallback given invalid entity table reference"); - if (scriptContext && entityContext.HasEntityTableRegistryIndex()) - { - AZ::ScriptDataContext callContext; - - if (scriptContext->CallCached(m_functionReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityContext.GetEntityTableRegistryIndex()); - callContext.CallExecute(); - } - } - } - - bool ScriptNetBindingTable::NetworkedTableValue::AssignValue(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName) - { - bool assignedValue = false; - if (HasDataSet()) - { - assignedValue = GetDataSet()->UpdateScriptProperty(scriptDataContext, propertyName); - } - else - { - if (m_shimmedScriptProperty == nullptr || !m_shimmedScriptProperty->TryRead(scriptDataContext,-1)) - { - delete m_shimmedScriptProperty; - m_shimmedScriptProperty = nullptr; - m_shimmedScriptProperty = scriptDataContext.ConstructScriptProperty(-1,propertyName.c_str()); - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(m_shimmedScriptProperty); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - } - } - - assignedValue = (m_shimmedScriptProperty != nullptr); - } - - return assignedValue; - } - - bool ScriptNetBindingTable::NetworkedTableValue::InspectValue(AZ::ScriptContext* scriptContext) const - { - AZ::ScriptProperty* inspectedProperty = m_shimmedScriptProperty; - - if (HasDataSet()) - { - inspectedProperty = GetDataSet()->Get(); - } - - bool inspectedValue = false; - - if (inspectedProperty) - { - inspectedValue = inspectedProperty->Write((*scriptContext)); - } - - if (!inspectedValue) - { - inspectedValue = true; - - AZ::ScriptPropertyNil nilProperty; - nilProperty.Write((*scriptContext)); - } - - return inspectedValue; - } - - ////////////// - // RPCHelper - ////////////// - - // Maybe make this guy create the table himself? - // Encapsulate the whole binding process in here. - ScriptNetBindingTable::RPCBindingHelper::RPCBindingHelper() - : m_masterReference(LUA_REFNIL) - , m_proxyReference(LUA_REFNIL) - { - } - - ScriptNetBindingTable::RPCBindingHelper::~RPCBindingHelper() - { - } - - void ScriptNetBindingTable::RPCBindingHelper::ReleaseTableIndex(AZ::ScriptContext& scriptContext) - { - if (m_masterReference != LUA_REFNIL) - { - scriptContext.ReleaseCached(m_masterReference); - m_masterReference = LUA_REFNIL; - } - - if (m_proxyReference != LUA_REFNIL) - { - scriptContext.ReleaseCached(m_proxyReference); - m_proxyReference = LUA_REFNIL; - } - } - - bool ScriptNetBindingTable::RPCBindingHelper::IsValid() const - { - // Proxy is optional, so we only care about having the master index. - return m_masterReference != LUA_REFNIL; - } - - void ScriptNetBindingTable::RPCBindingHelper::SetMasterFunction(int masterReference) - { - AZ_Error("ScriptComponent",m_masterReference == LUA_REFNIL || masterReference == LUA_REFNIL, "Trying to rebind RPC master callback"); - - if (m_masterReference == LUA_REFNIL || masterReference == LUA_REFNIL) - { - m_masterReference = masterReference; - } - } - - bool ScriptNetBindingTable::RPCBindingHelper::InvokeMaster(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params) - { - if (!entityScriptContext.HasScriptContext()) - { - AZ_Error("ScriptComponent",false,"Invoking RPC with invalid ScriptContext"); - return false; - } - - bool allowRPC = false; - - if (m_masterReference != LUA_REFNIL) - { - AZ::ScriptDataContext callContext; - AZ::ScriptContext* scriptContext = entityScriptContext.GetScriptContext(); - - if (scriptContext->CallCached(m_masterReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityScriptContext.GetEntityTableRegistryIndex()); - - for (AZ::ScriptProperty* property : params) - { - callContext.PushArgScriptProperty(property); - } - - if (callContext.CallExecute()) - { - bool hasResult = false; - if (callContext.GetNumResults() == 1) - { - hasResult = callContext.ReadResult(0,allowRPC); - } - - AZ_Assert(hasResult,"Master RPC function needs to return a boolean value"); - (void)hasResult; - } - } - - } - - return allowRPC; - } - - void ScriptNetBindingTable::RPCBindingHelper::SetProxyFunction(int proxyReference) - { - AZ_Error("ScriptComponent",m_proxyReference == LUA_REFNIL || proxyReference == LUA_REFNIL,"Trying to rebind an RPC Proxy call."); - - if (m_proxyReference == LUA_REFNIL || proxyReference == LUA_REFNIL) - { - m_proxyReference = proxyReference; - } - } - - void ScriptNetBindingTable::RPCBindingHelper::InvokeProxy(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params) - { - if (!entityScriptContext.HasScriptContext()) - { - AZ_Error("ScriptComponent",false,"Trying to call a callback without a script context."); - return; - } - - AZ_Warning("ScriptComponent",m_proxyReference != LUA_REFNIL,"Trying to invoke an RPC on the proxy without a callback being set."); - if (m_proxyReference != LUA_REFNIL) - { - AZ::ScriptDataContext callContext; - AZ::ScriptContext* scriptContext = entityScriptContext.GetScriptContext(); - - if (scriptContext->CallCached(m_proxyReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityScriptContext.GetEntityTableRegistryIndex()); - - for (AZ::ScriptProperty* property : params) - { - callContext.PushArgScriptProperty(property); - } - - callContext.CallExecute(); - } - } - } - - ////////////////////////// - // ScriptNetBindingTable - ////////////////////////// - void ScriptNetBindingTable::Reflect(AZ::ReflectContext* reflection) - { - NetworkContext* netContext = azrtti_cast(reflection); - - if (netContext) - { - // Using old method until we update the network context to allow for array offests. - // Or find a better way to handle the script replica chunk - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(ScriptComponentReplicaChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } - - // Template specialization for the ConvertPropertyArrayToTable GenericClass support to deal with extra memory copies. - template<> - AZ::ScriptPropertyTable* ScriptNetBindingTable::ConvertPropertyArrayToTable(AZ::ScriptPropertyGenericClassArray* arrayProperty) - { - AZ::ScriptPropertyTable* scriptPropertyTable = aznew AZ::ScriptPropertyTable(arrayProperty->m_name.c_str()); - - AZ::ScriptPropertyGenericClass emptyGenericClass; - - for (unsigned int i=0; i < arrayProperty->m_values.size(); ++i) - { - // Offset by 1 to deal with lua 1 indexing. - // Table will make a clone of our object. - // - // To avoid pointlessly double copying the data. Insert the empty class. - scriptPropertyTable->SetTableValue(i+1, &emptyGenericClass); - - // Then do a find for the class back, to load up the data into the final object directly. - AZ::ScriptPropertyGenericClass* ownedClass = static_cast(scriptPropertyTable->FindTableValue(i+1)); - - const AZ::DynamicSerializableField& serializableField = arrayProperty->m_values[i]; - - ownedClass->Set(serializableField); - } - - return scriptPropertyTable; - } - - ScriptNetBindingTable::ScriptNetBindingTable() - { - } - - ScriptNetBindingTable::~ScriptNetBindingTable() - { - - } - - void ScriptNetBindingTable::Unload() - { - // Unbind our elements from our script context. - if (m_entityScriptContext.HasScriptContext()) - { - AZ::ScriptContext& scriptContext = (*m_entityScriptContext.GetScriptContext()); - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - NetworkedTableValue& tableValue = tablePair.second; - tableValue.ReleaseCallback(scriptContext); - } - - for (RPCHelperMap::value_type& rpcPair : m_rpcHelperMap) - { - RPCBindingHelper& bindingHelper = rpcPair.second; - bindingHelper.ReleaseTableIndex(scriptContext); - } - } - - // Destroy the table values, since they might contain some memory - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - tablePair.second.Destroy(); - } - - m_networkedTable.clear(); - m_rpcHelperMap.clear(); - - m_entityScriptContext.Unload(); - } - - void ScriptNetBindingTable::CreateNetworkBindingTable(AZ::ScriptContext* scriptContext, int baseTableIndex, int entityTableIndex) - { - (void)baseTableIndex; - - lua_State* nativeContext = scriptContext->NativeContext(); - - lua_pushliteral(nativeContext,"IsMaster"); - lua_pushlightuserdata(nativeContext,this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__IsMaster,1); - lua_rawset(nativeContext,entityTableIndex); - - lua_pushliteral(nativeContext,"IsAuthoritative"); - lua_pushlightuserdata(nativeContext,this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__IsAuthoritative,1); - lua_rawset(nativeContext,entityTableIndex); - - lua_pushstring(nativeContext,ScriptComponent::NetRPCFieldName); - lua_createtable(nativeContext,0,0); - - int rpcTableIndex = lua_gettop(nativeContext); - - // Read the stack - AZ::ScriptDataContext stackContext; - if (scriptContext->ReadStack(stackContext)) - { - // Inspect the element we know to be our table context - AZ::ScriptDataContext entityDataContext; - if (stackContext.IsTable(baseTableIndex) && stackContext.InspectTable(baseTableIndex,entityDataContext)) - { - // Find our RPC table inside of baseTableIndex - int tableIndex = 0; - if (entityDataContext.PushTableElement(ScriptComponent::NetRPCFieldName,&tableIndex)) - { - // If it's a table, we want to inspect it. - AZ::ScriptDataContext rpcTable; - if (entityDataContext.IsTable(tableIndex) && entityDataContext.InspectTable(tableIndex,rpcTable)) - { - // Iterate over the fields here, and register and RPC for each element inside of that table. - int fieldIndex; - int elementIndex; - const char* fieldName; - - while (rpcTable.InspectNextElement(elementIndex, fieldName, fieldIndex)) - { - if (fieldName != nullptr) - { - RegisterRPC(rpcTable,fieldName,elementIndex,rpcTableIndex); - } - } - } - } - } - } - - lua_rawset(nativeContext,entityTableIndex); - } - - void ScriptNetBindingTable::FinalizeNetworkTable(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex) - { - m_entityScriptContext.ConfigureContext(scriptContext, entityTableRegistryIndex); - - if (m_replicaChunk) - { - AssignDataSets(); - } - } - - AZ::ScriptContext* ScriptNetBindingTable::GetScriptContext() const - { - return m_entityScriptContext.GetScriptContext(); - } - - bool ScriptNetBindingTable::IsMaster() const - { - return (m_replicaChunk != nullptr) ? m_replicaChunk->IsMaster() : true; - } - - bool ScriptNetBindingTable::AssignTableValue(AZ::ScriptDataContext& stackDataContext) - { - bool wroteValue = false; - AZ_Error("ScriptComponent",stackDataContext.GetScriptContext() == m_entityScriptContext.GetScriptContext(),"Trying to use a ScriptNetBindings in the wrong context."); - - // We do not want to allow assignments on proxy replicas - // since that information will be discarded anyway. - if ((m_replicaChunk && !m_replicaChunk->IsMaster()) || (stackDataContext.GetScriptContext() != m_entityScriptContext.GetScriptContext())) - { - return false; - } - - AZStd::string key; - - if (stackDataContext.ReadValue(-2,key)) - { - NetworkedTableValue* networkedTableValue = FindTableValue(key); - - // If we don't have the value, it means we aren't trying to network it. - if (networkedTableValue) - { - if (m_replicaChunk && !networkedTableValue->HasDataSet()) - { - ScriptComponentReplicaChunk* scriptChunk = static_cast(m_replicaChunk.get()); - - scriptChunk->AssignDataSet((*networkedTableValue)); - } - - wroteValue = networkedTableValue->AssignValue(stackDataContext,key); - } - } - - return wroteValue; - } - - bool ScriptNetBindingTable::InspectTableValue(AZ::ScriptDataContext& stackContext) const - { - bool readValue = false; - AZStd::string key; - - if (stackContext.ReadValue(-1,key)) - { - AZ::ScriptContext* scriptContext = stackContext.GetScriptContext(); - - if (scriptContext) - { - const NetworkedTableValue* networkTableValue = FindTableValue(key); - - if (networkTableValue) - { - readValue = networkTableValue->InspectValue((stackContext.GetScriptContext())); - - // Default to nil if we have a network table value registered, but couldn't - // inspect it for some reason. - if (!readValue) - { - readValue = true; - static AZ::ScriptPropertyNil s_nilValue; - s_nilValue.Write((*scriptContext)); - } - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to read value into invalid ScriptContext"); - } - } - - return readValue; - } - - bool ScriptNetBindingTable::RegisterDataSet(AZ::ScriptDataContext& networkTableContext, AZ::ScriptProperty* scriptProperty) - { - if (scriptProperty == nullptr) - { - AZ_Error("ScriptComponent",false,"Trying to Create a dataset for a null script property."); - return false; - } - - AZ::Uuid typeId = azrtti_typeid(scriptProperty); - - if ( typeId == azrtti_typeid() - || typeId == azrtti_typeid()) - { - AZ_Error("ScriptComponent",false,"Using unsupported type for ScriptProperty(%s) net binding. Value will not be networked.", scriptProperty->m_name.c_str()); - return false; - } - - // If we've already got an item inside of our network table. - // We need to surpress that problem, since it may happen when we reload the script - if (m_networkedTable.find(scriptProperty->m_name) != m_networkedTable.end()) - { - return true; - } - - int elementIndex; - bool enabled = false; - bool handledProperty = false; - - if (networkTableContext.PushTableElement("Enabled",&elementIndex)) - { - // If we have the enabled field and it's not a boolean. - // Assume false. - if (networkTableContext.IsBoolean(elementIndex)) - { - // If we didn't read in the enabled value, assume it's false. - if (!networkTableContext.ReadValue(elementIndex,enabled)) - { - enabled = false; - } - } - } - else - { - // If we don't have an enabled field, assume that we want to be bound. - enabled = true; - } - - if (enabled) - { - NetworkedTableValue networkedTableValue; - - // Convert the property arrays over to a table to simplify the logic flow of detecting - // the various changes, and to more readily support what the general LUA syntax. - if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyBooleanArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyNumberArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyStringArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyGenericClassArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else - { - networkedTableValue = NetworkedTableValue(scriptProperty->Clone()); - } - - if (networkTableContext.PushTableElement("OnNewValue", &elementIndex)) - { - if (networkTableContext.IsFunction(elementIndex)) - { - networkedTableValue.RegisterCallback( networkTableContext.CacheValue(elementIndex) ); - } - } - - if (networkTableContext.PushTableElement("ForceIndex",&elementIndex)) - { - if (networkTableContext.IsNumber(elementIndex)) - { - int forcedDataSetIndex = 0; - if (networkTableContext.ReadValue(elementIndex,forcedDataSetIndex)) - { - AZ_Error("ScriptComponent",forcedDataSetIndex >= 1 && forcedDataSetIndex <= ScriptComponentReplicaChunk::k_maxScriptableDataSets,"Trying to force Property (%s) to an invalid DataSetIndex(%i).",scriptProperty->m_name.c_str(),forcedDataSetIndex); - if(forcedDataSetIndex >= 1 && forcedDataSetIndex <= ScriptComponentReplicaChunk::k_maxScriptableDataSets) - { - networkedTableValue.SetForcedDataSetIndex(forcedDataSetIndex); - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to force Property (%s) to unknown DataSetIndex. Ignoring field.", scriptProperty->m_name.c_str()); - } - } - } - - AZStd::pair insertResult = m_networkedTable.insert(NetworkedTableMap::value_type(scriptProperty->m_name,networkedTableValue)); - - // If we failed to insert the object, we need to destroy the networked table value. - // To avoid leaking memory - if (!insertResult.second) - { - networkedTableValue.Destroy(); - } - - handledProperty = true; - } - - return handledProperty; - } - - bool ScriptNetBindingTable::InvokeRPC(AZ::ScriptDataContext& stackContext) - { - lua_State* nativeContext = stackContext.GetScriptContext()->NativeContext(); - - bool invokedRPC = false; - AZStd::string rpcName; - - // Assuming this is coming from an __call metamethod - // the lua stack will look as follows - // 1 - Table - // n - Params - if (stackContext.IsTable(1)) - { - // Get the RPC name - lua_pushliteral(nativeContext,"_rpcName"); - lua_gettable(nativeContext,1); - - if (stackContext.IsString(-1)) - { - if (stackContext.ReadValue(-1,rpcName)) - { - // Pop off the key value we just read in; It's no longer necessary - lua_pop(nativeContext,1); - - RPCHelperMap::iterator rpcIter = m_rpcHelperMap.find(rpcName); - - if (rpcIter != m_rpcHelperMap.end()) - { - bool foundParams = true; - - ScriptRPCMarshaler::Container paramContainer; - - // Need to start at 2, since 1 is our table. - for (int i=2; i <= lua_gettop(nativeContext); ++i) - { - AZ::ScriptProperty* property = stackContext.ConstructScriptProperty(i,"param"); - - if (property) - { - paramContainer.push_back(property); - } - else - { - foundParams = false; - break; - } - } - - // The script marshaler will clean up the keys after it has marshalled them out. - if (foundParams) - { - invokedRPC = true; - - if (m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptReplicaChunk = static_cast(m_replicaChunk.get()); - scriptReplicaChunk->m_scriptRPC(rpcName,paramContainer); - } - else - { - rpcIter->second.InvokeMaster(m_entityScriptContext,paramContainer); - } - } - else - { - for (AZ::ScriptProperty* property : paramContainer) - { - delete property; - } - - paramContainer.clear(); - } - } - } - else - { - // We failed to read, so we need to pop the value we pushed off the stack. - lua_pop(nativeContext,1); - } - } - else - { - // Pop off the value we added to the top of the stack - lua_pop(nativeContext,1); - } - } - - return invokedRPC; - } - - void ScriptNetBindingTable::RegisterRPC(AZ::ScriptDataContext& rpcTableContext, const AZStd::string& rpc, int elementIndex, int tableStackIndex) - { - if (rpcTableContext.IsTable(elementIndex)) - { - RPCBindingHelper helper; - - AZ::ScriptDataContext rpcContext; - if (rpcTableContext.InspectTable(elementIndex,rpcContext)) - { - int functionIndex = 0; - if (rpcContext.PushTableElement("OnMaster",&functionIndex)) - { - helper.SetMasterFunction(rpcContext.CacheValue(functionIndex)); - } - else - { - AZ_Error("ScriptNetBinding", false, "Could not find OnMaster function for RPC (%s).", rpc.c_str()); - } - - if (rpcContext.PushTableElement("OnProxy",&functionIndex)) - { - helper.SetProxyFunction(rpcContext.CacheValue(functionIndex)); - } - } - else - { - AZ_Error("ScriptNetBinding", false, "Could inspect table for RPC (%s).", rpc.c_str()); - } - - if (helper.IsValid()) - { - lua_State* nativeContext = rpcTableContext.GetScriptContext()->NativeContext(); - - // Create the RPC Table inside of our entity table to allow for functions to be called on it. - // - lua_pushlstring(nativeContext,rpc.c_str(),rpc.size()); - lua_createtable(nativeContext,0,1); - - // Set up a name field inside of the table - lua_pushliteral(nativeContext,"_rpcName"); - lua_pushlstring(nativeContext,rpc.c_str(),rpc.size()); - lua_rawset(nativeContext,-3); - - // - lua_createtable(nativeContext,0,1); - lua_pushliteral(nativeContext,"__call"); - lua_pushlightuserdata(nativeContext, this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__CallRPC,1); - lua_rawset(nativeContext,-3); - - lua_setmetatable(nativeContext,-2); - // - - lua_rawset(nativeContext,tableStackIndex); - // - - m_rpcHelperMap.insert(RPCHelperMap::value_type(rpc,helper)); - } - } - } - - GridMate::ReplicaChunkPtr ScriptNetBindingTable::GetNetworkBinding() - { - m_replicaChunk = GridMate::CreateReplicaChunk(); - m_replicaChunk->SetHandler(this); - - if (m_entityScriptContext.HasScriptContext()) - { - AssignDataSets(); - } - - return m_replicaChunk; - } - - void ScriptNetBindingTable::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - m_replicaChunk = chunk; - m_replicaChunk->SetHandler(this); - - if (m_entityScriptContext.HasScriptContext()) - { - AssignDataSets(); - } - } - - void ScriptNetBindingTable::UnbindFromNetwork() - { - if (m_replicaChunk) - { - m_replicaChunk->SetHandler(nullptr); - - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - tablePair.second.UnbindFromDataSet(); - } - - m_replicaChunk = nullptr; - } - } - - void ScriptNetBindingTable::OnPropertyUpdate(AZ::ScriptProperty*const& scriptProperty, const GridMate::TimeContext& tc) - { - AZ_Error("ScriptComponent",m_replicaChunk != nullptr,"DataSet callback method called without ReplicaChunk present."); - - if (scriptProperty && m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptReplicaChunk = static_cast(m_replicaChunk.get()); - - NetworkedTableValue* tableValue = FindTableValue(scriptProperty->m_name); - - if (tableValue) - { - if (!tableValue->HasDataSet()) - { - scriptReplicaChunk->AssignDataSetForProperty((*tableValue),scriptProperty); - AZ_Error("ScriptComponent",tableValue->HasDataSet(),"Unable to bind received ScriptProperty to DataSet."); - } - else - { - AZ_Error("ScriptComponent",scriptReplicaChunk->SanityCheckDataSet(scriptProperty,tableValue->GetDataSet()),"Mismatch between DataSet being chagned and mapping to dataset index."); - } - - if (tableValue->HasCallback()) - { - tableValue->InvokeCallback(m_entityScriptContext,tc); - } - } - else - { - AZ_Error("ScriptComponent",false,"Receiving update for unknown ScriptProperty."); - } - } - } - - bool ScriptNetBindingTable::OnInvokeRPC(AZStd::string functionName, AZStd::vector< AZ::ScriptProperty*> params, const GridMate::RpcContext& rpcContext) - { - (void)rpcContext; - - bool canProxyExecute = false; - AZ_Error("ScriptComponent",m_replicaChunk,"Receiving RPC callback with null ReplicaChunk."); - - RPCHelperMap::iterator rpcIter = m_rpcHelperMap.find(functionName); - - if (rpcIter != m_rpcHelperMap.end()) - { - RPCBindingHelper& rpcHelper = rpcIter->second; - - if (m_replicaChunk == nullptr || m_replicaChunk->IsMaster()) - { - canProxyExecute = rpcHelper.InvokeMaster(m_entityScriptContext,params); - } - else - { - // The canProxyExecute return value is meaningless on proxies. - rpcHelper.InvokeProxy(m_entityScriptContext,params); - } - } - - return canProxyExecute; - } - - const AZ::ScriptProperty* ScriptNetBindingTable::FindScriptProperty(const AZStd::string& name) const - { - const NetworkedTableValue* networkedTableValue = FindTableValue(name); - return networkedTableValue ? networkedTableValue->GetShimmedScriptProperty() : nullptr; - } - - void ScriptNetBindingTable::AssignDataSets() - { - if (m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptComponentChunk = static_cast(m_replicaChunk.get()); - - // Going to do this in two passes, first to do all of the forced ones, then all of the arbitrary ones. - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - if (tablePair.second.HasForcedDataSetIndex() && !tablePair.second.HasDataSet()) - { - if (!scriptComponentChunk->AssignDataSet(tablePair.second)) - { - // Remove the forced DataSet index since it was invalid. - // Second pass will assign this an arbitrary one. - tablePair.second.SetForcedDataSetIndex(-1); - } - } - } - - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - // Try to assign everything that doesn't already have a dataset. - if (!tablePair.second.HasDataSet()) - { - scriptComponentChunk->AssignDataSet(tablePair.second); - } - } - } - } - - ScriptNetBindingTable::NetworkedTableValue* ScriptNetBindingTable::FindTableValue(const AZStd::string& name) - { - NetworkedTableValue* retVal = nullptr; - NetworkedTableMap::iterator tableIter = m_networkedTable.find(name); - - if (tableIter != m_networkedTable.end()) - { - retVal = &(tableIter->second); - } - - return retVal; - } - - const ScriptNetBindingTable::NetworkedTableValue* ScriptNetBindingTable::FindTableValue(const AZStd::string& name) const - { - const NetworkedTableValue* retVal = nullptr; - NetworkedTableMap::const_iterator tableIter = m_networkedTable.find(name); - - if (tableIter != m_networkedTable.end()) - { - retVal = &(tableIter->second); - } - - return retVal; - } - - //////////////////////////////// - // ScriptComponentReplicaChunk - //////////////////////////////// - - ScriptComponentReplicaChunk::ScriptComponentReplicaChunk() - : m_scriptRPC("ScriptRPC") - , m_enabledDataSetMask(0) - { - } - - ScriptComponentReplicaChunk::~ScriptComponentReplicaChunk() - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - ScriptPropertyDataSet& dataSet = m_propertyDataSets[i]; - - dataSet.Modify([](AZ::ScriptProperty*& scriptProperty) - { - delete scriptProperty; - scriptProperty = nullptr; - return false; - }); - } - } - - bool ScriptComponentReplicaChunk::IsReplicaMigratable() - { - return true; - } - - AZ::u32 ScriptComponentReplicaChunk::CalculateDirtyDataSetMask(GridMate::MarshalContext& marshalContext) - { - if ((marshalContext.m_marshalFlags & GridMate::ReplicaMarshalFlags::ForceDirty)) - { - return m_enabledDataSetMask; - } - - return GridMate::ReplicaChunkBase::CalculateDirtyDataSetMask(marshalContext); - } - - bool ScriptComponentReplicaChunk::AssignDataSet(ScriptNetBindingTable::NetworkedTableValue& helper) - { - bool assigned = false; - - if (helper.HasForcedDataSetIndex()) - { - int testIndex = helper.GetForcedDataSetIndex() - 1; - - if (testIndex >= 0 && testIndex < k_maxScriptableDataSets) - { - ScriptPropertyDataSet* testDataSet = &m_propertyDataSets[testIndex]; - - if (!testDataSet->IsReserved()) - { - assigned = true; - helper.RegisterDataSet(testDataSet); - m_enabledDataSetMask |= (1 << testIndex); - } - else - { - AZ_Error("ScriptComponent",false,"Trying to register a networked value to a previously used DataSet."); - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to register a table value to an invalid DataSet index."); - } - } - else - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (!m_propertyDataSets[i].IsReserved()) - { - assigned = true; - helper.RegisterDataSet(&m_propertyDataSets[i]); - m_enabledDataSetMask |= (1 << i); - break; - } - } - - AZ_Error("ScriptComponent",assigned, "Trying to create more then %i datasets for a script",k_maxScriptableDataSets); - } - - return assigned; - } - - void ScriptComponentReplicaChunk::AssignDataSetForProperty(ScriptNetBindingTable::NetworkedTableValue& helper, AZ::ScriptProperty* targetProperty) - { - AZ_Error("ScriptComponent",!IsMaster(),"Binding table value to specified DataSet on Master(Master should be making that choice, not responding to a choice)."); - - if (!IsMaster()) - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (m_propertyDataSets[i].Get() == targetProperty) - { - helper.RegisterDataSet(&m_propertyDataSets[i]); - m_enabledDataSetMask |= (1 << i); - break; - } - } - } - } - - bool ScriptComponentReplicaChunk::SanityCheckDataSet(AZ::ScriptProperty* targetProperty, ScriptPropertyDataSet* assumedDataSet) - { - bool isSane = false; - - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (m_propertyDataSets[i].Get() == targetProperty) - { - isSane = &(m_propertyDataSets[i]) == assumedDataSet; - break; - } - } - - return isSane; - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h deleted file mode 100644 index eec28b71b0..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h +++ /dev/null @@ -1,320 +0,0 @@ -/* -* 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. -* -*/ -#ifndef AZFRAMEWORK_SCRIPT_NET_BINDINGS_H -#define AZFRAMEWORK_SCRIPT_NET_BINDINGS_H - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace AzFramework -{ - class ScriptPropertyDataSet; - class ScriptComponentReplicaChunk; - - // ScriptNetBindingTable will act as the go between for the ScriptComponent and the Replica's. - // It will also allow for holding of values in the case where you haven't been bound to a replica chunk yet and the - // script tries to interact with something that is networked. - // - // Allows for scripts to be re-used seamlessly in a offline vs online scenario(and support for going from offline to online), - // including RPCs(will alawys call the master version if offline) - class ScriptNetBindingTable - : public GridMate::ReplicaChunkInterface - { - private: - friend class ScriptComponentReplicaChunk; - friend class ScriptPropertyDataSet; - - // Helper struct to keep track of a a ScriptContext - // and the entityTableReference. Mainly used for - // calling in to functions in LUA where we want - // to push in the table reference as the first parameter - struct EntityScriptContext - { - public: - EntityScriptContext(); - - void Unload(); - - bool HasEntityTableRegistryIndex() const; - int GetEntityTableRegistryIndex() const; - - bool HasScriptContext() const; - AZ::ScriptContext* GetScriptContext() const; - - void ConfigureContext(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex); - - private: - - bool SanityCheckContext() const; - - AZ::ScriptContext* m_scriptContext; - int m_entityTableRegistryIndex; - }; - - class NetworkedTableValue; - friend NetworkedTableValue; - - typedef AZStd::unordered_map NetworkedTableMap; - - class RPCBindingHelper; - friend RPCBindingHelper; - - typedef AZStd::unordered_map RPCHelperMap; - - // Helper class that will wrap up our interactions with the actual stored value - // to hide the general use case of if we are connected to a replica or not. - // - // Additionally this will serve as a holding ground for a 'networked' - // value that doesn't have a dataset. - // - // Lastly holds onto the Callback references. - class NetworkedTableValue - { - public: - AZ_CLASS_ALLOCATOR(NetworkedTableValue, AZ::SystemAllocator, 0); - - NetworkedTableValue(AZ::ScriptProperty* initialValue = nullptr); - ~NetworkedTableValue(); - - void Destroy(); - - // Methods to register this value to a chunk - bool HasDataSet() const; - void RegisterDataSet(ScriptPropertyDataSet* dataSet); - void UnbindFromDataSet(); - ScriptPropertyDataSet* GetDataSet() const; - - // Information kept in order to force these values to use a particular dataset for debugging. - bool HasForcedDataSetIndex() const; - void SetForcedDataSetIndex(int index); - int GetForcedDataSetIndex() const; - - // Callback functions - bool HasCallback() const; - void RegisterCallback(int functionReference); - void ReleaseCallback(AZ::ScriptContext& scriptContext); - void InvokeCallback(EntityScriptContext& scriptContext, const GridMate::TimeContext& timeContext); - - bool AssignValue(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName); - bool InspectValue(AZ::ScriptContext* scriptContext) const; - - // Methods used for unit tests - const AZ::ScriptProperty* GetShimmedScriptProperty() const { return m_shimmedScriptProperty; } - private: - - // This value will be used if we have a networked property, but don't have a valid chunk yet. - // Works as a temporary store, which will be resolved once we get assigned to a DataSet - AZ::ScriptProperty* m_shimmedScriptProperty; - - // The data set we are bound to - ScriptPropertyDataSet* m_dataSet; - int m_forcedDataSetIndex; - - int m_functionReference; - }; - - // Future thoughts - // - Move the actual RPC meta table creation - // into this guy - class RPCBindingHelper - { - public: - AZ_CLASS_ALLOCATOR(RPCBindingHelper, AZ::SystemAllocator, 0); - - RPCBindingHelper(); - ~RPCBindingHelper(); - - void ReleaseTableIndex(AZ::ScriptContext& scriptContext); - - bool IsValid() const; - - void SetMasterFunction(int masterReference); - bool InvokeMaster(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params); - - void SetProxyFunction(int masterReference); - void InvokeProxy(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params); - - private: - int m_masterReference; - int m_proxyReference; - }; - - public: - AZ_CLASS_ALLOCATOR(ScriptNetBindingTable, AZ::SystemAllocator, 0); - static void Reflect(AZ::ReflectContext* reflect); - - ScriptNetBindingTable(); - ~ScriptNetBindingTable(); - - void Unload(); - - void CreateNetworkBindingTable(AZ::ScriptContext* scriptContext, int baseTableIndex, int entityTableIndex); - void FinalizeNetworkTable(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex); - - AZ::ScriptContext* GetScriptContext() const; - - bool IsMaster() const; - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // DataSet Functionality - // - // Called when the script wants to bind a function callback to when - // a value changes - // - // Might change this to just be register DataSet - bool RegisterDataSet(AZ::ScriptDataContext& stackContext, AZ::ScriptProperty* scriptProperty); - - // Called when the script wants to assign a value to the script value - bool AssignTableValue(AZ::ScriptDataContext& stackContext); - - // Called when the script wants to know the value of a script value. - bool InspectTableValue(AZ::ScriptDataContext& stackContext) const; - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - /// RPC Functionality - void RegisterRPC(AZ::ScriptDataContext& rpcTableContext, const AZStd::string& rpcName, int elementIndex, int tableStackIndex); - bool InvokeRPC(AZ::ScriptDataContext& stackContext); - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Netbinding Interface duplication here to be called from the ScriptComponent - GridMate::ReplicaChunkPtr GetNetworkBinding(); - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk); - void UnbindFromNetwork(); - - void OnPropertyUpdate(AZ::ScriptProperty*const& scriptProperty, const GridMate::TimeContext& tc); - bool OnInvokeRPC(AZStd::string functionName, AZStd::vector< AZ::ScriptProperty*> properties, const GridMate::RpcContext& rpcContext); - - // Methods used for unit tests - const AZ::ScriptProperty* FindScriptProperty(const AZStd::string& name) const; - - - private: - - void RegisterMetaTableCache(); - - template - AZ::ScriptPropertyTable* ConvertPropertyArrayToTable(PropertyArrayType* arrayProperty) - { - AZ::ScriptPropertyTable* scriptPropertyTable = aznew AZ::ScriptPropertyTable(arrayProperty->m_name.c_str()); - - PropertyType propertyType; - - for (unsigned int i=0; i < arrayProperty->m_values.size(); ++i) - { - propertyType.m_value = arrayProperty->m_values[i]; - - // Offset by 1 to deal with lua 1 indexing. - // Table will make a clone of our object. - scriptPropertyTable->SetTableValue(i+1, &propertyType); - } - - return scriptPropertyTable; - } - - void AssignDataSets(); - - NetworkedTableValue* FindTableValue(const AZStd::string& name); - const NetworkedTableValue* FindTableValue(const AZStd::string& name) const; - - EntityScriptContext m_entityScriptContext; - - GridMate::ReplicaChunkPtr m_replicaChunk; - - NetworkedTableMap m_networkedTable; - RPCHelperMap m_rpcHelperMap; - }; - - // Typedeffing out the RPC and DataSet definitions. - typedef GridMate::Rpc< GridMate::RpcArg< AZStd::string >, GridMate::RpcArg< ScriptRPCMarshaler::Container, ScriptRPCMarshaler > >::BindInterface ScriptPropertyRPC; - typedef GridMate::DataSet::BindInterface ScriptPropertyDataSetType; - - class ScriptComponentReplicaChunk; - - // Specialized DataSet used by the ScriptProperties, just to add some wrapped around functionality - // and to allow me to manipulate the DataSet throttler in order to properly manage a dirty flag - class ScriptPropertyDataSet - : public ScriptPropertyDataSetType - , public AZ::ScriptPropertyWatcherBus::Handler - , public AZ::ScriptPropertyWatcher - { - private: - friend class ScriptComponentReplicaChunk; - friend class ScriptNetBindingTable::NetworkedTableValue; - - const char* GetDataSetName(); - - public: - ScriptPropertyDataSet(); - ~ScriptPropertyDataSet(); - bool IsReserved() const; - - bool UpdateScriptProperty(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName); - void SetScriptProperty(AZ::ScriptProperty* scriptProperty); - - void OnObjectModified() override; - - private: - void Reserve(ScriptNetBindingTable::NetworkedTableValue* reserver); - void Release(ScriptNetBindingTable::NetworkedTableValue* reserver); - - ScriptNetBindingTable::NetworkedTableValue* m_reserver; - }; - - // The actual ReplicaChunk that the script will use - class ScriptComponentReplicaChunk - : public GridMate::ReplicaChunkBase - { - public: - AZ_CLASS_ALLOCATOR(ScriptComponentReplicaChunk, AZ::SystemAllocator,0); - static const int k_maxScriptableDataSets = GM_MAX_DATASETS_IN_CHUNK; - - static const char* GetChunkName() { return "ScriptComponentReplicaChunk"; } - - // Might want to add some type of comment field into the various fields so this can be properly parsed - // and determined what we are actually sending. - ScriptComponentReplicaChunk(); - ~ScriptComponentReplicaChunk(); - - bool IsReplicaMigratable() override; - - AZ::u32 CalculateDirtyDataSetMask(GridMate::MarshalContext& marshalContext) override; - - // Called from the Master, will assign the table value to the DataSet specified by the helper. - bool AssignDataSet(ScriptNetBindingTable::NetworkedTableValue& helper); - - // Called from teh Proxy. Will Assign the TableValue to the DataSet that contains the target property - void AssignDataSetForProperty(ScriptNetBindingTable::NetworkedTableValue& helper, AZ::ScriptProperty* targetProperty); - - // Only called inside of an assert, checks that the DataSet that the targetProperty is in is the same as the assumedDataSet - // Used to confirm that we don't get a confusion between master/proxy about which ScriptProperty is assigned to which DataSet. - bool SanityCheckDataSet(AZ::ScriptProperty* targetProperty, ScriptPropertyDataSet* assumedDataSet); - - ScriptPropertyRPC m_scriptRPC; - - private: - AZ::u32 m_enabledDataSetMask; - ScriptPropertyDataSet m_propertyDataSets[k_maxScriptableDataSets]; - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h new file mode 100644 index 0000000000..a0731626ef --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h @@ -0,0 +1,92 @@ +/* + * 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. + * + */ + +#pragma once + +#include +#include + +namespace AzFramework +{ + //! SessionConnectionConfig + //! The properties for handling join session request. + struct SessionConnectionConfig + { + // A unique identifier for registered player in session. + AZStd::string m_playerSessionId; + + // The DNS identifier assigned to the instance that is running the session. + AZStd::string m_dnsName; + + // The IP address of the session. + AZStd::string m_ipAddress; + + // The port number for the session. + uint16_t m_port; + }; + + //! SessionConnectionConfig + //! The properties for handling player connect/disconnect + struct PlayerConnectionConfig + { + // A unique identifier for player connection. + uint32_t m_playerConnectionId; + + // A unique identifier for registered player in session. + AZStd::string m_playerSessionId; + }; + + //! ISessionHandlingClientRequests + //! The session handling events to invoke multiplayer component handle the work on client side + class ISessionHandlingClientRequests + { + public: + AZ_RTTI(ISessionHandlingClientRequests, "{41DE6BD3-72BC-4443-BFF9-5B1B9396657A}"); + ISessionHandlingClientRequests() = default; + virtual ~ISessionHandlingClientRequests() = default; + + // Request the player join session + // @param sessionConnectionConfig The required properties to handle the player join session process + // @return The result of player join session process + virtual bool RequestPlayerJoinSession(const SessionConnectionConfig& sessionConnectionConfig) = 0; + + // Request the connected player leave session + virtual void RequestPlayerLeaveSession() = 0; + }; + + //! ISessionHandlingServerRequests + //! The session handling events to invoke server provider handle the work on server side + class ISessionHandlingServerRequests + { + public: + AZ_RTTI(ISessionHandlingServerRequests, "{4F0C17BA-F470-4242-A8CB-EC7EA805257C}"); + ISessionHandlingServerRequests() = default; + virtual ~ISessionHandlingServerRequests() = default; + + // Handle the destroy session process + virtual void HandleDestroySession() = 0; + + // Validate the player join session process + // @param playerConnectionConfig The required properties to validate the player join session process + // @return The result of player join session validation + virtual bool ValidatePlayerJoinSession(const PlayerConnectionConfig& playerConnectionConfig) = 0; + + // Handle the player leave session process + // @param playerConnectionConfig The required properties to handle the player leave session process + virtual void HandlePlayerLeaveSession(const PlayerConnectionConfig& playerConnectionConfig) = 0; + + // Retrieves the file location of a pem-encoded TLS certificate + // @return If successful, returns the file location of TLS certificate file; if not successful, returns + // empty string. + virtual AZStd::string GetSessionCertificate() = 0; + }; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.cpp b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.cpp new file mode 100644 index 0000000000..4eb42ab815 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.cpp @@ -0,0 +1,130 @@ +/* + * 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. + * + */ + +#include +#include +#include +#include + +namespace AzFramework +{ + void CreateSessionRequest::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0) + ->Field("creatorId", &CreateSessionRequest::m_creatorId) + ->Field("sessionProperties", &CreateSessionRequest::m_sessionProperties) + ->Field("sessionName", &CreateSessionRequest::m_sessionName) + ->Field("maxPlayer", &CreateSessionRequest::m_maxPlayer) + ; + + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) + { + editContext->Class("CreateSessionRequest", "The container for CreateSession request parameters") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_creatorId, + "CreatorId", "A unique identifier for a player or entity creating the session") + ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionProperties, + "SessionProperties", "A collection of custom properties for a session") + ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionName, + "SessionName", "A descriptive label that is associated with a session") + ->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_maxPlayer, + "MaxPlayer", "The maximum number of players that can be connected simultaneously to the session") + ; + } + } + } + + void SearchSessionsRequest::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0) + ->Field("filterExpression", &SearchSessionsRequest::m_filterExpression) + ->Field("sortExpression", &SearchSessionsRequest::m_sortExpression) + ->Field("maxResult", &SearchSessionsRequest::m_maxResult) + ->Field("nextToken", &SearchSessionsRequest::m_nextToken) + ; + + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) + { + editContext->Class("SearchSessionsRequest", "The container for SearchSessions request parameters") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_filterExpression, + "FilterExpression", "String containing the search criteria for the session search") + ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_sortExpression, + "SortExpression", "Instructions on how to sort the search results") + ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_maxResult, + "MaxResult", "The maximum number of results to return") + ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_nextToken, + "NextToken", "A token that indicates the start of the next sequential page of results") + ; + } + } + } + + void SearchSessionsResponse::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0) + ->Field("sessionConfigs", &SearchSessionsResponse::m_sessionConfigs) + ->Field("nextToken", &SearchSessionsResponse::m_nextToken) + ; + + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) + { + editContext->Class("SearchSessionsResponse", "The container for SearchSession request results") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_sessionConfigs, + "SessionConfigs", "A collection of sessions that match the search criteria and sorted in specific order") + ->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_nextToken, + "NextToken", "A token that indicates the start of the next sequential page of results") + ; + } + } + } + + void JoinSessionRequest::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0) + ->Field("sessionId", &JoinSessionRequest::m_sessionId) + ->Field("playerId", &JoinSessionRequest::m_playerId) + ->Field("playerData", &JoinSessionRequest::m_playerData) + ; + + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) + { + editContext->Class("JoinSessionRequest", "The container for JoinSession request parameters") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_sessionId, + "SessionId", "A unique identifier for the session") + ->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerId, + "PlayerId", "A unique identifier for a player. Player IDs are developer-defined") + ->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerData, + "PlayerData", "Developer-defined information related to a player") + ; + } + } + } +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h new file mode 100644 index 0000000000..da65eb47f0 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionRequests.h @@ -0,0 +1,195 @@ +/* + * 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. + * + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace AzFramework +{ + struct SessionConfig; + + //! CreateSessionRequest + //! The container for CreateSession request parameters. + struct CreateSessionRequest + { + AZ_RTTI(CreateSessionRequest, "{E39C2A45-89C9-4CFB-B337-9734DC798930}"); + static void Reflect(AZ::ReflectContext* context); + + CreateSessionRequest() = default; + virtual ~CreateSessionRequest() = default; + + // A unique identifier for a player or entity creating the session. + AZStd::string m_creatorId; + + // A collection of custom properties for a session. + AZStd::unordered_map m_sessionProperties; + + // A descriptive label that is associated with a session. + AZStd::string m_sessionName; + + // The maximum number of players that can be connected simultaneously to the session. + uint64_t m_maxPlayer; + }; + + //! SearchSessionsRequest + //! The container for SearchSessions request parameters. + struct SearchSessionsRequest + { + AZ_RTTI(SearchSessionsRequest, "{B49207A8-8549-4ADB-B7D9-D7A4932F9B4B}"); + static void Reflect(AZ::ReflectContext* context); + + SearchSessionsRequest() = default; + virtual ~SearchSessionsRequest() = default; + + // String containing the search criteria for the session search. If no filter expression is included, the request returns results + // for all active sessions. + AZStd::string m_filterExpression; + + // Instructions on how to sort the search results. If no sort expression is included, the request returns results in random order. + AZStd::string m_sortExpression; + + // The maximum number of results to return. + uint8_t m_maxResult; + + // A token that indicates the start of the next sequential page of results. + AZStd::string m_nextToken; + }; + + //! SearchSessionsResponse + //! The container for SearchSession request results. + struct SearchSessionsResponse + { + AZ_RTTI(SearchSessionsResponse, "{F93DE7DC-D381-4E08-8A3B-0B08F7C38714}"); + static void Reflect(AZ::ReflectContext* context); + + SearchSessionsResponse() = default; + virtual ~SearchSessionsResponse() = default; + + // A collection of sessions that match the search criteria and sorted in specific order. + AZStd::vector m_sessionConfigs; + + // A token that indicates the start of the next sequential page of results. + AZStd::string m_nextToken; + }; + + //! JoinSessionRequest + //! The container for JoinSession request parameters. + struct JoinSessionRequest + { + AZ_RTTI(JoinSessionRequest, "{519769E8-3CDE-4385-A0D7-24DBB3685657}"); + static void Reflect(AZ::ReflectContext* context); + + JoinSessionRequest() = default; + virtual ~JoinSessionRequest() = default; + + // A unique identifier for the session. + AZStd::string m_sessionId; + + // A unique identifier for a player. Player IDs are developer-defined. + AZStd::string m_playerId; + + // Developer-defined information related to a player. + AZStd::string m_playerData; + }; + + //! ISessionRequests + //! Pure virtual session interface class to abstract the details of session handling from application code. + class ISessionRequests + { + public: + AZ_RTTI(ISessionRequests, "{D6C41A71-DD8D-47FE-8515-FAF90670AE2F}"); + + ISessionRequests() = default; + virtual ~ISessionRequests() = default; + + // Create a session for players to find and join. + // @param createSessionRequest The request of CreateSession operation + // @return The request id if session creation request succeeds; empty if it fails + virtual AZStd::string CreateSession(const CreateSessionRequest& createSessionRequest) = 0; + + // Retrieve all active sessions that match the given search criteria and sorted in specific order. + // @param searchSessionsRequest The request of SearchSessions operation + // @return The response of SearchSessions operation + virtual SearchSessionsResponse SearchSessions(const SearchSessionsRequest& searchSessionsRequest) const = 0; + + // Reserve an open player slot in a session, and perform connection from client to server. + // @param joinSessionRequest The request of JoinSession operation + // @return True if joining session succeeds; False otherwise + virtual bool JoinSession(const JoinSessionRequest& joinSessionRequest) = 0; + + // Disconnect player from session. + virtual void LeaveSession() = 0; + }; + + //! ISessionAsyncRequests + //! Async version of ISessionRequests + class ISessionAsyncRequests + { + public: + AZ_RTTI(ISessionAsyncRequests, "{471542AF-96B9-4930-82FE-242A4E68432D}"); + + ISessionAsyncRequests() = default; + virtual ~ISessionAsyncRequests() = default; + + // CreateSession Async + // @param createSessionRequest The request of CreateSession operation + virtual void CreateSessionAsync(const CreateSessionRequest& createSessionRequest) = 0; + + // SearchSessions Async + // @param searchSessionsRequest The request of SearchSessions operation + virtual void SearchSessionsAsync(const SearchSessionsRequest& searchSessionsRequest) const = 0; + + // JoinSession Async + // @param joinSessionRequest The request of JoinSession operation + virtual void JoinSessionAsync(const JoinSessionRequest& joinSessionRequest) = 0; + + // LeaveSession Async + virtual void LeaveSessionAsync() = 0; + }; + + //! SessionAsyncRequestNotifications + //! The notifications correspond to session async requests + class SessionAsyncRequestNotifications + : public AZ::EBusTraits + { + public: + // Safeguard handler for multi-threaded use case + using MutexType = AZStd::recursive_mutex; + + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + ////////////////////////////////////////////////////////////////////////// + + // OnCreateSessionAsyncComplete is fired once CreateSessionAsync completes + // @param createSessionResponse The request id if session creation request succeeds; empty if it fails + virtual void OnCreateSessionAsyncComplete(const AZStd::string& createSessionReponse) = 0; + + // OnSearchSessionsAsyncComplete is fired once SearchSessionsAsync completes + // @param searchSessionsResponse The response of SearchSessions call + virtual void OnSearchSessionsAsyncComplete(const SearchSessionsResponse& searchSessionsResponse) = 0; + + // OnJoinSessionAsyncComplete is fired once JoinSessionAsync completes + // @param joinSessionsResponse True if joining session succeeds; False otherwise + virtual void OnJoinSessionAsyncComplete(bool joinSessionsResponse) = 0; + + // OnLeaveSessionAsyncComplete is fired once LeaveSessionAsync completes + virtual void OnLeaveSessionAsyncComplete() = 0; + }; + using SessionAsyncRequestNotificationBus = AZ::EBus; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp new file mode 100644 index 0000000000..12c5163031 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.cpp @@ -0,0 +1,74 @@ +/* + * 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. + * + */ + +#include +#include +#include + +namespace AzFramework +{ + void SessionConfig::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(0) + ->Field("creationTime", &SessionConfig::m_creationTime) + ->Field("terminationTime", &SessionConfig::m_terminationTime) + ->Field("creatorId", &SessionConfig::m_creatorId) + ->Field("sessionProperties", &SessionConfig::m_sessionProperties) + ->Field("sessionId", &SessionConfig::m_sessionId) + ->Field("sessionName", &SessionConfig::m_sessionName) + ->Field("dnsName", &SessionConfig::m_dnsName) + ->Field("ipAddress", &SessionConfig::m_ipAddress) + ->Field("port", &SessionConfig::m_port) + ->Field("maxPlayer", &SessionConfig::m_maxPlayer) + ->Field("currentPlayer", &SessionConfig::m_currentPlayer) + ->Field("status", &SessionConfig::m_status) + ->Field("statusReason", &SessionConfig::m_statusReason) + ; + + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) + { + editContext->Class("SessionConfig", "Properties describing a session") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creationTime, + "CreationTime", "A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_terminationTime, + "TerminationTime", "A time stamp indicating when this data object was terminated. Same format as creation time.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creatorId, + "CreatorId", "A unique identifier for a player or entity creating the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionProperties, + "SessionProperties", "A collection of custom properties for a session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionId, + "SessionId", "A unique identifier for the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionName, + "SessionName", "A descriptive label that is associated with a session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_dnsName, + "DnsName", "The DNS identifier assigned to the instance that is running the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_ipAddress, + "IpAddress", "The IP address of the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_port, + "Port", "The port number for the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_maxPlayer, + "MaxPlayer", "The maximum number of players that can be connected simultaneously to the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_currentPlayer, + "CurrentPlayer", "Number of players currently in the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_status, + "Status", "Current status of the session.") + ->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_statusReason, + "StatusReason", "Provides additional information about session status."); + } + } + } +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h new file mode 100644 index 0000000000..22d1c9e875 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Session/SessionConfig.h @@ -0,0 +1,70 @@ +/* +* 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. +* +*/ + +#pragma once + +#include +#include +#include + +namespace AzFramework +{ + //! SessionConfig + //! Properties describing a session. + struct SessionConfig + { + AZ_RTTI(SessionConfig, "{992DD4BE-8BA5-4071-8818-B99FD2952086}"); + static void Reflect(AZ::ReflectContext* context); + + SessionConfig() = default; + virtual ~SessionConfig() = default; + + // A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds. + uint64_t m_creationTime; + + // A time stamp indicating when this data object was terminated. Same format as creation time. + uint64_t m_terminationTime; + + // A unique identifier for a player or entity creating the session. + AZStd::string m_creatorId; + + // A collection of custom properties for a session. + AZStd::unordered_map m_sessionProperties; + + // A unique identifier for the session. + AZStd::string m_sessionId; + + // A descriptive label that is associated with a session. + AZStd::string m_sessionName; + + // The DNS identifier assigned to the instance that is running the session. + AZStd::string m_dnsName; + + // The IP address of the session. + AZStd::string m_ipAddress; + + // The port number for the session. + uint16_t m_port; + + // The maximum number of players that can be connected simultaneously to the session. + uint64_t m_maxPlayer; + + // Number of players currently in the session. + uint64_t m_currentPlayer; + + // Current status of the session. + AZStd::string m_status; + + // Provides additional information about session status. + AZStd::string m_statusReason; + }; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h b/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h new file mode 100644 index 0000000000..c472fcb228 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Session/SessionNotifications.h @@ -0,0 +1,50 @@ +/* + * 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. + * + */ + +#pragma once + +#include + +namespace AzFramework +{ + struct SessionConfig; + + //! SessionNotifications + //! The session notifications to listen for performing required operations + class SessionNotifications + : public AZ::EBusTraits + { + public: + // Safeguard handler for multi-threaded use case + using MutexType = AZStd::recursive_mutex; + + ////////////////////////////////////////////////////////////////////////// + // EBusTraits overrides + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + ////////////////////////////////////////////////////////////////////////// + + // OnSessionHealthCheck is fired in health check process + // @return The result of all OnSessionHealthCheck + virtual bool OnSessionHealthCheck() = 0; + + // OnCreateSessionBegin is fired at the beginning of session creation + // @param sessionConfig The properties to describe a session + // @return The result of all OnCreateSessionBegin notifications + virtual bool OnCreateSessionBegin(const SessionConfig& sessionConfig) = 0; + + // OnDestroySessionBegin is fired at the beginning of session termination + // @return The result of all OnDestroySessionBegin notifications + virtual bool OnDestroySessionBegin() = 0; + }; + using SessionNotificationBus = AZ::EBus; +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.cpp index 7ab2d48814..46b3dfe87c 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.cpp @@ -21,22 +21,6 @@ namespace AzFramework { } - Spawnable::Spawnable(Spawnable&& other) - : m_entities(AZStd::move(other.m_entities)) - { - } - - - Spawnable& Spawnable::operator=(Spawnable&& other) - { - if (this != &other) - { - m_entities = AZStd::move(other.m_entities); - } - - return *this; - } - const Spawnable::EntityList& Spawnable::GetEntities() const { return m_entities; diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.h b/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.h index 5e507b3498..677f0326cf 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.h +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/Spawnable.h @@ -19,10 +19,13 @@ #include #include -namespace AzFramework +namespace AZ { class ReflectContext; +} +namespace AzFramework +{ class Spawnable final : public AZ::Data::AssetData { @@ -38,11 +41,11 @@ namespace AzFramework Spawnable() = default; explicit Spawnable(const AZ::Data::AssetId& id, AssetStatus status = AssetStatus::NotLoaded); Spawnable(const Spawnable& rhs) = delete; - Spawnable(Spawnable&& other); + Spawnable(Spawnable&& other) = delete; ~Spawnable() override = default; Spawnable& operator=(const Spawnable& rhs) = delete; - Spawnable& operator=(Spawnable&& other); + Spawnable& operator=(Spawnable&& other) = delete; const EntityList& GetEntities() const; EntityList& GetEntities(); diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.cpp index b3ba1568bd..da046ff172 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.cpp @@ -10,6 +10,7 @@ * */ +#include #include #include #include @@ -88,4 +89,10 @@ namespace AzFramework { extensions.push_back(Spawnable::FileExtension); } + + uint32_t SpawnableAssetHandler::BuildSubId(AZStd::string_view id) + { + AZ::Uuid subIdHash = AZ::Uuid::CreateData(id.data(), id.size()); + return azlossy_caster(subIdHash.GetHash()); + } } // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.h index deef314955..78268bf71a 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.h +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableAssetHandler.h @@ -47,6 +47,7 @@ namespace AzFramework const char* GetGroup() const override; const char* GetBrowserIcon() const override; void GetAssetTypeExtensions(AZStd::vector& extensions) override; + static uint32_t BuildSubId(AZStd::string_view id); protected: LoadResult LoadAssetData( diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesContainer.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesContainer.cpp index 673701cac4..808de74e71 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesContainer.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesContainer.cpp @@ -38,19 +38,20 @@ namespace AzFramework void SpawnableEntitiesContainer::SpawnAllEntities() { AZ_Assert(m_threadData, "Calling SpawnAllEntities on a Spawnable container that's not set."); - SpawnableEntitiesInterface::Get()->SpawnAllEntities(m_threadData->m_spawnedEntitiesTicket); + SpawnableEntitiesInterface::Get()->SpawnAllEntities(m_threadData->m_spawnedEntitiesTicket, SpawnablePriority_Default); } void SpawnableEntitiesContainer::SpawnEntities(AZStd::vector entityIndices) { AZ_Assert(m_threadData, "Calling SpawnEntities on a Spawnable container that's not set."); - SpawnableEntitiesInterface::Get()->SpawnEntities(m_threadData->m_spawnedEntitiesTicket, AZStd::move(entityIndices)); + SpawnableEntitiesInterface::Get()->SpawnEntities( + m_threadData->m_spawnedEntitiesTicket, SpawnablePriority_Default, AZStd::move(entityIndices)); } void SpawnableEntitiesContainer::DespawnAllEntities() { AZ_Assert(m_threadData, "Calling DespawnEntities on a Spawnable container that's not set."); - SpawnableEntitiesInterface::Get()->DespawnAllEntities(m_threadData->m_spawnedEntitiesTicket); + SpawnableEntitiesInterface::Get()->DespawnAllEntities(m_threadData->m_spawnedEntitiesTicket, SpawnablePriority_Default); } void SpawnableEntitiesContainer::Reset(AZ::Data::Asset spawnable) @@ -66,8 +67,10 @@ namespace AzFramework m_monitor.Disconnect(); m_monitor.m_threadData.reset(); - SpawnableEntitiesInterface::Get()->Barrier(m_threadData->m_spawnedEntitiesTicket, - [threadData = m_threadData](EntitySpawnTicket&) mutable + SpawnableEntitiesInterface::Get()->Barrier( + m_threadData->m_spawnedEntitiesTicket, + SpawnablePriority_Default, + [threadData = m_threadData](EntitySpawnTicket::Id) mutable { threadData.reset(); }); @@ -83,8 +86,10 @@ namespace AzFramework void SpawnableEntitiesContainer::Alert(AlertCallback callback) { AZ_Assert(m_threadData, "Calling DespawnEntities on a Spawnable container that's not set."); - SpawnableEntitiesInterface::Get()->Barrier(m_threadData->m_spawnedEntitiesTicket, - [generation = m_threadData->m_generation, callback = AZStd::move(callback)](EntitySpawnTicket&) + SpawnableEntitiesInterface::Get()->Barrier( + m_threadData->m_spawnedEntitiesTicket, + SpawnablePriority_Default, + [generation = m_threadData->m_generation, callback = AZStd::move(callback)](EntitySpawnTicket::Id) { callback(generation); }); @@ -110,6 +115,7 @@ namespace AzFramework AZ_Assert(m_threadData, "SpawnableEntitiesContainer is monitoring a spawnable, but doesn't have the associated data."); AZ_TracePrintf("Spawnables", "Reloading spawnable '%s'.\n", replacementAsset.GetHint().c_str()); - SpawnableEntitiesInterface::Get()->ReloadSpawnable(m_threadData->m_spawnedEntitiesTicket, AZStd::move(replacementAsset)); + SpawnableEntitiesInterface::Get()->ReloadSpawnable( + m_threadData->m_spawnedEntitiesTicket, SpawnablePriority_Default, AZStd::move(replacementAsset)); } } // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp index a528797f63..ad1bf032c8 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.cpp @@ -14,6 +14,10 @@ namespace AzFramework { + // + // SpawnableEntityContainerView + // + SpawnableEntityContainerView::SpawnableEntityContainerView(AZ::Entity** begin, size_t length) : m_begin(begin) , m_end(begin + length) @@ -52,6 +56,9 @@ namespace AzFramework } + // + // SpawnableConstEntityContainerView + // SpawnableConstEntityContainerView::SpawnableConstEntityContainerView(AZ::Entity** begin, size_t length) : m_begin(begin) @@ -91,6 +98,136 @@ namespace AzFramework } + // + // SpawnableIndexEntityPair + // + + SpawnableIndexEntityPair::SpawnableIndexEntityPair(AZ::Entity** entityIterator, size_t* indexIterator) + : m_entity(entityIterator) + , m_index(indexIterator) + { + } + + AZ::Entity* SpawnableIndexEntityPair::GetEntity() + { + return *m_entity; + } + + const AZ::Entity* SpawnableIndexEntityPair::GetEntity() const + { + return *m_entity; + } + + size_t SpawnableIndexEntityPair::GetIndex() const + { + return *m_index; + } + + // + // SpawnableIndexEntityIterator + // + + SpawnableIndexEntityIterator::SpawnableIndexEntityIterator(AZ::Entity** entityIterator, size_t* indexIterator) + : m_value(entityIterator, indexIterator) + { + } + + SpawnableIndexEntityIterator& SpawnableIndexEntityIterator::operator++() + { + ++m_value.m_entity; + ++m_value.m_index; + return *this; + } + + SpawnableIndexEntityIterator SpawnableIndexEntityIterator::operator++(int) + { + SpawnableIndexEntityIterator result = *this; + ++m_value.m_entity; + ++m_value.m_index; + return result; + } + + SpawnableIndexEntityIterator& SpawnableIndexEntityIterator::operator--() + { + --m_value.m_entity; + --m_value.m_index; + return *this; + } + + SpawnableIndexEntityIterator SpawnableIndexEntityIterator::operator--(int) + { + SpawnableIndexEntityIterator result = *this; + --m_value.m_entity; + --m_value.m_index; + return result; + } + + bool SpawnableIndexEntityIterator::operator==(const SpawnableIndexEntityIterator& rhs) + { + return m_value.m_entity == rhs.m_value.m_entity && m_value.m_index == rhs.m_value.m_index; + } + + bool SpawnableIndexEntityIterator::operator!=(const SpawnableIndexEntityIterator& rhs) + { + return m_value.m_entity != rhs.m_value.m_entity || m_value.m_index != rhs.m_value.m_index; + } + + SpawnableIndexEntityPair& SpawnableIndexEntityIterator::operator*() + { + return m_value; + } + + const SpawnableIndexEntityPair& SpawnableIndexEntityIterator::operator*() const + { + return m_value; + } + + SpawnableIndexEntityPair* SpawnableIndexEntityIterator::operator->() + { + return &m_value; + } + + const SpawnableIndexEntityPair* SpawnableIndexEntityIterator::operator->() const + { + return &m_value; + } + + + // + // SpawnableConstIndexEntityContainerView + // + + SpawnableConstIndexEntityContainerView::SpawnableConstIndexEntityContainerView( + AZ::Entity** beginEntity, size_t* beginIndices, size_t length) + : m_begin(beginEntity, beginIndices) + , m_end(beginEntity + length, beginIndices + length) + { + } + + const SpawnableIndexEntityIterator& SpawnableConstIndexEntityContainerView::begin() + { + return m_begin; + } + + const SpawnableIndexEntityIterator& SpawnableConstIndexEntityContainerView::end() + { + return m_end; + } + + const SpawnableIndexEntityIterator& SpawnableConstIndexEntityContainerView::cbegin() + { + return m_begin; + } + + const SpawnableIndexEntityIterator& SpawnableConstIndexEntityContainerView::cend() + { + return m_end; + } + + + // + // EntitySpawnTicket + // EntitySpawnTicket::EntitySpawnTicket(EntitySpawnTicket&& rhs) : m_payload(rhs.m_payload) @@ -102,7 +239,9 @@ namespace AzFramework { auto manager = SpawnableEntitiesInterface::Get(); AZ_Assert(manager, "Attempting to create an entity spawn ticket while the SpawnableEntitiesInterface has no implementation."); - m_payload = manager->CreateTicket(AZStd::move(spawnable)); + AZStd::pair result = manager->CreateTicket(AZStd::move(spawnable)); + m_id = result.first; + m_payload = result.second; } EntitySpawnTicket::~EntitySpawnTicket() @@ -113,6 +252,7 @@ namespace AzFramework AZ_Assert(manager, "Attempting to destroy an entity spawn ticket while the SpawnableEntitiesInterface has no implementation."); manager->DestroyTicket(m_payload); m_payload = nullptr; + m_id = 0; } } @@ -126,12 +266,20 @@ namespace AzFramework AZ_Assert(manager, "Attempting to destroy an entity spawn ticket while the SpawnableEntitiesInterface has no implementation."); manager->DestroyTicket(m_payload); } + m_id = rhs.m_id; + rhs.m_id = 0; + m_payload = rhs.m_payload; rhs.m_payload = nullptr; } return *this; } + auto EntitySpawnTicket::GetId() const -> Id + { + return m_id; + } + bool EntitySpawnTicket::IsValid() const { return m_payload != nullptr; diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h index 95d0b9e3a7..27f45064b6 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesInterface.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -24,6 +25,14 @@ namespace AZ namespace AzFramework { + AZ_TYPE_SAFE_INTEGRAL(SpawnablePriority, uint8_t); + + inline static constexpr SpawnablePriority SpawnablePriority_Highest { 0 }; + inline static constexpr SpawnablePriority SpawnablePriority_High { 32 }; + inline static constexpr SpawnablePriority SpawnablePriority_Default { 128 }; + inline static constexpr SpawnablePriority SpawnablePriority_Low { 192 }; + inline static constexpr SpawnablePriority SpawnablePriority_Lowest { 255 }; + class SpawnableEntityContainerView { public: @@ -58,16 +67,84 @@ namespace AzFramework AZ::Entity** m_end; }; - //! Requests to the SpawnableEntitiesInterface require a ticket with a valid spawnable that be used as a template. A ticket can - //! be reused for multiple calls on the same spawnable and is safe to use by multiple threads at the same time. Entities created + class SpawnableIndexEntityPair + { + public: + friend class SpawnableIndexEntityIterator; + + AZ::Entity* GetEntity(); + const AZ::Entity* GetEntity() const; + size_t GetIndex() const; + + private: + SpawnableIndexEntityPair() = default; + SpawnableIndexEntityPair(const SpawnableIndexEntityPair&) = default; + SpawnableIndexEntityPair(SpawnableIndexEntityPair&&) = default; + SpawnableIndexEntityPair(AZ::Entity** entityIterator, size_t* indexIterator); + + SpawnableIndexEntityPair& operator=(const SpawnableIndexEntityPair&) = default; + SpawnableIndexEntityPair& operator=(SpawnableIndexEntityPair&&) = default; + + AZ::Entity** m_entity { nullptr }; + size_t* m_index { nullptr }; + }; + + class SpawnableIndexEntityIterator + { + public: + // Limited to bidirectional iterator as there's no use case for extending it further, but can be extended if a use case is found. + using iterator_category = AZStd::bidirectional_iterator_tag; + using value_type = SpawnableIndexEntityPair; + using difference_type = size_t; + using pointer = SpawnableIndexEntityPair*; + using reference = SpawnableIndexEntityPair&; + + SpawnableIndexEntityIterator(AZ::Entity** entityIterator, size_t* indexIterator); + + SpawnableIndexEntityIterator& operator++(); + SpawnableIndexEntityIterator operator++(int); + SpawnableIndexEntityIterator& operator--(); + SpawnableIndexEntityIterator operator--(int); + + bool operator==(const SpawnableIndexEntityIterator& rhs); + bool operator!=(const SpawnableIndexEntityIterator& rhs); + + SpawnableIndexEntityPair& operator*(); + const SpawnableIndexEntityPair& operator*() const; + SpawnableIndexEntityPair* operator->(); + const SpawnableIndexEntityPair* operator->() const; + + private: + SpawnableIndexEntityPair m_value; + }; + + class SpawnableConstIndexEntityContainerView + { + public: + SpawnableConstIndexEntityContainerView(AZ::Entity** beginEntity, size_t* beginIndices, size_t length); + + const SpawnableIndexEntityIterator& begin(); + const SpawnableIndexEntityIterator& end(); + const SpawnableIndexEntityIterator& cbegin(); + const SpawnableIndexEntityIterator& cend(); + + private: + SpawnableIndexEntityIterator m_begin; + SpawnableIndexEntityIterator m_end; + }; + + //! Requests to the SpawnableEntitiesInterface require a ticket with a valid spawnable that is used as a template. A ticket can + //! be reused for multiple calls on the same spawnable and is safe to be used by multiple threads at the same time. Entities created //! from the spawnable may be tracked by the ticket and so using the same ticket is needed to despawn the exact entities created - //! by a call so spawn entities. The life cycle of the spawned entities is tied to the ticket and all entities spawned using a + //! by a call to spawn entities. The life cycle of the spawned entities is tied to the ticket and all entities spawned using a //! ticket will be despawned when it's deleted. class EntitySpawnTicket { public: friend class SpawnableEntitiesDefinition; + using Id = uint64_t; + EntitySpawnTicket() = default; EntitySpawnTicket(const EntitySpawnTicket&) = delete; EntitySpawnTicket(EntitySpawnTicket&& rhs); @@ -77,24 +154,37 @@ namespace AzFramework EntitySpawnTicket& operator=(const EntitySpawnTicket&) = delete; EntitySpawnTicket& operator=(EntitySpawnTicket&& rhs); + Id GetId() const; bool IsValid() const; private: void* m_payload{ nullptr }; + Id m_id { 0 }; //!< An id that uniquely identifies a ticket. }; - using EntitySpawnCallback = AZStd::function; - using EntityDespawnCallback = AZStd::function; - using ReloadSpawnableCallback = AZStd::function; - using ListEntitiesCallback = AZStd::function; - using ClaimEntitiesCallback = AZStd::function; - using BarrierCallback = AZStd::function; + using EntitySpawnCallback = AZStd::function; + using EntityPreInsertionCallback = AZStd::function; + using EntityDespawnCallback = AZStd::function; + using ReloadSpawnableCallback = AZStd::function; + using ListEntitiesCallback = AZStd::function; + using ListIndicesEntitiesCallback = AZStd::function; + using ClaimEntitiesCallback = AZStd::function; + using BarrierCallback = AZStd::function; //! Interface definition to (de)spawn entities from a spawnable into the game world. + //! //! While the callbacks of the individual calls are being processed they will block processing any other request. Callbacks can be //! issued from threads other than the one that issued the call, including the main thread. + //! //! Calls on the same ticket are guaranteed to be executed in the order they are issued. Note that when issuing requests from //! multiple threads on the same ticket the order in which the requests are assigned to the ticket is not guaranteed. + //! + //! Most calls have a priority with values that range from 0 (highest priority) to 255 (lowest priority). The implementation of this + //! interface may choose to use priority lanes which doesn't guarantee that higher priority requests happen before lower priority + //! requests if they don't pass the priority lane threshold. Priority lanes and their thresholds are implementation specific and may + //! differ between platforms. Note that if a call happened on a ticket with lower priority followed by a one with a higher priority + //! the first lower priority call will still need to complete before the second higher priority call can be executed and the priority + //! of the first call will not be updated. class SpawnableEntitiesDefinition { public: @@ -105,48 +195,72 @@ namespace AzFramework virtual ~SpawnableEntitiesDefinition() = default; //! Spawn instances of all entities in the spawnable. - //! @param spawnable The Spawnable asset that will be used to create entity instances from. //! @param ticket Stores the results of the call. Use this ticket to spawn additional entities or to despawn them. + //! @param priority The priority at which this call will be executed. //! @param completionCallback Optional callback that's called when spawning entities has completed. This can be called from //! a different thread than the one that made the function call. The returned list of entities contains all the newly //! created entities. - virtual void SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback = {}) = 0; + virtual void SpawnAllEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, EntityPreInsertionCallback preInsertionCallback = {}, + EntitySpawnCallback completionCallback = {}) = 0; //! Spawn instances of some entities in the spawnable. //! @param ticket Stores the results of the call. Use this ticket to spawn additional entities or to despawn them. + //! @param priority The priority at which this call will be executed. //! @param entityIndices The indices into the template entities stored in the spawnable that will be used to spawn entities from. //! @param completionCallback Optional callback that's called when spawning entities has completed. This can be called from //! a different thread than the one that made this function call. The returned list of entities contains all the newly //! created entities. - virtual void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector entityIndices, - EntitySpawnCallback completionCallback = {}) = 0; + virtual void SpawnEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, AZStd::vector entityIndices, + EntityPreInsertionCallback preInsertionCallback = {}, EntitySpawnCallback completionCallback = {}) = 0; //! Removes all entities in the provided list from the environment. //! @param ticket The ticket previously used to spawn entities with. + //! @param priority The priority at which this call will be executed. //! @param completionCallback Optional callback that's called when despawning entities has completed. This can be called from //! a different thread than the one that made this function call. - virtual void DespawnAllEntities(EntitySpawnTicket& ticket, EntityDespawnCallback completionCallback = {}) = 0; + virtual void DespawnAllEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, EntityDespawnCallback completionCallback = {}) = 0; //! Removes all entities in the provided list from the environment and reconstructs the entities from the provided spawnable. - //! @param ticket Stores the results of the call. Use this ticket to spawn additional entities or to despawn them. + //! @param ticket Holds the information on the entities to reload. + //! @param priority The priority at which this call will be executed. //! @param spawnable The spawnable that will replace the existing spawnable. Both need to have the same asset id. //! @param completionCallback Optional callback that's called when the entities have been reloaded. This can be called from //! a different thread than the one that made this function call. The returned list of entities contains all the replacement //! entities. - virtual void ReloadSpawnable(EntitySpawnTicket& ticket, AZ::Data::Asset spawnable, + virtual void ReloadSpawnable( + EntitySpawnTicket& ticket, SpawnablePriority priority, AZ::Data::Asset spawnable, ReloadSpawnableCallback completionCallback = {}) = 0; //! List all entities that are spawned using this ticket. //! @param ticket Only the entities associated with this ticket will be listed. + //! @param priority The priority at which this call will be executed. //! @param listCallback Required callback that will be called to list the entities on. - virtual void ListEntities(EntitySpawnTicket& ticket, ListEntitiesCallback listCallback) = 0; + virtual void ListEntities(EntitySpawnTicket& ticket, SpawnablePriority priority, ListEntitiesCallback listCallback) = 0; + //! List all entities that are spawned using this ticket with their spawnable index. + //! Spawnables contain a flat list of entities, which are used as templates to spawn entities from. For every spawned entity + //! the index of the entity in the spawnable that was used as a template is stored. This version of ListEntities will return + //! both the entities and this index. The index can be used with SpawnEntities to create the same entities again. Note that + //! the same index may appear multiple times as there are no restriction on how many instance of a specific entity can be + //! created. + //! @param ticket Only the entities associated with this ticket will be listed. + //! @param priority The priority at which this call will be executed. + //! @param listCallback Required callback that will be called to list the entities and indices on. + virtual void ListIndicesAndEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, ListIndicesEntitiesCallback listCallback) = 0; //! Claim all entities that are spawned using this ticket. Ownership of the entities is transferred from the ticket to the //! caller through the callback. After this call the ticket will have no entities associated with it. The caller of //! this function will need to manage the entities after this call. //! @param ticket Only the entities associated with this ticket will be released. + //! @param priority The priority at which this call will be executed. //! @param listCallback Required callback that will be called to transfer the entities through. - virtual void ClaimEntities(EntitySpawnTicket& ticket, ClaimEntitiesCallback listCallback) = 0; + virtual void ClaimEntities(EntitySpawnTicket& ticket, SpawnablePriority priority, ClaimEntitiesCallback listCallback) = 0; //! Blocks until all operations made on the provided ticket before the barrier call have completed. - virtual void Barrier(EntitySpawnTicket& ticket, BarrierCallback completionCallback) = 0; + //! @param ticket The ticket to monitor. + //! @param priority The priority at which this call will be executed. + //! @param completionCallback Required callback that will be called as soon as the barrier has been reached. + virtual void Barrier(EntitySpawnTicket& ticket, SpawnablePriority priority, BarrierCallback completionCallback) = 0; //! Register a handler for OnSpawned events. virtual void AddOnSpawnedHandler(AZ::Event>::Handler& handler) = 0; @@ -155,7 +269,7 @@ namespace AzFramework virtual void AddOnDespawnedHandler(AZ::Event>::Handler& handler) = 0; protected: - [[nodiscard]] virtual void* CreateTicket(AZ::Data::Asset&& spawnable) = 0; + [[nodiscard]] virtual AZStd::pair CreateTicket(AZ::Data::Asset&& spawnable) = 0; virtual void DestroyTicket(void* ticket) = 0; template diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp index 3ab004b516..7b767d2a72 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.cpp @@ -10,108 +10,136 @@ * */ +#include #include +#include #include +#include #include #include +#include #include #include #include namespace AzFramework { - void SpawnableEntitiesManager::SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback) + template + void SpawnableEntitiesManager::QueueRequest(EntitySpawnTicket& ticket, SpawnablePriority priority, T&& request) { - SpawnAllEntitiesCommand queueEntry; - queueEntry.m_ticket = &ticket; - queueEntry.m_completionCallback = AZStd::move(completionCallback); + request.m_ticket = &GetTicketPayload(ticket); + Queue& queue = priority <= m_highPriorityThreshold ? m_highPriorityQueue : m_regularPriorityQueue; { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = GetTicketPayload(ticket).m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); + AZStd::scoped_lock queueLock(queue.m_pendingRequestMutex); + request.m_requestId = GetTicketPayload(ticket).m_nextRequestId++; + queue.m_pendingRequest.push(AZStd::move(request)); } } - void SpawnableEntitiesManager::SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector entityIndices, + SpawnableEntitiesManager::SpawnableEntitiesManager() + { + if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr) + { + AZ::u64 value = aznumeric_caster(m_highPriorityThreshold); + settingsRegistry->Get(value, "/O3DE/AzFramework/Spawnables/HighPriorityThreshold"); + m_highPriorityThreshold = aznumeric_cast(AZStd::clamp(value, 0llu, 255llu)); + } + } + + void SpawnableEntitiesManager::SpawnAllEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, EntityPreInsertionCallback preInsertionCallback, EntitySpawnCallback completionCallback) { + AZ_Assert(ticket.IsValid(), "Ticket provided to SpawnAllEntities hasn't been initialized."); + + SpawnAllEntitiesCommand queueEntry; + queueEntry.m_ticketId = ticket.GetId(); + queueEntry.m_completionCallback = AZStd::move(completionCallback); + queueEntry.m_preInsertionCallback = AZStd::move(preInsertionCallback); + QueueRequest(ticket, priority, AZStd::move(queueEntry)); + } + + void SpawnableEntitiesManager::SpawnEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, AZStd::vector entityIndices, + EntityPreInsertionCallback preInsertionCallback, EntitySpawnCallback completionCallback) + { + AZ_Assert(ticket.IsValid(), "Ticket provided to SpawnEntities hasn't been initialized."); + SpawnEntitiesCommand queueEntry; - queueEntry.m_ticket = &ticket; + queueEntry.m_ticketId = ticket.GetId(); queueEntry.m_entityIndices = AZStd::move(entityIndices); queueEntry.m_completionCallback = AZStd::move(completionCallback); - { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = GetTicketPayload(ticket).m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); - } + queueEntry.m_preInsertionCallback = AZStd::move(preInsertionCallback); + QueueRequest(ticket, priority, AZStd::move(queueEntry)); } - void SpawnableEntitiesManager::DespawnAllEntities(EntitySpawnTicket& ticket, EntityDespawnCallback completionCallback) + void SpawnableEntitiesManager::DespawnAllEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, EntityDespawnCallback completionCallback) { + AZ_Assert(ticket.IsValid(), "Ticket provided to DespawnAllEntities hasn't been initialized."); + DespawnAllEntitiesCommand queueEntry; - queueEntry.m_ticket = &ticket; + queueEntry.m_ticketId = ticket.GetId(); queueEntry.m_completionCallback = AZStd::move(completionCallback); - { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = GetTicketPayload(ticket).m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); - } + QueueRequest(ticket, priority, AZStd::move(queueEntry)); } - void SpawnableEntitiesManager::ReloadSpawnable(EntitySpawnTicket& ticket, AZ::Data::Asset spawnable, + void SpawnableEntitiesManager::ReloadSpawnable( + EntitySpawnTicket& ticket, SpawnablePriority priority, AZ::Data::Asset spawnable, ReloadSpawnableCallback completionCallback) { + AZ_Assert(ticket.IsValid(), "Ticket provided to ReloadSpawnable hasn't been initialized."); + ReloadSpawnableCommand queueEntry; - queueEntry.m_ticket = &ticket; + queueEntry.m_ticketId = ticket.GetId(); queueEntry.m_spawnable = AZStd::move(spawnable); queueEntry.m_completionCallback = AZStd::move(completionCallback); - { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = GetTicketPayload(ticket).m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); - } + QueueRequest(ticket, priority, AZStd::move(queueEntry)); } - void SpawnableEntitiesManager::ListEntities(EntitySpawnTicket& ticket, ListEntitiesCallback listCallback) + void SpawnableEntitiesManager::ListEntities(EntitySpawnTicket& ticket, SpawnablePriority priority, ListEntitiesCallback listCallback) { AZ_Assert(listCallback, "ListEntities called on spawnable entities without a valid callback to use."); + AZ_Assert(ticket.IsValid(), "Ticket provided to ListEntities hasn't been initialized."); ListEntitiesCommand queueEntry; - queueEntry.m_ticket = &ticket; + queueEntry.m_ticketId = ticket.GetId(); queueEntry.m_listCallback = AZStd::move(listCallback); - { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = GetTicketPayload(ticket).m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); - } + QueueRequest(ticket, priority, AZStd::move(queueEntry)); } - void SpawnableEntitiesManager::ClaimEntities(EntitySpawnTicket& ticket, ClaimEntitiesCallback listCallback) + void SpawnableEntitiesManager::ListIndicesAndEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, ListIndicesEntitiesCallback listCallback) + { + AZ_Assert(listCallback, "ListEntities called on spawnable entities without a valid callback to use."); + AZ_Assert(ticket.IsValid(), "Ticket provided to ListEntities hasn't been initialized."); + + ListIndicesEntitiesCommand queueEntry; + queueEntry.m_ticketId = ticket.GetId(); + queueEntry.m_listCallback = AZStd::move(listCallback); + QueueRequest(ticket, priority, AZStd::move(queueEntry)); + } + + void SpawnableEntitiesManager::ClaimEntities(EntitySpawnTicket& ticket, SpawnablePriority priority, ClaimEntitiesCallback listCallback) { AZ_Assert(listCallback, "ClaimEntities called on spawnable entities without a valid callback to use."); + AZ_Assert(ticket.IsValid(), "Ticket provided to ClaimEntities hasn't been initialized."); ClaimEntitiesCommand queueEntry; - queueEntry.m_ticket = &ticket; + queueEntry.m_ticketId = ticket.GetId(); queueEntry.m_listCallback = AZStd::move(listCallback); - { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = GetTicketPayload(ticket).m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); - } + QueueRequest(ticket, priority, AZStd::move(queueEntry)); } - void SpawnableEntitiesManager::Barrier(EntitySpawnTicket& ticket, BarrierCallback completionCallback) + void SpawnableEntitiesManager::Barrier(EntitySpawnTicket& ticket, SpawnablePriority priority, BarrierCallback completionCallback) { AZ_Assert(completionCallback, "Barrier on spawnable entities called without a valid callback to use."); + AZ_Assert(ticket.IsValid(), "Ticket provided to Barrier hasn't been initialized."); BarrierCommand queueEntry; - queueEntry.m_ticket = &ticket; + queueEntry.m_ticketId = ticket.GetId(); queueEntry.m_completionCallback = AZStd::move(completionCallback); - { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = GetTicketPayload(ticket).m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); - } + QueueRequest(ticket, priority, AZStd::move(queueEntry)); } void SpawnableEntitiesManager::AddOnSpawnedHandler(AZ::Event>::Handler& handler) @@ -124,34 +152,54 @@ namespace AzFramework handler.Connect(m_onDespawnedEvent); } - auto SpawnableEntitiesManager::ProcessQueue() -> CommandQueueStatus + auto SpawnableEntitiesManager::ProcessQueue(CommandQueuePriority priority) -> CommandQueueStatus + { + CommandQueueStatus result = CommandQueueStatus::NoCommandsLeft; + if ((priority & CommandQueuePriority::High) == CommandQueuePriority::High) + { + if (ProcessQueue(m_highPriorityQueue) == CommandQueueStatus::HasCommandsLeft) + { + result = CommandQueueStatus::HasCommandsLeft; + } + } + if ((priority & CommandQueuePriority::Regular) == CommandQueuePriority::Regular) + { + if (ProcessQueue(m_regularPriorityQueue) == CommandQueueStatus::HasCommandsLeft) + { + result = CommandQueueStatus::HasCommandsLeft; + } + } + return result; + } + + auto SpawnableEntitiesManager::ProcessQueue(Queue& queue) -> CommandQueueStatus { AZStd::queue pendingRequestQueue; { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - m_pendingRequestQueue.swap(pendingRequestQueue); + AZStd::scoped_lock queueLock(queue.m_pendingRequestMutex); + queue.m_pendingRequest.swap(pendingRequestQueue); } - if (!pendingRequestQueue.empty() || !m_delayedQueue.empty()) + if (!pendingRequestQueue.empty() || !queue.m_delayed.empty()) { AZ::SerializeContext* serializeContext = nullptr; AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext); AZ_Assert(serializeContext, "Failed to retrieve serialization context."); // Only process the requests that are currently in this queue, not the ones that could be re-added if they still can't complete. - size_t delayedSize = m_delayedQueue.size(); + size_t delayedSize = queue.m_delayed.size(); for (size_t i = 0; i < delayedSize; ++i) { - Requests& request = m_delayedQueue.front(); + Requests& request = queue.m_delayed.front(); bool result = AZStd::visit([this, serializeContext](auto&& args) -> bool { return ProcessRequest(args, *serializeContext); }, request); if (!result) { - m_delayedQueue.emplace_back(AZStd::move(request)); + queue.m_delayed.emplace_back(AZStd::move(request)); } - m_delayedQueue.pop_front(); + queue.m_delayed.pop_front(); } do @@ -165,7 +213,7 @@ namespace AzFramework }, request); if (!result) { - m_delayedQueue.emplace_back(AZStd::move(request)); + queue.m_delayed.emplace_back(AZStd::move(request)); } pendingRequestQueue.pop(); } @@ -173,20 +221,22 @@ namespace AzFramework // Spawning entities can result in more entities being queued to spawn. Repeat spawning until the queue is // empty to avoid a chain of entity spawning getting dragged out over multiple frames. { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - m_pendingRequestQueue.swap(pendingRequestQueue); + AZStd::scoped_lock queueLock(queue.m_pendingRequestMutex); + queue.m_pendingRequest.swap(pendingRequestQueue); } } while (!pendingRequestQueue.empty()); } - return m_delayedQueue.empty() ? CommandQueueStatus::NoCommandLeft : CommandQueueStatus::HasCommandsLeft; + return queue.m_delayed.empty() ? CommandQueueStatus::NoCommandsLeft : CommandQueueStatus::HasCommandsLeft; } - void* SpawnableEntitiesManager::CreateTicket(AZ::Data::Asset&& spawnable) + AZStd::pair SpawnableEntitiesManager::CreateTicket(AZ::Data::Asset&& spawnable) { + static AZStd::atomic_uint64_t idCounter { 1 }; + auto result = aznew Ticket(); result->m_spawnable = AZStd::move(spawnable); - return result; + return AZStd::make_pair(idCounter++, result); } void SpawnableEntitiesManager::DestroyTicket(void* ticket) @@ -194,9 +244,9 @@ namespace AzFramework DestroyTicketCommand queueEntry; queueEntry.m_ticket = reinterpret_cast(ticket); { - AZStd::scoped_lock queueLock(m_pendingRequestQueueMutex); - queueEntry.m_ticketId = reinterpret_cast(ticket)->m_nextTicketId++; - m_pendingRequestQueue.push(AZStd::move(queueEntry)); + AZStd::scoped_lock queueLock(m_regularPriorityQueue.m_pendingRequestMutex); + queueEntry.m_requestId = reinterpret_cast(ticket)->m_nextRequestId++; + m_regularPriorityQueue.m_pendingRequest.push(AZStd::move(queueEntry)); } } @@ -205,37 +255,90 @@ namespace AzFramework AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate); AZ_Assert(clone != nullptr, "Failed to clone spawnable entity."); clone->SetId(AZ::Entity::MakeId()); + GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, clone); return clone; } + AZ::Entity* SpawnableEntitiesManager::CloneSingleEntity(const AZ::Entity& entityTemplate, + EntityIdMap& templateToCloneEntityIdMap, AZ::SerializeContext& serializeContext) + { + return AZ::IdUtils::Remapper::CloneObjectAndGenerateNewIdsAndFixRefs( + &entityTemplate, templateToCloneEntityIdMap, &serializeContext); + } + bool SpawnableEntitiesManager::ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext) { - Ticket& ticket = GetTicketPayload(*request.m_ticket); - if (ticket.m_spawnable.IsReady() && request.m_ticketId == ticket.m_currentTicketId) + Ticket& ticket = *request.m_ticket; + if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId) { - size_t spawnedEntitiesCount = ticket.m_spawnedEntities.size(); + AZStd::vector& spawnedEntities = ticket.m_spawnedEntities; + AZStd::vector& spawnedEntityIndices = ticket.m_spawnedEntityIndices; - const Spawnable::EntityList& entities = ticket.m_spawnable->GetEntities(); - size_t entitiesSize = entities.size(); - ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize); - ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize); + // Keep track how many entities there were in the array initially + size_t spawnedEntitiesInitialCount = spawnedEntities.size(); - for(size_t i=0; iGetEntities(); + size_t entitiesToSpawnSize = entitiesToSpawn.size(); + + // Map keeps track of ids from template (spawnable) to clone (instance) + // Allowing patch ups of fields referring to entityIds outside of a given entity + EntityIdMap templateToCloneEntityIdMap; + + // Reserve buffers + spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize); + spawnedEntityIndices.reserve(spawnedEntityIndices.size() + entitiesToSpawnSize); + templateToCloneEntityIdMap.reserve(entitiesToSpawnSize); + + // Mark all indices as spawned + for (size_t i = 0; i < entitiesToSpawnSize; ++i) { - ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[i], serializeContext)); - ticket.m_spawnedEntityIndices.push_back(i); + const AZ::Entity& entityTemplate = *entitiesToSpawn[i]; + + AZ::Entity* clone = CloneSingleEntity(entityTemplate, templateToCloneEntityIdMap, serializeContext); + + AZ_Assert(clone != nullptr, "Failed to clone spawnable entity."); + + spawnedEntities.emplace_back(clone); + spawnedEntityIndices.push_back(i); } + // loadAll is true if every entity has been spawned only once + if (spawnedEntities.size() == entitiesToSpawnSize) + { + ticket.m_loadAll = true; + } + else + { + // Case where there were already spawns from a previous request + ticket.m_loadAll = false; + } + + // Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context. + if (request.m_preInsertionCallback) + { + request.m_preInsertionCallback(request.m_ticketId, SpawnableEntityContainerView( + ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end())); + } + + // Add to the game context, now the entities are active + AZStd::for_each(ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end(), + [](AZ::Entity* entity) + { + GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, entity); + }); + + // Let other systems know about newly spawned entities for any post-processing after adding to the scene/game context. if (request.m_completionCallback) { - request.m_completionCallback(*request.m_ticket, SpawnableConstEntityContainerView( - ticket.m_spawnedEntities.begin() + spawnedEntitiesCount, ticket.m_spawnedEntities.end())); + request.m_completionCallback(request.m_ticketId, SpawnableConstEntityContainerView( + ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end())); } m_onSpawnedEvent.Signal(ticket.m_spawnable); - ticket.m_currentTicketId++; + ticket.m_currentRequestId++; return true; } else @@ -246,32 +349,62 @@ namespace AzFramework bool SpawnableEntitiesManager::ProcessRequest(SpawnEntitiesCommand& request, AZ::SerializeContext& serializeContext) { - Ticket& ticket = GetTicketPayload(*request.m_ticket); - if (ticket.m_spawnable.IsReady() && request.m_ticketId == ticket.m_currentTicketId) + Ticket& ticket = *request.m_ticket; + if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId) { - size_t spawnedEntitiesCount = ticket.m_spawnedEntities.size(); + AZStd::vector& spawnedEntities = ticket.m_spawnedEntities; + AZStd::vector& spawnedEntityIndices = ticket.m_spawnedEntityIndices; - const Spawnable::EntityList& entities = ticket.m_spawnable->GetEntities(); - size_t entitiesSize = entities.size(); - ticket.m_spawnedEntities.reserve(ticket.m_spawnedEntities.size() + entitiesSize); - ticket.m_spawnedEntityIndices.reserve(ticket.m_spawnedEntityIndices.size() + entitiesSize); + // Keep track how many entities there were in the array initially + size_t spawnedEntitiesInitialCount = spawnedEntities.size(); + + // These are 'template' entities we'll be cloning from + const Spawnable::EntityList& entitiesToSpawn = ticket.m_spawnable->GetEntities(); + size_t entitiesToSpawnSize = request.m_entityIndices.size(); + + spawnedEntities.reserve(spawnedEntities.size() + entitiesToSpawnSize); + spawnedEntityIndices.reserve(spawnedEntityIndices.size() + entitiesToSpawnSize); for (size_t index : request.m_entityIndices) { - ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[index], serializeContext)); - ticket.m_spawnedEntityIndices.push_back(index); + if (index < entitiesToSpawn.size()) + { + const AZ::Entity& entityTemplate = *entitiesToSpawn[index]; + + AZ::Entity* clone = serializeContext.CloneObject(&entityTemplate); + AZ_Assert(clone != nullptr, "Failed to clone spawnable entity."); + clone->SetId(AZ::Entity::MakeId()); + + spawnedEntities.push_back(clone); + spawnedEntityIndices.push_back(index); + + } } ticket.m_loadAll = false; + // Let other systems know about newly spawned entities for any pre-processing before adding to the scene/game context. + if (request.m_preInsertionCallback) + { + request.m_preInsertionCallback(request.m_ticketId, SpawnableEntityContainerView( + ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end())); + } + + // Add to the game context, now the entities are active + AZStd::for_each(ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end(), + [](AZ::Entity* entity) + { + GameEntityContextRequestBus::Broadcast(&GameEntityContextRequestBus::Events::AddGameEntity, entity); + }); + if (request.m_completionCallback) { - request.m_completionCallback(*request.m_ticket, SpawnableConstEntityContainerView( - ticket.m_spawnedEntities.begin() + spawnedEntitiesCount, ticket.m_spawnedEntities.end())); + request.m_completionCallback(request.m_ticketId, SpawnableConstEntityContainerView( + ticket.m_spawnedEntities.begin() + spawnedEntitiesInitialCount, ticket.m_spawnedEntities.end())); } m_onSpawnedEvent.Signal(ticket.m_spawnable); - ticket.m_currentTicketId++; + ticket.m_currentRequestId++; return true; } else @@ -283,8 +416,8 @@ namespace AzFramework bool SpawnableEntitiesManager::ProcessRequest(DespawnAllEntitiesCommand& request, [[maybe_unused]] AZ::SerializeContext& serializeContext) { - Ticket& ticket = GetTicketPayload(*request.m_ticket); - if (request.m_ticketId == ticket.m_currentTicketId) + Ticket& ticket = *request.m_ticket; + if (request.m_requestId == ticket.m_currentRequestId) { for (AZ::Entity* entity : ticket.m_spawnedEntities) { @@ -300,12 +433,12 @@ namespace AzFramework if (request.m_completionCallback) { - request.m_completionCallback(*request.m_ticket); + request.m_completionCallback(request.m_ticketId); } m_onDespawnedEvent.Signal(ticket.m_spawnable); - ticket.m_currentTicketId++; + ticket.m_currentRequestId++; return true; } else @@ -316,11 +449,11 @@ namespace AzFramework bool SpawnableEntitiesManager::ProcessRequest(ReloadSpawnableCommand& request, AZ::SerializeContext& serializeContext) { - Ticket& ticket = GetTicketPayload(*request.m_ticket); + Ticket& ticket = *request.m_ticket; AZ_Assert(ticket.m_spawnable.GetId() == request.m_spawnable.GetId(), "Spawnable is being reloaded, but the provided spawnable has a different asset id. " "This will likely result in unexpected entities being created."); - if (ticket.m_spawnable.IsReady() && request.m_ticketId == ticket.m_currentTicketId) + if (ticket.m_spawnable.IsReady() && request.m_requestId == ticket.m_currentRequestId) { // Delete the original entities. for (AZ::Entity* entity : ticket.m_spawnedEntities) @@ -343,10 +476,23 @@ namespace AzFramework // to load every, simply start over. ticket.m_spawnedEntityIndices.clear(); - size_t entitiesSize = entities.size(); - for (size_t i = 0; i < entitiesSize; ++i) + size_t entitiesToSpawnSize = entities.size(); + + // Map keeps track of ids from template (spawnable) to clone (instance) + // Allowing patch ups of fields referring to entityIds outside of a given entity + EntityIdMap templateToCloneEntityIdMap; + templateToCloneEntityIdMap.reserve(entitiesToSpawnSize); + + // Mark all indices as spawned + for (size_t i = 0; i < entitiesToSpawnSize; ++i) { - ticket.m_spawnedEntities.push_back(SpawnSingleEntity(*entities[i], serializeContext)); + const AZ::Entity& entityTemplate = *entities[i]; + + AZ::Entity* clone = CloneSingleEntity(entityTemplate, templateToCloneEntityIdMap, serializeContext); + + AZ_Assert(clone != nullptr, "Failed to clone spawnable entity."); + + ticket.m_spawnedEntities.emplace_back(clone); ticket.m_spawnedEntityIndices.push_back(i); } } @@ -363,11 +509,11 @@ namespace AzFramework if (request.m_completionCallback) { - request.m_completionCallback(*request.m_ticket, SpawnableConstEntityContainerView( + request.m_completionCallback(request.m_ticketId, SpawnableConstEntityContainerView( ticket.m_spawnedEntities.begin(), ticket.m_spawnedEntities.end())); } - ticket.m_currentTicketId++; + ticket.m_currentRequestId++; m_onSpawnedEvent.Signal(ticket.m_spawnable); @@ -381,12 +527,31 @@ namespace AzFramework bool SpawnableEntitiesManager::ProcessRequest(ListEntitiesCommand& request, [[maybe_unused]] AZ::SerializeContext& serializeContext) { - Ticket& ticket = GetTicketPayload(*request.m_ticket); - if (request.m_ticketId == ticket.m_currentTicketId) + Ticket& ticket = *request.m_ticket; + if (request.m_requestId == ticket.m_currentRequestId) { - request.m_listCallback(*request.m_ticket, SpawnableConstEntityContainerView( + request.m_listCallback(request.m_ticketId, SpawnableConstEntityContainerView( ticket.m_spawnedEntities.begin(), ticket.m_spawnedEntities.end())); - ticket.m_currentTicketId++; + ticket.m_currentRequestId++; + return true; + } + else + { + return false; + } + } + + bool SpawnableEntitiesManager::ProcessRequest(ListIndicesEntitiesCommand& request, [[maybe_unused]] AZ::SerializeContext& serializeContext) + { + Ticket& ticket = *request.m_ticket; + if (request.m_requestId == ticket.m_currentRequestId) + { + AZ_Assert( + ticket.m_spawnedEntities.size() == ticket.m_spawnedEntityIndices.size(), + "Entities and indices on spawnable ticket have gone out of sync."); + request.m_listCallback(request.m_ticketId, SpawnableConstIndexEntityContainerView( + ticket.m_spawnedEntities.begin(), ticket.m_spawnedEntityIndices.begin(), ticket.m_spawnedEntities.size())); + ticket.m_currentRequestId++; return true; } else @@ -397,16 +562,16 @@ namespace AzFramework bool SpawnableEntitiesManager::ProcessRequest(ClaimEntitiesCommand& request, [[maybe_unused]] AZ::SerializeContext& serializeContext) { - Ticket& ticket = GetTicketPayload(*request.m_ticket); - if (request.m_ticketId == ticket.m_currentTicketId) + Ticket& ticket = *request.m_ticket; + if (request.m_requestId == ticket.m_currentRequestId) { - request.m_listCallback(*request.m_ticket, SpawnableEntityContainerView( + request.m_listCallback(request.m_ticketId, SpawnableEntityContainerView( ticket.m_spawnedEntities.begin(), ticket.m_spawnedEntities.end())); ticket.m_spawnedEntities.clear(); ticket.m_spawnedEntityIndices.clear(); - ticket.m_currentTicketId++; + ticket.m_currentRequestId++; return true; } else @@ -417,15 +582,15 @@ namespace AzFramework bool SpawnableEntitiesManager::ProcessRequest(BarrierCommand& request, [[maybe_unused]] AZ::SerializeContext& serializeContext) { - Ticket& ticket = GetTicketPayload(*request.m_ticket); - if (request.m_ticketId == ticket.m_currentTicketId) + Ticket& ticket = *request.m_ticket; + if (request.m_requestId == ticket.m_currentRequestId) { if (request.m_completionCallback) { - request.m_completionCallback(*request.m_ticket); + request.m_completionCallback(request.m_ticketId); } - ticket.m_currentTicketId++; + ticket.m_currentRequestId++; return true; } else @@ -436,7 +601,7 @@ namespace AzFramework bool SpawnableEntitiesManager::ProcessRequest(DestroyTicketCommand& request, [[maybe_unused]] AZ::SerializeContext& serializeContext) { - if (request.m_ticketId == request.m_ticket->m_currentTicketId) + if (request.m_requestId == request.m_ticket->m_currentRequestId) { for (AZ::Entity* entity : request.m_ticket->m_spawnedEntities) { @@ -455,24 +620,4 @@ namespace AzFramework return false; } } - - bool SpawnableEntitiesManager::IsEqualTicket(const EntitySpawnTicket* lhs, const EntitySpawnTicket* rhs) - { - return GetTicketPayload(lhs) == GetTicketPayload(rhs); - } - - bool SpawnableEntitiesManager::IsEqualTicket(const Ticket* lhs, const EntitySpawnTicket* rhs) - { - return lhs == GetTicketPayload(rhs); - } - - bool SpawnableEntitiesManager::IsEqualTicket(const EntitySpawnTicket* lhs, const Ticket* rhs) - { - return GetTicketPayload(lhs) == rhs; - } - - bool SpawnableEntitiesManager::IsEqualTicket(const Ticket* lhs, const Ticket* rhs) - { - return lhs = rhs; - } } // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h index c70b9ccaa6..afffdab8b5 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableEntitiesManager.h @@ -34,31 +34,49 @@ namespace AzFramework { public: AZ_RTTI(AzFramework::SpawnableEntitiesManager, "{6E14333F-128C-464C-94CA-A63B05A5E51C}"); + AZ_CLASS_ALLOCATOR(SpawnableEntitiesManager, AZ::SystemAllocator, 0); + + using EntityIdMap = AZStd::unordered_map; enum class CommandQueueStatus : bool { HasCommandsLeft, - NoCommandLeft + NoCommandsLeft }; + enum class CommandQueuePriority + { + High = 1 << 0, + Regular = 1 << 1 + }; + + SpawnableEntitiesManager(); ~SpawnableEntitiesManager() override = default; // // The following functions are thread safe // - void SpawnAllEntities(EntitySpawnTicket& ticket, EntitySpawnCallback completionCallback = {}) override; - void SpawnEntities(EntitySpawnTicket& ticket, AZStd::vector entityIndices, + void SpawnAllEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, EntityPreInsertionCallback preInsertionCallback = {}, EntitySpawnCallback completionCallback = {}) override; - void DespawnAllEntities(EntitySpawnTicket& ticket, EntityDespawnCallback completionCallback = {}) override; + void SpawnEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, AZStd::vector entityIndices, + EntityPreInsertionCallback preInsertionCallback = {}, + EntitySpawnCallback completionCallback = {}) override; + void DespawnAllEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, EntityDespawnCallback completionCallback = {}) override; - void ReloadSpawnable(EntitySpawnTicket& ticket, AZ::Data::Asset spawnable, + void ReloadSpawnable( + EntitySpawnTicket& ticket, SpawnablePriority priority, AZ::Data::Asset spawnable, ReloadSpawnableCallback completionCallback = {}) override; - void ListEntities(EntitySpawnTicket& ticket, ListEntitiesCallback listCallback) override; - void ClaimEntities(EntitySpawnTicket& ticket, ClaimEntitiesCallback listCallback) override; + void ListEntities(EntitySpawnTicket& ticket, SpawnablePriority priority, ListEntitiesCallback listCallback) override; + void ListIndicesAndEntities( + EntitySpawnTicket& ticket, SpawnablePriority priority, ListIndicesEntitiesCallback listCallback) override; + void ClaimEntities(EntitySpawnTicket& ticket, SpawnablePriority priority, ClaimEntitiesCallback listCallback) override; - void Barrier(EntitySpawnTicket& spawnInfo, BarrierCallback completionCallback) override; + void Barrier(EntitySpawnTicket& spawnInfo, SpawnablePriority priority, BarrierCallback completionCallback) override; void AddOnSpawnedHandler(AZ::Event>::Handler& handler) override; void AddOnDespawnedHandler(AZ::Event>::Handler& handler) override; @@ -67,13 +85,9 @@ namespace AzFramework // The following function is thread safe but intended to be run from the main thread. // - CommandQueueStatus ProcessQueue(); + CommandQueueStatus ProcessQueue(CommandQueuePriority priority); protected: - void* CreateTicket(AZ::Data::Asset&& spawnable) override; - void DestroyTicket(void* ticket) override; - - private: struct Ticket { AZ_CLASS_ALLOCATOR(Ticket, AZ::ThreadPoolAllocator, 0); @@ -82,85 +96,123 @@ namespace AzFramework AZStd::vector m_spawnedEntities; AZStd::vector m_spawnedEntityIndices; AZ::Data::Asset m_spawnable; - uint32_t m_nextTicketId{ 0 }; //!< Next id for this ticket. - uint32_t m_currentTicketId{ 0 }; //!< The id for the command that should be executed. + uint32_t m_nextRequestId{ 0 }; //!< Next id for this ticket. + uint32_t m_currentRequestId { 0 }; //!< The id for the command that should be executed. bool m_loadAll{ true }; }; struct SpawnAllEntitiesCommand { EntitySpawnCallback m_completionCallback; - EntitySpawnTicket* m_ticket; - uint32_t m_ticketId; + EntityPreInsertionCallback m_preInsertionCallback; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; }; struct SpawnEntitiesCommand { AZStd::vector m_entityIndices; EntitySpawnCallback m_completionCallback; - EntitySpawnTicket* m_ticket; - uint32_t m_ticketId; + EntityPreInsertionCallback m_preInsertionCallback; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; }; struct DespawnAllEntitiesCommand { EntityDespawnCallback m_completionCallback; - EntitySpawnTicket* m_ticket; - uint32_t m_ticketId; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; }; struct ReloadSpawnableCommand { AZ::Data::Asset m_spawnable; ReloadSpawnableCallback m_completionCallback; - EntitySpawnTicket* m_ticket; - uint32_t m_ticketId; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; }; struct ListEntitiesCommand { ListEntitiesCallback m_listCallback; - EntitySpawnTicket* m_ticket; - uint32_t m_ticketId; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; + }; + struct ListIndicesEntitiesCommand + { + ListIndicesEntitiesCallback m_listCallback; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; }; struct ClaimEntitiesCommand { ClaimEntitiesCallback m_listCallback; - EntitySpawnTicket* m_ticket; - uint32_t m_ticketId; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; }; struct BarrierCommand { BarrierCallback m_completionCallback; - EntitySpawnTicket* m_ticket; - uint32_t m_ticketId; + Ticket* m_ticket; + EntitySpawnTicket::Id m_ticketId; + uint32_t m_requestId; }; struct DestroyTicketCommand { Ticket* m_ticket; - uint32_t m_ticketId; + uint32_t m_requestId; }; - using Requests = AZStd::variant; + using Requests = AZStd::variant< + SpawnAllEntitiesCommand, SpawnEntitiesCommand, DespawnAllEntitiesCommand, ReloadSpawnableCommand, ListEntitiesCommand, + ListIndicesEntitiesCommand, ClaimEntitiesCommand, BarrierCommand, DestroyTicketCommand>; - AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate, AZ::SerializeContext& serializeContext); + struct Queue + { + AZStd::deque m_delayed; //!< Requests that were processed before, but couldn't be completed. + AZStd::queue m_pendingRequest; //!< Requests waiting to be processed for the first time. + AZStd::mutex m_pendingRequestMutex; + }; + + template + void QueueRequest(EntitySpawnTicket& ticket, SpawnablePriority priority, T&& request); + AZStd::pair CreateTicket(AZ::Data::Asset&& spawnable) override; + void DestroyTicket(void* ticket) override; + + CommandQueueStatus ProcessQueue(Queue& queue); + + AZ::Entity* SpawnSingleEntity(const AZ::Entity& entityTemplate, + AZ::SerializeContext& serializeContext); + + AZ::Entity* CloneSingleEntity(const AZ::Entity& entityTemplate, + EntityIdMap& templateToCloneEntityIdMap, AZ::SerializeContext& serializeContext); bool ProcessRequest(SpawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext); bool ProcessRequest(SpawnEntitiesCommand& request, AZ::SerializeContext& serializeContext); bool ProcessRequest(DespawnAllEntitiesCommand& request, AZ::SerializeContext& serializeContext); bool ProcessRequest(ReloadSpawnableCommand& request, AZ::SerializeContext& serializeContext); bool ProcessRequest(ListEntitiesCommand& request, AZ::SerializeContext& serializeContext); + bool ProcessRequest(ListIndicesEntitiesCommand& request, AZ::SerializeContext& serializeContext); bool ProcessRequest(ClaimEntitiesCommand& request, AZ::SerializeContext& serializeContext); bool ProcessRequest(BarrierCommand& request, AZ::SerializeContext& serializeContext); bool ProcessRequest(DestroyTicketCommand& request, AZ::SerializeContext& serializeContext); - [[nodiscard]] static bool IsEqualTicket(const EntitySpawnTicket* lhs, const EntitySpawnTicket* rhs); - [[nodiscard]] static bool IsEqualTicket(const Ticket* lhs, const EntitySpawnTicket* rhs); - [[nodiscard]] static bool IsEqualTicket(const EntitySpawnTicket* lhs, const Ticket* rhs); - [[nodiscard]] static bool IsEqualTicket(const Ticket* lhs, const Ticket* rhs); - - AZStd::deque m_delayedQueue; //!< Requests that were processed before, but couldn't be completed. - AZStd::queue m_pendingRequestQueue; - AZStd::mutex m_pendingRequestQueueMutex; + Queue m_highPriorityQueue; + Queue m_regularPriorityQueue; AZ::Event> m_onSpawnedEvent; AZ::Event> m_onDespawnedEvent; + + //! The threshold used to determine if a request goes in the regular (if bigger than the value) or high priority queue (if smaller + //! or equal to this value). The starting value of 64 is chosen as it's between default values SpawnablePriority_High and + //! SpawnablePriority_Default which gives users a bit of room to fine tune the priorities as this value can be configured + //! through the Settings Registry under the key "/O3DE/AzFramework/Spawnables/HighPriorityThreshold". + SpawnablePriority m_highPriorityThreshold { 64 }; }; + + AZ_DEFINE_ENUM_BITWISE_OPERATORS(AzFramework::SpawnableEntitiesManager::CommandQueuePriority); } // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp index 262f006f15..300ff1441e 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.cpp @@ -48,10 +48,23 @@ namespace AzFramework void SpawnableSystemComponent::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) { - m_entitiesManager.ProcessQueue(); + m_entitiesManager.ProcessQueue( + SpawnableEntitiesManager::CommandQueuePriority::High | SpawnableEntitiesManager::CommandQueuePriority::Regular); RootSpawnableNotificationBus::ExecuteQueuedEvents(); } + int SpawnableSystemComponent::GetTickOrder() + { + return AZ::ComponentTickBus::TICK_GAME; + } + + void SpawnableSystemComponent::OnSystemTick() + { + // Handle only high priority spawning events such as those created from network. These need to happen even if the client + // doesn't have focus to avoid time-out issues for instance. + m_entitiesManager.ProcessQueue(SpawnableEntitiesManager::CommandQueuePriority::High); + } + void SpawnableSystemComponent::OnCatalogLoaded([[maybe_unused]] const char* catalogFile) { if (!m_catalogAvailable) @@ -168,7 +181,8 @@ namespace AzFramework SpawnableEntitiesManager::CommandQueueStatus queueStatus; do { - queueStatus = m_entitiesManager.ProcessQueue(); + queueStatus = m_entitiesManager.ProcessQueue( + SpawnableEntitiesManager::CommandQueuePriority::High | SpawnableEntitiesManager::CommandQueuePriority::Regular); } while (queueStatus == SpawnableEntitiesManager::CommandQueueStatus::HasCommandsLeft); } diff --git a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h index b29fbea5e4..1549b86385 100644 --- a/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Spawnable/SpawnableSystemComponent.h @@ -28,6 +28,7 @@ namespace AzFramework class SpawnableSystemComponent : public AZ::Component , public AZ::TickBus::Handler + , public AZ::SystemTickBus::Handler , public AssetCatalogEventBus::Handler , public RootSpawnableInterface::Registrar , public RootSpawnableNotificationBus::Handler @@ -58,6 +59,13 @@ namespace AzFramework // void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; + int GetTickOrder() override; + + // + // SystemTickBus + // + + void OnSystemTick() override; // // AssetCatalogEventBus diff --git a/Code/Framework/AzFramework/AzFramework/TargetManagement/NeighborhoodAPI.cpp b/Code/Framework/AzFramework/AzFramework/TargetManagement/NeighborhoodAPI.cpp index 44c601f5f5..7f3d0770c0 100644 --- a/Code/Framework/AzFramework/AzFramework/TargetManagement/NeighborhoodAPI.cpp +++ b/Code/Framework/AzFramework/AzFramework/TargetManagement/NeighborhoodAPI.cpp @@ -41,7 +41,7 @@ namespace Neighborhood { //--------------------------------------------------------------------- void NeighborReplica::OnReplicaActivate(const GridMate::ReplicaContext& /*rc*/) { - // TODO: Should we send the message to ourselves as well (master)? + // TODO: Should we send the message to ourselves as well? if (IsProxy()) { AZ_Assert(m_persistentName.Get().c_str(), "Received NeighborReplica with missing persistent name!"); @@ -52,7 +52,7 @@ namespace Neighborhood { //--------------------------------------------------------------------- void NeighborReplica::OnReplicaDeactivate(const GridMate::ReplicaContext& /*rc*/) { - // TODO: Should we send the message to ourselves as well (master)? + // TODO: Should we send the message to ourselves as well? if (IsProxy()) { EBUS_EVENT(NeighborhoodBus, OnNodeLeft, *this); diff --git a/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp b/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp index e44185bd33..d3ba48d587 100644 --- a/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp @@ -177,7 +177,7 @@ namespace AzFramework Neighborhood::NeighborReplicaPtr replicaChunk = GridMate::CreateReplicaChunk(session->GetMyMember()->GetId().Compact(), m_component->m_settings->m_persistentName.c_str(), Neighborhood::NEIGHBOR_CAP_LUA_VM | Neighborhood::NEIGHBOR_CAP_LUA_DEBUGGER); replicaChunk->SetDisplayName(m_component->m_settings->m_persistentName.c_str()); replica->AttachReplicaChunk(replicaChunk); - session->GetReplicaMgr()->AddMaster(replica); + session->GetReplicaMgr()->AddPrimary(replica); } } diff --git a/Code/CryEngine/CryCommon/ThermalInfo.h b/Code/Framework/AzFramework/AzFramework/Thermal/ThermalInfo.h similarity index 100% rename from Code/CryEngine/CryCommon/ThermalInfo.h rename to Code/Framework/AzFramework/AzFramework/Thermal/ThermalInfo.h diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index e9dace3433..559f7ce460 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -15,9 +15,9 @@ #include #include #include +#include #include #include -#include namespace AzFramework { @@ -29,8 +29,8 @@ namespace AzFramework AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(float, ed_cameraSystemDefaultOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 100.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); @@ -125,63 +125,60 @@ namespace AzFramework { if (orientation.GetElement(2, 0) > -1.0f) { - x = std::atan2(orientation.GetElement(2, 1), orientation.GetElement(2, 2)); - y = std::asin(-orientation.GetElement(2, 0)); - z = std::atan2(orientation.GetElement(1, 0), orientation.GetElement(0, 0)); + x = AZStd::atan2(orientation.GetElement(2, 1), orientation.GetElement(2, 2)); + y = AZStd::asin(-orientation.GetElement(2, 0)); + z = AZStd::atan2(orientation.GetElement(1, 0), orientation.GetElement(0, 0)); } else { x = 0.0f; y = AZ::Constants::Pi * 0.5f; - z = -std::atan2(-orientation.GetElement(2, 1), orientation.GetElement(1, 1)); + z = -AZStd::atan2(-orientation.GetElement(2, 1), orientation.GetElement(1, 1)); } } else { x = 0.0f; y = -AZ::Constants::Pi * 0.5f; - z = std::atan2(-orientation.GetElement(1, 2), orientation.GetElement(1, 1)); + z = AZStd::atan2(-orientation.GetElement(1, 2), orientation.GetElement(1, 1)); } - return {x, y, z}; + return { x, y, z }; } void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform) { const auto eulerAngles = AzFramework::EulerAngles(AZ::Matrix3x3::CreateFromTransform(transform)); - camera.m_lookAt = transform.GetTranslation(); camera.m_pitch = eulerAngles.GetX(); camera.m_yaw = eulerAngles.GetZ(); + // note: m_lookDist is negative so we must invert it here + camera.m_lookAt = transform.GetTranslation() + (camera.Rotation().GetBasisY() * -camera.m_lookDist); } bool CameraSystem::HandleEvents(const InputEvent& event) { - if (const auto& cursor_motion = AZStd::get_if(&event)) + if (const auto& horizonalMotion = AZStd::get_if(&event)) { - m_currentCursorPosition = cursor_motion->m_position; + m_motionDelta.m_x = horizonalMotion->m_delta; + } + else if (const auto& verticalMotion = AZStd::get_if(&event)) + { + m_motionDelta.m_y = verticalMotion->m_delta; } else if (const auto& scroll = AZStd::get_if(&event)) { m_scrollDelta = scroll->m_delta; } - return m_cameras.HandleEvents(event); + return m_cameras.HandleEvents(event, m_motionDelta, m_scrollDelta); } Camera CameraSystem::StepCamera(const Camera& targetCamera, const float deltaTime) { - const auto cursorDelta = m_currentCursorPosition.has_value() && m_lastCursorPosition.has_value() - ? m_currentCursorPosition.value() - m_lastCursorPosition.value() - : ScreenVector(0, 0); - - if (m_currentCursorPosition.has_value()) - { - m_lastCursorPosition = m_currentCursorPosition; - } - - const auto nextCamera = m_cameras.StepCamera(targetCamera, cursorDelta, m_scrollDelta, deltaTime); + const auto nextCamera = m_cameras.StepCamera(targetCamera, m_motionDelta, m_scrollDelta, deltaTime); + m_motionDelta = ScreenVector{ 0, 0 }; m_scrollDelta = 0.0f; return nextCamera; @@ -192,18 +189,17 @@ namespace AzFramework m_idleCameraInputs.push_back(AZStd::move(cameraInput)); } - bool Cameras::HandleEvents(const InputEvent& event) + bool Cameras::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) { bool handling = false; for (auto& cameraInput : m_activeCameraInputs) { - cameraInput->HandleEvents(event); - handling = !cameraInput->Idle() || handling; + handling = cameraInput->HandleEvents(event, cursorDelta, scrollDelta) || handling; } for (auto& cameraInput : m_idleCameraInputs) { - cameraInput->HandleEvents(event); + handling = cameraInput->HandleEvents(event, cursorDelta, scrollDelta) || handling; } return handling; @@ -215,8 +211,11 @@ namespace AzFramework { auto& cameraInput = m_idleCameraInputs[i]; const bool canBegin = cameraInput->Beginning() && - std::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(), - [](const auto& input) { return !input->Exclusive(); }) && + AZStd::all_of(m_activeCameraInputs.cbegin(), m_activeCameraInputs.cend(), + [](const auto& input) + { + return !input->Exclusive(); + }) && (!cameraInput->Exclusive() || (cameraInput->Exclusive() && m_activeCameraInputs.empty())); if (canBegin) @@ -232,12 +231,13 @@ namespace AzFramework } } - // accumulate - Camera nextCamera = targetCamera; - for (auto& cameraInput : m_activeCameraInputs) - { - nextCamera = cameraInput->StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime); - } + const Camera nextCamera = AZStd::accumulate( + AZStd::begin(m_activeCameraInputs), AZStd::end(m_activeCameraInputs), targetCamera, + [cursorDelta, scrollDelta, deltaTime](Camera acc, auto& camera) + { + acc = camera->StepCamera(acc, cursorDelta, scrollDelta, deltaTime); + return acc; + }); for (int i = 0; i < m_activeCameraInputs.size();) { @@ -266,27 +266,63 @@ namespace AzFramework { m_activeCameraInputs[i]->Reset(); m_idleCameraInputs.push_back(m_activeCameraInputs[i]); - m_activeCameraInputs[i] = m_activeCameraInputs[m_activeCameraInputs.size() - 1]; + using AZStd::swap; + swap(m_activeCameraInputs[i], m_activeCameraInputs[m_activeCameraInputs.size() - 1]); m_activeCameraInputs.pop_back(); } } - void RotateCameraInput::HandleEvents(const InputEvent& event) + void Cameras::Clear() { - if (const auto& input = AZStd::get_if(&event)) + Reset(); + AZ_Assert(m_activeCameraInputs.empty(), "Active Camera Inputs is not empty"); + + m_idleCameraInputs.clear(); + } + + RotateCameraInput::RotateCameraInput(const InputChannelId rotateChannelId) + : m_rotateChannelId(rotateChannelId) + { + } + + bool RotateCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) + { + const ClickDetector::ClickEvent clickEvent = [&event, this] { - if (input->m_channelId == m_rotateChannelId) + if (const auto& input = AZStd::get_if(&event)) { - if (input->m_state == InputChannel::State::Began) + if (input->m_channelId == m_rotateChannelId) { - BeginActivation(); - } - else if (input->m_state == InputChannel::State::Ended) - { - EndActivation(); + if (input->m_state == InputChannel::State::Began) + { + return ClickDetector::ClickEvent::Down; + } + else if (input->m_state == InputChannel::State::Ended) + { + return ClickDetector::ClickEvent::Up; + } } } + return ClickDetector::ClickEvent::Nil; + }(); + + switch (const auto outcome = m_clickDetector.DetectClick(clickEvent, cursorDelta); outcome) + { + case ClickDetector::ClickOutcome::Move: + BeginActivation(); + break; + case ClickDetector::ClickOutcome::Release: + EndActivation(); + break; + default: + // noop + break; } + + // note - must also check !ending to ensure the mouse up (release) event + // is not consumed and can be propagated to other systems. + // (don't swallow mouse up events) + return !Idle() && !Ending(); } Camera RotateCameraInput::StepCamera( @@ -298,7 +334,10 @@ namespace AzFramework nextCamera.m_pitch -= float(cursorDelta.m_y) * ed_cameraSystemRotateSpeed; nextCamera.m_yaw -= float(cursorDelta.m_x) * ed_cameraSystemRotateSpeed; - const auto clampRotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); }; + const auto clampRotation = [](const float angle) + { + return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); + }; nextCamera.m_yaw = clampRotation(nextCamera.m_yaw); // clamp pitch to be +-90 degrees @@ -307,7 +346,14 @@ namespace AzFramework return nextCamera; } - void PanCameraInput::HandleEvents(const InputEvent& event) + PanCameraInput::PanCameraInput(const InputChannelId panChannelId, PanAxesFn panAxesFn) + : m_panAxesFn(AZStd::move(panAxesFn)) + , m_panChannelId(panChannelId) + { + } + + bool PanCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto& input = AZStd::get_if(&event)) { @@ -323,6 +369,8 @@ namespace AzFramework } } } + + return !Idle(); } Camera PanCameraInput::StepCamera( @@ -336,9 +384,10 @@ namespace AzFramework const auto deltaPanX = float(cursorDelta.m_x) * panAxes.m_horizontalAxis * ed_cameraSystemPanSpeed; const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * ed_cameraSystemPanSpeed; - const auto inv = [](const bool invert) { - constexpr float Dir[] = {1.0f, -1.0f}; - return Dir[static_cast(invert)]; + const auto inv = [](const bool invert) + { + constexpr float Dir[] = { 1.0f, -1.0f }; + return Dir[aznumeric_cast(invert)]; }; nextCamera.m_lookAt += deltaPanX * inv(ed_cameraSystemPanInvertX); @@ -382,17 +431,18 @@ namespace AzFramework return TranslationType::Nil; } - void TranslateCameraInput::HandleEvents(const InputEvent& event) + TranslateCameraInput::TranslateCameraInput(TranslationAxesFn translationAxesFn) + : m_translationAxesFn(AZStd::move(translationAxesFn)) + { + } + + bool TranslateCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto& input = AZStd::get_if(&event)) { if (input->m_state == InputChannel::State::Began) { - if (input->m_state == InputChannel::State::Updated) - { - return; - } - m_translation |= translationFromKey(input->m_channelId); if (m_translation != TranslationType::Nil) { @@ -404,7 +454,8 @@ namespace AzFramework m_boost = true; } } - else if (input->m_state == InputChannel::State::Ended) + // ensure we don't process end events in the idle state + else if (input->m_state == InputChannel::State::Ended && !Idle()) { m_translation &= ~(translationFromKey(input->m_channelId)); if (m_translation == TranslationType::Nil) @@ -417,6 +468,8 @@ namespace AzFramework } } } + + return !Idle(); } Camera TranslateCameraInput::StepCamera( @@ -430,7 +483,8 @@ namespace AzFramework const auto axisY = translationBasis.GetBasisY(); const auto axisZ = translationBasis.GetBasisZ(); - const float speed = [boost = m_boost]() { + const float speed = [boost = m_boost]() + { return ed_cameraSystemTranslateSpeed * (boost ? ed_cameraSystemBoostMultiplier : 1.0f); }(); @@ -478,7 +532,7 @@ namespace AzFramework m_boost = false; } - void OrbitCameraInput::HandleEvents(const InputEvent& event) + bool OrbitCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) { if (const auto* input = AZStd::get_if(&event)) { @@ -497,8 +551,10 @@ namespace AzFramework if (Active()) { - m_orbitCameras.HandleEvents(event); + return m_orbitCameras.HandleEvents(event, cursorDelta, scrollDelta); } + + return !Idle(); } Camera OrbitCameraInput::StepCamera( @@ -508,18 +564,41 @@ namespace AzFramework if (Beginning()) { - float hit_distance = 0.0f; - if (AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight)) - .CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance)) + const auto hasLookAt = [&nextCamera, &targetCamera, &lookAtFn = m_lookAtFn] { - hit_distance = AZStd::min(hit_distance, ed_cameraSystemMaxOrbitDistance); - nextCamera.m_lookDist = -hit_distance; - nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance; - } - else + if (lookAtFn) + { + // pass through the camera's position and look vector for use in the lookAt function + if (const auto lookAt = lookAtFn(targetCamera.Translation(), targetCamera.Rotation().GetBasisY())) + { + auto transform = AZ::Transform::CreateLookAt(targetCamera.m_lookAt, *lookAt); + nextCamera.m_lookDist = -lookAt->GetDistance(targetCamera.m_lookAt); + UpdateCameraFromTransform(nextCamera, transform); + + return true; + } + } + return false; + }(); + + if (!hasLookAt) { - nextCamera.m_lookDist = -ed_cameraSystemMaxOrbitDistance; - nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMaxOrbitDistance; + float hit_distance = 0.0f; + AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight)) + .CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance); + + if (hit_distance > 0.0f) + { + hit_distance = AZStd::min(hit_distance, ed_cameraSystemMaxOrbitDistance); + nextCamera.m_lookDist = -hit_distance; + nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance; + } + else + { + nextCamera.m_lookDist = -ed_cameraSystemMinOrbitDistance; + nextCamera.m_lookAt = + targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMinOrbitDistance; + } } } @@ -539,12 +618,15 @@ namespace AzFramework return nextCamera; } - void OrbitDollyScrollCameraInput::HandleEvents(const InputEvent& event) + bool OrbitDollyScrollCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto* scroll = AZStd::get_if(&event)) { BeginActivation(); } + + return !Idle(); } Camera OrbitDollyScrollCameraInput::StepCamera( @@ -557,7 +639,13 @@ namespace AzFramework return nextCamera; } - void OrbitDollyCursorMoveCameraInput::HandleEvents(const InputEvent& event) + OrbitDollyCursorMoveCameraInput::OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId) + : m_dollyChannelId(dollyChannelId) + { + } + + bool OrbitDollyCursorMoveCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto& input = AZStd::get_if(&event)) { @@ -573,6 +661,8 @@ namespace AzFramework } } } + + return !Idle(); } Camera OrbitDollyCursorMoveCameraInput::StepCamera( @@ -584,12 +674,15 @@ namespace AzFramework return nextCamera; } - void ScrollTranslationCameraInput::HandleEvents(const InputEvent& event) + bool ScrollTranslationCameraInput::HandleEvents( + const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] float scrollDelta) { if (const auto* scroll = AZStd::get_if(&event)) { BeginActivation(); } + + return !Idle(); } Camera ScrollTranslationCameraInput::StepCamera( @@ -610,18 +703,24 @@ namespace AzFramework Camera SmoothCamera(const Camera& currentCamera, const Camera& targetCamera, const float deltaTime) { - const auto clamp_rotation = [](const float angle) { return std::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); }; + const auto clamp_rotation = [](const float angle) + { + return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi); + }; // keep yaw in 0 - 360 range float targetYaw = clamp_rotation(targetCamera.m_yaw); const float currentYaw = clamp_rotation(currentCamera.m_yaw); // return the sign of the float input (-1, 0, 1) - const auto sign = [](const float value) { return aznumeric_cast((0.0f < value) - (value < 0.0f)); }; + const auto sign = [](const float value) + { + return aznumeric_cast((0.0f < value) - (value < 0.0f)); + }; // ensure smooth transition when moving across 0 - 360 boundary const float yawDelta = targetYaw - currentYaw; - if (std::abs(yawDelta) >= AZ::Constants::Pi) + if (AZStd::abs(yawDelta) >= AZ::Constants::Pi) { targetYaw -= AZ::Constants::TwoPi * sign(yawDelta); } @@ -629,42 +728,44 @@ namespace AzFramework Camera camera; // note: the math for the lerp smoothing implementation for camera rotation and translation was inspired by this excellent // article by Scott Lembcke: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php - const float lookRate = std::exp2(ed_cameraSystemLookSmoothness); - const float lookT = std::exp2(-lookRate * deltaTime); + const float lookRate = AZStd::exp2(ed_cameraSystemLookSmoothness); + const float lookT = AZStd::exp2(-lookRate * deltaTime); camera.m_pitch = AZ::Lerp(targetCamera.m_pitch, currentCamera.m_pitch, lookT); camera.m_yaw = AZ::Lerp(targetYaw, currentYaw, lookT); - const float moveRate = std::exp2(ed_cameraSystemTranslateSmoothness); - const float moveT = std::exp2(-moveRate * deltaTime); + const float moveRate = AZStd::exp2(ed_cameraSystemTranslateSmoothness); + const float moveT = AZStd::exp2(-moveRate * deltaTime); camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveT); camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveT); return camera; } - InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize) + InputEvent BuildInputEvent(const InputChannel& inputChannel) { const auto& inputChannelId = inputChannel.GetInputChannelId(); const auto& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId(); - const bool wasMouseButton = - AZStd::any_of(InputDeviceMouse::Button::All.begin(), InputDeviceMouse::Button::All.end(), [inputChannelId](const auto& button) { + const bool wasMouseButton = AZStd::any_of( + InputDeviceMouse::Button::All.begin(), InputDeviceMouse::Button::All.end(), + [inputChannelId](const auto& button) + { return button == inputChannelId; }); - if (inputChannelId == InputDeviceMouse::Movement::X || inputChannelId == InputDeviceMouse::Movement::Y) + if (inputChannelId == InputDeviceMouse::Movement::X) { - const auto* position = inputChannel.GetCustomData(); - AZ_Assert(position, "Expected PositionData2D but found nullptr"); - - return CursorMotionEvent{ScreenPoint( - position->m_normalizedPosition.GetX() * windowSize.m_width, position->m_normalizedPosition.GetY() * windowSize.m_height)}; + return HorizontalMotionEvent{ aznumeric_cast(inputChannel.GetValue()) }; + } + else if (inputChannelId == InputDeviceMouse::Movement::Y) + { + return VerticalMotionEvent{ aznumeric_cast(inputChannel.GetValue()) }; } else if (inputChannelId == InputDeviceMouse::Movement::Z) { - return ScrollEvent{inputChannel.GetValue()}; + return ScrollEvent{ inputChannel.GetValue() }; } else if (wasMouseButton || InputDeviceKeyboard::IsKeyboardDevice(inputDeviceId)) { - return DiscreteInputEvent{inputChannelId, inputChannel.GetState()}; + return DiscreteInputEvent{ inputChannelId, inputChannel.GetState() }; } return AZStd::monostate{}; diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h index 6ccd7c43eb..a02f796899 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -33,9 +34,9 @@ namespace AzFramework AZ::Vector3 m_lookAt = AZ::Vector3::CreateZero(); //!< Position of camera when m_lookDist is zero, //!< or position of m_lookAt when m_lookDist is greater //!< than zero. - float m_yaw{0.0}; - float m_pitch{0.0}; - float m_lookDist{0.0}; //!< Zero gives first person free look, otherwise orbit about m_lookAt + float m_yaw{ 0.0 }; + float m_pitch{ 0.0 }; + float m_lookDist{ 0.0 }; //!< Zero gives first person free look, otherwise orbit about m_lookAt //! View camera transform (v in MVP). AZ::Transform View() const; @@ -70,11 +71,16 @@ namespace AzFramework void UpdateCameraFromTransform(Camera& camera, const AZ::Transform& transform); - struct CursorMotionEvent + //! Generic motion type + template + struct MotionEvent { - ScreenPoint m_position; + int m_delta; }; + using HorizontalMotionEvent = MotionEvent; + using VerticalMotionEvent = MotionEvent; + struct ScrollEvent { float m_delta; @@ -86,7 +92,7 @@ namespace AzFramework InputChannel::State m_state; //!< Channel state. (e.g. Begin/update/end event). }; - using InputEvent = AZStd::variant; + using InputEvent = AZStd::variant; class CameraInput { @@ -147,7 +153,7 @@ namespace AzFramework ResetImpl(); } - virtual void HandleEvents(const InputEvent& event) = 0; + virtual bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) = 0; virtual Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) = 0; virtual bool Exclusive() const @@ -169,16 +175,34 @@ namespace AzFramework class Cameras { public: - void AddCamera(AZStd::shared_ptr cameraInput); - bool HandleEvents(const InputEvent& event); + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta); Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime); + + void AddCamera(AZStd::shared_ptr cameraInput); + //! Reset the state of all cameras. void Reset(); + //! Remove all cameras that were added. + void Clear(); + //! Is one of the cameras in the active camera inputs marked as 'exclusive'. + //! @note This implies no other sibling cameras can begin while the exclusive camera is running. + bool Exclusive() const; private: AZStd::vector> m_activeCameraInputs; AZStd::vector> m_idleCameraInputs; }; + inline bool Cameras::Exclusive() const + { + return AZStd::any_of( + m_activeCameraInputs.begin(), m_activeCameraInputs.end(), + [](const auto& cameraInput) + { + return cameraInput->Exclusive(); + }); + } + + //! Responsible for updating a series of cameras given various inputs. class CameraSystem { public: @@ -188,24 +212,22 @@ namespace AzFramework Cameras m_cameras; private: - float m_scrollDelta = 0.0f; - AZStd::optional m_lastCursorPosition; - AZStd::optional m_currentCursorPosition; + ScreenVector m_motionDelta; //!< The delta used for look/orbit/pan (rotation + translation) - two dimensional. + float m_scrollDelta = 0.0f; //!< The delta used for dolly/movement (translation) - one dimensional. }; class RotateCameraInput : public CameraInput { public: - explicit RotateCameraInput(const InputChannelId rotateChannelId) - : m_rotateChannelId(rotateChannelId) - { - } + explicit RotateCameraInput(InputChannelId rotateChannelId); - void HandleEvents(const InputEvent& event) override; + // CameraInput overrides ... + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; private: InputChannelId m_rotateChannelId; + ClickDetector m_clickDetector; }; struct PanAxes @@ -219,7 +241,7 @@ namespace AzFramework inline PanAxes LookPan(const Camera& camera) { const AZ::Matrix3x3 orientation = camera.Rotation(); - return {orientation.GetBasisX(), orientation.GetBasisZ()}; + return { orientation.GetBasisX(), orientation.GetBasisZ() }; } inline PanAxes OrbitPan(const Camera& camera) @@ -227,23 +249,22 @@ namespace AzFramework const AZ::Matrix3x3 orientation = camera.Rotation(); const auto basisX = orientation.GetBasisX(); - const auto basisY = [&orientation] { + const auto basisY = [&orientation] + { const auto forward = orientation.GetBasisY(); return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized(); }(); - return {basisX, basisY}; + return { basisX, basisY }; } class PanCameraInput : public CameraInput { public: - PanCameraInput(const InputChannelId panChannelId, PanAxesFn panAxesFn) - : m_panAxesFn(AZStd::move(panAxesFn)) - , m_panChannelId(panChannelId) - { - } - void HandleEvents(const InputEvent& event) override; + PanCameraInput(InputChannelId panChannelId, PanAxesFn panAxesFn); + + // CameraInput overrides ... + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; private: @@ -269,7 +290,8 @@ namespace AzFramework const AZ::Matrix3x3 orientation = camera.Rotation(); const auto basisX = orientation.GetBasisX(); - const auto basisY = [&orientation] { + const auto basisY = [&orientation] + { const auto forward = orientation.GetBasisY(); return AZ::Vector3(forward.GetX(), forward.GetY(), 0.0f).GetNormalized(); }(); @@ -281,11 +303,10 @@ namespace AzFramework class TranslateCameraInput : public CameraInput { public: - explicit TranslateCameraInput(TranslationAxesFn translationAxesFn) - : m_translationAxesFn(AZStd::move(translationAxesFn)) - { - } - void HandleEvents(const InputEvent& event) override; + explicit TranslateCameraInput(TranslationAxesFn translationAxesFn); + + // CameraInput overrides ... + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; void ResetImpl() override; @@ -354,17 +375,18 @@ namespace AzFramework class OrbitDollyScrollCameraInput : public CameraInput { public: - void HandleEvents(const InputEvent& event) override; + // CameraInput overrides ... + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; }; class OrbitDollyCursorMoveCameraInput : public CameraInput { public: - explicit OrbitDollyCursorMoveCameraInput(const InputChannelId dollyChannelId) - : m_dollyChannelId(dollyChannelId) {} + explicit OrbitDollyCursorMoveCameraInput(InputChannelId dollyChannelId); - void HandleEvents(const InputEvent& event) override; + // CameraInput overrides ... + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; private: @@ -374,25 +396,40 @@ namespace AzFramework class ScrollTranslationCameraInput : public CameraInput { public: - void HandleEvents(const InputEvent& event) override; + // CameraInput overrides ... + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; }; class OrbitCameraInput : public CameraInput { public: - void HandleEvents(const InputEvent& event) override; + using LookAtFn = AZStd::function(const AZ::Vector3& position, const AZ::Vector3& direction)>; + + // CameraInput overrides ... + bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; - bool Exclusive() const override - { - return true; - } + bool Exclusive() const override; Cameras m_orbitCameras; + + //! Override the default behavior for how a look-at point is calculated. + void SetLookAtFn(const LookAtFn& lookAtFn); + + private: + LookAtFn m_lookAtFn; }; - struct WindowSize; + inline void OrbitCameraInput::SetLookAtFn(const LookAtFn& lookAtFn) + { + m_lookAtFn = lookAtFn; + } + + inline bool OrbitCameraInput::Exclusive() const + { + return true; + } //! Map from a generic InputChannel event to a camera specific InputEvent. - InputEvent BuildInputEvent(const InputChannel& inputChannel, const WindowSize& windowSize); + InputEvent BuildInputEvent(const InputChannel& inputChannel); } // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp index b7603e5c4c..4a443cb4bf 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp @@ -74,7 +74,6 @@ namespace AzFramework void SetCameraClippingVolumeFromPerspectiveFovMatrixRH(CameraState& cameraState, const AZ::Matrix4x4& clipFromView) { - const float m11 = clipFromView(1, 1); const float m22 = clipFromView(2, 2); const float m23 = clipFromView(2, 3); cameraState.m_nearClip = m23 / m22; @@ -84,7 +83,12 @@ namespace AzFramework { AZStd::swap(cameraState.m_nearClip, cameraState.m_farClip); } - cameraState.m_fovOrZoom = 2 * (AZ::Constants::HalfPi - atanf(m11)); + cameraState.m_fovOrZoom = RetrieveFov(clipFromView); + } + + float RetrieveFov(const AZ::Matrix4x4& clipFromView) + { + return 2.0f * (AZ::Constants::HalfPi - AZStd::atan(clipFromView(1, 1))); } void CameraState::Reflect(AZ::SerializeContext& serializeContext) diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h index 71d0a932c7..2565612bc3 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h @@ -17,54 +17,57 @@ namespace AzFramework { - /// Represents the camera state populated by the viewport camera. + //! Represents the camera state populated by the viewport camera. struct CameraState { - /// @cond + //! @cond AZ_TYPE_INFO(CameraState, "{D309D934-044C-4BA8-91F1-EA3A45177A52}") CameraState() = default; - /// @endcond + //! @endcond static void Reflect(AZ::SerializeContext& context); - /// Return the vertical fov of the camera when the view is in perspective. + //! Return the vertical fov of the camera when the view is in perspective. float VerticalFovRadian() const { return m_fovOrZoom; } - /// Return the zoom amount of the camera when the view is in orthographic. + //! Return the zoom amount of the camera when the view is in orthographic. float Zoom() const { return m_fovOrZoom; } - AZ::Vector3 m_position = AZ::Vector3::CreateZero(); ///< World position of the camera. - AZ::Vector3 m_forward = AZ::Vector3::CreateAxisY(); ///< Forward look direction of the camera (world space). - AZ::Vector3 m_side = AZ::Vector3::CreateAxisX(); ///< Side vector of camera (orthogonal to forward and up). - AZ::Vector3 m_up = AZ::Vector3::CreateAxisZ(); ///< Up vector of the camera (cameras frame - world space). - AZ::Vector2 m_viewportSize = AZ::Vector2::CreateZero(); ///< Dimensions of the viewport. - float m_nearClip = 0.01f; ///< Near clip plane of the camera. - float m_farClip = 100.0f; ///< Far clip plane of the camera. - float m_fovOrZoom = 0.0f; ///< Fov or zoom of camera depending on if it is using orthographic projection or not. - bool m_orthographic = false; ///< Is the camera using orthographic projection or not. + AZ::Vector3 m_position = AZ::Vector3::CreateZero(); //!< World position of the camera. + AZ::Vector3 m_forward = AZ::Vector3::CreateAxisY(); //!< Forward look direction of the camera (world space). + AZ::Vector3 m_side = AZ::Vector3::CreateAxisX(); //!< Side vector of camera (orthogonal to forward and up). + AZ::Vector3 m_up = AZ::Vector3::CreateAxisZ(); //!< Up vector of the camera (cameras frame - world space). + AZ::Vector2 m_viewportSize = AZ::Vector2::CreateZero(); //!< Dimensions of the viewport. + float m_nearClip = 0.01f; //!< Near clip plane of the camera. + float m_farClip = 100.0f; //!< Far clip plane of the camera. + float m_fovOrZoom = 0.0f; //!< Fov or zoom of camera depending on if it is using orthographic projection or not. + bool m_orthographic = false; //!< Is the camera using orthographic projection or not. }; - /// Create a camera at the given transform with a specific viewport size. - /// @note The near/far clip planes and fov are sensible default values - please - /// use SetCameraClippingVolume to override them. + //! Create a camera at the given transform with a specific viewport size. + //! @note The near/far clip planes and fov are sensible default values - please + //! use SetCameraClippingVolume to override them. CameraState CreateDefaultCamera(const AZ::Transform& transform, const AZ::Vector2& viewportSize); - /// Create a camera at the given position (no orientation) with a specific viewport size. - /// @note The near/far clip planes and fov are sensible default values - please - /// use SetCameraClippingVolume to override them. + //! Create a camera at the given position (no orientation) with a specific viewport size. + //! @note The near/far clip planes and fov are sensible default values - please + //! use SetCameraClippingVolume to override them. CameraState CreateIdentityDefaultCamera(const AZ::Vector3& position, const AZ::Vector2& viewportSize); - /// Create a camera transformed by the given view to world matrix with a specific viewport size. - /// @note The near/far clip planes and fov are sensible default values - please - /// use SetCameraClippingVolume to override them. + //! Create a camera transformed by the given view to world matrix with a specific viewport size. + //! @note The near/far clip planes and fov are sensible default values - please + //! use SetCameraClippingVolume to override them. CameraState CreateCameraFromWorldFromViewMatrix(const AZ::Matrix4x4& worldFromView, const AZ::Vector2& viewportSize); - /// Override the default near/far clipping planes and fov of the camera. + //! Override the default near/far clipping planes and fov of the camera. void SetCameraClippingVolume(CameraState& cameraState, float nearPlane, float farPlane, float fovRad); - /// Override the default near/far clipping planes and fov of the camera by inferring them the specified right handed transform into clip space. + //! Override the default near/far clipping planes and fov of the camera by inferring them the specified right handed transform into clip space. void SetCameraClippingVolumeFromPerspectiveFovMatrixRH(CameraState& cameraState, const AZ::Matrix4x4& clipFromView); - /// Set the transform for an existing camera. + //! Retrieve the field of view (Fov) from the perspective projection matrix (view space to clip space). + float RetrieveFov(const AZ::Matrix4x4& clipFromView); + + //! Set the transform for an existing camera. void SetCameraTransform(CameraState& cameraState, const AZ::Transform& transform); } // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.cpp new file mode 100644 index 0000000000..c276463554 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.cpp @@ -0,0 +1,73 @@ +/* + * 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. + * + */ + +#include +#include + +namespace AzFramework +{ + ClickDetector::ClickOutcome ClickDetector::DetectClick(const ClickEvent clickEvent, const ScreenVector& cursorDelta) + { + const auto previousDetectionState = m_detectionState; + if (previousDetectionState == DetectionState::WaitingForMove) + { + // only allow the action to begin if the mouse has been moved a small amount + m_moveAccumulator += ScreenVectorLength(cursorDelta); + if (m_moveAccumulator > m_deadZone) + { + m_detectionState = DetectionState::Moved; + } + } + + if (clickEvent == ClickEvent::Down) + { + const auto now = std::chrono::steady_clock::now(); + if (m_tryBeginTime) + { + const std::chrono::duration diff = now - m_tryBeginTime.value(); + if (diff.count() < m_doubleClickInterval) + { + return ClickOutcome::Nil; + } + } + + m_detectionState = DetectionState::WaitingForMove; + m_moveAccumulator = 0.0f; + + m_tryBeginTime = now; + } + else if (clickEvent == ClickEvent::Up) + { + const auto clickOutcome = [detectionState = m_detectionState] { + if (detectionState == DetectionState::WaitingForMove) + { + return ClickOutcome::Click; + } + if (detectionState == DetectionState::Moved) + { + return ClickOutcome::Release; + } + return ClickOutcome::Nil; + }(); + + m_detectionState = DetectionState::Nil; + return clickOutcome; + } + + if (previousDetectionState == DetectionState::WaitingForMove && m_detectionState == DetectionState::Moved) + { + return ClickOutcome::Move; + } + + return ClickOutcome::Nil; + } +} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.h b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.h new file mode 100644 index 0000000000..a595735d28 --- /dev/null +++ b/Code/Framework/AzFramework/AzFramework/Viewport/ClickDetector.h @@ -0,0 +1,84 @@ +/* + * 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. + * + */ + +#pragma once + +#include + +#include + +namespace AzFramework +{ + struct ScreenVector; + + //! Utility class to help detect different types of mouse click (mouse down and up with + //! no movement), mouse move (down and initial move after some threshold) and mouse release + //! (mouse down with movement and then mouse up). + class ClickDetector + { + //! Alias for recording time of mouse down events + using Time = std::chrono::time_point; + + public: + //! Internal representation of click event (map from external event for this when + //! calling DetectClick). + enum class ClickEvent + { + Nil, + Down, + Up + }; + + //! The type of mouse click. + enum class ClickOutcome + { + Nil, //!< Not recognized. + Move, //!< Initial move after mouse down. + Click, //!< Mouse down and up with no intermediate movement. + Release //!< Mouse down with movement and then mouse up. + }; + + //! Called from any type of 'handle event' function. + ClickOutcome DetectClick(ClickEvent clickEvent, const ScreenVector& cursorDelta); + + //! Override the default double click interval. + //! @note Default is 400ms - system default. + void SetDoubleClickInterval(float doubleClickInterval); + //! Override the dead zone before a 'move' outcome will be triggered. + void SetDeadZone(float deadZone); + + private: + //! Internal state of ClickDetector based on incoming events. + enum class DetectionState + { + Nil, //!< Initial state + WaitingForMove, //! Mouse down has happened but mouse hasn't yet moved. + Moved //! Mouse has moved, no longer will be counted as a click. + }; + + float m_moveAccumulator = 0.0f; //!< How far the mouse has moved after mouse down. + float m_deadZone = 2.0f; //!< How far to move before a click is cancelled (when Move will fire). + float m_doubleClickInterval = 0.4f; //!< Default double click interval, can be overridden. + DetectionState m_detectionState; //!< Internal state of ClickDetector. + AZStd::optional