Merge pull request #11 from AMZN-alexpete/github/staging
Integrating latest from github/staging
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
*.ilk
|
||||
*.suo
|
||||
*.user
|
||||
*.o
|
||||
*.temp
|
||||
*.bootstrap.digests
|
||||
*.log
|
||||
*.exp
|
||||
*.vssettings
|
||||
*.exportlog
|
||||
*.mayaSwatches
|
||||
*.ma.swatches
|
||||
*.bak
|
||||
*.bak2
|
||||
*.akd
|
||||
Solutions
|
||||
BinTemp
|
||||
*.options
|
||||
*.pyc
|
||||
*.db
|
||||
Cache
|
||||
AssetProcessor_tmp.exe
|
||||
Builders_Temp
|
||||
Bin64vc*
|
||||
$tmp*
|
||||
.pytest_cache
|
||||
__pycache__
|
||||
# Python Module egg file
|
||||
*.egg
|
||||
*.egg-link
|
||||
@@ -1,590 +0,0 @@
|
||||
; ---- Enable/Disable platforms for the entire project. AssetProcessor will automatically add the current platform by default.
|
||||
|
||||
; PLATFORM DEFINITIONS
|
||||
; [Platform (unique identifier)]
|
||||
; tags=(comma-seperated-tags)
|
||||
;
|
||||
; note: the 'identifier' of a platform is the word(s) following the "Platform" keyword (so [Platform pc] means identifier
|
||||
; is 'pc' for example. This is used to name its assets folder in the cache and should be used in your bootstrap.cfg
|
||||
; or your main.cpp to choose what assets to load for that particular platform.
|
||||
; Its primary use is to enable additional non-host platforms (Ios, android...) that are not the current platform.
|
||||
; note: 'tags' is a comma-seperated list of tags to tag the platform with that builders can inspect to decide what to do.
|
||||
|
||||
; while builders can accept any tags you add in order to make decisions, common tags are
|
||||
; tools - this platform can host the tools and editor and such
|
||||
; renderer - this platform runs the client engine and renders on a GPU. If missing we could be on a server-only platform
|
||||
; mobile - a mobile platform such as a set top box or phone with limited resources
|
||||
; console - a console platform
|
||||
; server - a server platform of some kind, usually headless, no renderer.
|
||||
|
||||
[Platform pc]
|
||||
tags=tools,renderer,dx12,vulkan
|
||||
|
||||
[Platform es3]
|
||||
tags=android,mobile,renderer,vulkan
|
||||
|
||||
[Platform ios]
|
||||
tags=mobile,renderer,metal
|
||||
|
||||
[Platform osx_gl]
|
||||
tags=tools,renderer,metal
|
||||
|
||||
; this is an example of a headless platform that has no renderer.
|
||||
; To use this you would still need to make sure 'assetplatform' in your startup params in your main() chooses this 'server' platform as your server 'assets' flavor
|
||||
[Platform server]
|
||||
tags=server,dx12,vulkan
|
||||
|
||||
; this section allows you to turn on various platforms in addition to the host platform you're running on
|
||||
; 'enabled' is AUTOMATICALLY TRUE for the current platform that you are running on, so it is not necessary to force it to true for that platform
|
||||
; To enable any additional platform, just uncomment the appropriate line below.
|
||||
|
||||
[Platforms]
|
||||
;pc=enabled
|
||||
;es3=enabled
|
||||
;ios=enabled
|
||||
;osx_gl=enabled
|
||||
;jasper=enabled
|
||||
;provo=enabled
|
||||
;salem=enabled
|
||||
;server=enabled
|
||||
|
||||
; ---- The number of worker jobs, 0 means use the number of Logical Cores
|
||||
[Jobs]
|
||||
minJobs=1
|
||||
maxJobs=0
|
||||
|
||||
; cacheServerAddress is the location of the asset server cache.
|
||||
; Currently for a network share server this would be the absolute file path to the network share folder.
|
||||
[Server]
|
||||
;cacheServerAddress=
|
||||
|
||||
; ---- add any metadata file type here that needs to be monitored by the AssetProcessor.
|
||||
; Modifying these meta file will cause the source asset to re-compile again.
|
||||
; They are specified in the following format
|
||||
; metadata extension=original extension to replace
|
||||
; if the metadata extension does not replace the original, then the original can be blank
|
||||
; so for example if your normal file is blah.tif and your metafile for that file is blah.tif.exportsettings
|
||||
; then your declaration would be exportsettings= ; ie, it would be blank
|
||||
; however if your metafile REPLACES the extension (for example, if you have the file blah.i_caf and its metafile is blah.exportsettings)
|
||||
; then you specify the original extension here to narrow the scope.
|
||||
; If a relative path to a specific file is provided instead of an extension, a change to the file will change all files
|
||||
; with the associated extension (e.g. Animations/SkeletonList.xml=i_caf will cause all i_caf files to recompile when
|
||||
; Animations/SkeletonList.xml within the current game project changes)
|
||||
|
||||
[MetaDataTypes]
|
||||
exportsettings=
|
||||
animsettings=i_caf
|
||||
Animations/SkeletonList.xml=i_caf
|
||||
cbc=abc
|
||||
fbx.assetinfo=fbx
|
||||
|
||||
; ---- add any folders to scan here. The priority order is the order they appear here
|
||||
; available macros are
|
||||
; @ROOT@ - the location of engineroot.txt
|
||||
; @GAMENAME@ - the name of the current game project, for example 'RPGSample'
|
||||
; note that they are sorted by their 'order' value, and the lower the order the more important an asset is
|
||||
; lower order numbers override higher ones.
|
||||
; If specified, output will be prepended to every path found in that recognizer's watch folder.
|
||||
; Note that you can also make the scan folder platform specific by using the keywords include and exclude.
|
||||
; Both include and exclude can contain either platform tags, platform identifiers or both.
|
||||
; if no include is specified, all currently enabled platforms are included by default.
|
||||
; If includes ARE specified, it will be filtered down by the list of currently enabled platforms.
|
||||
; [ScanFolder (unique identifier)]
|
||||
; include = (comma seperated platform tags or identifiers)
|
||||
; exclude = (comma seperated platform tags or identifiers)
|
||||
; For example if you want to include a scan folder only for platforms that have the platform tags tools and renderer
|
||||
; but omit it for platform osx_gl, you will have a scanfolder rule like
|
||||
; [ScanFolder (unique identifier)]
|
||||
; watch=@ROOT@/foo
|
||||
; include = tools, renderer
|
||||
; exclude = osx_gl
|
||||
|
||||
[ScanFolder Game]
|
||||
watch=@ROOT@/@GAMENAME@
|
||||
display=@GAMENAME@
|
||||
recursive=1
|
||||
order=0
|
||||
|
||||
; gems will be auto-added from 100 onwards
|
||||
|
||||
[ScanFolder Root]
|
||||
watch=@ROOT@
|
||||
recursive=0
|
||||
order=10000
|
||||
|
||||
[ScanFolder Engine]
|
||||
watch=@ENGINEROOT@/Engine
|
||||
recursive=1
|
||||
order=20000
|
||||
|
||||
[ScanFolder Editor]
|
||||
watch=@ENGINEROOT@/Editor
|
||||
output=editor
|
||||
recursive=1
|
||||
order=30000
|
||||
include=tools,renderer
|
||||
|
||||
|
||||
;Excludes files that match the pattern or glob
|
||||
; if you use a pattern, remember to escape your backslashes (\\)
|
||||
[Exclude _LevelBackups]
|
||||
pattern=.*\\/Levels\\/.*\\/_savebackup\\/.*
|
||||
|
||||
[Exclude _LevelAutoBackups]
|
||||
pattern=.*\\/Levels\\/.*\\/_autobackup\\/.*
|
||||
|
||||
[Exclude HoldFiles]
|
||||
pattern=.*\\/Levels\\/.*_hold\\/.*
|
||||
|
||||
[Exclude TempFiles]
|
||||
; note that $ has meaning to regex, so we escape it.
|
||||
pattern=.*\\/\\$tmp[0-9]*_.*
|
||||
|
||||
[Exclude AlembicCompressionTemplates]
|
||||
pattern=.*\\/Presets\\/GeomCache\\/.*
|
||||
|
||||
[Exclude TmpAnimationCompression]
|
||||
pattern=.*\\/Editor\\/Tmp\\/AnimationCompression\\/.*
|
||||
|
||||
[Exclude EventLog]
|
||||
pattern=.*\\/Editor\\/.*eventlog\\.xml
|
||||
|
||||
[Exclude GameGemsCode]
|
||||
pattern=.*\\/Gem\\/Code\\/.*
|
||||
|
||||
[Exclude GameGemsResources]
|
||||
pattern=.*\\/Gem\\/Resources\\/.*
|
||||
|
||||
[Exclude Private Certs]
|
||||
pattern=.*\DynamicContent\\/Certificates\\/Private\\/.*
|
||||
|
||||
[Exclude CMakeLists]
|
||||
pattern=.*\\/CMakeLists.txt
|
||||
|
||||
[Exclude CMakeFiles]
|
||||
pattern=.*\\/.*\\.cmake
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Large Worlds Test
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
[Exclude Work In Progress Folders]
|
||||
pattern=.*\\/WIP\\/.*
|
||||
|
||||
[Exclude Content Source Folders]
|
||||
pattern=.*\\/CONTENT_SOURCE\\/.*
|
||||
|
||||
[Exclude Art Source Folders]
|
||||
pattern=.*\\/ArtSource\\/.*
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; RC params mapping examples
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
; note that productAssetType is a means of setting the output asset Type (as in AZ::Data::AssetType) of a simple job
|
||||
; and is the recommended way to specify that a certain kind of file (such as '*.myextension') becomes registered as the
|
||||
; actual UUID of that type in the engine itself.
|
||||
|
||||
; Use a regex for matching files, same params for all platforms
|
||||
;[RC TGAs]
|
||||
;pattern=.+\\.tga$
|
||||
;params=/tga /texture
|
||||
|
||||
; Use a glob, have special params for es3 platform
|
||||
;[RC TIFFs]
|
||||
;glob=*.tif
|
||||
;params=/texture
|
||||
;es3=/pvrt
|
||||
|
||||
; You can also modify a version to compile all matching files again
|
||||
; By default the version is empty
|
||||
;[RC tif]
|
||||
;glob=*.tif
|
||||
;params = \\someparams
|
||||
;version =1.0
|
||||
; This will make the AssetProcessor compile all the .tif files again
|
||||
|
||||
; you can also optionally supply a priority.
|
||||
; this is used to sort jobs when no other external circumstance sorts them
|
||||
; for example, copy jobs will be higher in priority than other jobs that are not copy jobs
|
||||
; however if they're both copy jobs or both not, and no other circumstances apply, then priority will be used.
|
||||
; default priority is zero if not specified
|
||||
|
||||
; you can specify an option to skip processing for a file type based on the platform.
|
||||
; for example, if you dont want to process tif files for ios, you can make tif files
|
||||
; process on any platform except for ios:
|
||||
;[RC tif]
|
||||
;glob=*.tif
|
||||
;params = \\someparams
|
||||
;ios=skip
|
||||
|
||||
; you can specify an option to output product dependencies for a copy job.
|
||||
; please note that you only need to set this option when cry code is required to parse the asset.
|
||||
; otherwise product dependencies will be output automatically by the CopyDependencyBuilder.
|
||||
; for example, if you want to output the product dependencies for font assets:
|
||||
;[RC font]
|
||||
;glob=*.font
|
||||
;params=copy
|
||||
;outputProductDependencies=true
|
||||
|
||||
; you can also specify an option to make all jobs critical that matches some pattern/glob.
|
||||
; for example, if you want to make all png files critical than set critical to true.
|
||||
; Note that by default all copy jobs are critical.
|
||||
; Critical jobs are processed before non critical jobs and also prevent the runtime or editor from starting until they are all complete.
|
||||
;[RC png]
|
||||
;glob=*.png
|
||||
;params = \\someparams
|
||||
;critical=true
|
||||
|
||||
; you can also specify an option to make all the job store in the asset server cache location if you are running AP in server mode.
|
||||
; For example, if you want to store all png jobs in the asset server cache location including their logs, you can set checkServer = true.
|
||||
; The client(i.e if you are running AP in non-server mode) will also check for this flag to know which jobs to fetch from the asset server cache location.
|
||||
; if unsucessful, it will process the job locally as usual.
|
||||
;[RC png]
|
||||
;glob=*.png
|
||||
;params = \\someparams
|
||||
;critical=true
|
||||
;checkServer=true
|
||||
|
||||
; note that the FULL PATH to the file will be used as the match, not the relative path
|
||||
; so ensure start your patterns with .* or as appropriate.
|
||||
; Also, any rules which match will apply - so if you have two rules which both apply to PNG files for example
|
||||
; but you only want one, you might want to use exclusion patterns:
|
||||
|
||||
;Example: process everything EXCEPT the ones in the libs/ui folder with these params
|
||||
;[RC png-normal]
|
||||
;pattern=(?!.*libs\\/ui\\/).*\\.png
|
||||
;params=/imagecompressor=CTSquish /streaming=0
|
||||
;lockSource=true
|
||||
|
||||
;Example: Process everything in the libs/ui folder with linear color space
|
||||
;[RC png-ui]
|
||||
;pattern=(.*libs\\/ui\\/).*\\.png
|
||||
;params=/imagecompressor=CTSquish /streaming=0 /colorspace=linear,linear
|
||||
;lockSource=true
|
||||
|
||||
; More example Regexes:
|
||||
; pattern=(?!(.*libs\\/ui\\/)|(.*editor\\/).*\\.png
|
||||
; This pattern will not match anything with editor/ or libs/ui/ in it
|
||||
; pattern=((.*libs\\/ui\\/)|(.*editor\\/).*\\.png
|
||||
; This pattern will only match anything with editor/ or libs/ui/ in it
|
||||
|
||||
;Give every [Section Name] its own unique Name or else they will overwrite each other!
|
||||
|
||||
[RC i_caf]
|
||||
glob=*.i_caf
|
||||
params=/cafAlignTracks=1 /animConfigFolder=Animations /skipdba=1 /refresh=1
|
||||
; force server to send the 'pc' platform to RC.EXE so it compiles the same as PC.
|
||||
server=/cafAlignTracks=1 /animConfigFolder=Animations /skipdba=1 /refresh=1 /p=pc
|
||||
priority=5
|
||||
productAssetType={6023CFF8-FCBA-4528-A8BF-6E0E10B9AB9C}
|
||||
|
||||
[RC caf]
|
||||
glob=*.caf
|
||||
params=copy
|
||||
productAssetType={6023CFF8-FCBA-4528-A8BF-6E0E10B9AB9C}
|
||||
; same as above
|
||||
|
||||
[RC mp4]
|
||||
glob=*.mp4
|
||||
params=copy
|
||||
productAssetType={DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}
|
||||
|
||||
[RC mkv]
|
||||
glob=*.mkv
|
||||
params=copy
|
||||
productAssetType={DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}
|
||||
; same as above
|
||||
|
||||
[RC webm]
|
||||
glob=*.webm
|
||||
params=copy
|
||||
productAssetType={DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}
|
||||
; same as above
|
||||
|
||||
[RC mov]
|
||||
glob=*.mov
|
||||
params=copy
|
||||
productAssetType={DDFEE0B2-9E5A-412C-8C77-AB100E24C1DF}
|
||||
; same as above
|
||||
|
||||
[RC bk2]
|
||||
glob=*.bk2
|
||||
params=copy
|
||||
productAssetType={BF4879B9-B893-41D2-80E9-24A7BDCD2B50}
|
||||
|
||||
[RC img]
|
||||
glob=*.img
|
||||
params=copy
|
||||
|
||||
[RC dba]
|
||||
glob=*.dba
|
||||
params=copy
|
||||
productAssetType={511562BE-65A5-4538-A5F1-AC685366243E}
|
||||
version=2
|
||||
|
||||
[RC cgf]
|
||||
glob=*.cgf
|
||||
params=/VertexPositionFormat=exporter /VertexIndexFormat=u32
|
||||
; on server, feed rc.exe the param /p=pc to force it to compile assets for server platform in pc format.
|
||||
server=/VertexPositionFormat=exporter /VertexIndexFormat=u32 /p=pc
|
||||
lockSource=true
|
||||
priority=10
|
||||
; allow CGF files to compile first, so untextured models appear before their textures for faster startup
|
||||
; other available params: /SplitLODs=1
|
||||
|
||||
[RC surfaceTagNameList]
|
||||
glob=*.surfaceTagNameList
|
||||
params=copy
|
||||
productAssetType={A471B2A9-85FC-4993-842D-1881CBC03A2B}
|
||||
|
||||
[RC gradImageSettings]
|
||||
glob=*.gradimagesettings
|
||||
params=copy
|
||||
productAssetType={B36FEB5C-41B6-4B58-A212-21EF5AEF523C}
|
||||
|
||||
[RC fbx]
|
||||
glob=*.fbx
|
||||
; Priority set to 9 so its "before" things like materials but after things like actors and motions (which build using a proper AssetBuilderSDK builder and thus are not in this file)
|
||||
priority=9
|
||||
version=5
|
||||
|
||||
[RC chr]
|
||||
glob=*.chr
|
||||
params=copy
|
||||
productAssetType={60161B46-21F0-4396-A4F0-F2CCF0664CDE}
|
||||
version=2
|
||||
|
||||
[RC skin]
|
||||
glob=*.skin
|
||||
params=copy
|
||||
|
||||
[RC cfi]
|
||||
glob=*.cfi
|
||||
params=copy
|
||||
|
||||
[RC cfx]
|
||||
glob=*.cfx
|
||||
params=copy
|
||||
|
||||
[RC cfr]
|
||||
glob=*.cfr
|
||||
params=copy
|
||||
|
||||
; Warning: If you change the VertexIndexFormat, make sure you update the vtx_idx typedef in Code\CryEngine\CryCommon\ProjectDefines.h
|
||||
[RC abc]
|
||||
glob=*.abc
|
||||
params=/SkipFilesWithoutBuildConfig=0 /VertexIndexFormat=u32
|
||||
console=/SkipFilesWithoutBuildConfig=0 /VertexIndexFormat=u32
|
||||
mobile=/SkipFilesWithoutBuildConfig=0 /VertexIndexFormat=u16
|
||||
version=3
|
||||
server=skip
|
||||
|
||||
[RC png-entityicon]
|
||||
pattern=(.*EntityIcons\\/).*\\.png
|
||||
productAssetType={3436C30E-E2C5-4C3B-A7B9-66C94A28701B}
|
||||
params=skip ; only tools-supporting platforms should copy this file. Everyone else can skip.
|
||||
tools=copy
|
||||
|
||||
[RC usm]
|
||||
glob=*.usm
|
||||
params=copy
|
||||
server=skip
|
||||
|
||||
[RC animevents]
|
||||
glob=*.animevents
|
||||
params=copy
|
||||
productAssetType={C1D209C1-F81A-4586-A34E-1615995F9F3F}
|
||||
version=2
|
||||
|
||||
[RC adb]
|
||||
glob=*.adb
|
||||
params=copy
|
||||
productAssetType={50908273-CA36-4668-9828-15DD5092F973}
|
||||
|
||||
[RC bspace]
|
||||
glob=*.bspace
|
||||
params=copy
|
||||
|
||||
[RC cdf]
|
||||
glob=*.cdf
|
||||
params=copy
|
||||
productAssetType={DF036C63-9AE6-4AC3-A6AC-8A1D76126C01}
|
||||
; note - this used to be skinnedMeshAsset but its now Character Definition File specific.
|
||||
; .skin has its own type.
|
||||
|
||||
[RC chrparams]
|
||||
glob=*.chrparams
|
||||
params=copy
|
||||
productAssetType={4BBB785A-6824-4803-A607-F9323E7BEEF1}
|
||||
version=2
|
||||
|
||||
[RC comb]
|
||||
glob=*.comb
|
||||
params=copy
|
||||
|
||||
[RC dlg]
|
||||
glob=*.dlg
|
||||
params=copy
|
||||
|
||||
[RC csv]
|
||||
glob=*.csv
|
||||
params=copy
|
||||
|
||||
[RC json]
|
||||
glob=*.json
|
||||
params=copy
|
||||
|
||||
[RC lmg]
|
||||
glob=*.lmg
|
||||
params=copy
|
||||
|
||||
[RC smtl]
|
||||
glob=*.smtl
|
||||
params=copy
|
||||
|
||||
[RC sub]
|
||||
glob=*.sub
|
||||
params=copy
|
||||
productAssetType={71F9D30E-13F7-40D6-A3C9-E5358004B31F}
|
||||
version=2
|
||||
|
||||
[RC sbsar]
|
||||
glob=*.sbsar
|
||||
params=copy
|
||||
|
||||
[RC loc.agsxml]
|
||||
glob=*.loc.agsxml
|
||||
params=copy
|
||||
version=1
|
||||
|
||||
[RC node]
|
||||
glob=*.node
|
||||
params=copy
|
||||
|
||||
[RC veg]
|
||||
glob=*.veg
|
||||
params=copy
|
||||
|
||||
[RC dat]
|
||||
glob=*.dat
|
||||
params=copy
|
||||
|
||||
[RC lut]
|
||||
glob=*.lut
|
||||
params=copy
|
||||
|
||||
[RC txt]
|
||||
pattern=^(?!.*PreloadLibs.txt).*\\.txt
|
||||
params=copy
|
||||
|
||||
[RC cal]
|
||||
glob=*.cal
|
||||
params=copy
|
||||
|
||||
[RC grp]
|
||||
glob=*.grp
|
||||
params=copy
|
||||
productAssetType={7629EDD3-A361-49A2-B271-252127097D81}
|
||||
version=2
|
||||
|
||||
[RC xls]
|
||||
glob=*.xls
|
||||
params=copy
|
||||
|
||||
[RC ini]
|
||||
glob=*.ini
|
||||
params=copy
|
||||
|
||||
[RC ttf]
|
||||
glob=*.ttf
|
||||
params=copy
|
||||
|
||||
[RC otf]
|
||||
glob=*.otf
|
||||
params=copy
|
||||
|
||||
[RC ext]
|
||||
glob=*.ext
|
||||
params=copy
|
||||
|
||||
[RC pak]
|
||||
; Copy all pak files except level.pak, level.pak has its own builder.
|
||||
pattern=^((?!\\/level\\.pak).)*\\.pak$
|
||||
params=copy
|
||||
|
||||
[RC ctc]
|
||||
glob=*.ctc
|
||||
params=copy
|
||||
|
||||
[RC uiprefab]
|
||||
glob=*.uiprefab
|
||||
params=copy
|
||||
server=skip
|
||||
|
||||
[RC sprite]
|
||||
glob=*.sprite
|
||||
params=copy
|
||||
server=skip
|
||||
|
||||
[RC bin]
|
||||
glob=*.bin
|
||||
params=copy
|
||||
|
||||
[RC inputbindings]
|
||||
glob=*.inputbindings
|
||||
params=copy
|
||||
productAssetType={25971C7A-26E2-4D08-A146-2EFCC1C36B0C}
|
||||
|
||||
[RC physmaterial]
|
||||
glob=*.physmaterial
|
||||
params=copy
|
||||
productAssetType={9E366D8C-33BB-4825-9A1F-FA3ADBE11D0F}
|
||||
|
||||
[RC ocm]
|
||||
glob=*.ocm
|
||||
params=copy
|
||||
|
||||
; Feature tests use the raw .tif files for the golden image comparison
|
||||
[RC goldenimages]
|
||||
pattern=.*GoldenImages\\/.*\\.tif
|
||||
params=copy
|
||||
server=skip
|
||||
|
||||
; Copy over certificates for use with FileDataSource
|
||||
[RC CertificatePEM]
|
||||
glob=*.pem
|
||||
params=copy
|
||||
|
||||
; Copy over certificates for use with Dynamic Content
|
||||
[RC CertificateDER]
|
||||
glob=*.der
|
||||
params=copy
|
||||
|
||||
[RC PhysXMeshAsset]
|
||||
glob=*.pxmesh
|
||||
params=copy
|
||||
productAssetType={7A2871B9-5EAB-4DE0-A901-B0D2C6920DDB}
|
||||
|
||||
; Copy over cooked PhysX heightfield
|
||||
[RC PhysX HeightField]
|
||||
glob=*.pxheightfield
|
||||
params=copy
|
||||
productAssetType={B61189FE-B2D7-4AF1-8951-CB5C0F7834FC}
|
||||
|
||||
[RC filetag]
|
||||
glob=*.filetag
|
||||
params=copy
|
||||
productAssetType={F3BE5CAB-85B7-44B7-9495-863863F6B267}
|
||||
|
||||
; Precompiled shader srg
|
||||
[RC azsrg]
|
||||
glob=*.azsrg
|
||||
params=copy
|
||||
productAssetType={F8C9F4AE-3F6A-45AD-B4FB-0CA415FCC2E1}
|
||||
|
||||
; Precompiled shader variant
|
||||
[RC azshadervariant]
|
||||
glob=*.azshadervariant
|
||||
params=copy
|
||||
productAssetType={9F4D654B-4439-4C61-8DCD-F1C7C5560768}
|
||||
+224
-15
@@ -1,4 +1,23 @@
|
||||
{
|
||||
// ---- Enable/Disable platforms for the entire project. AssetProcessor will automatically add the current platform by default.
|
||||
|
||||
// PLATFORM DEFINITIONS
|
||||
// [Platform (unique identifier)]
|
||||
// tags=(comma-seperated-tags)
|
||||
//
|
||||
// note: the 'identifier' of a platform is the word(s) following the "Platform" keyword (so [Platform pc] means identifier
|
||||
// is 'pc' for example. This is used to name its assets folder in the cache and should be used in your bootstrap.cfg
|
||||
// or your main.cpp to choose what assets to load for that particular platform.
|
||||
// Its primary use is to enable additional non-host platforms (Ios, android...) that are not the current platform.
|
||||
// note: 'tags' is a comma-seperated list of tags to tag the platform with that builders can inspect to decide what to do.
|
||||
|
||||
// while builders can accept any tags you add in order to make decisions, common tags are
|
||||
// tools - this platform can host the tools and editor and such
|
||||
// renderer - this platform runs the client engine and renders on a GPU. If missing we could be on a server-only platform
|
||||
// mobile - a mobile platform such as a set top box or phone with limited resources
|
||||
// console - a console platform
|
||||
// server - a server platform of some kind, usually headless, no renderer.
|
||||
|
||||
"Amazon": {
|
||||
"AssetProcessor": {
|
||||
"Settings": {
|
||||
@@ -14,27 +33,82 @@
|
||||
"Platform osx_gl": {
|
||||
"tags": "tools,renderer,metal"
|
||||
},
|
||||
// this is an example of a headless platform that has no renderer.
|
||||
// To use this you would still need to make sure 'assetplatform' in your startup params in your main() chooses this 'server' platform as your server 'assets' flavor
|
||||
"Platform server": {
|
||||
"tags": "server,dx12,vulkan"
|
||||
},
|
||||
// this section allows you to turn on various platforms in addition to the host platform you're running on
|
||||
// 'enabled' is AUTOMATICALLY TRUE for the current platform that you are running on, so it is not necessary to force it to true for that platform
|
||||
// To enable any additional platform, just uncomment the appropriate line below.
|
||||
"Platforms": {
|
||||
//"pc": "enabled",
|
||||
//"es3": "enabled",
|
||||
//"ios": "enabled",
|
||||
//"osx_gl": "enabled",
|
||||
//"server": "enabled"
|
||||
},
|
||||
// ---- The number of worker jobs, 0 means use the number of Logical Cores
|
||||
"Jobs": {
|
||||
"minJobs": 1,
|
||||
"maxJobs": 0
|
||||
},
|
||||
// cacheServerAddress is the location of the asset server cache.
|
||||
// Currently for a network share server this would be the absolute file path to the network share folder.
|
||||
"Server": {
|
||||
//"cacheServerAddress": ""
|
||||
},
|
||||
|
||||
// ---- add any metadata file type here that needs to be monitored by the AssetProcessor.
|
||||
// Modifying these meta file will cause the source asset to re-compile again.
|
||||
// They are specified in the following format
|
||||
// metadata extension=original extension to replace
|
||||
// if the metadata extension does not replace the original, then the original can be blank
|
||||
// so for example if your normal file is blah.tif and your metafile for that file is blah.tif.exportsettings
|
||||
// then your declaration would be exportsettings= ; ie, it would be blank
|
||||
// however if your metafile REPLACES the extension (for example, if you have the file blah.i_caf and its metafile is blah.exportsettings)
|
||||
// then you specify the original extension here to narrow the scope.
|
||||
// If a relative path to a specific file is provided instead of an extension, a change to the file will change all files
|
||||
// with the associated extension (e.g. Animations/SkeletonList.xml=i_caf will cause all i_caf files to recompile when
|
||||
// Animations/SkeletonList.xml within the current game project changes)
|
||||
|
||||
"MetaDataTypes": {
|
||||
"animsettings": "i_caf",
|
||||
"Animations": {
|
||||
"SkeletonList.xml": "i_caf"
|
||||
},
|
||||
"Animations/SkeletonList.xml": "i_caf",
|
||||
"cbc": "abc",
|
||||
"fbx.assetinfo": "fbx"
|
||||
},
|
||||
|
||||
// ---- add any folders to scan here. The priority order is the order they appear here
|
||||
// available macros are
|
||||
// @ROOT@ - the location of asset root
|
||||
// @PROJECTROOT@ - the location of the project root, for example 'Q:\MyProjects\RPGSample'
|
||||
// note that they are sorted by their 'order' value, and the lower the order the more important an asset is
|
||||
// lower order numbers override higher ones.
|
||||
// If specified, output will be prepended to every path found in that recognizer's watch folder.
|
||||
// Note that you can also make the scan folder platform specific by using the keywords include and exclude.
|
||||
// Both include and exclude can contain either platform tags, platform identifiers or both.
|
||||
// if no include is specified, all currently enabled platforms are included by default.
|
||||
// If includes ARE specified, it will be filtered down by the list of currently enabled platforms.
|
||||
// "ScanFolder (unique identifier)": {
|
||||
// "include": "(comma seperated platform tags or identifiers)",
|
||||
// "exclude": "(comma seperated platform tags or identifiers)"
|
||||
// }
|
||||
// For example if you want to include a scan folder only for platforms that have the platform tags tools and renderer
|
||||
// but omit it for platform osx_gl, you will have a scanfolder rule like
|
||||
// "ScanFolder (unique identifier)": {
|
||||
// "watch": "@ROOT@/foo",
|
||||
// "include": "tools, renderer",
|
||||
// "exclude": "osx_gl"
|
||||
// }
|
||||
|
||||
"ScanFolder Game": {
|
||||
"watch": "@ROOT@/@GAMENAME@",
|
||||
"display": "@GAMENAME@",
|
||||
"watch": "@PROJECTROOT@",
|
||||
"display": "@PROJECTROOT@",
|
||||
"recursive": 1,
|
||||
"order": 0
|
||||
},
|
||||
// gems will be auto-added from 100 onwards
|
||||
"ScanFolder Root": {
|
||||
"watch": "@ROOT@",
|
||||
"recursive": 0,
|
||||
@@ -52,6 +126,9 @@
|
||||
"order": 30000,
|
||||
"include": "tools,renderer"
|
||||
},
|
||||
|
||||
// Excludes files that match the pattern or glob
|
||||
// if you use a pattern, remember to escape your backslashes (\\)
|
||||
"Exclude _LevelBackups": {
|
||||
"pattern": ".*\\\\/Levels\\\\/.*\\\\/_savebackup\\\\/.*"
|
||||
},
|
||||
@@ -61,6 +138,7 @@
|
||||
"Exclude HoldFiles": {
|
||||
"pattern": ".*\\\\/Levels\\\\/.*_hold\\\\/.*"
|
||||
},
|
||||
// note that $ has meaning to regex, so we escape it.
|
||||
"Exclude TempFiles": {
|
||||
"pattern": ".*\\\\/\\\\$tmp[0-9]*_.*"
|
||||
},
|
||||
@@ -88,6 +166,16 @@
|
||||
"Exclude CMakeFiles": {
|
||||
"pattern": ".*\\\\/.*\\\\.cmake"
|
||||
},
|
||||
"Exclude User": {
|
||||
"pattern": ".*/[Uu]ser/.*"
|
||||
},
|
||||
"Exclude Build": {
|
||||
"pattern": ".*/[Bb]uild/.*"
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Large Worlds Test
|
||||
// ------------------------------------------------------------------------------
|
||||
"Exclude Work In Progress Folders": {
|
||||
"pattern": ".*\\\\/WIP\\\\/.*"
|
||||
},
|
||||
@@ -97,9 +185,112 @@
|
||||
"Exclude Art Source Folders": {
|
||||
"pattern": ".*\\\\/ArtSource\\\\/.*"
|
||||
},
|
||||
//------------------------------------------------------------------------------
|
||||
// RC params mapping examples
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// note that productAssetType is a means of setting the output asset Type (as in AZ::Data::AssetType) of a simple job
|
||||
// and is the recommended way to specify that a certain kind of file (such as '*.myextension') becomes registered as the
|
||||
// actual UUID of that type in the engine itself.
|
||||
|
||||
// Use a regex for matching files, same params for all platforms
|
||||
// "RC TGAs": {
|
||||
// "pattern": ".+\\\\.tga$",
|
||||
// "params": "/tga /texture"
|
||||
//}
|
||||
|
||||
// Use a glob, have special params for es3 platform
|
||||
// "RC TIFFs": {
|
||||
// "glob": "*.tif",
|
||||
// "params": "/texture",
|
||||
// "es3": "/pvrt"
|
||||
//}
|
||||
|
||||
// You can also modify a version to compile all matching files again
|
||||
// By default the version is empty
|
||||
// "RC tif": {
|
||||
// "glob": "*.tif",
|
||||
// "params": "\\someparams",
|
||||
// "version": 1.0
|
||||
//}
|
||||
// This will make the AssetProcessor compile all the .tif files again
|
||||
|
||||
// you can also optionally supply a priority.
|
||||
// this is used to sort jobs when no other external circumstance sorts them
|
||||
// for example, copy jobs will be higher in priority than other jobs that are not copy jobs
|
||||
// however if they're both copy jobs or both not, and no other circumstances apply, then priority will be used.
|
||||
// default priority is zero if not specified
|
||||
|
||||
// you can specify an option to skip processing for a file type based on the platform.
|
||||
// for example, if you dont want to process tif files for ios, you can make tif files
|
||||
// process on any platform except for ios:
|
||||
// "RC tif": {
|
||||
// "glob": "*.tif",
|
||||
// "params": "\\someparams",
|
||||
// "ios": "skip"
|
||||
//}
|
||||
|
||||
// you can specify an option to output product dependencies for a copy job.
|
||||
// please note that you only need to set this option when cry code is required to parse the asset.
|
||||
// otherwise product dependencies will be output automatically by the CopyDependencyBuilder.
|
||||
// for example, if you want to output the product dependencies for font assets:
|
||||
// "RC font": {
|
||||
// "glob": "*.font",
|
||||
// "params": "copy",
|
||||
// "outputProductDependencies": true
|
||||
//}
|
||||
|
||||
// you can also specify an option to make all jobs critical that matches some pattern/glob.
|
||||
// for example, if you want to make all png files critical than set critical to true.
|
||||
// Note that by default all copy jobs are critical.
|
||||
// Critical jobs are processed before non critical jobs and also prevent the runtime or editor from starting until they are all complete.
|
||||
// "RC png": {
|
||||
// "glob": "*.png",
|
||||
// "params": "\\someparams",
|
||||
// "critical": true
|
||||
//}
|
||||
|
||||
// you can also specify an option to make all the job store in the asset server cache location if you are running AP in server mode.
|
||||
// For example, if you want to store all png jobs in the asset server cache location including their logs, you can set checkServer = true.
|
||||
// The client(i.e if you are running AP in non-server mode) will also check for this flag to know which jobs to fetch from the asset server cache location.
|
||||
// if unsucessful, it will process the job locally as usual.
|
||||
// "RC png": {
|
||||
// "glob": "*.png",
|
||||
// "params": "\\someparams",
|
||||
// "critical": true,
|
||||
// "checkServer": true
|
||||
//}
|
||||
|
||||
// note that the FULL PATH to the file will be used as the match, not the relative path
|
||||
// so ensure start your patterns with .* or as appropriate.
|
||||
// Also, any rules which match will apply - so if you have two rules which both apply to PNG files for example
|
||||
// but you only want one, you might want to use exclusion patterns:
|
||||
|
||||
//Example: process everything EXCEPT the ones in the libs/ui folder with these params
|
||||
// "RC png-normal": {
|
||||
// "pattern": "(?!.*libs\\\\/ui\\\\/).*\\.png",
|
||||
// "params": "/imagecompressor=CTSquish /streaming=0",
|
||||
// "lockSource": true
|
||||
//}
|
||||
|
||||
//Example: Process everything in the libs/ui folder with linear color space
|
||||
// "RC png-ui": {
|
||||
// "pattern": "(.*libs\\\\/ui\\\\/).*\\.png",
|
||||
// "params": "/imagecompressor=CTSquish /streaming=0 /colorspace=linear,linear",
|
||||
// "lockSource": true
|
||||
//}
|
||||
|
||||
// More example Regexes:
|
||||
// "pattern": "(?!(.*libs\\\\/ui\\\\/)|(.*editor\\\\/).*\\\\.png"
|
||||
// This pattern will not match anything with editor/ or libs/ui/ in it
|
||||
// "pattern": "((.*libs\\\\/ui\\\\/)|(.*editor\\\\/).*\\\\.png"
|
||||
// This pattern will only match anything with editor/ or libs/ui/ in it
|
||||
|
||||
// Give every [Section Name] its own unique Name or else they will overwrite each other!
|
||||
"RC i_caf": {
|
||||
"glob": "*.i_caf",
|
||||
"params": "/cafAlignTracks=1 /animConfigFolder=Animations /skipdba=1 /refresh=1",
|
||||
// force server to send the 'pc' platform to RC.EXE so it compiles the same as PC.
|
||||
"server": "/cafAlignTracks=1 /animConfigFolder=Animations /skipdba=1 /refresh=1 /p=pc",
|
||||
"priority": 5,
|
||||
"productAssetType": "{6023CFF8-FCBA-4528-A8BF-6E0E10B9AB9C}"
|
||||
@@ -147,9 +338,12 @@
|
||||
"RC cgf": {
|
||||
"glob": "*.cgf",
|
||||
"params": "/VertexPositionFormat=exporter /VertexIndexFormat=u32",
|
||||
// on server, feed rc.exe the param /p=pc to force it to compile assets for server platform in pc format.
|
||||
"server": "/VertexPositionFormat=exporter /VertexIndexFormat=u32 /p=pc",
|
||||
"lockSource": true,
|
||||
"priority": 10
|
||||
// allow CGF files to compile first, so untextured models appear before their textures for faster startup
|
||||
// other available params: /SplitLODs=1
|
||||
},
|
||||
"RC surfaceTagNameList": {
|
||||
"glob": "*.surfaceTagNameList",
|
||||
@@ -163,8 +357,9 @@
|
||||
},
|
||||
"RC fbx": {
|
||||
"glob": "*.fbx",
|
||||
// Priority set to 9 so its "before" things like materials but after things like actors and motions (which build using a proper AssetBuilderSDK builder and thus are not in this file)
|
||||
"priority": 9,
|
||||
"version": 4
|
||||
"version": 5
|
||||
},
|
||||
"RC chr": {
|
||||
"glob": "*.chr",
|
||||
@@ -188,6 +383,7 @@
|
||||
"glob": "*.cfr",
|
||||
"params": "copy"
|
||||
},
|
||||
// Warning: If you change the VertexIndexFormat, make sure you update the vtx_idx typedef in Code\CryEngine\CryCommon\ProjectDefines.h
|
||||
"RC abc": {
|
||||
"glob": "*.abc",
|
||||
"params": "/SkipFilesWithoutBuildConfig=0 /VertexIndexFormat=u32",
|
||||
@@ -199,7 +395,7 @@
|
||||
"RC png-entityicon": {
|
||||
"pattern": "(.*EntityIcons\\\\/).*\\\\.png",
|
||||
"productAssetType": "{3436C30E-E2C5-4C3B-A7B9-66C94A28701B}",
|
||||
"params": "skip ; only tools-supporting platforms should copy this file. Everyone else can skip.",
|
||||
"params": "skip",
|
||||
"tools": "copy"
|
||||
},
|
||||
"RC usm": {
|
||||
@@ -227,6 +423,9 @@
|
||||
"params": "copy",
|
||||
"productAssetType": "{DF036C63-9AE6-4AC3-A6AC-8A1D76126C01}"
|
||||
},
|
||||
// note - this used to be skinnedMeshAsset but its now Character Definition File specific.
|
||||
// .skin has its own type.
|
||||
|
||||
"RC chrparams": {
|
||||
"glob": "*.chrparams",
|
||||
"params": "copy",
|
||||
@@ -272,13 +471,6 @@
|
||||
"params": "copy",
|
||||
"version": 1
|
||||
},
|
||||
"RC Editor Slice Copy": {
|
||||
"glob": "*.slice",
|
||||
"params": "copy",
|
||||
"critical": true,
|
||||
"productAssetType": "{C62C7A87-9C09-4148-A985-12F2C99C0A45}",
|
||||
"priority": 2
|
||||
},
|
||||
"RC node": {
|
||||
"glob": "*.node",
|
||||
"params": "copy"
|
||||
@@ -329,6 +521,7 @@
|
||||
"glob": "*.ext",
|
||||
"params": "copy"
|
||||
},
|
||||
// Copy all pak files except level.pak, level.pak has its own builder.
|
||||
"RC pak": {
|
||||
"pattern": "^((?!\\\\/level\\\\.pak).)*\\\\.pak$",
|
||||
"params": "copy"
|
||||
@@ -365,15 +558,18 @@
|
||||
"glob": "*.ocm",
|
||||
"params": "copy"
|
||||
},
|
||||
// Feature tests use the raw .tif files for the golden image comparison
|
||||
"RC goldenimages": {
|
||||
"pattern": ".*GoldenImages\\\\/.*\\\\.tif",
|
||||
"params": "copy",
|
||||
"server": "skip"
|
||||
},
|
||||
// Copy over certificates for use with FileDataSource
|
||||
"RC CertificatePEM": {
|
||||
"glob": "*.pem",
|
||||
"params": "copy"
|
||||
},
|
||||
// Copy over certificates for use with Dynamic Content
|
||||
"RC CertificateDER": {
|
||||
"glob": "*.der",
|
||||
"params": "copy"
|
||||
@@ -383,6 +579,7 @@
|
||||
"params": "copy",
|
||||
"productAssetType": "{7A2871B9-5EAB-4DE0-A901-B0D2C6920DDB}"
|
||||
},
|
||||
// Copy over cooked PhysX heightfield
|
||||
"RC PhysX HeightField": {
|
||||
"glob": "*.pxheightfield",
|
||||
"params": "copy",
|
||||
@@ -392,8 +589,20 @@
|
||||
"glob": "*.filetag",
|
||||
"params": "copy",
|
||||
"productAssetType": "{F3BE5CAB-85B7-44B7-9495-863863F6B267}"
|
||||
},
|
||||
// Precompiled shader srg
|
||||
"RC azsrg": {
|
||||
"glob": "*.azsrg",
|
||||
"params": "copy",
|
||||
"productAssetType": "{F8C9F4AE-3F6A-45AD-B4FB-0CA415FCC2E1}"
|
||||
},
|
||||
// Precompiled shader variant
|
||||
"RC azshadervariant": {
|
||||
"glob": "*.azshadervariant",
|
||||
"params": "copy",
|
||||
"productAssetType": "{9F4D654B-4439-4C61-8DCD-F1C7C5560768}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+66
-45
@@ -119,6 +119,7 @@ def LoadPipelineConfig(String pipelineName, String branchName) {
|
||||
PullFilesFromGit(PIPELINE_CONFIG_FILE, branchName)
|
||||
def pipelineConfig = {}
|
||||
pipelineConfig = readJSON file: PIPELINE_CONFIG_FILE
|
||||
palRm(PIPELINE_CONFIG_FILE)
|
||||
pipelineConfig.platforms = EMPTY_JSON
|
||||
|
||||
// Load the pipeline configs per platform
|
||||
@@ -137,6 +138,7 @@ def LoadPipelineConfig(String pipelineName, String branchName) {
|
||||
pipelineConfig.platforms[platform] = EMPTY_JSON
|
||||
pipelineConfig.platforms[platform].PIPELINE_ENV = readJSON file: pipeline_config_path.toString()
|
||||
}
|
||||
palRm(pipeline_config_path.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +157,7 @@ def LoadPipelineConfig(String pipelineName, String branchName) {
|
||||
if(platform) {
|
||||
pipelineConfig.platforms[platform].build_types = readJSON file: build_config_path.toString()
|
||||
}
|
||||
palRm(build_config_path.toString())
|
||||
}
|
||||
}
|
||||
return pipelineConfig
|
||||
@@ -202,39 +205,45 @@ def PullFilesFromGit(String filenamePath, String branchName, boolean failIfNotFo
|
||||
folderPathParts.remove(folderPathParts.size()-1) // remove the filename
|
||||
def folderPath = folderPathParts.join('/')
|
||||
if (folderPath.contains('*')) {
|
||||
|
||||
def currentPath = ''
|
||||
for (int i = 0; i < folderPathParts.size(); i++) {
|
||||
if (folderPathParts[i] == '*') {
|
||||
palMkdir(currentPath)
|
||||
retry(3) { palSh("aws codecommit get-folder --repository-name ${repositoryName} --commit-specifier ${branchName} --folder-path ${currentPath} > ${currentPath}/.codecommit", "GetFolder ${currentPath}") }
|
||||
def folderInfo = readJSON file: "${currentPath}/.codecommit"
|
||||
folderInfo.subFolders.each { folder ->
|
||||
def newSubPath = currentPath + '/' + folder.relativePath
|
||||
for (int j = i+1; j < folderPathParts.size(); j++) {
|
||||
newSubPath = newSubPath + '/' + folderPathParts[j]
|
||||
|
||||
try {
|
||||
def currentPath = ''
|
||||
for (int i = 0; i < folderPathParts.size(); i++) {
|
||||
if (folderPathParts[i] == '*') {
|
||||
palMkdir(currentPath)
|
||||
retry(3) { palSh("aws codecommit get-folder --repository-name ${repositoryName} --commit-specifier ${branchName} --folder-path ${currentPath} > ${currentPath}/.codecommit", "GetFolder ${currentPath}") }
|
||||
def folderInfo = readJSON file: "${currentPath}/.codecommit"
|
||||
folderInfo.subFolders.each { folder ->
|
||||
def newSubPath = currentPath + '/' + folder.relativePath
|
||||
for (int j = i+1; j < folderPathParts.size(); j++) {
|
||||
newSubPath = newSubPath + '/' + folderPathParts[j]
|
||||
}
|
||||
newSubPath = newSubPath + '/' + filename
|
||||
PullFilesFromGit(newSubPath, branchName, false, repositoryName)
|
||||
}
|
||||
newSubPath = newSubPath + '/' + filename
|
||||
PullFilesFromGit(newSubPath, branchName, false, repositoryName)
|
||||
palRm("${currentPath}/.codecommit")
|
||||
}
|
||||
if (i == 0) {
|
||||
currentPath = folderPathParts[i]
|
||||
} else {
|
||||
currentPath = currentPath + '/' + folderPathParts[i]
|
||||
}
|
||||
palRm("${currentPath}/.codecommit")
|
||||
}
|
||||
if (i == 0) {
|
||||
currentPath = folderPathParts[i]
|
||||
} else {
|
||||
currentPath = currentPath + '/' + folderPathParts[i]
|
||||
}
|
||||
} catch(Exception e) {
|
||||
}
|
||||
|
||||
} else if (filename.contains('*')) {
|
||||
|
||||
palMkdir(folderPath)
|
||||
retry(3) { palSh("aws codecommit get-folder --repository-name ${repositoryName} --commit-specifier ${branchName} --folder-path ${folderPath} > ${folderPath}/.codecommit", "GetFolder ${folderPath}") }
|
||||
def folderInfo = readJSON file: "${folderPath}/.codecommit"
|
||||
folderInfo.files.each { file ->
|
||||
PullFilesFromGit("${folderPath}/${filename}", branchName, false, repositoryName)
|
||||
try {
|
||||
palMkdir(folderPath)
|
||||
retry(3) { palSh("aws codecommit get-folder --repository-name ${repositoryName} --commit-specifier ${branchName} --folder-path ${folderPath} > ${folderPath}/.codecommit", "GetFolder ${folderPath}") }
|
||||
def folderInfo = readJSON file: "${folderPath}/.codecommit"
|
||||
folderInfo.files.each { file ->
|
||||
PullFilesFromGit("${folderPath}/${filename}", branchName, false, repositoryName)
|
||||
}
|
||||
palRm("${folderPath}/.codecommit")
|
||||
} catch(Exception e) {
|
||||
}
|
||||
palRm("${folderPath}/.codecommit")
|
||||
|
||||
} else {
|
||||
|
||||
@@ -271,18 +280,7 @@ def PullFilesFromGit(String filenamePath, String branchName, boolean failIfNotFo
|
||||
}
|
||||
}
|
||||
|
||||
def SetLfsCredentials(cmd, lbl = '') {
|
||||
if (env.IS_UNIX) {
|
||||
sh label: lbl,
|
||||
script: cmd
|
||||
} else {
|
||||
bat label: lbl,
|
||||
script: cmd
|
||||
}
|
||||
}
|
||||
|
||||
def CheckoutRepo(boolean disableSubmodules = false) {
|
||||
palSh('git lfs uninstall', 'Git LFS Uninstall') // Prevent git from pulling lfs objects during checkout
|
||||
|
||||
if(fileExists('.git')) {
|
||||
// If the repository after checkout is locked, likely we took a snapshot while git was running,
|
||||
@@ -292,7 +290,7 @@ def CheckoutRepo(boolean disableSubmodules = false) {
|
||||
palSh('git gc', 'Git GarbageCollect')
|
||||
}
|
||||
if(fileExists(indexLockFile)) { // if it is still there, remove it
|
||||
palRm(indexLockFile, 'Remove index.lock')
|
||||
palRm(indexLockFile)
|
||||
}
|
||||
palSh('git remote prune origin', 'Git reset')
|
||||
}
|
||||
@@ -329,14 +327,6 @@ def CheckoutRepo(boolean disableSubmodules = false) {
|
||||
}
|
||||
}
|
||||
|
||||
// Run lfs in a separate step. Jenkins is unable to load the credentials for the custom LFS endpoint
|
||||
withCredentials([usernamePassword(credentialsId: "${env.GITHUB_USER}", passwordVariable: 'accesstoken', usernameVariable: 'username')]) {
|
||||
SetLfsCredentials("git config -f .lfsconfig lfs.url https://${username}:${accesstoken}@${env.LFS_URL}", 'Set credentials')
|
||||
}
|
||||
palSh('git lfs install', 'Git LFS Install')
|
||||
palSh('git lfs pull', 'Git LFS Pull')
|
||||
}
|
||||
|
||||
// CHANGE_ID is used by some scripts to identify uniquely the current change (usually metric jobs)
|
||||
palSh('git rev-parse HEAD > commitid', 'Getting commit id')
|
||||
env.CHANGE_ID = readFile file: 'commitid'
|
||||
@@ -406,6 +396,26 @@ def Build(Map options, String platform, String type, String workspace) {
|
||||
}
|
||||
}
|
||||
|
||||
def TestMetrics(Map options, Map buildType, String workspace, String branchName, String repoName) {
|
||||
catchError(buildResult: null, stageResult: null) {
|
||||
def cmakeBuildDir = [workspace, buildType.value.PARAMETERS.OUTPUT_DIRECTORY].join('/')
|
||||
def command = "${options.PYTHON_DIR}/python.cmd -u mars/scripts/python/ctest_test_metric_scraper.py -e jenkins.creds.user ${username} -e jenkins.creds.pass ${apitoken} ${cmakeBuildDir} ${branchName} %BUILD_NUMBER% AR ${buildType.value.PARAMETERS.CONFIGURATION} ${repoName} "
|
||||
if (params.DESTINATION_BRANCH)
|
||||
command += '--destination-branch "$DESTINATION_BRANCH" '
|
||||
dir(workspace) {
|
||||
checkout scm: [
|
||||
$class: 'GitSCM',
|
||||
extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'mars']],
|
||||
userRemoteConfigs: [[url: "${env.MARS_REPO}", name: 'mars']]
|
||||
]
|
||||
withCredentials([usernamePassword(credentialsId: "${env.SERVICE_USER}", passwordVariable: 'apitoken', usernameVariable: 'username')]) {
|
||||
bat label: "Publishing ${buildType.key} Test Metrics",
|
||||
script: command
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def PostBuildCommonSteps(String workspace, boolean mount = true) {
|
||||
echo 'Starting post-build common steps...'
|
||||
|
||||
@@ -448,6 +458,14 @@ def CreateBuildStage(Map pipelineConfig, String platformName, String jobName, Ma
|
||||
}
|
||||
}
|
||||
|
||||
def CreateTestMetricsStage(Map pipelineConfig, Map buildJob, String branchName, Map environmentVars) {
|
||||
return {
|
||||
stage("${buildJob.key}") {
|
||||
TestMetrics(pipelineConfig, buildJob, environmentVars['WORKSPACE'], branchName, env.DEFAULT_REPOSITORY_NAME)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def CreateTeardownStage(Map environmentVars) {
|
||||
return {
|
||||
stage("Teardown") {
|
||||
@@ -538,6 +556,9 @@ try {
|
||||
} else {
|
||||
CreateBuildStage(pipelineConfig, platform.key, build_job.key, envVars).call()
|
||||
}
|
||||
if (env.MARS_REPO && platform.key == 'Windows' && build_job.key.startsWith('test')) {
|
||||
CreateTestMetricsStage(pipelineConfig, build_job, branchName, envVars).call()
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
// https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/model/Result.java
|
||||
|
||||
@@ -9,4 +9,12 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#
|
||||
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/project.json" project_json)
|
||||
|
||||
string(JSON project_target_name ERROR_VARIABLE json_error GET ${project_json} "project_name")
|
||||
if(${json_error})
|
||||
message(FATAL_ERROR "Unable to read key 'project_name' from 'project.json'")
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY LY_PROJECTS_TARGET_NAME ${project_target_name})
|
||||
add_subdirectory(Gem)
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
<ObjectStream version="1">
|
||||
<Class name="ComponentApplication::Descriptor" version="2" type="{70277A3E-2AF5-4309-9BBF-6161AFBDE792}">
|
||||
<Class name="bool" field="useExistingAllocator" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="grabAllMemory" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecords" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecordsSaveNames" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecordsAttemptDecodeImmediately" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="int" field="recordingMode" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
|
||||
<Class name="AZ::u64" field="stackRecordLevels" value="5" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="bool" field="autoIntegrityCheck" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="markUnallocatedMemory" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="doNotUsePools" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="enableScriptReflection" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="pageSize" value="65536" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="poolPageSize" value="4096" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="blockAlignment" value="65536" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZ::u64" field="blockSize" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="AZ::u64" field="reservedOS" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="AZ::u64" field="reservedDebug" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="bool" field="enableDrilling" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="useOverrunDetection" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="useMalloc" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="allocatorRemappings" type="{82897F6E-6389-5BEF-B427-761DB35AC1CC}"/>
|
||||
<Class name="AZStd::vector" field="modules" type="{8E779F80-AEAA-565B-ABB1-DE10B18CF995}">
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Maestro.Editor.3b9a978ed6f742a1acb99f74379a342c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.TextureAtlas.5a149b6b3c964064bd4970f0e92f72e2.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LmbrCentral.Editor.ff06785f7145416b9d46fde39098cb0c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LyShine.Editor.0fefab3f13364722b2eab3b96ce2bf20.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.HttpRequestor.28479e255bde466e91fc34eec808d9c7.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptEvents.Editor.32d8ba21703e4bbbb08487366e48dd69.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ExpressionEvaluation.4c6f9df57ca2468f93c8d860ee6a1167.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AssetValidation.5a5c3c10b91d4b4ea8baef474c5b5d49.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Gestures.6056556b6088413984309c4a413593ad.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.CertificateManager.659cffff33b14a10835bafc6ea623f98.v0.0.1" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.DebugDraw.Editor.66239f50bf754354b514c850c8b841fb.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AudioSystem.Editor.6f63f2b6d07f4b89b4b7c86ebee7feb8.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GameLift.76de765796504906b73be7365a9bff06.v2.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.SceneProcessing.Editor.7c2578f634df4345aca98d671e39b8ab.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GraphCanvas.Editor.875b6fcbdeea44deaae7984ad9bb6cdc.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.InAppPurchases.92fe57eae7d3402a90761973678c079a.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AutomatedTesting.afc25e1593194d6283d9ff744ab6d5a1.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.EditorPythonBindings.Editor.b658359393884c4381c2fe2952b1472a.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Metastream.c02d7efe05134983b5699d9ee7594c3a.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.WhiteBox.Editor.c5833dbda2e045d3a5f16b7414280c27.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ImageProcessing.Editor.eeffbd9211cf4ce0b5cc73696b427cbe.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.TestAssetBuilder.Editor.f5c92f1560714010ba30467d93feecef.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Camera.Editor.f910686b6725452fbfc4671f95f733c6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.EMotionFX.Editor.044a63ea67d04479aa5daf62ded9d9ca.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GraphModel.Editor.0844f64a3acf4f5abf3a535dc9b63bc9.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.PhysX.Editor.4e08125824434932a0fe3717259caa47.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.CameraFramework.54f2763fe191432fa681ce4a354eedf5.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.SurfaceData.Editor.5de82d29d6094bfe97c1a4d35fcd5fbe.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AudioEngineWwise.Editor.67a80e2ac865406c990f2715feb55f7f.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointMovement.73d8779dc28a4123b7c9ed76217464af.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointCamera.834070b9537d44df83559e2045c3859f.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptCanvasGem.Editor.869a0d0ec11a45c299917d45c81555e6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GradientSignal.Editor.8825563d9d964ec3be3bab681f3bd9f2.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ImGui.Editor.bab8807a1bc646b3909f3cc200ffeedf.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ChatPlay.bfbc60c63ffd4b00927003735b26ce99.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.TouchBending.Editor.c58d2057f3724b22ae0df0be68a4e316.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.FastNoise.Editor.c5f23032407f49ca8d8de1733423565c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LyShineExamples.c7935ecf5e8047fe8ca947b34b11cadb.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Vegetation.Editor.f394e7cf54424bba89615381bba9511b.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointInput.Editor.09f4bedeee614358bc36788e77f97e51.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LandscapeCanvas.Editor.19c2b2d5018940108baf252934b8e6bf.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptCanvasPhysics.1c27519a4dda4ffaaeebf91514e5b1e8.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.PhysXDebug.Editor.516145e2d9904b13813f1b54605e26a6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Entity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
|
||||
<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="Name" value="SystemEntity" type="{EF8FF807-DDEE-4EB0-B678-4CA3A2C490A4}"/>
|
||||
<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="Components" type="{2BADE35A-6F1B-4698-B2BC-3373D010020C}">
|
||||
<Class name="PhysicsSystemComponent" field="element" value="" version="1" type="{1586DBA1-F5F0-49AB-9F59-AE62C0E60AE0}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="5881970355815182227" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="NavigationSystemComponent" field="element" value="" version="1" type="{3D27484B-00C4-4F3F-9605-2BF3E5C317FF}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="3408791856679455729" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="EditorSelectionAccentSystemComponent" field="element" value="" type="{6E0F0E2C-1FE5-4AFB-9672-DC92B3D2D844}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="4281709857282575192" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AudioSystemComponent" field="element" version="1" type="{666E28D2-FC99-4D41-861D-3758C5070653}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="4028172539943260142" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="LyShineSystemComponent" field="element" value="" type="{B0C78B8D-1E5B-47D7-95D0-EC69C0513804}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="13584318858523138243" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="LyEditorMetricsSystemComponent" field="element" value="" type="{B8C74085-F6B7-4E2F-8135-78C991CC53C5}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="8970396848016072155" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="StereoRendererComponent" field="element" version="1" type="{BBFE0965-5564-4739-8219-AFE8209A5E57}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
<ObjectStream version="1">
|
||||
<Class name="ComponentApplication::Descriptor" version="2" type="{70277A3E-2AF5-4309-9BBF-6161AFBDE792}">
|
||||
<Class name="bool" field="useExistingAllocator" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="grabAllMemory" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecords" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecordsSaveNames" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecordsAttemptDecodeImmediately" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="int" field="recordingMode" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
|
||||
<Class name="AZ::u64" field="stackRecordLevels" value="5" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="bool" field="autoIntegrityCheck" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="markUnallocatedMemory" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="doNotUsePools" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="enableScriptReflection" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="pageSize" value="65536" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="poolPageSize" value="4096" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="blockAlignment" value="65536" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZ::u64" field="blockSize" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="AZ::u64" field="reservedOS" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="AZ::u64" field="reservedDebug" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="bool" field="enableDrilling" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="useOverrunDetection" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="useMalloc" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="allocatorRemappings" type="{82897F6E-6389-5BEF-B427-761DB35AC1CC}"/>
|
||||
<Class name="AZStd::vector" field="modules" type="{8E779F80-AEAA-565B-ABB1-DE10B18CF995}">
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Maestro.3b9a978ed6f742a1acb99f74379a342c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.TextureAtlas.5a149b6b3c964064bd4970f0e92f72e2.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LmbrCentral.ff06785f7145416b9d46fde39098cb0c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LyShine.0fefab3f13364722b2eab3b96ce2bf20.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.HttpRequestor.28479e255bde466e91fc34eec808d9c7.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptEvents.32d8ba21703e4bbbb08487366e48dd69.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ExpressionEvaluation.4c6f9df57ca2468f93c8d860ee6a1167.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AssetValidation.5a5c3c10b91d4b4ea8baef474c5b5d49.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Gestures.6056556b6088413984309c4a413593ad.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.CertificateManager.659cffff33b14a10835bafc6ea623f98.v0.0.1" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.DebugDraw.66239f50bf754354b514c850c8b841fb.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AudioSystem.6f63f2b6d07f4b89b4b7c86ebee7feb8.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GameLift.76de765796504906b73be7365a9bff06.v2.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GraphCanvas.875b6fcbdeea44deaae7984ad9bb6cdc.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.InAppPurchases.92fe57eae7d3402a90761973678c079a.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AutomatedTesting.afc25e1593194d6283d9ff744ab6d5a1.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Metastream.c02d7efe05134983b5699d9ee7594c3a.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.WhiteBox.c5833dbda2e045d3a5f16b7414280c27.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Camera.f910686b6725452fbfc4671f95f733c6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.EMotionFX.044a63ea67d04479aa5daf62ded9d9ca.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.PhysX.4e08125824434932a0fe3717259caa47.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.CameraFramework.54f2763fe191432fa681ce4a354eedf5.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.SurfaceData.5de82d29d6094bfe97c1a4d35fcd5fbe.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AudioEngineWwise.67a80e2ac865406c990f2715feb55f7f.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointMovement.73d8779dc28a4123b7c9ed76217464af.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointCamera.834070b9537d44df83559e2045c3859f.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptCanvasGem.869a0d0ec11a45c299917d45c81555e6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GradientSignal.8825563d9d964ec3be3bab681f3bd9f2.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ImGui.bab8807a1bc646b3909f3cc200ffeedf.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ChatPlay.bfbc60c63ffd4b00927003735b26ce99.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.TouchBending.c58d2057f3724b22ae0df0be68a4e316.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.FastNoise.c5f23032407f49ca8d8de1733423565c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LyShineExamples.c7935ecf5e8047fe8ca947b34b11cadb.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Vegetation.f394e7cf54424bba89615381bba9511b.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointInput.09f4bedeee614358bc36788e77f97e51.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptCanvasPhysics.1c27519a4dda4ffaaeebf91514e5b1e8.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.PhysXDebug.516145e2d9904b13813f1b54605e26a6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Entity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
|
||||
<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="Name" value="SystemEntity" type="{EF8FF807-DDEE-4EB0-B678-4CA3A2C490A4}"/>
|
||||
<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="Components" type="{2BADE35A-6F1B-4698-B2BC-3373D010020C}">
|
||||
<Class name="PhysicsSystemComponent" field="element" value="" version="1" type="{1586DBA1-F5F0-49AB-9F59-AE62C0E60AE0}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="14545574550664822512" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="NavigationSystemComponent" field="element" value="" version="1" type="{3D27484B-00C4-4F3F-9605-2BF3E5C317FF}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="9809863829757322975" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="LyShineSystemComponent" field="element" value="" type="{B0C78B8D-1E5B-47D7-95D0-EC69C0513804}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="3706545825063126910" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AudioSystemComponent" field="element" version="1" type="{666E28D2-FC99-4D41-861D-3758C5070653}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="17265601292746528732" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="StereoRendererComponent" field="element" version="1" type="{BBFE0965-5564-4739-8219-AFE8209A5E57}"/>
|
||||
<Class name="LmbrCentralSystemComponent" field="element" value="" version="1" type="{CE249D37-C1D6-4A64-932D-C937B0EC2B8C}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="17265313386362322770" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AssetDatabaseComponent" field="element" value="" version="1" type="{D5A73BCC-0098-4D1E-8FE4-C86101E374AC}">
|
||||
<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
|
||||
<Class name="AZ::u64" field="Id" value="18338415854038604706" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
<ObjectStream version="3">
|
||||
<Class name="ComponentApplication::Descriptor" version="2" type="{70277A3E-2AF5-4309-9BBF-6161AFBDE792}">
|
||||
<Class name="bool" field="useExistingAllocator" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="grabAllMemory" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecords" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecordsSaveNames" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="allocationRecordsAttemptDecodeImmediately" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="int" field="recordingMode" value="2" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
|
||||
<Class name="AZ::u64" field="stackRecordLevels" value="5" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="bool" field="autoIntegrityCheck" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="markUnallocatedMemory" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="doNotUsePools" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="enableScriptReflection" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="pageSize" value="65536" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="poolPageSize" value="4096" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="blockAlignment" value="65536" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="AZ::u64" field="blockSize" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="AZ::u64" field="reservedOS" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="AZ::u64" field="reservedDebug" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
<Class name="bool" field="enableDrilling" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="useOverrunDetection" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="useMalloc" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="AZStd::vector" field="allocatorRemappings" type="{82897F6E-6389-5BEF-B427-761DB35AC1CC}"/>
|
||||
<Class name="AZStd::vector" field="modules" type="{8E779F80-AEAA-565B-ABB1-DE10B18CF995}">
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Maestro.3b9a978ed6f742a1acb99f74379a342c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.TextureAtlas.5a149b6b3c964064bd4970f0e92f72e2.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LmbrCentral.ff06785f7145416b9d46fde39098cb0c.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LyShine.0fefab3f13364722b2eab3b96ce2bf20.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.HttpRequestor.28479e255bde466e91fc34eec808d9c7.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptEvents.32d8ba21703e4bbbb08487366e48dd69.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ExpressionEvaluation.4c6f9df57ca2468f93c8d860ee6a1167.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AssetValidation.5a5c3c10b91d4b4ea8baef474c5b5d49.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Gestures.6056556b6088413984309c4a413593ad.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.CertificateManager.659cffff33b14a10835bafc6ea623f98.v0.0.1" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.DebugDraw.66239f50bf754354b514c850c8b841fb.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AudioSystem.6f63f2b6d07f4b89b4b7c86ebee7feb8.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GameLift.76de765796504906b73be7365a9bff06.v2.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.GraphCanvas.875b6fcbdeea44deaae7984ad9bb6cdc.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.InAppPurchases.92fe57eae7d3402a90761973678c079a.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AutomatedTesting.afc25e1593194d6283d9ff744ab6d5a1.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Metastream.c02d7efe05134983b5699d9ee7594c3a.v1.0.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.WhiteBox.c5833dbda2e045d3a5f16b7414280c27.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.Camera.f910686b6725452fbfc4671f95f733c6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.EMotionFX.044a63ea67d04479aa5daf62ded9d9ca.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.PhysX.4e08125824434932a0fe3717259caa47.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.PhysXCharacters.50f9ae1e09ac471bbd9d86ca8063ddf9.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.CameraFramework.54f2763fe191432fa681ce4a354eedf5.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.AudioEngineWwise.67a80e2ac865406c990f2715feb55f7f.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointMovement.73d8779dc28a4123b7c9ed76217464af.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointCamera.834070b9537d44df83559e2045c3859f.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptCanvasGem.869a0d0ec11a45c299917d45c81555e6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ImGui.bab8807a1bc646b3909f3cc200ffeedf.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ChatPlay.bfbc60c63ffd4b00927003735b26ce99.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.LyShineExamples.c7935ecf5e8047fe8ca947b34b11cadb.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.StartingPointInput.09f4bedeee614358bc36788e77f97e51.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.ScriptCanvasPhysics.1c27519a4dda4ffaaeebf91514e5b1e8.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
<Class name="DynamicModuleDescriptor" field="element" type="{D2932FA3-9942-4FD2-A703-2E750F57C003}">
|
||||
<Class name="AZStd::string" field="dynamicLibraryPath" value="Gem.PhysXDebug.516145e2d9904b13813f1b54605e26a6.v0.1.0" type="{189CC2ED-FDDE-5680-91D4-9F630A79187F}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Entity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
|
||||
<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="AZStd::string" field="Name" value="SystemEntity" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
|
||||
<Class name="AZStd::vector" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}"/>
|
||||
<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
</ObjectStream>
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
; The PythonTest folder contains benchmarksettings test assets that should only get processed when
|
||||
; the test is run, and the assets are temporarily copied to a separate folder.
|
||||
[Exclude PythonTest Benchmark Settings Assets]
|
||||
pattern=.*\\/PythonTests\\/.*benchmarksettings
|
||||
|
||||
[Exclude fbx_tests]
|
||||
pattern=.*\\/fbx_tests\\/assets\\/.*
|
||||
|
||||
[Exclude wwise_bank_dependency_tests]
|
||||
pattern=.*\\/wwise_bank_dependency_tests\\/assets\\/.*
|
||||
|
||||
[Exclude AssetProcessorTestAssets]
|
||||
pattern=.*\\/asset_processor_tests\\/assets\\/.*
|
||||
|
||||
[Exclude Restricted AssetProcessorTestAssets]
|
||||
pattern=.*\\/asset_processor_tests\\/restricted\\/.*
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"Amazon": {
|
||||
"AssetProcessor": {
|
||||
"Settings": {
|
||||
"Exclude PythonTest Benchmark Settings Assets": {
|
||||
"pattern": ".*\\\\/PythonTests\\\\/.*benchmarksettings"
|
||||
},
|
||||
"Exclude fbx_tests": {
|
||||
"pattern": ".*\\\\/fbx_tests\\\\/assets\\\\/.*"
|
||||
},
|
||||
"Exclude wwise_bank_dependency_tests": {
|
||||
"pattern": ".*\\\\/wwise_bank_dependency_tests\\\\/assets\\\\/.*"
|
||||
},
|
||||
"Exclude AssetProcessorTestAssets": {
|
||||
"pattern": ".*\\\\/asset_processor_tests\\\\/assets\\\\/.*"
|
||||
},
|
||||
"Exclude Restricted AssetProcessorTestAssets": {
|
||||
"pattern": ".*\\\\/asset_processor_tests\\\\/restricted\\\\/.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Legacy::CryRenderNULL
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PhysicsTests_Sandbox
|
||||
@@ -42,6 +44,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Legacy::CryRenderNULL
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Physics
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -49,7 +53,7 @@ endif()
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::ScriptCanvasTests
|
||||
TEST_SUITE main
|
||||
TEST_SUITE periodic
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Active.py
|
||||
TIMEOUT 3600
|
||||
@@ -58,6 +62,20 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Legacy::CryRenderNULL
|
||||
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 3600
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
Legacy::CryRenderNULL
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -74,6 +92,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
Legacy::CryRenderNULL
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
WhiteBox
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -108,7 +128,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
Gem::EditorPythonBindings.Editor
|
||||
COMPONENT TestTools
|
||||
COMPONENT TestTools
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -136,7 +156,6 @@ 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 ##
|
||||
|
||||
ly_add_pytest(
|
||||
NAME DynamicVegetationTests_Main_NoGPU
|
||||
TEST_SERIAL
|
||||
@@ -150,6 +169,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
Legacy::CryRenderNULL
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
@@ -165,6 +186,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
AutomatedTesting.GameLauncher
|
||||
AutomatedTesting.Assets
|
||||
Legacy::CryRenderNULL
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
@@ -179,10 +202,11 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
Legacy::CryRenderNULL
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
## LandscapeCanvas ##
|
||||
|
||||
ly_add_pytest(
|
||||
NAME LandscapeCanvasTests_Main
|
||||
TEST_SERIAL
|
||||
@@ -194,6 +218,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
Legacy::CryRenderNULL
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
## GradientSignal ##
|
||||
@@ -209,6 +235,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
Legacy::CryRenderNULL
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
ly_add_pytest(
|
||||
@@ -222,6 +250,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
Legacy::Editor
|
||||
AutomatedTesting.Assets
|
||||
Legacy::CryRenderNULL
|
||||
COMPONENT
|
||||
LargeWorlds
|
||||
)
|
||||
|
||||
endif()
|
||||
@@ -239,6 +269,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
|
||||
Legacy::CryRenderNULL
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
COMPONENT
|
||||
Editor
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
+6
-6
@@ -24,7 +24,7 @@ from . import ap_setup_fixture as ap_setup_fixture
|
||||
def ap_all_platforms_setup_fixture(request, workspace, ap_setup_fixture) -> Dict[str, str]:
|
||||
|
||||
dev_dir = os.path.join(workspace.paths.dev())
|
||||
cache_dir = os.path.join(dev_dir, "Cache")
|
||||
cache_dir = workspace.paths.cache()
|
||||
|
||||
# add some useful locations
|
||||
resources = ap_setup_fixture
|
||||
@@ -33,11 +33,11 @@ def ap_all_platforms_setup_fixture(request, workspace, ap_setup_fixture) -> Dict
|
||||
resources["platform_cache"] = os.path.join(workspace.paths.platform_cache(), workspace.project.lower())
|
||||
|
||||
# Specific platform cache locations
|
||||
resources["pc_cache_location"] = os.path.join(cache_dir, workspace.project, "pc")
|
||||
resources["es3_cache_location"] = os.path.join(cache_dir, workspace.project, "es3")
|
||||
resources["ios_cache_location"] = os.path.join(cache_dir, workspace.project, "ios")
|
||||
resources["osx_gl_cache_location"] = os.path.join(cache_dir, workspace.project, "osx_gl")
|
||||
resources["provo_cache_location"] = os.path.join(cache_dir, workspace.project, "provo")
|
||||
resources["pc_cache_location"] = os.path.join(cache_dir, "pc")
|
||||
resources["es3_cache_location"] = os.path.join(cache_dir, "es3")
|
||||
resources["ios_cache_location"] = os.path.join(cache_dir, "ios")
|
||||
resources["osx_gl_cache_location"] = os.path.join(cache_dir, "osx_gl")
|
||||
resources["provo_cache_location"] = os.path.join(cache_dir, "provo")
|
||||
resources["all_platforms"] = ["pc", "es3", "ios", "osx_gl", "provo"]
|
||||
|
||||
return resources
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ def ap_external_project_setup_fixture(request, workspace) -> Dict:
|
||||
paths = mock()
|
||||
paths.asset_processor = lambda: resources["ap_path"]
|
||||
paths.asset_processor_batch = lambda: resources["ap_batch_path"]
|
||||
paths.asset_processor_config_file = lambda: os.path.join(resources["project_dir"], "AssetProcessorConfig.ini")
|
||||
paths.asset_processor_config_file = lambda: os.path.join(resources["project_dir"], "AssetProcessorConfig.setreg")
|
||||
mock_workspace.paths = paths
|
||||
resources["external_workspace"] = mock_workspace
|
||||
|
||||
|
||||
+3
-2
@@ -163,7 +163,7 @@ class TestsAssetProcessorBatch_AllPlatforms(object):
|
||||
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", external_resources["project_name"])
|
||||
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
|
||||
@@ -273,7 +273,8 @@ class TestsAssetProcessorBatch_Windows(object):
|
||||
"AssetProcessor: Error: Platform in config file or command line 'notaplatform'" should be present in the logs
|
||||
"""
|
||||
asset_processor.create_temp_asset_root()
|
||||
error_search_terms = "AssetProcessor: Error: Platform in config file or command line 'notaplatform'"
|
||||
error_search_terms = 'AssetProcessor: Error: The list of enabled platforms in the settings registry does not contain platform ' \
|
||||
'"notaplatform"'
|
||||
# Run APBatch expecting it to fail
|
||||
asset_processor.run_and_check_output(True, error_search_terms, platforms='notaplatform')
|
||||
|
||||
|
||||
+15
-19
@@ -25,7 +25,7 @@ import ly_test_tools.environment.waiter as waiter
|
||||
import ly_test_tools.environment.file_system as fs
|
||||
import ly_test_tools.environment.process_utils as process_utils
|
||||
import ly_test_tools.launchers.launcher_helper as launcher_helper
|
||||
from ly_test_tools.lumberyard.asset_processor import ASSET_PROCESSOR_PLATFORM_MAP
|
||||
from ly_test_tools.lumberyard.asset_processor import ASSET_PROCESSOR_PLATFORM_MAP, ASSET_PROCESSOR_SETTINGS_ROOT_KEY
|
||||
|
||||
# Import fixtures
|
||||
from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
|
||||
@@ -136,7 +136,7 @@ class TestsAssetProcessorGUI_WindowsAndMac(object):
|
||||
# Validate that no fatal errors (crashes) are reported within a certain time frame (10 seconds timeout)
|
||||
# This applies to AP and GameLauncher.exe
|
||||
time.sleep(CHECK_ALIVE_SECONDS)
|
||||
launcher_name = f"{workspace.project.title()}Launcher"
|
||||
launcher_name = f"{workspace.project.title()}.GameLauncher"
|
||||
# fmt:off
|
||||
assert process_utils.process_exists(launcher_name, ignore_extensions=True), \
|
||||
f"{launcher_name} was not live during the check."
|
||||
@@ -221,23 +221,20 @@ class TestsAssetProcessorGUI_AllPlatforms(object):
|
||||
|
||||
assert not test_assets_added_to_cache(), "Test assets are present in cache before adding scan folder"
|
||||
|
||||
# Add test assets folder in dev to AP config file (AssetProcessorPlatformConfig.ini) to be scanned
|
||||
ap_config_file = os.path.join(asset_processor.temp_asset_root(), 'AssetProcessorPlatformConfig.ini')
|
||||
config = configparser.ConfigParser()
|
||||
config.read(ap_config_file)
|
||||
config["ScanFolder C4874115"] = {
|
||||
"watch": "@ROOT@/C4874115",
|
||||
"output": "C4874115",
|
||||
"recursive": "1",
|
||||
"order": "5000",
|
||||
}
|
||||
with open(ap_config_file, "w") as configfile:
|
||||
config.write(configfile)
|
||||
# Supply an additional scan folder for the test via the settings registry regset parameters
|
||||
test_scan_folder_params = []
|
||||
|
||||
test_scan_folder_root_key = f"{ASSET_PROCESSOR_SETTINGS_ROOT_KEY}/ScanFolder C4874115"
|
||||
test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/watch=@ROOT@/C4874115"')
|
||||
test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/output=C4874115"')
|
||||
test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/recursive=1"')
|
||||
test_scan_folder_params.append(f'--regset="{test_scan_folder_root_key}/order=5000"')
|
||||
|
||||
# Run AP GUI and read the config file we just modified to pick up our scan folder
|
||||
# Pass in a pattern so we don't spend time processing unrelated folders
|
||||
result, _ = asset_processor.gui_process(quitonidle=True, add_config_scan_folders=True,
|
||||
scan_folder_pattern="*C4874115*")
|
||||
scan_folder_pattern="*C4874115*",
|
||||
extra_params=test_scan_folder_params)
|
||||
assert result, "AP GUI failed"
|
||||
|
||||
# Verify test assets processed into cache after adding scan folder
|
||||
@@ -255,10 +252,9 @@ class TestsAssetProcessorGUI_AllPlatforms(object):
|
||||
test_ip_address = "1.1.1.1" # an IP address without Asset Processor
|
||||
|
||||
asset_processor.create_temp_asset_root()
|
||||
# Edit remote_ip setting in bootstrap.cfg to an IP address without Asset Processor
|
||||
workspace.settings.modify_bootstrap_setting("remote_ip", test_ip_address,
|
||||
bootstrap_path=os.path.join(asset_processor.temp_asset_root(),
|
||||
'bootstrap.cfg'))
|
||||
# Set the remote_ip setting through the settings registry to an IP address without Asset Processor
|
||||
extra_params = []
|
||||
extra_params.append(f'--regset="/Amazon/AzCore/Bootstrap/remote_ip={test_ip_address}"')
|
||||
|
||||
# Run AP Gui to verify that assets process regardless of the new address
|
||||
result, _ = asset_processor.gui_process(quitonidle=True)
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ class TestsMissingDependencies_WindowsAndMac(object):
|
||||
self._missing_dep_helper = missing_dep_helper
|
||||
self._asset_processor.create_temp_asset_root()
|
||||
self._asset_processor.add_source_folder_assets(f"AutomatedTesting\\TestAssets")
|
||||
missing_dep_helper.asset_db = os.path.join(asset_processor.temp_asset_root(), "Cache", workspace.project,
|
||||
missing_dep_helper.asset_db = os.path.join(asset_processor.temp_asset_root(), "Cache",
|
||||
"assetdb.sqlite")
|
||||
self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Slices")
|
||||
self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Materials")
|
||||
|
||||
@@ -597,9 +597,9 @@ class TestsFBX_AllPlatforms(object):
|
||||
|
||||
# Load the asset database.
|
||||
db_path = os.path.join(asset_processor.temp_asset_root(), "Cache",
|
||||
workspace.project, "assetdb.sqlite")
|
||||
"assetdb.sqlite")
|
||||
cache_root = os.path.dirname(os.path.join(asset_processor.temp_asset_root(), "Cache",
|
||||
workspace.project, ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
|
||||
ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
|
||||
|
||||
if blackbox_params.scene_debug_file:
|
||||
debug_graph_path = os.path.join(asset_processor.project_test_cache_folder(), blackbox_params.scene_debug_file)
|
||||
|
||||
@@ -131,8 +131,9 @@ class TestAutomationBase:
|
||||
crash_info = f.read()
|
||||
except Exception as ex:
|
||||
crash_info += f"\n{str(ex)}"
|
||||
|
||||
error_str = f"Editor.exe crashed, return code: 0x{return_code:0X}\n\nCrash log:\n{crash_info}"
|
||||
|
||||
return_code_str = f"0x{return_code:0X}" if isinstance(return_code, int) else "None"
|
||||
error_str = f"Editor.exe crashed, return code: {return_code_str}\n\nCrash log:\n{crash_info}"
|
||||
errors.append(TestRunError("CRASH", error_str))
|
||||
|
||||
self.test_times[testcase_name] = time.time() - test_starttime
|
||||
|
||||
@@ -19,16 +19,11 @@ sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesti
|
||||
|
||||
from base import TestAutomationBase
|
||||
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.SUITE_periodic
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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)
|
||||
@@ -36,4 +31,3 @@ class TestAutomation(TestAutomationBase):
|
||||
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)
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or 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
|
||||
|
||||
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_sandbox
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
|
||||
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)
|
||||
@@ -3,15 +3,45 @@
|
||||
{
|
||||
"Gems":
|
||||
{
|
||||
"AutomatedTesting.Assets":
|
||||
"DevTextures":
|
||||
{
|
||||
"SourcePaths":
|
||||
[
|
||||
"Gems/DevTextures"
|
||||
]
|
||||
},
|
||||
"PBSreferenceMaterials":
|
||||
{
|
||||
"SourcePaths":
|
||||
[
|
||||
"Gems/PBSreferenceMaterials"
|
||||
]
|
||||
},
|
||||
"PhysicsEntities":
|
||||
{
|
||||
"SourcePaths":
|
||||
[
|
||||
"Gems/PhysicsEntities"
|
||||
]
|
||||
},
|
||||
"PhysXSamples":
|
||||
{
|
||||
"SourcePaths":
|
||||
[
|
||||
"Gems/PhysXSamples"
|
||||
]
|
||||
},
|
||||
"PrimitiveAssets":
|
||||
{
|
||||
"SourcePaths":
|
||||
[
|
||||
"Gems/PrimitiveAssets"
|
||||
]
|
||||
},
|
||||
"UiBasics":
|
||||
{
|
||||
"SourcePaths":
|
||||
[
|
||||
"Gems/DevTextures",
|
||||
"Gems/PBSreferenceMaterials",
|
||||
"Gems/PhysicsEntities",
|
||||
"Gems/PhysXSamples",
|
||||
"Gems/PrimitiveAssets",
|
||||
"Gems/UiBasics"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
import azlmbr.scene as sceneApi
|
||||
from scene_api import scene_data as sceneData
|
||||
import uuid
|
||||
|
||||
def update_manifest(scene):
|
||||
graph = sceneData.SceneGraph(scene.graph)
|
||||
@@ -27,7 +28,9 @@ def update_manifest(scene):
|
||||
sceneManifest = sceneData.SceneManifest()
|
||||
|
||||
for activeMeshIndex in range(len(chunkNameList)):
|
||||
meshGroup = sceneManifest.add_mesh_group(chunkNameList[activeMeshIndex])
|
||||
chunkName = chunkNameList[activeMeshIndex]
|
||||
meshGroup = sceneManifest.add_mesh_group(chunkName)
|
||||
meshGroup['id'] = '{' + str(uuid.uuid5(uuid.NAMESPACE_DNS, scene.sourceFilename + chunkName)) + '}'
|
||||
sceneManifest.mesh_group_add_comment(meshGroup, 'auto generated by test_chunks_builder')
|
||||
sceneManifest.mesh_group_set_origin(meshGroup, None, 0, 0, 0, 1.0)
|
||||
for meshIndex in range(len(chunkNameList)):
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
../Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/*map.tif
|
||||
@engroot@/Gems/LyShineExamples/Assets/UI/Textures/LyShineExamples/*map.tif
|
||||
|
||||
|
||||
@@ -1,298 +0,0 @@
|
||||
{
|
||||
"GemListFormatVersion": 2,
|
||||
"Gems": [
|
||||
{
|
||||
"Path": "Gems/EMotionFX",
|
||||
"Uuid": "044a63ea67d04479aa5daf62ded9d9ca",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "EMotionFX"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/PBSreferenceMaterials",
|
||||
"Uuid": "07375b61b1a2424bb03088bbdf28b2c8",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "PBSreferenceMaterials"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/GraphModel",
|
||||
"Uuid": "0844f64a3acf4f5abf3a535dc9b63bc9",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "GraphModel"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/StartingPointInput",
|
||||
"Uuid": "09f4bedeee614358bc36788e77f97e51",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "StartingPointInput"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/LyShine",
|
||||
"Uuid": "0fefab3f13364722b2eab3b96ce2bf20",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "LyShine"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/LandscapeCanvas",
|
||||
"Uuid": "19c2b2d5018940108baf252934b8e6bf",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "LandscapeCanvas"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/ScriptCanvasPhysics",
|
||||
"Uuid": "1c27519a4dda4ffaaeebf91514e5b1e8",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "ScriptCanvasPhysics"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/HttpRequestor",
|
||||
"Uuid": "28479e255bde466e91fc34eec808d9c7",
|
||||
"Version": "1.0.0",
|
||||
"_comment": "HttpRequestor"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/DevTextures",
|
||||
"Uuid": "2c227161447b4d77a5b07c093e214fe3",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "DevTextures"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/ScriptEvents",
|
||||
"Uuid": "32d8ba21703e4bbbb08487366e48dd69",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "ScriptEvents"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/Maestro",
|
||||
"Uuid": "3b9a978ed6f742a1acb99f74379a342c",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "Maestro"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/ExpressionEvaluation",
|
||||
"Uuid": "4c6f9df57ca2468f93c8d860ee6a1167",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "ExpressionEvaluation"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/PhysX",
|
||||
"Uuid": "4e08125824434932a0fe3717259caa47",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "PhysX"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/PhysXDebug",
|
||||
"Uuid": "516145e2d9904b13813f1b54605e26a6",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "PhysXDebug"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/CameraFramework",
|
||||
"Uuid": "54f2763fe191432fa681ce4a354eedf5",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "CameraFramework"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/TextureAtlas",
|
||||
"Uuid": "5a149b6b3c964064bd4970f0e92f72e2",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "TextureAtlas"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/SurfaceData",
|
||||
"Uuid": "5de82d29d6094bfe97c1a4d35fcd5fbe",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "SurfaceData"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/AssetValidation",
|
||||
"Uuid": "5a5c3c10b91d4b4ea8baef474c5b5d49",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "AssetValidation"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/Gestures",
|
||||
"Uuid": "6056556b6088413984309c4a413593ad",
|
||||
"Version": "1.0.0",
|
||||
"_comment": "Gestures"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/CertificateManager",
|
||||
"Uuid": "659cffff33b14a10835bafc6ea623f98",
|
||||
"Version": "0.0.1",
|
||||
"_comment": "CertificateManager"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/DebugDraw",
|
||||
"Uuid": "66239f50bf754354b514c850c8b841fb",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "DebugDraw"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/UiBasics",
|
||||
"Uuid": "6bb61c9e547043f0afc5019d6d460b78",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "UiBasics"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/AudioSystem",
|
||||
"Uuid": "6f63f2b6d07f4b89b4b7c86ebee7feb8",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "AudioSystem"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/StartingPointMovement",
|
||||
"Uuid": "73d8779dc28a4123b7c9ed76217464af",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "StartingPointMovement"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/GameLift",
|
||||
"Uuid": "76de765796504906b73be7365a9bff06",
|
||||
"Version": "2.0.0",
|
||||
"_comment": "GameLift"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/SceneProcessing",
|
||||
"Uuid": "7c2578f634df4345aca98d671e39b8ab",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "SceneProcessing"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/StartingPointCamera",
|
||||
"Uuid": "834070b9537d44df83559e2045c3859f",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "StartingPointCamera"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/ScriptCanvas",
|
||||
"Uuid": "869a0d0ec11a45c299917d45c81555e6",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "ScriptCanvasGem"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/GraphCanvas",
|
||||
"Uuid": "875b6fcbdeea44deaae7984ad9bb6cdc",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "GraphCanvas"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/GradientSignal",
|
||||
"Uuid": "8825563d9d964ec3be3bab681f3bd9f2",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "GradientSignal"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/InAppPurchases",
|
||||
"Uuid": "92fe57eae7d3402a90761973678c079a",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "InAppPurchases"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/PhysicsEntities",
|
||||
"Uuid": "99ea531451fc4f64a5a9fe8f385e8a76",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "PhysicsEntities"
|
||||
},
|
||||
{
|
||||
"Path": "AutomatedTesting/Gem",
|
||||
"Uuid": "afc25e1593194d6283d9ff744ab6d5a1",
|
||||
"Version": "0.1.0"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/EditorPythonBindings",
|
||||
"Uuid": "b658359393884c4381c2fe2952b1472a",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "EditorPythonBindings"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/ImGui",
|
||||
"Uuid": "bab8807a1bc646b3909f3cc200ffeedf",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "ImGui"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/ChatPlay",
|
||||
"Uuid": "bfbc60c63ffd4b00927003735b26ce99",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "ChatPlay"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/Metastream",
|
||||
"Uuid": "c02d7efe05134983b5699d9ee7594c3a",
|
||||
"Version": "1.0.0",
|
||||
"_comment": "Metastream"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/PhysXSamples",
|
||||
"Uuid": "c4a4aadba44241ae9f0141e145def7f7",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "PhysXSamples"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/Water",
|
||||
"Uuid": "c5083fcf89b24ab68fb0611c01a07b1d",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "Water"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/WhiteBox",
|
||||
"Uuid": "c5833dbda2e045d3a5f16b7414280c27",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "WhiteBox"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/TouchBending",
|
||||
"Uuid": "c58d2057f3724b22ae0df0be68a4e316",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "TouchBending"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/FastNoise",
|
||||
"Uuid": "c5f23032407f49ca8d8de1733423565c",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "FastNoise"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/LyShineExamples",
|
||||
"Uuid": "c7935ecf5e8047fe8ca947b34b11cadb",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "LyShineExamples"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/PrimitiveAssets",
|
||||
"Uuid": "ed07631f95fb4be1bd10cd37298ec697",
|
||||
"Version": "1.0.0",
|
||||
"_comment": "PrimitiveAssets"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/ImageProcessing",
|
||||
"Uuid": "eeffbd9211cf4ce0b5cc73696b427cbe",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "ImageProcessing"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/Vegetation",
|
||||
"Uuid": "f394e7cf54424bba89615381bba9511b",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "Vegetation"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/TestAssetBuilder",
|
||||
"Uuid": "f5c92f1560714010ba30467d93feecef",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "TestAssetBuilder"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/Camera",
|
||||
"Uuid": "f910686b6725452fbfc4671f95f733c6",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "Camera"
|
||||
},
|
||||
{
|
||||
"Path": "Gems/LmbrCentral",
|
||||
"Uuid": "ff06785f7145416b9d46fde39098cb0c",
|
||||
"Version": "0.1.0",
|
||||
"_comment": "LmbrCentral"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -24,12 +24,12 @@ def printMessage(message):
|
||||
def getCurrentProject():
|
||||
bootstrap = open("bootstrap.cfg", "r")
|
||||
|
||||
gameProjectRegex = re.compile("^sys_game_folder\s*=\s*(.*)")
|
||||
gameProjectRegex = re.compile(r"^project_path\s*=\s*(.*)")
|
||||
|
||||
for line in bootstrap:
|
||||
gameFolderMatch = gameProjectRegex.match(line)
|
||||
if gameFolderMatch:
|
||||
return gameFolderMatch.group(1)
|
||||
return os.path.basename(gameFolderMatch.group(1))
|
||||
return None
|
||||
|
||||
|
||||
|
||||
+22
-5
@@ -24,7 +24,7 @@ endif()
|
||||
include(cmake/Version.cmake)
|
||||
|
||||
if(NOT PROJECT_NAME)
|
||||
project(Lumberyard
|
||||
project(O3DE
|
||||
LANGUAGES C CXX
|
||||
VERSION ${LY_VERSION_STRING}
|
||||
)
|
||||
@@ -83,13 +83,30 @@ 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 were registered:
|
||||
# 1. link targets where the dependency was yet not declared, we need to have the declaration so we do different
|
||||
# 1. 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
|
||||
# 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
|
||||
# linking logic depending on the type of target
|
||||
ly_delayed_target_link_libraries()
|
||||
# 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
|
||||
ly_delayed_generate_settings_registry()
|
||||
# 3. 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()
|
||||
|
||||
@@ -1080,7 +1080,7 @@ void C3DEngine::WorldStreamUpdate()
|
||||
|
||||
if (GetCVars()->e_StreamSaveStartupResultsIntoXML)
|
||||
{
|
||||
const char* testResultsFile = "@cache@/TestResults/Streaming_Level_Start_Throughput.xml";
|
||||
const char* testResultsFile = "@usercache@/TestResults/Streaming_Level_Start_Throughput.xml";
|
||||
|
||||
AZ::IO::HandleType resultsFile = gEnv->pCryPak->FOpen(testResultsFile, "wb");
|
||||
if (resultsFile != AZ::IO::InvalidHandle)
|
||||
|
||||
@@ -952,7 +952,7 @@ void C3DEngine::ProcessStreamingLatencyTest(const CCamera& camIn, CCamera& camOu
|
||||
|
||||
if (GetCVars()->e_SQTestCount == 0)
|
||||
{
|
||||
const char* testResultsFile = "@cache@/TestResults/Streaming_Latency_Test.xml";
|
||||
const char* testResultsFile = "@usercache@/TestResults/Streaming_Latency_Test.xml";
|
||||
|
||||
AZ::IO::HandleType resultsFile = gEnv->pCryPak->FOpen(testResultsFile, "wb");
|
||||
if (resultsFile != AZ::IO::InvalidHandle)
|
||||
|
||||
@@ -461,7 +461,7 @@ void C3DEngine::UnloadLevel()
|
||||
m_ptexIconLowMemoryUsage = nullptr;
|
||||
m_ptexIconHighMemoryUsage = nullptr;
|
||||
m_ptexIconEditorConnectedToConsole = nullptr;
|
||||
|
||||
|
||||
if (m_pOpticsManager && !gEnv->IsEditor())
|
||||
{
|
||||
m_pOpticsManager->Reset();
|
||||
@@ -656,7 +656,7 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
|
||||
// set default render parameters.
|
||||
// for some reason this is not done later???
|
||||
m_pSkyLightManager->UpdateRenderParams();
|
||||
}
|
||||
}
|
||||
|
||||
// Load LevelData.xml File.
|
||||
XmlNodeRef xmlLevelData = GetSystem()->LoadXmlFromFile(GetLevelFilePath(LEVEL_DATA_FILE));
|
||||
@@ -687,17 +687,7 @@ bool C3DEngine::LoadLevel(const char* szFolderName, const char* szMissionName)
|
||||
// preload level cgfs
|
||||
if (GetCVars()->e_StatObjPreload && !gEnv->IsEditor())
|
||||
{
|
||||
if (GetCVars()->e_StatObjPreload == 2)
|
||||
{
|
||||
GetSystem()->OutputLoadingTimeStats();
|
||||
}
|
||||
|
||||
m_pObjManager->PreloadLevelObjects();
|
||||
|
||||
if (GetCVars()->e_StatObjPreload == 2)
|
||||
{
|
||||
GetSystem()->OutputLoadingTimeStats();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<struct IStatObj*>* pStatObjTable = NULL;
|
||||
|
||||
@@ -317,7 +317,8 @@ int CLightEntity::UpdateGSMLightSourceDynamicShadowFrustum(int nDynamicLodCount,
|
||||
|
||||
if (bDoGSM)
|
||||
{
|
||||
Vec3 vSunDir = Get3DEngine()->GetSunDir().GetNormalized(); // todo: remove GetNormalized() once GetSunDir() returns the normalized value
|
||||
//Vec3 vSunDir = Get3DEngine()->GetSunDir().GetNormalized(); // todo: remove GetNormalized() once GetSunDir() returns the normalized value
|
||||
Vec3 vSunDir = Vec3(1.0f, 0.0f, 0.0f);
|
||||
Vec3 vCameraDirWithoutDepth = vCameraDir - vCameraDir.Dot(vSunDir) * vSunDir;
|
||||
|
||||
Vec3 vFocusPos = passInfo.GetCamera().GetPosition() + vCameraDirWithoutDepth * fGSMBoxSize;
|
||||
|
||||
@@ -117,10 +117,6 @@ CMatInfo::CMatInfo()
|
||||
|
||||
ZeroStruct(m_streamZoneInfo);
|
||||
|
||||
#ifdef TRACE_MATERIAL_LEAKS
|
||||
m_sLoadingCallstack = GetSystem()->GetLoadingProfilerCallstack();
|
||||
#endif
|
||||
|
||||
// Used to know when a .dccmtl file has been changed,
|
||||
// requiring the source material to be updated
|
||||
m_dccMaterialHash = 0;
|
||||
@@ -341,7 +337,7 @@ ISurfaceType* CMatInfo::GetSurfaceType()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CMatInfo::SetSubMtlCount(int numSubMtl)
|
||||
{
|
||||
AUTO_LOCK(GetSubMaterialResizeLock());
|
||||
AUTO_LOCK(GetSubMaterialResizeLock());
|
||||
if (numSubMtl > 0)
|
||||
{
|
||||
m_Flags |= MTL_FLAG_MULTI_SUBMTL;
|
||||
@@ -1112,15 +1108,6 @@ void CMatInfo::SetTexelDensityDebug([[maybe_unused]] int mode)
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* CMatInfo::GetLoadingCallstack()
|
||||
{
|
||||
#ifdef TRACE_MATERIAL_LEAKS
|
||||
return m_sLoadingCallstack.c_str();
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
void CMatInfo::PrecacheMaterial(const float _fEntDistance, IRenderMesh* pRenderMesh, bool bFullUpdate, bool bDrawNear)
|
||||
{
|
||||
// FUNCTION_PROFILER_3DENGINE;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <IMaterial.h>
|
||||
|
||||
#if !defined(CONSOLE)
|
||||
# define TRACE_MATERIAL_LEAKS
|
||||
# define SUPPORT_MATERIAL_EDITING
|
||||
#endif
|
||||
|
||||
@@ -203,7 +202,7 @@ public:
|
||||
bool SetGetMaterialParamFloat(const char* sParamName, float& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override;
|
||||
bool SetGetMaterialParamVec3(const char* sParamName, Vec3& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override;
|
||||
bool SetGetMaterialParamVec4(const char* sParamName, Vec4& v, bool bGet, bool allowShaderParam = false, int materialIndex = 0) override;
|
||||
|
||||
|
||||
void SetDirty(bool dirty = true) override;
|
||||
bool IsDirty() const override;
|
||||
|
||||
@@ -264,11 +263,6 @@ public:
|
||||
bool IsForwardRenderingRequired();
|
||||
bool IsNearestCubemapRequired();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Debug routines
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual const char* GetLoadingCallstack(); // trace leaking materials by callstack
|
||||
|
||||
void DisableTextureStreaming() override;
|
||||
virtual void RequestTexturesLoading(const float fMipFactor);
|
||||
|
||||
@@ -286,13 +280,6 @@ public:
|
||||
void SetDccMaterialHash(uint32 hash) override { m_dccMaterialHash = hash; }
|
||||
|
||||
virtual CryCriticalSection& GetSubMaterialResizeLock();
|
||||
public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// for debug purposes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#ifdef TRACE_MATERIAL_LEAKS
|
||||
string m_sLoadingCallstack;
|
||||
#endif
|
||||
|
||||
private:
|
||||
friend class CMatMan;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#pragma once
|
||||
|
||||
#if !defined(CONSOLE)
|
||||
# define TRACE_CGF_LEAKS
|
||||
# define SUPPORT_TERRAIN_AO_PRE_COMPUTATIONS
|
||||
#endif
|
||||
|
||||
@@ -337,13 +336,6 @@ public:
|
||||
std::vector<uint16> m_chunkBoneIds;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// for debug purposes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#ifdef TRACE_CGF_LEAKS
|
||||
string m_sLoadingCallstack;
|
||||
#endif
|
||||
|
||||
private:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sub objects.
|
||||
@@ -419,7 +411,7 @@ public:
|
||||
virtual unsigned int GetBreakableByGame() { return m_bBreakableByGame; };
|
||||
|
||||
//Note: This function checks both the children and root data
|
||||
//It should really be 'has any deformable objects'
|
||||
//It should really be 'has any deformable objects'
|
||||
//Should eventually be refactored as part of an eventual statobj refactor.
|
||||
virtual bool IsDeformable() override;
|
||||
|
||||
|
||||
@@ -56,10 +56,6 @@ CStatObj::CStatObj()
|
||||
m_fLodDistance = 0.0f;
|
||||
|
||||
Init();
|
||||
|
||||
#ifdef TRACE_CGF_LEAKS
|
||||
m_sLoadingCallstack = GetSystem()->GetLoadingProfilerCallstack();
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1064,7 +1064,7 @@ namespace Audio
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Interface methods
|
||||
virtual bool Initialize(const SSystemInitParams* initParams) = 0;
|
||||
virtual bool Initialize() = 0;
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -392,7 +392,7 @@ struct IMaterial
|
||||
virtual void SetDirty(bool dirty = true) = 0;
|
||||
virtual bool IsDirty() const = 0;
|
||||
|
||||
//! Returns true if the material is the parent of a group of materials
|
||||
//! Returns true if the material is the parent of a group of materials
|
||||
virtual bool IsMaterialGroup() const = 0;
|
||||
|
||||
//! Returns true if the material is a single material belongs to a material group
|
||||
@@ -411,11 +411,6 @@ struct IMaterial
|
||||
// - 2, fast sketch mode.
|
||||
virtual void SetSketchMode(int mode) = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Debug routines
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual const char* GetLoadingCallstack() = 0; // trace leaking materials by callstack
|
||||
|
||||
// Sets FT_DONT_STREAM flag for all textures used by the material
|
||||
// If a stream is already in process, this will stop the stream and flush the device texture
|
||||
virtual void DisableTextureStreaming() = 0;
|
||||
|
||||
@@ -119,8 +119,6 @@ namespace AZ
|
||||
|
||||
class IResourceCompilerHelper;
|
||||
|
||||
class CBootProfilerRecord;
|
||||
|
||||
namespace Serialization {
|
||||
struct IArchiveHost;
|
||||
}
|
||||
@@ -629,15 +627,7 @@ struct SSystemInitParams
|
||||
void* hWnd; //
|
||||
void* hWndForInputSystem; // the HWND for the input devices, distinct from the hWnd, which the rendering system overrides anyways
|
||||
|
||||
char remoteIP[256];
|
||||
int remotePort;
|
||||
bool remoteFileIO;
|
||||
bool remoteResourceCompiler;
|
||||
bool connectToRemote;
|
||||
bool waitForConnection; // if true, wait for the remote connection to be established before proceeding to system init.
|
||||
char assetsPlatform[64]; // what flavor of assets to load. Corresponds to those in rc.ini and asset processor ini
|
||||
char gameFolderName[256]; // just the name. Not the full path.
|
||||
char branchToken[12]; // information written by the assetprocessor which help determine whether the game/editor are running from the same branch or not
|
||||
|
||||
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).
|
||||
@@ -648,45 +638,6 @@ struct SSystemInitParams
|
||||
IOutputPrintSink* pPrintSync; // Print Sync which can be used to catch all output from engine
|
||||
char szSystemCmdLine[2048]; // Command line.
|
||||
|
||||
|
||||
// set some paths before you create the system.
|
||||
|
||||
// rootPath - (REQUIRED) folder containing root. Must contain system.cfg or bootstrap.cfg basically.
|
||||
// the remainder are optional and if specified should contain prefixes that can be prepended to any file to get to that location:
|
||||
// READ ONLY!
|
||||
char rootPath[256];
|
||||
char rootPathCache[256];
|
||||
|
||||
// assetsPath - (REQUIRED) - where you assets live. The engine config parser will default this to @root@/gamename
|
||||
// READ ONLY!
|
||||
char assetsPath[256];
|
||||
char assetsPathCache[256];
|
||||
|
||||
// userPath - (OPTIONAL) User path contains a folder for preferences persistent storage. May be persisted to the cloud (by things like IOS)
|
||||
// If not specified, this is assumed @root@/User/
|
||||
// WRITABLE
|
||||
char userPath[256];
|
||||
|
||||
// cachePath - (OPTIONAL) a temporary store that can be erased at any time and does not need to be persisted
|
||||
// on the cloud or anything like that. if not specified, this will be @user@/Cache
|
||||
// WRITABLE
|
||||
char cachePath[256];
|
||||
|
||||
// logPath - (OPTIONAL) a log path folder.
|
||||
// If not specified, it will be @cache@/Logs
|
||||
// WRITABLE
|
||||
char logPath[256];
|
||||
|
||||
// the game should never use these values instead, the game should be using crypak or fileio with aliases:
|
||||
// @root@ To get to the folder where system.cfg lives
|
||||
// @assets@ to get to the folder containing game assets (textures and such) - by default, this is @root@/Gamename/
|
||||
// @devroot@ to get to source files that are checked into source control (PC EDITOR ONLY!)
|
||||
// @engroot@ to get to path to the engine root folder
|
||||
// @user@ to access user store
|
||||
// @cache@ to access temporary cache
|
||||
// @log@ to access log file and other forensic storage
|
||||
char szBinariesDir[256];
|
||||
|
||||
bool bEditor; // When running in Editor mode.
|
||||
bool bPreview; // When running in Preview mode (Minimal initialization).
|
||||
bool bTestMode; // When running in Automated testing mode.
|
||||
@@ -730,26 +681,7 @@ struct SSystemInitParams
|
||||
hWnd = NULL;
|
||||
hWndForInputSystem = NULL;
|
||||
|
||||
memset(rootPath, 0, sizeof(rootPath));
|
||||
memset(rootPathCache, 0, sizeof(rootPathCache));
|
||||
memset(userPath, 0, sizeof(userPath));
|
||||
memset(assetsPath, 0, sizeof(assetsPath));
|
||||
memset(assetsPathCache, 0, sizeof(assetsPathCache));
|
||||
memset(cachePath, 0, sizeof(cachePath));
|
||||
memset(logPath, 0, sizeof(logPath));
|
||||
memset(gameFolderName, 0, sizeof(gameFolderName));
|
||||
memset(branchToken, 0, sizeof(branchToken));
|
||||
|
||||
memset(remoteIP, 0, sizeof(remoteIP));
|
||||
azstrcpy(remoteIP, sizeof(remoteIP), "127.0.0.1");
|
||||
memset(assetsPlatform, 0, sizeof(assetsPlatform));
|
||||
azstrcpy(assetsPlatform, sizeof(assetsPlatform), "pc");
|
||||
|
||||
remotePort = 45643;
|
||||
remoteFileIO = false;
|
||||
remoteResourceCompiler = false;
|
||||
connectToRemote = false;
|
||||
waitForConnection = false;
|
||||
|
||||
pLog = NULL;
|
||||
pLogCallback = NULL;
|
||||
@@ -762,7 +694,6 @@ struct SSystemInitParams
|
||||
pValidator = NULL;
|
||||
pPrintSync = NULL;
|
||||
memset(szSystemCmdLine, 0, sizeof(szSystemCmdLine));
|
||||
memset(szBinariesDir, 0, sizeof(szBinariesDir));
|
||||
|
||||
bEditor = false;
|
||||
bPreview = false;
|
||||
@@ -798,17 +729,6 @@ struct SSystemInitParams
|
||||
|
||||
pSharedEnvironment = nullptr;
|
||||
}
|
||||
|
||||
bool UseAssetCache() const
|
||||
{
|
||||
#if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_MAC) || defined(AZ_PLATFORM_LINUX)
|
||||
char checkPath[AZ_MAX_PATH_LEN] = { 0 };
|
||||
azsnprintf(checkPath, AZ_MAX_PATH_LEN, "%s/engine.json", rootPathCache);
|
||||
return AZ::IO::SystemFile::Exists(checkPath);
|
||||
#else
|
||||
return false;
|
||||
#endif // defined(AZ_PLATFORM_WINDOWS) || AZ_TRAIT_OS_PLATFORM_APPLE
|
||||
}
|
||||
};
|
||||
|
||||
// Notes:
|
||||
@@ -1228,11 +1148,6 @@ struct ISystem
|
||||
// Gets number of CPUs
|
||||
virtual int GetLogicalCPUCount() = 0;
|
||||
|
||||
//! Get the 'kind' of assets you need to load - this describes the flavor of assets you are going to load
|
||||
//! based on the platform you're on - so for example, android on ES3 will be 'es3' but android on opengl might load PC assets or others...
|
||||
//! This is defined in bootstrap.cfg and is read-only during runtime.
|
||||
virtual const char* GetAssetsPlatform() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Return the rendering driver name. GL or Metal
|
||||
virtual const char* GetRenderingDriverName() const = 0;
|
||||
@@ -1406,43 +1321,6 @@ struct ISystem
|
||||
// True if system running in Test mode.
|
||||
virtual bool IsTestMode() const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Loading time/memory profiling
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Summary:
|
||||
// Starts function loading stats profiling.
|
||||
virtual struct SLoadingTimeContainer* StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName) = 0;
|
||||
|
||||
// Summary:
|
||||
// Ends function loading stats profiling.
|
||||
virtual void EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler) = 0;
|
||||
|
||||
// Summary:
|
||||
// Starts function profiling with bootprofiler (session must be started).
|
||||
virtual CBootProfilerRecord* StartBootSectionProfiler(const char* name, const char* args) = 0;
|
||||
|
||||
// Summary:
|
||||
// Ends function profiling with bootprofiler.
|
||||
virtual void StopBootSectionProfiler(CBootProfilerRecord* record) = 0;
|
||||
|
||||
|
||||
// Summary:
|
||||
// Starts frame session
|
||||
virtual void StartBootProfilerSessionFrames(const char* pName) = 0;
|
||||
|
||||
// Summary:
|
||||
// Stops frame session
|
||||
virtual void StopBootProfilerSessionFrames() = 0;
|
||||
|
||||
// Summary:
|
||||
// Prints loading stats into log.
|
||||
virtual void OutputLoadingTimeStats() = 0;
|
||||
|
||||
// Summary:
|
||||
// Starts function loading stats profiling.
|
||||
virtual const char* GetLoadingProfilerCallstack() = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// File version.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -1581,10 +1459,10 @@ struct ISystem
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Summary:
|
||||
// Enable/Disable drawing the console
|
||||
// Enable/Disable drawing the console
|
||||
virtual void SetConsoleDrawEnabled(bool enabled) = 0;
|
||||
|
||||
// Enable/Disable drawing the UI
|
||||
// Enable/Disable drawing the UI
|
||||
virtual void SetUIDrawEnabled(bool enabled) = 0;
|
||||
|
||||
// Summary:
|
||||
@@ -1772,79 +1650,19 @@ struct DiskOperationInfo
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
|
||||
struct CLoadingTimeProfiler
|
||||
{
|
||||
CLoadingTimeProfiler(ISystem* pSystem, const char* szFuncName)
|
||||
: m_pSystem(pSystem)
|
||||
{
|
||||
m_pSystem = pSystem;
|
||||
m_pTimeContainer = m_pSystem->StartLoadingSectionProfiling(this, szFuncName);
|
||||
}
|
||||
|
||||
~CLoadingTimeProfiler()
|
||||
{
|
||||
m_pSystem->EndLoadingSectionProfiling(this);
|
||||
}
|
||||
|
||||
struct SLoadingTimeContainer* m_pTimeContainer;
|
||||
double m_fConstructorTime;
|
||||
double m_fConstructorMemUsage;
|
||||
|
||||
DiskOperationInfo m_constructorInfo;
|
||||
|
||||
ISystem* m_pSystem;
|
||||
};
|
||||
|
||||
class CSYSBootProfileBlock
|
||||
{
|
||||
ISystem* m_pSystem;
|
||||
CBootProfilerRecord* m_pRecord;
|
||||
public:
|
||||
CSYSBootProfileBlock(ISystem* pSystem, const char* name, const char* args = NULL)
|
||||
: m_pSystem(pSystem)
|
||||
{
|
||||
if (m_pSystem)
|
||||
{
|
||||
m_pRecord = m_pSystem->StartBootSectionProfiler(name, args);
|
||||
}
|
||||
}
|
||||
|
||||
~CSYSBootProfileBlock()
|
||||
{
|
||||
if (m_pSystem)
|
||||
{
|
||||
m_pSystem->StopBootSectionProfiler(m_pRecord);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef AZ_PROFILE_TELEMETRY
|
||||
#if defined(ENABLE_LOADING_PROFILER) && AZ_PROFILE_TELEMETRY
|
||||
|
||||
#define LOADING_TIME_PROFILE_SECTION AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzCore)
|
||||
#define LOADING_TIME_PROFILE_SECTION_ARGS(...) AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, __VA_ARGS__)
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED(sectionName) AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzCore, sectionName)
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, args) AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, sectionName, args)
|
||||
|
||||
#else
|
||||
|
||||
#define LOADING_TIME_PROFILE_SECTION CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv && gEnv->pSystem ? gEnv->pSystem : nullptr, __FUNCTION__);
|
||||
#define LOADING_TIME_PROFILE_SECTION_ARGS(args) CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv->pSystem, __FUNCTION__, args);
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED(sectionName) CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv->pSystem, sectionName);
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, args) CSYSBootProfileBlock AZ_JOIN(_profileBlockLine, __LINE__)(gEnv->pSystem, sectionName, args);
|
||||
|
||||
#endif // AZ_PROFILE_TELEMETRY
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, ...) AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::AzCore, sectionName, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
#define LOADING_TIME_PROFILE_SECTION
|
||||
#define LOADING_TIME_PROFILE_SECTION_ARGS(args)
|
||||
#define LOADING_TIME_PROFILE_SECTION_ARGS(...)
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED(sectionName)
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, args)
|
||||
#define LOADING_TIME_PROFILE_SESSION_SECTION(sessionName)
|
||||
#define LOADING_TIME_PROFILE_SESSION_START(sessionName)
|
||||
#define LOADING_TIME_PROFILE_SESSION_STOP(sessionName)
|
||||
#define LOADING_TIME_PROFILE_SECTION_NAMED_ARGS(sectionName, ...)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1865,7 +1683,7 @@ extern SC_API SSystemGlobalEnvironment* gEnv;
|
||||
inline ISystem* GetISystem()
|
||||
{
|
||||
// Some unit tests temporarily install and then uninstall ISystem* mocks.
|
||||
// It is generally okay for runtime and tool systems which call this function to cache the returned pointer,
|
||||
// It is generally okay for runtime and tool systems which call this function to cache the returned pointer,
|
||||
// because their lifetime is usually shorter than the lifetime of the ISystem* implementation.
|
||||
// It is NOT safe for this function to cache it as a static itself, though, as the static it would cache
|
||||
// it inside may outlive the the actual instance implementing ISystem* when unit tests are torn down and then restarted.
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/SystemFile.h> // for max path len
|
||||
#include <ISystem.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <ISystem.h>
|
||||
|
||||
namespace MaterialUtils
|
||||
{
|
||||
//! UnifyMaterialName - given a non-unified material name, remove the extension, unify the slashes
|
||||
@@ -75,14 +77,11 @@ namespace MaterialUtils
|
||||
static char cachedGameName[AZ_MAX_PATH_LEN] = { 0 };
|
||||
if (!removals[removalSize - 1])
|
||||
{
|
||||
if ((gEnv) && (gEnv->pConsole))
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
if (!projectName.empty())
|
||||
{
|
||||
ICVar* pGameNameCVar = gEnv->pConsole->GetCVar("sys_game_folder");
|
||||
if (pGameNameCVar)
|
||||
{
|
||||
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, pGameNameCVar->GetString());
|
||||
azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/");
|
||||
}
|
||||
azstrcpy(cachedGameName, AZ_MAX_PATH_LEN, projectName.c_str());
|
||||
azstrcat(cachedGameName, AZ_MAX_PATH_LEN, "/");
|
||||
}
|
||||
|
||||
if (cachedGameName[0] == 0)
|
||||
|
||||
@@ -55,8 +55,6 @@ public:
|
||||
int());
|
||||
MOCK_METHOD0(GetLogicalCPUCount,
|
||||
int());
|
||||
MOCK_CONST_METHOD0(GetAssetsPlatform,
|
||||
const char*());
|
||||
MOCK_CONST_METHOD0(GetRenderingDriverName,
|
||||
const char*());
|
||||
MOCK_METHOD1(DumpMemoryUsageStatistics,
|
||||
@@ -206,22 +204,6 @@ public:
|
||||
bool());
|
||||
MOCK_METHOD3(SetFrameProfiler,
|
||||
void(bool on, bool display, char* prefix));
|
||||
MOCK_METHOD2(StartLoadingSectionProfiling,
|
||||
struct SLoadingTimeContainer*(CLoadingTimeProfiler * pProfiler, const char* szFuncName));
|
||||
MOCK_METHOD1(EndLoadingSectionProfiling,
|
||||
void(CLoadingTimeProfiler * pProfiler));
|
||||
MOCK_METHOD2(StartBootSectionProfiler,
|
||||
CBootProfilerRecord * (const char* name, const char* args));
|
||||
MOCK_METHOD1(StopBootSectionProfiler,
|
||||
void(CBootProfilerRecord * record));
|
||||
MOCK_METHOD1(StartBootProfilerSessionFrames,
|
||||
void(const char* pName));
|
||||
MOCK_METHOD0(StopBootProfilerSessionFrames,
|
||||
void());
|
||||
MOCK_METHOD0(OutputLoadingTimeStats,
|
||||
void());
|
||||
MOCK_METHOD0(GetLoadingProfilerCallstack,
|
||||
const char*());
|
||||
MOCK_METHOD0(GetFileVersion,
|
||||
const SFileVersion&());
|
||||
MOCK_METHOD0(GetProductVersion,
|
||||
|
||||
@@ -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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ISystem.h"
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
|
||||
// any of the following tags can be present in the bootstrap.cfg
|
||||
// you can also prefix it with a platform.
|
||||
// so for example, you can specify remote_ip alone to specify it for all platforms
|
||||
// or you could specify android_remote_ip to change it for android only.
|
||||
// the instructions are executed in the order that they appear, so you can set the default
|
||||
// by using the non-platform-specific version, and then later on in the file you
|
||||
// can override specific platforms.
|
||||
|
||||
#define CONFIG_KEY_FOR_REMOTEIP "remote_ip"
|
||||
#define CONFIG_KEY_FOR_REMOTEPORT "remote_port"
|
||||
#define CONFIG_KEY_FOR_GAMEFOLDER "sys_game_folder"
|
||||
#define CONFIG_KEY_FOR_REMOTEFILEIO "remote_filesystem"
|
||||
#define CONFIG_KEY_FOR_CONNECTTOREMOTE "connect_to_remote"
|
||||
#define CONFIG_KEY_WAIT_FOR_CONNECT "wait_for_connect"
|
||||
#define DEFAULT_GAMEDLL "EmptyTemplate"
|
||||
#define DEFAULT_GAMEFOLDER "EmptyTemplate"
|
||||
#define DEFAULT_REMOTEIP "127.0.0.1"
|
||||
#define DEFAULT_REMOTEPORT 45643
|
||||
#define CONFIG_KEY_FOR_ASSETS "assets"
|
||||
#define CONFIG_KEY_FOR_BRANCHTOKEN "assetProcessor_branch_token"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CEngineConfig
|
||||
{
|
||||
public:
|
||||
string m_gameFolder; // folder only ("MyGame")
|
||||
string m_assetPlatform; // what platform folder assets are from if more than one is available or using VFS ("pc" / "es3")
|
||||
bool m_connectToRemote;
|
||||
bool m_remoteFileIO;
|
||||
bool m_waitForConnect;
|
||||
string m_remoteIP;
|
||||
int m_remotePort;
|
||||
|
||||
string m_rootFolder; // The engine root folder
|
||||
string m_branchToken;
|
||||
|
||||
CEngineConfig([[maybe_unused]] const char** sourcePaths = nullptr, [[maybe_unused]] size_t numSearchPaths = 0, [[maybe_unused]] size_t numLevelsUp = 3)
|
||||
: m_gameFolder(DEFAULT_GAMEFOLDER)
|
||||
, m_connectToRemote(false)
|
||||
, m_remoteFileIO(false)
|
||||
, m_remotePort(DEFAULT_REMOTEPORT)
|
||||
, m_waitForConnect(false)
|
||||
, m_remoteIP(DEFAULT_REMOTEIP)
|
||||
{
|
||||
m_assetPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
|
||||
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString gameFolder;
|
||||
auto gameFolderKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/%s",
|
||||
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, CONFIG_KEY_FOR_GAMEFOLDER);
|
||||
if (settingsRegistry->Get(gameFolder, gameFolderKey))
|
||||
{
|
||||
m_gameFolder.assign(gameFolder.c_str(), gameFolder.size());
|
||||
}
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString engineRoot;
|
||||
if (settingsRegistry->Get(engineRoot, AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder))
|
||||
{
|
||||
m_rootFolder.assign(engineRoot.c_str(), engineRoot.size());
|
||||
}
|
||||
}
|
||||
|
||||
OnLoadSettings();
|
||||
}
|
||||
|
||||
void CopyToStartupParams(SSystemInitParams& startupParams) const
|
||||
{
|
||||
startupParams.remoteFileIO = m_remoteFileIO;
|
||||
startupParams.remotePort = m_remotePort;
|
||||
startupParams.connectToRemote = m_connectToRemote;
|
||||
startupParams.waitForConnection = m_waitForConnect;
|
||||
|
||||
azstrncpy(startupParams.remoteIP, sizeof(startupParams.remoteIP), m_remoteIP.c_str(), m_remoteIP.length() + 1); // +1 for the null terminator
|
||||
azstrncpy(startupParams.assetsPlatform, sizeof(startupParams.assetsPlatform), m_assetPlatform.c_str(), m_assetPlatform.length() + 1); // +1 for the null terminator
|
||||
azstrncpy(startupParams.rootPath, sizeof(startupParams.rootPath), m_rootFolder.c_str(), m_rootFolder.length() + 1); // +1 for the null terminator
|
||||
azstrncpy(startupParams.gameFolderName, sizeof(startupParams.gameFolderName), m_gameFolder.c_str(), m_gameFolder.length() + 1); // +1 for the null terminator
|
||||
azstrncpy(startupParams.branchToken, sizeof(startupParams.branchToken), m_branchToken.c_str(), m_branchToken.length() + 1); // +1 for the null terminator
|
||||
|
||||
// compute assets path based on game folder name
|
||||
string gameFolderLower(m_gameFolder);
|
||||
gameFolderLower.MakeLower();
|
||||
azsnprintf(startupParams.assetsPath, sizeof(startupParams.assetsPath), "%s/%s", startupParams.rootPath, gameFolderLower.c_str());
|
||||
|
||||
// compute where the cache should be located
|
||||
azsnprintf(startupParams.rootPathCache, sizeof(startupParams.rootPathCache), "%s/Cache/%s/%s", m_rootFolder.c_str(), m_gameFolder.c_str(), m_assetPlatform.c_str());
|
||||
azsnprintf(startupParams.assetsPathCache, sizeof(startupParams.assetsPathCache), "%s/%s", startupParams.rootPathCache, gameFolderLower.c_str());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void OnLoadSettings()
|
||||
{
|
||||
auto settingsRegistry = AZ::SettingsRegistry::Get();
|
||||
if (settingsRegistry == nullptr)
|
||||
{
|
||||
AZ_Warning("ParseEngineConfig", false, "Attempting to load configuration data while SettingsRegistry does not exist");
|
||||
return;
|
||||
|
||||
}
|
||||
AZ::SettingsRegistryInterface::FixedValueString settingsKeyPrefix = AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey;
|
||||
AZ::SettingsRegistryInterface::FixedValueString settingsValueString;
|
||||
AZ::s64 settingsValueInt{};
|
||||
|
||||
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_FOR_REMOTEFILEIO))
|
||||
{
|
||||
m_remoteFileIO = settingsValueInt != 0;
|
||||
}
|
||||
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_WAIT_FOR_CONNECT))
|
||||
{
|
||||
m_waitForConnect = settingsValueInt != 0;
|
||||
}
|
||||
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_FOR_CONNECTTOREMOTE))
|
||||
{
|
||||
m_connectToRemote = settingsValueInt != 0;
|
||||
}
|
||||
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueInt, settingsKeyPrefix, CONFIG_KEY_FOR_REMOTEPORT))
|
||||
{
|
||||
m_remotePort = aznumeric_cast<AZ::u16>(settingsValueInt);
|
||||
}
|
||||
if (settingsValueString = {};
|
||||
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueString, settingsKeyPrefix, CONFIG_KEY_FOR_REMOTEIP))
|
||||
{
|
||||
m_remoteIP.assign(settingsValueString.c_str(), settingsValueString.size());
|
||||
}
|
||||
if (settingsValueString = {};
|
||||
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, settingsValueString, settingsKeyPrefix, CONFIG_KEY_FOR_ASSETS))
|
||||
{
|
||||
m_assetPlatform.assign(settingsValueString.c_str(), settingsValueString.size());
|
||||
}
|
||||
if (settingsValueString = {};
|
||||
settingsRegistry->Get(settingsValueString, settingsKeyPrefix + "/" + CONFIG_KEY_FOR_BRANCHTOKEN))
|
||||
{
|
||||
m_branchToken.assign(settingsValueString.c_str(), settingsValueString.size());
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
@@ -293,7 +293,7 @@ typedef uint32 vtx_idx;
|
||||
|
||||
#if defined(ENABLE_PROFILING_CODE)
|
||||
# define USE_DISK_PROFILER
|
||||
//# define ENABLE_LOADING_PROFILER // Not guaranteed to have enough slots for all the threads in the system
|
||||
# define ENABLE_LOADING_PROFILER // requires AZ_PROFILE_TELEMETRY to also be defined
|
||||
#endif
|
||||
|
||||
#if defined(SOFTCODE_ENABLED)
|
||||
|
||||
@@ -110,7 +110,6 @@ set(FILES
|
||||
AzDXGIFormat.h
|
||||
SFunctor.h
|
||||
FunctorBaseFunction.h
|
||||
ParseEngineConfig.h
|
||||
CustomMemoryHeap.h
|
||||
FunctorBaseMember.h
|
||||
stridedptr.h
|
||||
|
||||
@@ -1,630 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS 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(ENABLE_LOADING_PROFILER)
|
||||
|
||||
#include "BootProfiler.h"
|
||||
#include "ThreadInfo.h"
|
||||
#include <stack>
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
StaticInstance<CBootProfiler, AZStd::no_destruct<CBootProfiler>> gProfilerInstance;
|
||||
enum
|
||||
{
|
||||
eMAX_THREADS_TO_PROFILE = 128,
|
||||
eNUM_RECORDS_PER_POOL = 2048, // so, eNUM_RECORDS_PER_POOL * sizeof(CBootProfilerRecord) == mem consumed by pool item
|
||||
// sizeof(CProfileBlockTimes)==152,
|
||||
// poolmem = 304Kb for 1 pool per thread
|
||||
};
|
||||
}
|
||||
|
||||
int CBootProfiler::CV_sys_bp_frames = 0;
|
||||
float CBootProfiler::CV_sys_bp_time_threshold = 0;
|
||||
|
||||
class CProfileBlockTimes
|
||||
{
|
||||
protected:
|
||||
LARGE_INTEGER m_startTimeStamp;
|
||||
LARGE_INTEGER m_stopTimeStamp;
|
||||
LARGE_INTEGER m_freq;
|
||||
CProfileBlockTimes()
|
||||
{
|
||||
memset(&m_startTimeStamp, 0, sizeof(m_startTimeStamp));
|
||||
memset(&m_stopTimeStamp, 0, sizeof(m_stopTimeStamp));
|
||||
memset(&m_freq, 0, sizeof(m_freq));
|
||||
}
|
||||
};
|
||||
|
||||
class CBootProfilerRecord
|
||||
{
|
||||
public:
|
||||
const char* m_label;
|
||||
LARGE_INTEGER m_startTimeStamp;
|
||||
LARGE_INTEGER m_stopTimeStamp;
|
||||
LARGE_INTEGER m_freq;
|
||||
|
||||
CBootProfilerRecord* m_pParent;
|
||||
typedef AZStd::vector<CBootProfilerRecord*> ChildVector;
|
||||
ChildVector m_Childs;
|
||||
|
||||
CryFixedStringT<256> m_args;
|
||||
|
||||
ILINE CBootProfilerRecord(const char* label, LARGE_INTEGER timestamp, LARGE_INTEGER freq, const char* args)
|
||||
: m_label(label)
|
||||
, m_startTimeStamp(timestamp)
|
||||
, m_freq(freq)
|
||||
, m_pParent(NULL)
|
||||
{
|
||||
memset(&m_stopTimeStamp, 0, sizeof(m_stopTimeStamp));
|
||||
if (args)
|
||||
{
|
||||
m_args = args;
|
||||
}
|
||||
}
|
||||
|
||||
ILINE ~CBootProfilerRecord()
|
||||
{
|
||||
// childs are allocated via pool as well, the destructors of each child
|
||||
// is called explicitly, for the purpose of freeing memory occupied by
|
||||
// m_Child vector. Otherwise there will be a memory leak.
|
||||
ChildVector::iterator it = m_Childs.begin();
|
||||
while (it != m_Childs.end())
|
||||
{
|
||||
(*it)->~CBootProfilerRecord();
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void Print(AZ::IO::HandleType fileHandle, char* buf, size_t buf_size, size_t depth, LARGE_INTEGER stopTime, const char* threadName, const float timeThreshold)
|
||||
{
|
||||
if (m_stopTimeStamp.QuadPart == 0)
|
||||
{
|
||||
m_stopTimeStamp = stopTime;
|
||||
}
|
||||
|
||||
const float time = (float)(m_stopTimeStamp.QuadPart - m_startTimeStamp.QuadPart) * 1000.f / (float)m_freq.QuadPart;
|
||||
|
||||
if (timeThreshold > 0.0f && time < timeThreshold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string tabs; //tabs(depth++, '\t')
|
||||
tabs.insert(0, depth++, '\t');
|
||||
|
||||
{
|
||||
string label = m_label;
|
||||
label.replace("&", "&");
|
||||
label.replace("<", "<");
|
||||
label.replace(">", ">");
|
||||
label.replace("\"", """);
|
||||
label.replace("'", "'");
|
||||
|
||||
if (m_args.size() > 0)
|
||||
{
|
||||
m_args.replace("&", "&");
|
||||
m_args.replace("<", "<");
|
||||
m_args.replace(">", ">");
|
||||
m_args.replace("\"", """);
|
||||
m_args.replace("'", "'");
|
||||
m_args.replace("%", "%");
|
||||
}
|
||||
|
||||
sprintf_s(buf, buf_size, "%s<block name=\"%s\" totalTimeMS=\"%f\" startTime=\"%" PRIu64 "\" stopTime=\"%" PRIu64 "\" args=\"%s\"> \n",
|
||||
tabs.c_str(), label.c_str(), time, m_startTimeStamp.QuadPart, m_stopTimeStamp.QuadPart, m_args.c_str());
|
||||
AZ::IO::Print(fileHandle, buf);
|
||||
}
|
||||
|
||||
const size_t childsSize = m_Childs.size();
|
||||
for (size_t i = 0; i < childsSize; ++i)
|
||||
{
|
||||
CBootProfilerRecord* record = m_Childs[i];
|
||||
assert(record);
|
||||
record->Print(fileHandle, buf, buf_size, depth, stopTime, threadName, timeThreshold);
|
||||
}
|
||||
|
||||
sprintf_s(buf, buf_size, "%s</block>\n", tabs.c_str());
|
||||
AZ::IO::Print(fileHandle, buf);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CProfileInfo
|
||||
{
|
||||
friend class CBootProfilerSession;
|
||||
private:
|
||||
CBootProfilerRecord* m_pRoot;
|
||||
CBootProfilerRecord* m_pCurrent;
|
||||
public:
|
||||
CProfileInfo()
|
||||
: m_pRoot(NULL)
|
||||
, m_pCurrent(NULL) {}
|
||||
};
|
||||
|
||||
|
||||
class CBootProfilerThreadsInterface
|
||||
{
|
||||
protected:
|
||||
CBootProfilerThreadsInterface()
|
||||
{
|
||||
memset(m_threadInfo, 0, sizeof(m_threadInfo));
|
||||
m_threadCounter = 0;
|
||||
}
|
||||
|
||||
unsigned int GetThreadIndexByID(unsigned int threadID);
|
||||
const char* GetThreadNameByIndex(unsigned int threadIndex);
|
||||
|
||||
int m_threadCounter;
|
||||
private:
|
||||
unsigned int m_threadInfo[eMAX_THREADS_TO_PROFILE]; //threadIDs
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
ILINE unsigned int CBootProfilerThreadsInterface::GetThreadIndexByID(unsigned int threadID)
|
||||
{
|
||||
for (int i = 0; i < eMAX_THREADS_TO_PROFILE; ++i)
|
||||
{
|
||||
if (m_threadInfo[i] == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (m_threadInfo[i] == threadID)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int counter = CryInterlockedIncrement(&m_threadCounter) - 1; //count to index
|
||||
m_threadInfo[counter] = threadID;
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
ILINE const char* CBootProfilerThreadsInterface::GetThreadNameByIndex(unsigned int threadIndex)
|
||||
{
|
||||
assert(threadIndex < m_threadCounter);
|
||||
|
||||
const char* threadName = CryThreadGetName(m_threadInfo[threadIndex]);
|
||||
return threadName;
|
||||
}
|
||||
|
||||
class CRecordPool
|
||||
{
|
||||
public:
|
||||
CRecordPool()
|
||||
: m_baseAddr(NULL)
|
||||
, m_allocCounter(0)
|
||||
, m_next(NULL)
|
||||
{
|
||||
m_baseAddr = (CBootProfilerRecord*)CryModuleMemalign(eNUM_RECORDS_PER_POOL * sizeof(CBootProfilerRecord), 16);
|
||||
}
|
||||
~CRecordPool()
|
||||
{
|
||||
CryModuleMemalignFree(m_baseAddr);
|
||||
delete m_next;
|
||||
}
|
||||
|
||||
ILINE CBootProfilerRecord* allocateRecord()
|
||||
{
|
||||
if (m_allocCounter < eNUM_RECORDS_PER_POOL)
|
||||
{
|
||||
CBootProfilerRecord* newRecord = m_baseAddr + m_allocCounter;
|
||||
++m_allocCounter;
|
||||
return newRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ILINE void setNextPool(CRecordPool* pool) { m_next = pool; }
|
||||
|
||||
private:
|
||||
CBootProfilerRecord* m_baseAddr;
|
||||
uint32 m_allocCounter;
|
||||
|
||||
CRecordPool* m_next;
|
||||
};
|
||||
|
||||
class CBootProfilerSession
|
||||
: public CBootProfilerThreadsInterface
|
||||
, protected CProfileBlockTimes
|
||||
{
|
||||
public:
|
||||
CBootProfilerSession();
|
||||
~CBootProfilerSession();
|
||||
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
CBootProfilerRecord* StartBlock(const char* name, const char* args);
|
||||
void StopBlock(CBootProfilerRecord* record);
|
||||
|
||||
void CollectResults(const char* filename, const float timeThreshold);
|
||||
|
||||
private:
|
||||
string m_name;
|
||||
|
||||
CProfileInfo m_threadsProfileInfo[eMAX_THREADS_TO_PROFILE];
|
||||
CRecordPool* m_threadsRecordsPool[eMAX_THREADS_TO_PROFILE]; //head
|
||||
CRecordPool* m_threadsCurrentPools[eMAX_THREADS_TO_PROFILE]; //current
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBootProfilerSession::CBootProfilerSession()
|
||||
{
|
||||
memset(m_threadsProfileInfo, 0, sizeof(m_threadsProfileInfo));
|
||||
|
||||
memset(m_threadsRecordsPool, 0, sizeof(m_threadsRecordsPool));
|
||||
memset(m_threadsCurrentPools, 0, sizeof(m_threadsCurrentPools));
|
||||
}
|
||||
|
||||
CBootProfilerSession::~CBootProfilerSession()
|
||||
{
|
||||
for (unsigned int i = 0; i < m_threadCounter; ++i)
|
||||
{
|
||||
CProfileInfo& profile = m_threadsProfileInfo[i];
|
||||
|
||||
// Since m_pRoot is allocated using memory pool (line 296),
|
||||
// its destructor is called explicitly to free the memory of
|
||||
// m_Childs and each of its child.
|
||||
|
||||
if (profile.m_pRoot)
|
||||
{
|
||||
profile.m_pRoot->~CBootProfilerRecord();
|
||||
}
|
||||
delete m_threadsRecordsPool[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CBootProfilerSession::Start()
|
||||
{
|
||||
LARGE_INTEGER time, freq;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&time);
|
||||
m_startTimeStamp = time;
|
||||
m_freq = freq;
|
||||
}
|
||||
|
||||
void CBootProfilerSession::Stop()
|
||||
{
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
m_stopTimeStamp = time;
|
||||
}
|
||||
|
||||
CBootProfilerRecord* CBootProfilerSession::StartBlock(const char* name, const char* args)
|
||||
{
|
||||
const unsigned int curThread = CryGetCurrentThreadId();
|
||||
const unsigned int threadIndex = GetThreadIndexByID(curThread);
|
||||
|
||||
assert(threadIndex < eMAX_THREADS_TO_PROFILE);
|
||||
|
||||
CProfileInfo& profile = m_threadsProfileInfo[threadIndex];
|
||||
|
||||
CRecordPool* pool = m_threadsCurrentPools[threadIndex];
|
||||
|
||||
if (!profile.m_pRoot)
|
||||
{
|
||||
if (!pool)
|
||||
{
|
||||
pool = new CRecordPool;
|
||||
m_threadsRecordsPool[threadIndex] = pool;
|
||||
m_threadsCurrentPools[threadIndex] = pool;
|
||||
}
|
||||
|
||||
CBootProfilerRecord* rec = pool->allocateRecord();
|
||||
profile.m_pRoot = profile.m_pCurrent = new(rec)CBootProfilerRecord("root", m_startTimeStamp, m_freq, args);
|
||||
}
|
||||
|
||||
assert(pool);
|
||||
|
||||
LARGE_INTEGER time, freq;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
QueryPerformanceCounter(&time);
|
||||
|
||||
CBootProfilerRecord* pParent = profile.m_pCurrent;
|
||||
assert(pParent);
|
||||
assert(profile.m_pRoot);
|
||||
|
||||
CBootProfilerRecord* rec = pool->allocateRecord();
|
||||
if (!rec)
|
||||
{
|
||||
//pool is full, create a new one
|
||||
pool = new CRecordPool;
|
||||
m_threadsCurrentPools[threadIndex]->setNextPool(pool);
|
||||
m_threadsCurrentPools[threadIndex] = pool;
|
||||
|
||||
rec = pool->allocateRecord();
|
||||
}
|
||||
|
||||
profile.m_pCurrent = new(rec)CBootProfilerRecord(name, time, freq, args);
|
||||
profile.m_pCurrent->m_pParent = pParent;
|
||||
pParent->m_Childs.push_back(profile.m_pCurrent);
|
||||
|
||||
return profile.m_pCurrent;
|
||||
}
|
||||
|
||||
void CBootProfilerSession::StopBlock(CBootProfilerRecord* record)
|
||||
{
|
||||
if (record)
|
||||
{
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
record->m_stopTimeStamp = time;
|
||||
|
||||
unsigned int curThread = CryGetCurrentThreadId();
|
||||
unsigned int threadIndex = GetThreadIndexByID(curThread);
|
||||
assert(threadIndex < eMAX_THREADS_TO_PROFILE);
|
||||
|
||||
CProfileInfo& profile = m_threadsProfileInfo[threadIndex];
|
||||
profile.m_pCurrent = record->m_pParent;
|
||||
}
|
||||
}
|
||||
|
||||
void CBootProfilerSession::CollectResults(const char* filename, const float timeThreshold)
|
||||
{
|
||||
if (!gEnv || !gEnv->pCryPak)
|
||||
{
|
||||
AZ_Warning("BootProfiler", false, "CryPak not set - skipping CollectResults");
|
||||
return;
|
||||
}
|
||||
static const char* szTestResults = "@cache@\\TestResults";
|
||||
string filePath = string(szTestResults) + "\\" + "bp_" + filename + ".xml";
|
||||
char path[AZ::IO::IArchive::MaxPath] = "";
|
||||
gEnv->pCryPak->AdjustFileName(filePath.c_str(), path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
|
||||
gEnv->pCryPak->MakeDir(szTestResults);
|
||||
|
||||
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
|
||||
gEnv->pFileIO->Open(path, AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeBinary, fileHandle);
|
||||
if (fileHandle == AZ::IO::InvalidHandle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[512];
|
||||
const unsigned int buf_size = sizeof(buf);
|
||||
|
||||
sprintf_s(buf, buf_size, "<root>\n");
|
||||
AZ::IO::Print(fileHandle, buf);
|
||||
|
||||
const size_t numThreads = m_threadCounter;
|
||||
for (size_t i = 0; i < numThreads; ++i)
|
||||
{
|
||||
CBootProfilerRecord* pRoot = m_threadsProfileInfo[i].m_pRoot;
|
||||
if (pRoot)
|
||||
{
|
||||
pRoot->m_stopTimeStamp = m_stopTimeStamp;
|
||||
|
||||
const char* threadName = GetThreadNameByIndex(i);
|
||||
if (!threadName)
|
||||
{
|
||||
threadName = "UNKNOWN";
|
||||
}
|
||||
|
||||
|
||||
const float time = (float)(pRoot->m_stopTimeStamp.QuadPart - pRoot->m_startTimeStamp.QuadPart) * 1000.f / (float)pRoot->m_freq.QuadPart;
|
||||
|
||||
sprintf_s(buf, buf_size, "\t<thread name=\"%s\" totalTimeMS=\"%f\" startTime=\"%" PRIu64 "\" stopTime=\"%" PRIu64 "\" > \n", threadName, time,
|
||||
pRoot->m_startTimeStamp.QuadPart, pRoot->m_stopTimeStamp.QuadPart);
|
||||
AZ::IO::Print(fileHandle, buf);
|
||||
|
||||
for (size_t recordIdx = 0; recordIdx < pRoot->m_Childs.size(); ++recordIdx)
|
||||
{
|
||||
CBootProfilerRecord* record = pRoot->m_Childs[recordIdx];
|
||||
assert(record);
|
||||
record->Print(fileHandle, buf, buf_size, 2, m_stopTimeStamp, threadName, timeThreshold);
|
||||
}
|
||||
|
||||
sprintf_s(buf, buf_size, "\t</thread>\n");
|
||||
AZ::IO::Print(fileHandle, buf);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf_s(buf, buf_size, "</root>\n");
|
||||
AZ::IO::Print(fileHandle, buf);
|
||||
gEnv->pFileIO->Close(fileHandle);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CBootProfiler& CBootProfiler::GetInstance()
|
||||
{
|
||||
return gProfilerInstance;
|
||||
}
|
||||
|
||||
CBootProfiler::CBootProfiler()
|
||||
: m_pCurrentSession(NULL)
|
||||
, m_pFrameRecord(NULL)
|
||||
, m_levelLoadAdditionalFrames(0)
|
||||
{
|
||||
}
|
||||
|
||||
CBootProfiler::~CBootProfiler()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
|
||||
for (TSessionMap::iterator it = m_sessions.begin(); it != m_sessions.end(); ++it)
|
||||
{
|
||||
CBootProfilerSession* session = it->second;
|
||||
delete session;
|
||||
}
|
||||
}
|
||||
|
||||
// start session
|
||||
void CBootProfiler::StartSession(const char* sessionName)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
|
||||
|
||||
TSessionMap::const_iterator it = m_sessions.find(sessionName);
|
||||
if (it == m_sessions.end())
|
||||
{
|
||||
m_pCurrentSession = new CBootProfilerSession();
|
||||
m_sessions[sessionName] = m_pCurrentSession;
|
||||
m_pCurrentSession->Start();
|
||||
}
|
||||
}
|
||||
|
||||
// stop session
|
||||
void CBootProfiler::StopSession(const char* sessionName)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
|
||||
if (m_pCurrentSession)
|
||||
{
|
||||
TSessionMap::iterator it = m_sessions.find(sessionName);
|
||||
if (it != m_sessions.end())
|
||||
{
|
||||
if (m_pCurrentSession == it->second)
|
||||
{
|
||||
CBootProfilerSession* session = m_pCurrentSession;
|
||||
m_pCurrentSession = NULL;
|
||||
|
||||
session->Stop();
|
||||
session->CollectResults(sessionName, CV_sys_bp_time_threshold);
|
||||
|
||||
delete session;
|
||||
}
|
||||
m_sessions.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CBootProfilerRecord* CBootProfiler::StartBlock(const char* name, const char* args)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
|
||||
if (m_pCurrentSession)
|
||||
{
|
||||
return m_pCurrentSession->StartBlock(name, args);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CBootProfiler::StopBlock(CBootProfilerRecord* record)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
|
||||
if (m_pCurrentSession)
|
||||
{
|
||||
m_pCurrentSession->StopBlock(record);
|
||||
}
|
||||
}
|
||||
|
||||
void CBootProfiler::StartFrame(const char* name)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
|
||||
if (CV_sys_bp_frames)
|
||||
{
|
||||
StartSession("frames");
|
||||
m_pFrameRecord = StartBlock(name, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void CBootProfiler::StopFrame()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> recordGuard{ m_recordMutex };
|
||||
if (m_pCurrentSession && CV_sys_bp_frames)
|
||||
{
|
||||
StopBlock(m_pFrameRecord);
|
||||
m_pFrameRecord = NULL;
|
||||
|
||||
--CV_sys_bp_frames;
|
||||
if (0 == CV_sys_bp_frames)
|
||||
{
|
||||
StopSession("frames");
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pCurrentSession && m_levelLoadAdditionalFrames)
|
||||
{
|
||||
--m_levelLoadAdditionalFrames;
|
||||
if (0 == m_levelLoadAdditionalFrames)
|
||||
{
|
||||
StopSession("level");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBootProfiler::Init(ISystem* pSystem)
|
||||
{
|
||||
//REGISTER_CVAR(sys_BootProfiler, 1, VF_DEV_ONLY,
|
||||
// "Collect and output session statistics into TestResults/bp_(session_name).xml \n"
|
||||
// "0 = Disabled\n"
|
||||
// "1 = Enabled\n");
|
||||
|
||||
pSystem->GetISystemEventDispatcher()->RegisterListener(this);
|
||||
StartSession("boot");
|
||||
}
|
||||
|
||||
void CBootProfiler::RegisterCVars()
|
||||
{
|
||||
REGISTER_CVAR2("sys_bp_frames", &CV_sys_bp_frames, 0, VF_DEV_ONLY, "Starts frame profiling for specified number of frames using BootProfiler");
|
||||
REGISTER_CVAR2("sys_bp_time_threshold", &CV_sys_bp_time_threshold, 0.1f, VF_DEV_ONLY, "If greater than 0 don't write blocks that took less time (default 0.1 ms)");
|
||||
}
|
||||
|
||||
void CBootProfiler::OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case ESYSTEM_EVENT_GAME_POST_INIT_DONE:
|
||||
{
|
||||
StopSession("boot");
|
||||
break;
|
||||
}
|
||||
case ESYSTEM_EVENT_GAME_MODE_SWITCH_START:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case ESYSTEM_EVENT_GAME_MODE_SWITCH_END:
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case ESYSTEM_EVENT_LEVEL_LOAD_START:
|
||||
{
|
||||
break;
|
||||
}
|
||||
case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE:
|
||||
{
|
||||
StartSession("level");
|
||||
break;
|
||||
}
|
||||
case ESYSTEM_EVENT_LEVEL_LOAD_END:
|
||||
{
|
||||
StopSession("level");
|
||||
break;
|
||||
}
|
||||
case ESYSTEM_EVENT_LEVEL_PRECACHE_END:
|
||||
{
|
||||
//level loading can be stopped here, or m_levelLoadAdditionalFrames can be used to prolong dump for this amount of frames
|
||||
//StopSession("level");
|
||||
m_levelLoadAdditionalFrames = 20;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBootProfiler::SetFrameCount(int frameCount)
|
||||
{
|
||||
CV_sys_bp_frames = frameCount;
|
||||
}
|
||||
#endif
|
||||
@@ -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_CRYSYSTEM_BOOTPROFILER_H
|
||||
#define CRYINCLUDE_CRYSYSTEM_BOOTPROFILER_H
|
||||
#pragma once
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/parallel/mutex.h>
|
||||
|
||||
class CBootProfilerRecord;
|
||||
class CBootProfilerSession;
|
||||
|
||||
class CBootProfiler
|
||||
: public ISystemEventListener
|
||||
{
|
||||
friend class CBootProfileBLock;
|
||||
public:
|
||||
CBootProfiler();
|
||||
~CBootProfiler();
|
||||
|
||||
static CBootProfiler& GetInstance();
|
||||
|
||||
void Init(ISystem* pSystem);
|
||||
void RegisterCVars();
|
||||
|
||||
void StartSession(const char* sessionName);
|
||||
void StopSession(const char* sessionName);
|
||||
|
||||
CBootProfilerRecord* StartBlock(const char* name, const char* args);
|
||||
void StopBlock(CBootProfilerRecord* record);
|
||||
|
||||
void StartFrame(const char* name);
|
||||
void StopFrame();
|
||||
protected:
|
||||
// === ISystemEventListener
|
||||
virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam);
|
||||
void SetFrameCount(int frameCount);
|
||||
|
||||
private:
|
||||
CBootProfilerSession* m_pCurrentSession;
|
||||
typedef AZStd::unordered_map<AZStd::string, CBootProfilerSession*> TSessionMap;
|
||||
TSessionMap m_sessions;
|
||||
|
||||
static int CV_sys_bp_frames;
|
||||
static float CV_sys_bp_time_threshold;
|
||||
CBootProfilerRecord* m_pFrameRecord;
|
||||
AZStd::recursive_mutex m_recordMutex;
|
||||
int m_levelLoadAdditionalFrames;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // CRYINCLUDE_CRYSYSTEM_BOOTPROFILER_H
|
||||
@@ -277,17 +277,6 @@ int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer)
|
||||
sprintf_s(excCode, "0x%08X", exception_pointer->ExceptionRecord->ExceptionCode);
|
||||
WriteLineToLog("Exception: %s, at Address: %s", excCode, excAddr);
|
||||
|
||||
if (CSystem* pSystem = (CSystem*)GetSystem())
|
||||
{
|
||||
if (const char* pLoadingProfilerCallstack = pSystem->GetLoadingProfilerCallstack())
|
||||
{
|
||||
if (pLoadingProfilerCallstack[0])
|
||||
{
|
||||
WriteLineToLog("<CrySystem> LoadingProfilerCallstack: %s", pLoadingProfilerCallstack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
IMemoryManager::SProcessMemInfo memInfo;
|
||||
if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo))
|
||||
@@ -593,7 +582,7 @@ void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
|
||||
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
|
||||
for (unsigned int i2 = 0; i2 < numFrames; ++i2)
|
||||
{
|
||||
fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]);
|
||||
fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include "System.h"
|
||||
#include <AzFramework/IO/FileOperations.h>
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
//#if !defined(LINUX)
|
||||
|
||||
#include <ISystem.h>
|
||||
@@ -186,21 +186,17 @@ AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
|
||||
}
|
||||
}
|
||||
|
||||
if (gEnv->pConsole)
|
||||
{
|
||||
if (ICVar* pCVarGameDir = gEnv->pConsole->GetCVar("sys_game_folder"))
|
||||
{
|
||||
sprintf(s, "GameDir: %s\n", pCVarGameDir->GetString());
|
||||
azstrcat(str, length, s);
|
||||
}
|
||||
}
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
azstrcat(str, length, "ProjectDir: ");
|
||||
azstrcat(str, length, projectPath.c_str());
|
||||
azstrcat(str, length, "\n");
|
||||
|
||||
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_APPEND_MODULENAME
|
||||
GetModuleFileNameA(NULL, s, sizeof(s));
|
||||
|
||||
// Log EXE filename only if possible (not full EXE path which could contain sensitive info)
|
||||
AZStd::string exeName;
|
||||
if (AzFramework::StringFunc::Path::GetFullFileName(s, exeName))
|
||||
if (AZ::StringFunc::Path::GetFullFileName(s, exeName))
|
||||
{
|
||||
azstrcat(str, length, "Executable: ");
|
||||
azstrcat(str, length, exeName.c_str());
|
||||
|
||||
@@ -1,647 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS 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(ENABLE_LOADING_PROFILER)
|
||||
|
||||
#include "System.h"
|
||||
#include "LoadingProfiler.h"
|
||||
|
||||
#define LOADING_TIME_CONTAINER_MAX_TEXT_SIZE 1024
|
||||
#define MAX_LOADING_TIME_PROFILER_STACK_DEPTH 16
|
||||
|
||||
//#define SAVE_SAVELEVELSTATS_IN_ROOT
|
||||
|
||||
struct SLoadingTimeContainer
|
||||
: public _i_reference_target_t
|
||||
{
|
||||
SLoadingTimeContainer() {}
|
||||
|
||||
SLoadingTimeContainer(SLoadingTimeContainer* pParent, const char* pPureFuncName, const int nRootIndex)
|
||||
{
|
||||
m_dSelfMemUsage = m_dTotalMemUsage = m_dSelfTime = m_dTotalTime = 0;
|
||||
m_nCounter = 1;
|
||||
m_pFuncName = pPureFuncName;
|
||||
m_pParent = pParent;
|
||||
m_nRootIndex = nRootIndex;
|
||||
}
|
||||
|
||||
static int Cmp_SLoadingTimeContainer_Time(const void* v1, const void* v2)
|
||||
{
|
||||
SLoadingTimeContainer* pChunk1 = (SLoadingTimeContainer*)v1;
|
||||
SLoadingTimeContainer* pChunk2 = (SLoadingTimeContainer*)v2;
|
||||
|
||||
if (pChunk1->m_dSelfTime > pChunk2->m_dSelfTime)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (pChunk1->m_dSelfTime < pChunk2->m_dSelfTime)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Cmp_SLoadingTimeContainer_MemUsage(const void* v1, const void* v2)
|
||||
{
|
||||
SLoadingTimeContainer* pChunk1 = (SLoadingTimeContainer*)v1;
|
||||
SLoadingTimeContainer* pChunk2 = (SLoadingTimeContainer*)v2;
|
||||
|
||||
if (pChunk1->m_dSelfMemUsage > pChunk2->m_dSelfMemUsage)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (pChunk1->m_dSelfMemUsage < pChunk2->m_dSelfMemUsage)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double GetUsedMemory(ISystem* pSysytem)
|
||||
{
|
||||
static IMemoryManager::SProcessMemInfo processMemInfo;
|
||||
pSysytem->GetIMemoryManager()->GetProcessMemInfo(processMemInfo);
|
||||
return double(processMemInfo.PagefileUsage) / double(1024 * 1024);
|
||||
}
|
||||
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for (size_t i = 0, end = m_pChilds.size(); i < end; ++i)
|
||||
{
|
||||
delete m_pChilds[i];
|
||||
}
|
||||
}
|
||||
|
||||
~SLoadingTimeContainer()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
|
||||
double m_dSelfTime, m_dTotalTime;
|
||||
double m_dSelfMemUsage, m_dTotalMemUsage;
|
||||
uint32 m_nCounter;
|
||||
|
||||
const char* m_pFuncName;
|
||||
SLoadingTimeContainer* m_pParent;
|
||||
int m_nRootIndex;
|
||||
std::vector<SLoadingTimeContainer*> m_pChilds;
|
||||
|
||||
DiskOperationInfo m_selfInfo;
|
||||
DiskOperationInfo m_totalInfo;
|
||||
bool m_bUsed;
|
||||
};
|
||||
|
||||
bool operator== (const SLoadingTimeContainer& a, const SLoadingTimeContainer& b)
|
||||
{
|
||||
return b.m_pFuncName == a.m_pFuncName;
|
||||
}
|
||||
|
||||
bool operator== (const SLoadingTimeContainer& a, const char* b)
|
||||
{
|
||||
return b == a.m_pFuncName;
|
||||
}
|
||||
|
||||
|
||||
SLoadingTimeContainer* CLoadingProfilerSystem::m_pCurrentLoadingTimeContainer = 0;
|
||||
SLoadingTimeContainer* CLoadingProfilerSystem::m_pRoot[2] = {0, 0};
|
||||
int CLoadingProfilerSystem::m_iActiveRoot = 0;
|
||||
ICVar* CLoadingProfilerSystem::m_pEnableProfile = 0;
|
||||
int CLoadingProfilerSystem::nLoadingProfileMode = 1;
|
||||
int CLoadingProfilerSystem::nLoadingProfilerNotTrackedAllocations = -1;
|
||||
CryCriticalSection CLoadingProfilerSystem::csLock;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLoadingProfilerSystem::OutputLoadingTimeStats(ILog* pLog, int nMode)
|
||||
{
|
||||
nLoadingProfileMode = nMode;
|
||||
|
||||
PodArray<SLoadingTimeContainer> arrNoStack;
|
||||
CreateNoStackList(arrNoStack);
|
||||
|
||||
|
||||
if (nLoadingProfileMode > 0)
|
||||
{ // loading mem stats per func
|
||||
pLog->Log("------ Level loading memory allocations (MB) by function ------------");
|
||||
pLog->Log(" ||Self | Total | Calls | Function (%d MB lost)||", nLoadingProfilerNotTrackedAllocations);
|
||||
pLog->Log("---------------------------------------------------------------------");
|
||||
|
||||
qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_MemUsage);
|
||||
|
||||
for (int i = 0; i < arrNoStack.Count(); i++)
|
||||
{
|
||||
const SLoadingTimeContainer* pTimeContainer = &arrNoStack[i];
|
||||
pLog->Log("|%6.1f | %6.1f | %6d | %s|",
|
||||
pTimeContainer->m_dSelfMemUsage, pTimeContainer->m_dTotalMemUsage, (int)pTimeContainer->m_nCounter, pTimeContainer->m_pFuncName);
|
||||
}
|
||||
|
||||
pLog->Log("---------------------------------------------------------------------");
|
||||
}
|
||||
|
||||
if (nLoadingProfileMode > 0)
|
||||
{ // loading time stats per func
|
||||
pLog->Log("----------- Level loading time (sec) by function --------------------");
|
||||
pLog->Log(" ||Self | Total | Calls | Function||");
|
||||
pLog->Log("---------------------------------------------------------------------");
|
||||
|
||||
qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_Time);
|
||||
|
||||
for (int i = 0; i < arrNoStack.Count(); i++)
|
||||
{
|
||||
const SLoadingTimeContainer* pTimeContainer = &arrNoStack[i];
|
||||
pLog->Log("|%6.1f | %6.1f | %6d | %s|",
|
||||
pTimeContainer->m_dSelfTime, pTimeContainer->m_dTotalTime, (int)pTimeContainer->m_nCounter, pTimeContainer->m_pFuncName);
|
||||
}
|
||||
|
||||
if (nLoadingProfileMode == 1)
|
||||
{
|
||||
pLog->Log("----- ( Use sys_ProfileLevelLoading 2 for more detailed stats ) -----");
|
||||
}
|
||||
else
|
||||
{
|
||||
pLog->Log("---------------------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
if (nLoadingProfileMode > 0)
|
||||
{ // file info
|
||||
pLog->Log("----------------------------- Level file information by function --------------------------------");
|
||||
pLog->Log("|| Self | Total |Bandwith| Calls | Function||");
|
||||
pLog->Log("|| Seeks |FileOpen|FileRead| Seeks |FileOpen|FileRead| Kb/s | | ||");
|
||||
|
||||
qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_Time);
|
||||
|
||||
for (int i = 0; i < arrNoStack.Count(); i++)
|
||||
{
|
||||
const SLoadingTimeContainer* pTimeContainer = &arrNoStack[i];
|
||||
double bandwidth = pTimeContainer->m_dSelfTime > 0 ? (pTimeContainer->m_selfInfo.m_dOperationSize / pTimeContainer->m_dSelfTime / 1024.0) : 0.;
|
||||
pLog->Log("|%6d | %6d | %6d |%6d | %6d | %6d | %6.1f | %6d | %s|",
|
||||
pTimeContainer->m_selfInfo.m_nSeeksCount, pTimeContainer->m_selfInfo.m_nFileOpenCount, pTimeContainer->m_selfInfo.m_nFileReadCount,
|
||||
pTimeContainer->m_totalInfo.m_nSeeksCount, pTimeContainer->m_totalInfo.m_nFileOpenCount, pTimeContainer->m_totalInfo.m_nFileReadCount,
|
||||
bandwidth, (int)pTimeContainer->m_nCounter, pTimeContainer->m_pFuncName);
|
||||
}
|
||||
|
||||
if (nLoadingProfileMode == 1)
|
||||
{
|
||||
pLog->Log("----- ( Use sys_ProfileLevelLoading 2 for more detailed stats ) -----");
|
||||
}
|
||||
else
|
||||
{
|
||||
pLog->Log("---------------------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CSystemEventListner_LoadingProfiler
|
||||
: public ISystemEventListener
|
||||
{
|
||||
private:
|
||||
CLoadingTimeProfiler* m_pPrecacheProfiler;
|
||||
ESystemEvent lastEvent;
|
||||
public:
|
||||
CSystemEventListner_LoadingProfiler()
|
||||
: m_pPrecacheProfiler(NULL) {}
|
||||
|
||||
virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case ESYSTEM_EVENT_GAME_MODE_SWITCH_START:
|
||||
{
|
||||
CLoadingProfilerSystem::Clean();
|
||||
if (m_pPrecacheProfiler == NULL)
|
||||
{
|
||||
m_pPrecacheProfiler = new CLoadingTimeProfiler(gEnv->pSystem, "ModeSwitch");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ESYSTEM_EVENT_GAME_MODE_SWITCH_END:
|
||||
{
|
||||
SAFE_DELETE(m_pPrecacheProfiler);
|
||||
CLoadingProfilerSystem::SaveTimeContainersToFile(gEnv->bMultiplayer == true ? "mode_switch_mp.lmbrlp" : "mode_switch_sp.lmbrlp", 0.0, true);
|
||||
}
|
||||
|
||||
case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE:
|
||||
{
|
||||
CLoadingProfilerSystem::Clean();
|
||||
if (m_pPrecacheProfiler == NULL)
|
||||
{
|
||||
m_pPrecacheProfiler = new CLoadingTimeProfiler(gEnv->pSystem, "LevelLoading");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ESYSTEM_EVENT_LEVEL_LOAD_END:
|
||||
{
|
||||
delete m_pPrecacheProfiler;
|
||||
m_pPrecacheProfiler = new CLoadingTimeProfiler(gEnv->pSystem, "Precache");
|
||||
break;
|
||||
}
|
||||
case ESYSTEM_EVENT_LEVEL_PRECACHE_END:
|
||||
{
|
||||
if (lastEvent == ESYSTEM_EVENT_LEVEL_PRECACHE_FIRST_FRAME)
|
||||
{
|
||||
SAFE_DELETE(m_pPrecacheProfiler);
|
||||
string levelName = "no_level";
|
||||
ICVar* sv_map = gEnv->pConsole->GetCVar("sv_map");
|
||||
if (sv_map)
|
||||
{
|
||||
levelName = sv_map->GetString();
|
||||
}
|
||||
|
||||
string levelNameFullProfile = levelName + "_LP.lmbrlp";
|
||||
string levelNameThreshold = levelName + "_LP_OneSec.lmbrlp";
|
||||
CLoadingProfilerSystem::SaveTimeContainersToFile(levelNameFullProfile.c_str(), 0.0, false);
|
||||
CLoadingProfilerSystem::SaveTimeContainersToFile(levelNameThreshold.c_str(), 1.0, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESYSTEM_EVENT_LEVEL_POST_UNLOAD:
|
||||
{
|
||||
// Ensure that the precache profiler is dead
|
||||
SAFE_DELETE(m_pPrecacheProfiler);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (event != ESYSTEM_EVENT_RANDOM_SEED)
|
||||
{
|
||||
lastEvent = event;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static CSystemEventListner_LoadingProfiler g_system_event_listener_loadingProfiler;
|
||||
|
||||
void CLoadingProfilerSystem::Init()
|
||||
{
|
||||
gEnv->pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_loadingProfiler);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CLoadingProfilerSystem::ShutDown()
|
||||
{
|
||||
if (gEnv && gEnv->pSystem && gEnv->pSystem->GetISystemEventDispatcher())
|
||||
{
|
||||
gEnv->pSystem->GetISystemEventDispatcher()->RemoveListener(&g_system_event_listener_loadingProfiler);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
SLoadingTimeContainer* CLoadingProfilerSystem::StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName)
|
||||
{
|
||||
if (!nLoadingProfileMode || !gEnv->pConsole)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD threadID = GetCurrentThreadId();
|
||||
|
||||
static DWORD dwMainThreadId = GetCurrentThreadId();
|
||||
if (threadID != dwMainThreadId)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!m_pEnableProfile)
|
||||
{
|
||||
if (gEnv->pConsole)
|
||||
{
|
||||
m_pEnableProfile = gEnv->pConsole->GetCVar("sys_ProfileLevelLoading");
|
||||
if (!m_pEnableProfile)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pEnableProfile->GetIVal() <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//if (m_pCurrentLoadingTimeContainer == m_pRoot && strstr(szFuncName,"Open"))
|
||||
//{
|
||||
// pProfiler->m_constructorInfo.m_nFileOpenCount +=1;
|
||||
//}
|
||||
|
||||
CryAutoCriticalSection lock(csLock);
|
||||
|
||||
if (true /*pProfiler && pProfiler->m_pSystem*/)
|
||||
{
|
||||
ITimer* pTimer = pProfiler->m_pSystem->GetITimer();
|
||||
pProfiler->m_fConstructorTime = pTimer->GetAsyncTime().GetSeconds();
|
||||
pProfiler->m_fConstructorMemUsage = SLoadingTimeContainer::GetUsedMemory(pProfiler->m_pSystem);
|
||||
|
||||
DiskOperationInfo info;
|
||||
pProfiler->m_constructorInfo = info;
|
||||
|
||||
if (nLoadingProfilerNotTrackedAllocations < 0)
|
||||
{
|
||||
nLoadingProfilerNotTrackedAllocations = (int)pProfiler->m_fConstructorMemUsage;
|
||||
}
|
||||
}
|
||||
|
||||
SLoadingTimeContainer* pParent = m_pCurrentLoadingTimeContainer;
|
||||
if (!pParent)
|
||||
{
|
||||
pParent = m_pCurrentLoadingTimeContainer = m_pRoot[m_iActiveRoot] = new SLoadingTimeContainer(0, "Root", m_iActiveRoot);
|
||||
}
|
||||
|
||||
for (size_t i = 0, end = m_pCurrentLoadingTimeContainer->m_pChilds.size(); i < end; ++i)
|
||||
{
|
||||
if (m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_pFuncName == szFuncName)
|
||||
{
|
||||
assert(m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_pParent == m_pCurrentLoadingTimeContainer);
|
||||
assert(!m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_bUsed);
|
||||
m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_bUsed = true;
|
||||
m_pCurrentLoadingTimeContainer->m_pChilds[i]->m_nCounter++;
|
||||
m_pCurrentLoadingTimeContainer = m_pCurrentLoadingTimeContainer->m_pChilds[i];
|
||||
return m_pCurrentLoadingTimeContainer;
|
||||
}
|
||||
}
|
||||
|
||||
m_pCurrentLoadingTimeContainer = new SLoadingTimeContainer(pParent, szFuncName, pParent->m_nRootIndex);
|
||||
m_pCurrentLoadingTimeContainer->m_bUsed = true;
|
||||
{
|
||||
// Need to iterate from the end than
|
||||
pParent->m_pChilds.push_back(m_pCurrentLoadingTimeContainer);
|
||||
}
|
||||
|
||||
return m_pCurrentLoadingTimeContainer;
|
||||
}
|
||||
|
||||
void CLoadingProfilerSystem::EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler)
|
||||
{
|
||||
if (!nLoadingProfileMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static DWORD dwMainThreadId = GetCurrentThreadId();
|
||||
|
||||
if (GetCurrentThreadId() != dwMainThreadId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pProfiler->m_pTimeContainer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CryAutoCriticalSection lock(csLock);
|
||||
|
||||
if (true /*pProfiler && pProfiler->m_pSystem*/)
|
||||
{
|
||||
ITimer* pTimer = pProfiler->m_pSystem->GetITimer();
|
||||
double fSelfTime = pTimer->GetAsyncTime().GetSeconds() - pProfiler->m_fConstructorTime;
|
||||
double fMemUsage = SLoadingTimeContainer::GetUsedMemory(pProfiler->m_pSystem);
|
||||
double fSelfMemUsage = fMemUsage - pProfiler->m_fConstructorMemUsage;
|
||||
|
||||
|
||||
if (fSelfTime < 0.0)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
pProfiler->m_pTimeContainer->m_dSelfTime += fSelfTime;
|
||||
pProfiler->m_pTimeContainer->m_dTotalTime += fSelfTime;
|
||||
pProfiler->m_pTimeContainer->m_dSelfMemUsage += fSelfMemUsage;
|
||||
pProfiler->m_pTimeContainer->m_dTotalMemUsage += fSelfMemUsage;
|
||||
|
||||
DiskOperationInfo info;
|
||||
info -= pProfiler->m_constructorInfo;
|
||||
pProfiler->m_pTimeContainer->m_totalInfo += info;
|
||||
pProfiler->m_pTimeContainer->m_selfInfo += info;
|
||||
pProfiler->m_pTimeContainer->m_bUsed = false;
|
||||
|
||||
SLoadingTimeContainer* pParent = pProfiler->m_pTimeContainer->m_pParent;
|
||||
pParent->m_selfInfo -= info;
|
||||
pParent->m_dSelfTime -= fSelfTime;
|
||||
pParent->m_dSelfMemUsage -= fSelfMemUsage;
|
||||
if (pProfiler->m_pTimeContainer->m_pParent && pProfiler->m_pTimeContainer->m_pParent->m_nRootIndex == m_iActiveRoot)
|
||||
{
|
||||
m_pCurrentLoadingTimeContainer = pProfiler->m_pTimeContainer->m_pParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* CLoadingProfilerSystem::GetLoadingProfilerCallstack()
|
||||
{
|
||||
CryAutoCriticalSection lock(csLock);
|
||||
|
||||
static char szStack[1024];
|
||||
|
||||
szStack[0] = 0;
|
||||
|
||||
SLoadingTimeContainer* pC = m_pCurrentLoadingTimeContainer;
|
||||
|
||||
PodArray<SLoadingTimeContainer*> arrItems;
|
||||
|
||||
while (pC)
|
||||
{
|
||||
arrItems.Add(pC);
|
||||
pC = pC->m_pParent;
|
||||
}
|
||||
|
||||
for (int i = arrItems.Count() - 1; i >= 0; i--)
|
||||
{
|
||||
cry_strcat(szStack, " > ");
|
||||
cry_strcat(szStack, arrItems[i]->m_pFuncName);
|
||||
}
|
||||
|
||||
return &szStack[0];
|
||||
}
|
||||
|
||||
void CLoadingProfilerSystem::FillProfilersList(AZStd::vector<SLoadingProfilerInfo>& profilers)
|
||||
{
|
||||
UpdateSelfStatistics(m_pRoot[m_iActiveRoot]);
|
||||
|
||||
PodArray<SLoadingTimeContainer> arrNoStack;
|
||||
CreateNoStackList(arrNoStack);
|
||||
//qsort(arrNoStack.GetElements(), arrNoStack.Count(), sizeof(arrNoStack[0]), SLoadingTimeContainer::Cmp_SLoadingTimeContainer_Time);
|
||||
|
||||
uint32 count = arrNoStack.Size();
|
||||
profilers.resize(count);
|
||||
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
profilers[i].name = arrNoStack[i].m_pFuncName;
|
||||
profilers[i].selfTime = arrNoStack[i].m_dSelfTime;
|
||||
profilers[i].callsTotal = arrNoStack[i].m_nCounter;
|
||||
profilers[i].totalTime = arrNoStack[i].m_dTotalTime;
|
||||
profilers[i].memorySize = arrNoStack[i].m_dTotalMemUsage;
|
||||
profilers[i].selfInfo = arrNoStack[i].m_selfInfo;
|
||||
profilers[i].totalInfo = arrNoStack[i].m_totalInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CLoadingProfilerSystem::AddTimeContainerFunction(PodArray<SLoadingTimeContainer>& arrNoStack, SLoadingTimeContainer* node)
|
||||
{
|
||||
if (!node)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SLoadingTimeContainer* it = std::find(arrNoStack.begin(), arrNoStack.end(), node->m_pFuncName);
|
||||
|
||||
if (it == arrNoStack.end())
|
||||
{
|
||||
arrNoStack.push_back(*node);
|
||||
}
|
||||
else
|
||||
{
|
||||
it->m_dSelfMemUsage += node->m_dSelfMemUsage;
|
||||
it->m_dSelfTime += node->m_dSelfTime;
|
||||
it->m_dTotalMemUsage += node->m_dTotalMemUsage;
|
||||
it->m_dTotalTime += node->m_dTotalTime;
|
||||
it->m_nCounter += node->m_nCounter;
|
||||
it->m_selfInfo += node->m_selfInfo;
|
||||
it->m_totalInfo += node->m_totalInfo;
|
||||
}
|
||||
|
||||
for (size_t i = 0, end = node->m_pChilds.size(); i < end; ++i)
|
||||
{
|
||||
AddTimeContainerFunction(arrNoStack, node->m_pChilds[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void CLoadingProfilerSystem::CreateNoStackList(PodArray<SLoadingTimeContainer>& arrNoStack)
|
||||
{
|
||||
AddTimeContainerFunction(arrNoStack, m_pRoot[m_iActiveRoot]);
|
||||
}
|
||||
|
||||
#define g_szTestResults "@cache@\\TestResults"
|
||||
|
||||
void CLoadingProfilerSystem::SaveTimeContainersToFile(const char* name, double fMinTotalTime, bool bClean)
|
||||
{
|
||||
if (m_pRoot[m_iActiveRoot])
|
||||
{
|
||||
const char* levelName = name;
|
||||
//Ignore any folders in the input name
|
||||
const char* folder = strrchr(name, '/');
|
||||
if (folder != NULL)
|
||||
{
|
||||
levelName = folder + 1;
|
||||
}
|
||||
char path[AZ::IO::IArchive::MaxPath];
|
||||
path[sizeof(path) - 1] = 0;
|
||||
|
||||
gEnv->pCryPak->AdjustFileName(string(string(g_szTestResults) + "\\" + levelName).c_str(), path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
|
||||
gEnv->pCryPak->MakeDir(g_szTestResults);
|
||||
|
||||
AZ::IO::HandleType handle = AZ::IO::InvalidHandle;
|
||||
|
||||
AZ::IO::Result f = AZ::IO::FileIOBase::GetInstance()->Open(path,AZ::IO::OpenMode::ModeWrite, handle);
|
||||
|
||||
if (handle != AZ::IO::InvalidHandle)
|
||||
{
|
||||
UpdateSelfStatistics(m_pRoot[m_iActiveRoot]);
|
||||
WriteTimeContainerToFile(m_pRoot[m_iActiveRoot], handle, 0, fMinTotalTime);
|
||||
AZ::IO::FileIOBase::GetInstance()->Close(handle);
|
||||
}
|
||||
|
||||
if (bClean)
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLoadingProfilerSystem::WriteTimeContainerToFile(SLoadingTimeContainer* p, AZ::IO::HandleType &handle, unsigned int depth, double fMinTotalTime)
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->m_dTotalTime < fMinTotalTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CryFixedStringT<MAX_LOADING_TIME_PROFILER_STACK_DEPTH> sDepth;
|
||||
for (unsigned int i = 0; i < depth; i++)
|
||||
{
|
||||
sDepth += "\t";
|
||||
}
|
||||
|
||||
CryFixedStringT<128> str(p->m_pFuncName);
|
||||
str.replace(':', '_');
|
||||
|
||||
char data[4096];
|
||||
AZ::u64 bytesWritten;
|
||||
|
||||
azsnprintf(data, sizeof(data), "%s<%s selfTime='%f' selfMemory='%f' totalTime='%f' totalMemory='%f' count='%i' totalSeeks='%i' totalReads='%i' totalOpens='%i' totalDiskSize='%f' selfSeeks='%i' selfReads='%i' selfOpens='%i' selfDiskSize='%f'>\n",
|
||||
sDepth.c_str(), str.c_str(), p->m_dSelfTime, p->m_dSelfMemUsage, p->m_dTotalTime, p->m_dTotalMemUsage, p->m_nCounter,
|
||||
p->m_totalInfo.m_nSeeksCount, p->m_totalInfo.m_nFileReadCount, p->m_totalInfo.m_nFileOpenCount, p->m_totalInfo.m_dOperationSize,
|
||||
p->m_selfInfo.m_nSeeksCount, p->m_selfInfo.m_nFileReadCount, p->m_selfInfo.m_nFileOpenCount, p->m_selfInfo.m_dOperationSize);
|
||||
|
||||
AZ::IO::FileIOBase::GetInstance()->Write(handle, data, strlen(data), &bytesWritten);
|
||||
|
||||
for (size_t i = 0, end = p->m_pChilds.size(); i < end; ++i)
|
||||
{
|
||||
WriteTimeContainerToFile(p->m_pChilds[i], handle, depth + 1, fMinTotalTime);
|
||||
}
|
||||
|
||||
azsnprintf(data, sizeof(data), "%s</%s>\n", sDepth.c_str(), str.c_str());
|
||||
AZ::IO::FileIOBase::GetInstance()->Write(handle, data, strlen(data), &bytesWritten);
|
||||
|
||||
}
|
||||
|
||||
void CLoadingProfilerSystem::UpdateSelfStatistics(SLoadingTimeContainer* p)
|
||||
{
|
||||
if (p == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
p->m_dSelfMemUsage = 0;
|
||||
p->m_dSelfTime = 0;
|
||||
p->m_nCounter = 1;
|
||||
p->m_selfInfo.m_dOperationSize = 0;
|
||||
p->m_selfInfo.m_nFileOpenCount = 0;
|
||||
p->m_selfInfo.m_nFileReadCount = 0;
|
||||
p->m_selfInfo.m_nSeeksCount = 0;
|
||||
|
||||
for (size_t i = 0, end = p->m_pChilds.size(); i < end; ++i)
|
||||
{
|
||||
p->m_dTotalMemUsage += p->m_pChilds[i]->m_dTotalMemUsage;
|
||||
p->m_dTotalTime += p->m_pChilds[i]->m_dTotalTime;
|
||||
p->m_totalInfo += p->m_pChilds[i]->m_totalInfo;
|
||||
}
|
||||
}
|
||||
|
||||
void CLoadingProfilerSystem::Clean()
|
||||
{
|
||||
m_iActiveRoot = (m_iActiveRoot + 1) % 2;
|
||||
if (m_pRoot[m_iActiveRoot])
|
||||
{
|
||||
delete m_pRoot[m_iActiveRoot];
|
||||
}
|
||||
m_pCurrentLoadingTimeContainer = m_pRoot[m_iActiveRoot] = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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_CRYSYSTEM_LOADINGPROFILER_H
|
||||
#define CRYINCLUDE_CRYSYSTEM_LOADINGPROFILER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
|
||||
struct SLoadingTimeContainer;
|
||||
|
||||
|
||||
struct SLoadingProfilerInfo
|
||||
{
|
||||
string name;
|
||||
double selfTime;
|
||||
double totalTime;
|
||||
uint32 callsTotal;
|
||||
double memorySize;
|
||||
|
||||
DiskOperationInfo selfInfo;
|
||||
DiskOperationInfo totalInfo;
|
||||
};
|
||||
|
||||
|
||||
class CLoadingProfilerSystem
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void ShutDown();
|
||||
static void CreateNoStackList(PodArray<SLoadingTimeContainer>&);
|
||||
static void OutputLoadingTimeStats(ILog* pLog, int nMode);
|
||||
static SLoadingTimeContainer* StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName);
|
||||
static void EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler);
|
||||
static const char* GetLoadingProfilerCallstack();
|
||||
static void FillProfilersList(AZStd::vector<SLoadingProfilerInfo>& profilers);
|
||||
static void FlushTimeContainers();
|
||||
static void SaveTimeContainersToFile(const char*, double fMinTotalTime, bool bClean);
|
||||
static void WriteTimeContainerToFile(SLoadingTimeContainer* p, AZ::IO::HandleType &handle, unsigned int depth, double fMinTotalTime);
|
||||
|
||||
static void UpdateSelfStatistics(SLoadingTimeContainer* p);
|
||||
static void Clean();
|
||||
protected:
|
||||
static void AddTimeContainerFunction(PodArray<SLoadingTimeContainer>&, SLoadingTimeContainer*);
|
||||
protected:
|
||||
static int nLoadingProfileMode;
|
||||
static int nLoadingProfilerNotTrackedAllocations;
|
||||
static CryCriticalSection csLock;
|
||||
static int m_iMaxArraySize;
|
||||
static SLoadingTimeContainer* m_pCurrentLoadingTimeContainer;
|
||||
static SLoadingTimeContainer* m_pRoot[2];
|
||||
static int m_iActiveRoot;
|
||||
static ICVar* m_pEnableProfile;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // CRYINCLUDE_CRYSYSTEM_LOADINGPROFILER_H
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <ISystem.h>
|
||||
|
||||
#include <AzCore/Socket/AzSocket.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#undef LockDebug
|
||||
//#define LockDebug(str1,str2) {string strMessage;strMessage.Format(str1,str2);if (m_clients.size()) OutputDebugString(strMessage.c_str());}
|
||||
@@ -46,16 +47,13 @@ public:
|
||||
|
||||
const char* path = nullptr; // Don't call GetGameFolder here, it returns a full absolute path and we just really want the game name
|
||||
|
||||
if (ICVar* pVar = gEnv->pConsole->GetCVar("sys_game_folder"))
|
||||
{
|
||||
path = pVar->GetString();
|
||||
}
|
||||
if (!path)
|
||||
AZ::IO::FixedMaxPathString projectPath = AZ::Utils::GetProjectPath();
|
||||
if (projectPath.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pNotificationNetwork->Send("SystemInfo", path, ::strlen(path) + 1);
|
||||
pNotificationNetwork->Send("SystemInfo", projectPath.c_str(), projectPath.size());
|
||||
}
|
||||
} g_queryNotification;
|
||||
|
||||
|
||||
@@ -1243,7 +1243,7 @@ namespace
|
||||
{
|
||||
char path[AZ::IO::IArchive::MaxPath];
|
||||
path[sizeof(path) - 1] = 0;
|
||||
gEnv->pCryPak->AdjustFileName("@cache@\\TestResults\\StreamingLog.txt", path, AZ_ARRAY_SIZE(path), AZ::IO::IArchive::FLAGS_PATH_REAL | AZ::IO::IArchive::FLAGS_FOR_WRITING);
|
||||
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");
|
||||
|
||||
@@ -157,7 +157,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
#include "ServerThrottle.h"
|
||||
#include "ILocalMemoryUsage.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "LoadingProfiler.h"
|
||||
#include "HMDBus.h"
|
||||
#include "OverloadSceneManager/OverloadSceneManager.h"
|
||||
#include <IThreadManager.h>
|
||||
@@ -168,7 +167,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
#include "IZStdDecompressor.h"
|
||||
#include "zlib.h"
|
||||
#include "RemoteConsole/RemoteConsole.h"
|
||||
#include "BootProfiler.h"
|
||||
|
||||
#include <PNoise3.h>
|
||||
#include <StringUtils.h>
|
||||
@@ -320,10 +318,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
|
||||
m_bIsAsserting = false;
|
||||
m_pSystemEventDispatcher = new CSystemEventDispatcher(); // Must be first.
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CBootProfiler::GetInstance().Init(this);
|
||||
#endif
|
||||
|
||||
if (m_pSystemEventDispatcher)
|
||||
{
|
||||
m_pSystemEventDispatcher->RegisterListener(this);
|
||||
@@ -422,7 +416,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
|
||||
// m_sys_filecache = NULL;
|
||||
m_gpu_particle_physics = NULL;
|
||||
m_pCpu = NULL;
|
||||
m_sys_game_folder = NULL;
|
||||
|
||||
m_bInitializedSuccessfully = false;
|
||||
m_bShaderCacheGenMode = false;
|
||||
@@ -634,10 +627,6 @@ void CSystem::ShutDown()
|
||||
EBUS_EVENT(CrySystemEventBus, OnCrySystemShutdown, *this);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CLoadingProfilerSystem::ShutDown();
|
||||
#endif
|
||||
|
||||
if (m_pUserCallback)
|
||||
{
|
||||
m_pUserCallback->OnShutdown();
|
||||
@@ -657,7 +646,7 @@ void CSystem::ShutDown()
|
||||
SAFE_DELETE(m_pTextModeConsole);
|
||||
|
||||
KillPhysicsThread();
|
||||
|
||||
|
||||
if (m_sys_firstlaunch)
|
||||
{
|
||||
m_sys_firstlaunch->Set("0");
|
||||
@@ -828,7 +817,7 @@ void CSystem::ShutDown()
|
||||
void CSystem::Quit()
|
||||
{
|
||||
CryLogAlways("CSystem::Quit invoked from thread %" PRI_THREADID " (main is %" PRI_THREADID ")", GetCurrentThreadId(), gEnv->mMainThreadId);
|
||||
|
||||
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::ExitMainLoop);
|
||||
|
||||
// If this was set from anywhere but the main thread, bail and let the main thread handle shutdown
|
||||
@@ -857,13 +846,13 @@ void CSystem::Quit()
|
||||
|
||||
/*
|
||||
* TODO: This call to _exit, _Exit, TerminateProcess etc. needs to
|
||||
* eventually be removed. This causes an extremely early exit before we
|
||||
* actually perform cleanup. When this gets called most managers are
|
||||
* eventually be removed. This causes an extremely early exit before we
|
||||
* actually perform cleanup. When this gets called most managers are
|
||||
* simply never deleted and we leave it to the OS to clean up our mess
|
||||
* which is just really bad practice. However there are LOTS of issues
|
||||
* with shutdown at the moment. Removing this will simply cause
|
||||
* a crash when either the Editor or Launcher initiate shutdown. Both
|
||||
* applications crash differently too. Bugs will be logged about those
|
||||
* with shutdown at the moment. Removing this will simply cause
|
||||
* a crash when either the Editor or Launcher initiate shutdown. Both
|
||||
* applications crash differently too. Bugs will be logged about those
|
||||
* issues.
|
||||
*/
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
@@ -1117,7 +1106,7 @@ void CSystem::CreatePhysicsThread()
|
||||
#include AZ_RESTRICTED_FILE(System_cpp)
|
||||
#endif
|
||||
|
||||
{
|
||||
{
|
||||
m_PhysThread = new CPhysicsThreadTask;
|
||||
GetIThreadTaskManager()->RegisterTask(m_PhysThread, threadParams);
|
||||
}
|
||||
@@ -1412,7 +1401,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
|
||||
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)
|
||||
@@ -1428,7 +1417,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
|
||||
switch (stat.GetType())
|
||||
{
|
||||
case AZ::IO::Statistic::Type::FloatingPoint:
|
||||
gEnv->pRenderer->DrawTextQueued(Vec3(10, y, 1.0f), ti,
|
||||
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:
|
||||
@@ -2744,10 +2733,10 @@ bool CSystem::HandleMessage([[maybe_unused]] HWND hWnd, UINT uMsg, WPARAM wParam
|
||||
{
|
||||
// System event translation
|
||||
case WM_CLOSE:
|
||||
/*
|
||||
/*
|
||||
Trigger CSystem to call Quit() the next time
|
||||
it calls Update(). HandleMessages can get messages
|
||||
pumped to it from SyncMainWithRender which would
|
||||
pumped to it from SyncMainWithRender which would
|
||||
be called recurively by Quit(). Doing so would
|
||||
cause the render thread to deadlock and the main
|
||||
thread to spin in SRenderThread::WaitFlushFinishedCond.
|
||||
@@ -2897,11 +2886,6 @@ std::shared_ptr<AZ::IO::FileIOBase> CSystem::CreateLocalFileIO()
|
||||
return std::make_shared<AZ::IO::LocalFileIO>();
|
||||
}
|
||||
|
||||
const char* CSystem::GetAssetsPlatform() const
|
||||
{
|
||||
return m_assetPlatform.c_str();
|
||||
}
|
||||
|
||||
IViewSystem* CSystem::GetIViewSystem()
|
||||
{
|
||||
return m_pViewSystem;
|
||||
|
||||
@@ -45,7 +45,6 @@ struct IConsoleCmdArgs;
|
||||
class CServerThrottle;
|
||||
struct ICryFactoryRegistryImpl;
|
||||
struct IZLibCompressor;
|
||||
class CLoadingProfilerSystem;
|
||||
class CWatchdogThread;
|
||||
class CThreadManager;
|
||||
|
||||
@@ -437,11 +436,6 @@ public:
|
||||
|
||||
uint32 GetUsedMemory();
|
||||
|
||||
//! For asset processor, we need to know what kind of assets we're loading. This comes all the way from bootstrap.cfg
|
||||
//! It will be a string like "pc" or "es3" or such and controls what kind of assets we have access to (its used when for example
|
||||
//! attempting to open a file when multiple different assets for different platforms are available.)
|
||||
const char* GetAssetsPlatform() const;
|
||||
|
||||
virtual void DumpMemoryUsageStatistics(bool bUseKB);
|
||||
virtual void DumpMemoryCoverage();
|
||||
void CollectMemInfo(SCryEngineStatsGlobalMemInfo&);
|
||||
@@ -685,7 +679,7 @@ private:
|
||||
bool InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInitParams& initParams);
|
||||
|
||||
bool InitFont(const SSystemInitParams& initParams);
|
||||
bool InitFileSystem(const SSystemInitParams& initParams);
|
||||
bool InitFileSystem();
|
||||
bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams);
|
||||
bool InitStreamEngine();
|
||||
bool Init3DEngine(const SSystemInitParams& initParams);
|
||||
@@ -792,7 +786,7 @@ public:
|
||||
|
||||
const CTimeValue& GetLastTickTime(void) const { return m_lastTickTime; }
|
||||
const ICVar* GetDedicatedMaxRate(void) const { return m_svDedicatedMaxRate; }
|
||||
|
||||
|
||||
const char* GetRenderingDriverName(void) const
|
||||
{
|
||||
if(m_rDriver)
|
||||
@@ -802,7 +796,7 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<AZ::IO::FileIOBase> CreateLocalFileIO();
|
||||
|
||||
// Gets the dimensions (in pixels) of the primary physical display.
|
||||
@@ -914,7 +908,6 @@ private: // ------------------------------------------------------
|
||||
|
||||
// DLL names
|
||||
ICVar* m_sys_dll_response_system;
|
||||
ICVar* m_sys_game_folder;
|
||||
#if !defined(_RELEASE)
|
||||
ICVar* m_sys_resource_cache_folder;
|
||||
#endif
|
||||
@@ -950,7 +943,6 @@ private: // ------------------------------------------------------
|
||||
ICVar* m_rFullscreenWindow;
|
||||
ICVar* m_rFullscreenNativeRes;
|
||||
ICVar* m_rDriver;
|
||||
ICVar* m_cvGameName;
|
||||
ICVar* m_rDisplayInfo;
|
||||
ICVar* m_rOverscanBordersDrawDebugView;
|
||||
ICVar* m_sysNoUpdate;
|
||||
@@ -1040,8 +1032,6 @@ private: // ------------------------------------------------------
|
||||
|
||||
uint64 m_nUpdateCounter;
|
||||
|
||||
int sys_ProfileLevelLoading, sys_ProfileLevelLoadingDump;
|
||||
|
||||
bool m_executedCommandLine = false;
|
||||
|
||||
AZStd::unique_ptr<AzFramework::MissingAssetLogger> m_missingAssetLogger;
|
||||
@@ -1072,18 +1062,6 @@ public:
|
||||
void CloseLanguageAudioPak(const char* sLanguage);
|
||||
void UpdateMovieSystem(const int updateFlags, const float fFrameTime, const bool bPreUpdate);
|
||||
|
||||
// level loading profiling
|
||||
virtual void OutputLoadingTimeStats();
|
||||
virtual struct SLoadingTimeContainer* StartLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler, const char* szFuncName);
|
||||
virtual void EndLoadingSectionProfiling(CLoadingTimeProfiler* pProfiler);
|
||||
virtual const char* GetLoadingProfilerCallstack();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
virtual CBootProfilerRecord* StartBootSectionProfiler(const char* name, const char* args);
|
||||
virtual void StopBootSectionProfiler(CBootProfilerRecord* record);
|
||||
virtual void StartBootProfilerSessionFrames(const char* pName);
|
||||
virtual void StopBootProfilerSessionFrames();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CryAssert and error related.
|
||||
virtual bool RegisterErrorObserver(IErrorObserver* errorObserver);
|
||||
@@ -1139,17 +1117,9 @@ protected: // -------------------------------------------------------------
|
||||
ITextModeConsole* m_pTextModeConsole;
|
||||
INotificationNetwork* m_pNotificationNetwork;
|
||||
|
||||
string m_binariesDir;
|
||||
string m_currentLanguageAudio;
|
||||
string m_assetPlatform; // ("es3" / "pc" / etc) describes the KIND of assets we load and controls where they're loaded from
|
||||
string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_es3.cfg or system_android_opengl.cfg or system_windows_pc.cfg
|
||||
|
||||
// the following variables capture what was set up in the systeminitparams after/during InitFileSystem
|
||||
// They are not actually to be used except to establish aliases like @user@
|
||||
string m_userRootDir;
|
||||
string m_cacheDir;
|
||||
string m_logsDir;
|
||||
|
||||
std::vector< std::pair<CTimeValue, float> > m_updateTimes;
|
||||
|
||||
CMemoryFragmentationProfiler m_MemoryFragmentationProfiler;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include "SystemCFG.h"
|
||||
@@ -252,15 +253,8 @@ void CSystem::LogVersion()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CSystem::LogBuildInfo()
|
||||
{
|
||||
ICVar* pGameName = m_env.pConsole->GetCVar("sys_game_name");
|
||||
if (pGameName)
|
||||
{
|
||||
CryLogAlways("GameName: %s", pGameName->GetString());
|
||||
}
|
||||
else
|
||||
{
|
||||
CryLogAlways("Couldn't find game name in cvar sys_game_name");
|
||||
}
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
CryLogAlways("GameName: %s", projectName.c_str());
|
||||
CryLogAlways("BuildTime: " __DATE__ " " __TIME__);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include <LoadScreenBus.h>
|
||||
#include <LyShine/Bus/UiSystemBus.h>
|
||||
#include <AzFramework/Logging/MissingAssetLogger.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
#include <AzFramework/API/AtomActiveInterface.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
@@ -115,8 +116,6 @@
|
||||
#include "SystemCFG.h"
|
||||
#include "AutoDetectSpec.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "LoadingProfiler.h"
|
||||
#include "BootProfiler.h"
|
||||
#include "VisRegTest.h"
|
||||
#include "MTSafeAllocator.h"
|
||||
#include "NotificationNetwork.h"
|
||||
@@ -498,7 +497,7 @@ struct SysSpecOverrideSinkConsole
|
||||
else
|
||||
{
|
||||
// If the cvar doesn't exist, calling this function only saves the value in case it's registered later where
|
||||
// at that point it will be set from the stored value. This is required because otherwise registering the
|
||||
// at that point it will be set from the stored value. This is required because otherwise registering the
|
||||
// cvar bypasses any callbacks and uses values directly from the cvar group files.
|
||||
gEnv->pConsole->LoadConfigVar(szKey, szValue);
|
||||
}
|
||||
@@ -618,13 +617,13 @@ static void LoadDetectedSpec(ICVar* pVar)
|
||||
if (gEnv->IsEditor())
|
||||
{
|
||||
ESystemConfigPlatform configPlatform = GetISystem()->GetConfigPlatform();
|
||||
// Check if the config platform is set first.
|
||||
// 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())
|
||||
@@ -779,7 +778,7 @@ static void LoadDetectedSpec(ICVar* pVar)
|
||||
MobileSysInspect::GetSpecForGPUAndAPI(adapterDesc, apiver, gpuConfigFile);
|
||||
GetISystem()->LoadConfiguration(gpuConfigFile.c_str(), pSysSpecOverrideSinkConsole);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if (bMultiGPUEnabled)
|
||||
{
|
||||
@@ -832,23 +831,7 @@ AZStd::unique_ptr<AZ::DynamicModuleHandle> CSystem::LoadDynamiclibrary(const cha
|
||||
{
|
||||
AZStd::unique_ptr<AZ::DynamicModuleHandle> handle = AZ::DynamicModuleHandle::Create(dllName);
|
||||
|
||||
bool libraryLoaded = false;
|
||||
#ifdef WIN32
|
||||
if (m_binariesDir.empty())
|
||||
{
|
||||
libraryLoaded = handle->Load(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
char currentDirectory[1024];
|
||||
AZ::Utils::GetExecutableDirectory(currentDirectory, AZ_ARRAY_SIZE(currentDirectory));
|
||||
SetCurrentDirectory(m_binariesDir.c_str());
|
||||
libraryLoaded = handle->Load(false);
|
||||
SetCurrentDirectory(currentDirectory);
|
||||
}
|
||||
#else
|
||||
libraryLoaded = handle->Load(false);
|
||||
#endif
|
||||
bool libraryLoaded = handle->Load(false);
|
||||
// We need to inject the environment first thing so that allocators are available immediately
|
||||
InjectEnvironmentFunction injectEnv = handle->GetFunction<InjectEnvironmentFunction>(INJECT_ENVIRONMENT_FUNCTION);
|
||||
if (injectEnv)
|
||||
@@ -974,7 +957,7 @@ bool CSystem::InitializeEngineModule(const char* dllName, const char* moduleClas
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
#else
|
||||
|
||||
dllfile.append(dllName);
|
||||
|
||||
@@ -1007,7 +990,7 @@ bool CSystem::InitializeEngineModule(const char* dllName, const char* moduleClas
|
||||
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();
|
||||
@@ -1453,7 +1436,7 @@ bool CSystem::InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInit
|
||||
|
||||
displayWidth *= scaleFactor;
|
||||
displayHeight *= scaleFactor;
|
||||
|
||||
|
||||
const int maxWidth = m_rMaxWidth->GetIVal();
|
||||
if (maxWidth > 0 && maxWidth < displayWidth)
|
||||
{
|
||||
@@ -1524,7 +1507,7 @@ bool CSystem::InitRenderer(WIN_HINSTANCE hinst, WIN_HWND hwnd, const SSystemInit
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
bool CSystem::InitFileSystem(const SSystemInitParams& initParams)
|
||||
bool CSystem::InitFileSystem()
|
||||
{
|
||||
LOADING_TIME_PROFILE_SECTION;
|
||||
using namespace AzFramework::AssetSystem;
|
||||
@@ -1549,136 +1532,6 @@ bool CSystem::InitFileSystem(const SSystemInitParams& initParams)
|
||||
}
|
||||
#endif // !defined(_RELEASE)
|
||||
|
||||
bool usingAssetCache = initParams.UseAssetCache();
|
||||
const char* rootPath = usingAssetCache ? initParams.rootPathCache : initParams.rootPath;
|
||||
const char* assetsPath = usingAssetCache ? initParams.assetsPathCache : initParams.assetsPath;
|
||||
|
||||
if (rootPath == 0)
|
||||
{
|
||||
AZ_Assert(false, "No root path specified in SystemInitParams");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (assetsPath == 0)
|
||||
{
|
||||
AZ_Assert(false, "No assets path specified in SystemInitParams");
|
||||
return false;
|
||||
}
|
||||
|
||||
// establish the root folder and assets folder immediately.
|
||||
// Other folders that can be computed from the root can be specified later.
|
||||
m_env.pFileIO->SetAlias("@root@", rootPath);
|
||||
m_env.pFileIO->SetAlias("@assets@", assetsPath);
|
||||
|
||||
if (initParams.userPath[0] == 0)
|
||||
{
|
||||
string outPath = PathUtil::Make(m_env.pFileIO->GetAlias("@root@"), "user");
|
||||
|
||||
m_env.pFileIO->SetAlias("@user@", outPath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_env.pFileIO->SetAlias("@user@", initParams.userPath);
|
||||
}
|
||||
|
||||
if (initParams.logPath[0] == 0)
|
||||
{
|
||||
char resolveBuffer[AZ_MAX_PATH_LEN] = { 0 };
|
||||
|
||||
m_env.pFileIO->ResolvePath("@user@", resolveBuffer, AZ_MAX_PATH_LEN);
|
||||
string outPath = PathUtil::Make(resolveBuffer, "log");
|
||||
m_env.pFileIO->SetAlias("@log@", outPath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_env.pFileIO->SetAlias("@log@", initParams.logPath);
|
||||
}
|
||||
|
||||
m_env.pFileIO->CreatePath("@root@");
|
||||
m_env.pFileIO->CreatePath("@user@");
|
||||
m_env.pFileIO->CreatePath("@log@");
|
||||
|
||||
if ((!m_env.IsInToolMode()) || (m_bShaderCacheGenMode)) // in tool mode, the promise is that you won't access @cache@!
|
||||
{
|
||||
string finalCachePath;
|
||||
if (initParams.cachePath[0] == 0)
|
||||
{
|
||||
char resolveBuffer[AZ_MAX_PATH_LEN] = { 0 };
|
||||
|
||||
m_env.pFileIO->ResolvePath("@user@", resolveBuffer, AZ_MAX_PATH_LEN);
|
||||
finalCachePath = PathUtil::Make(resolveBuffer, "cache");
|
||||
}
|
||||
else
|
||||
{
|
||||
finalCachePath = initParams.cachePath;
|
||||
}
|
||||
|
||||
#if defined(AZ_PLATFORM_WINDOWS)
|
||||
// Search for a non-locked cache directory because shaders require separate caches for each running instance.
|
||||
// We only need to do this check for Windows, because consoles can't have multiple instances running simultaneously.
|
||||
// Ex: running editor and game, running multiple games, or multiple non-interactive editor instances
|
||||
// for parallel level exports.
|
||||
|
||||
string originalPath = finalCachePath;
|
||||
#if defined(REMOTE_ASSET_PROCESSOR)
|
||||
bool allowEngineConnection = !initParams.bToolMode && !initParams.bTestMode;
|
||||
bool allowRemoteIO = allowEngineConnection && initParams.remoteFileIO && !initParams.bEditor;
|
||||
|
||||
if (!allowRemoteIO) // not running on VFS
|
||||
#endif
|
||||
{
|
||||
int attemptNumber = 0;
|
||||
|
||||
// The number of max attempts ultimately dictates the number of Lumberyard instances that can run
|
||||
// simultaneously. This should be a reasonably high number so that it doesn't artificially limit
|
||||
// the number of instances (ex: parallel level exports via multiple Editor runs). It also shouldn't
|
||||
// be set *infinitely* high - each cache folder is GBs in size, and finding a free directory is a
|
||||
// linear search, so the more instances we allow, the longer the search will take.
|
||||
// 128 seems like a reasonable compromise.
|
||||
constexpr int maxAttempts = 128;
|
||||
|
||||
char workBuffer[AZ_MAX_PATH_LEN] = { 0 };
|
||||
while (attemptNumber < maxAttempts)
|
||||
{
|
||||
finalCachePath = originalPath;
|
||||
if (attemptNumber != 0)
|
||||
{
|
||||
azsnprintf(workBuffer, AZ_MAX_PATH_LEN, "%s%i", originalPath.c_str(), attemptNumber);
|
||||
finalCachePath = workBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
finalCachePath = originalPath;
|
||||
}
|
||||
|
||||
++attemptNumber; // do this here so we don't forget
|
||||
|
||||
m_env.pFileIO->CreatePath(finalCachePath.c_str());
|
||||
// if the directory already exists, check for locked file
|
||||
string outLockPath = PathUtil::Make(finalCachePath.c_str(), "lockfile.txt");
|
||||
|
||||
// note, the zero here after GENERIC_READ|GENERIC_WRITE indicates no share access at all
|
||||
g_cacheLock = CreateFileA(outLockPath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0);
|
||||
if (g_cacheLock != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (attemptNumber >= maxAttempts)
|
||||
{
|
||||
AZ_Assert(false, "Couldn't find a valid asset cache folder for the Asset Processor after %i attempts.", attemptNumber);
|
||||
AZ_Printf("FileSystem", "Couldn't find a valid asset cache folder for the Asset Processor after %i attempts.", attemptNumber);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(AZ_PLATFORM_WINDOWS)
|
||||
AZ_Printf("FileSystem", "Using %s folder for asset cache.\n", finalCachePath.c_str());
|
||||
m_env.pFileIO->SetAlias("@cache@", finalCachePath.c_str());
|
||||
m_env.pFileIO->CreatePath("@cache@");
|
||||
}
|
||||
|
||||
m_env.pCryPak = AZ::Interface<AZ::IO::IArchive>::Get();
|
||||
m_env.pFileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
AZ_Assert(m_env.pCryPak, "CryPak has not been initialized on AZ::Interface");
|
||||
@@ -1755,7 +1608,6 @@ void CSystem::ShutdownFileSystem()
|
||||
bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams)
|
||||
{
|
||||
LOADING_TIME_PROFILE_SECTION;
|
||||
// Load value of sys_game_folder from system.cfg into the sys_game_folder console variable
|
||||
{
|
||||
ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink();
|
||||
LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink);
|
||||
@@ -1767,17 +1619,19 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams& initPara
|
||||
#endif
|
||||
|
||||
GetISystem()->SetConfigPlatform(GetDevicePlatform());
|
||||
|
||||
|
||||
#if defined(CRY_ENABLE_RC_HELPER)
|
||||
if (!m_env.pResourceCompilerHelper)
|
||||
{
|
||||
m_env.pResourceCompilerHelper = new CResourceCompilerHelper();
|
||||
}
|
||||
#endif
|
||||
// you may not set these in game.cfg or in system.cfg
|
||||
m_sys_game_folder->ForceSet(initParams.gameFolderName);
|
||||
|
||||
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "GameDir: %s\n", m_sys_game_folder->GetString());
|
||||
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))
|
||||
@@ -1857,7 +1711,7 @@ bool CSystem::InitFont(const SSystemInitParams& initParams)
|
||||
bool CSystem::Init3DEngine(const SSystemInitParams& initParams)
|
||||
{
|
||||
LOADING_TIME_PROFILE_SECTION(GetISystem());
|
||||
|
||||
|
||||
if (!InitializeEngineModule(DLL_3DENGINE, "EngineModule_Cry3DEngine", initParams))
|
||||
{
|
||||
return false;
|
||||
@@ -1930,7 +1784,7 @@ bool CSystem::InitVTuneProfiler()
|
||||
LOADING_TIME_PROFILE_SECTION(GetISystem());
|
||||
|
||||
#ifdef PROFILE_WITH_VTUNE
|
||||
|
||||
|
||||
WIN_HMODULE hModule = LoadDLL("VTuneApi.dll");
|
||||
if (!hModule)
|
||||
{
|
||||
@@ -2033,7 +1887,7 @@ void CSystem::OpenBasicPaks()
|
||||
bBasicPaksLoaded = true;
|
||||
|
||||
LOADING_TIME_PROFILE_SECTION;
|
||||
|
||||
|
||||
// open pak files
|
||||
constexpr AZStd::string_view paksFolder = "@assets@/*.pak"; // (@assets@ assumed)
|
||||
m_env.pCryPak->OpenPacks(paksFolder);
|
||||
@@ -2188,12 +2042,6 @@ string GetUniqueLogFileName(string logFileName)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OnLevelLoadingDump([[maybe_unused]] ICVar* pArgs)
|
||||
{
|
||||
gEnv->pSystem->OutputLoadingTimeStats();
|
||||
}
|
||||
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
static wstring GetErrorStringUnsupportedCPU()
|
||||
{
|
||||
@@ -2415,8 +2263,8 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
|
||||
signal(SIGILL, CryEngineSignalHandler);
|
||||
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
|
||||
|
||||
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
|
||||
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is
|
||||
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
|
||||
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is
|
||||
// initialized to this instance's SSystemGlobalEnvironment (m_env), we will force set it again here
|
||||
// to m_env
|
||||
if (!gEnv)
|
||||
@@ -2451,7 +2299,7 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
|
||||
// Linux is all console for now and so no room for dialog boxes!
|
||||
m_env.bNoAssertDialog = true;
|
||||
#endif
|
||||
|
||||
|
||||
m_pCmdLine = new CCmdLine(startupParams.szSystemCmdLine);
|
||||
|
||||
AZCoreLogSink::Connect();
|
||||
@@ -2461,25 +2309,25 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
|
||||
{
|
||||
azConsole->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead());
|
||||
}
|
||||
|
||||
m_assetPlatform = startupParams.assetsPlatform;
|
||||
|
||||
// compute system config name
|
||||
if (m_assetPlatform.empty())
|
||||
|
||||
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry)
|
||||
{
|
||||
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, R"(A valid asset platform is missing in "%s/assets" key in the SettingsRegistry.)""\n"
|
||||
R"(This can be set via the via the --regset "%s/assets=<value>" command line option)"
|
||||
R"(, by setting value at the "%s/assets path" within a *.setreg file that is loaded by the application)"
|
||||
R"( or by setting the "assets" field in the bootstrap.cfg.)",
|
||||
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
|
||||
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
|
||||
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
|
||||
return false;
|
||||
}
|
||||
AZ::SettingsRegistryInterface::FixedValueString assetPlatform;
|
||||
if (!AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, assetPlatform,
|
||||
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "assets"))
|
||||
{
|
||||
assetPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
|
||||
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, R"(A valid asset platform is missing in "%s/assets" key in the SettingsRegistry.)""\n"
|
||||
R"(This typically done by setting he "assets" field in the bootstrap.cfg for within a .setreg file)""\n"
|
||||
R"(A fallback of %s will be used.)",
|
||||
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
|
||||
assetPlatform.c_str());
|
||||
}
|
||||
|
||||
m_systemConfigName = "system_" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_";
|
||||
m_systemConfigName += m_assetPlatform;
|
||||
m_systemConfigName += ".cfg";
|
||||
m_systemConfigName = "system_" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_";
|
||||
m_systemConfigName += assetPlatform.c_str();
|
||||
m_systemConfigName += ".cfg";
|
||||
}
|
||||
|
||||
AZ_Assert(CryMemory::IsHeapValid(), "Memory heap must be valid before continuing SystemInit.");
|
||||
|
||||
@@ -2518,11 +2366,6 @@ AZ_POP_DISABLE_WARNING
|
||||
m_hInst = (WIN_HINSTANCE)startupParams.hInstance;
|
||||
m_hWnd = (WIN_HWND)startupParams.hWnd;
|
||||
|
||||
m_userRootDir = startupParams.userPath;
|
||||
m_logsDir = startupParams.logPath;
|
||||
m_cacheDir = startupParams.cachePath;
|
||||
|
||||
m_binariesDir = startupParams.szBinariesDir;
|
||||
m_bEditor = startupParams.bEditor;
|
||||
m_bPreviewMode = startupParams.bPreview;
|
||||
m_bTestMode = startupParams.bTestMode;
|
||||
@@ -2666,17 +2509,13 @@ AZ_POP_DISABLE_WARNING
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// File system, must be very early
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
if (!InitFileSystem(startupParams))
|
||||
if (!InitFileSystem())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
InlineInitializationProcessing("CSystem::Init InitFileSystem");
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CLoadingProfilerSystem::Init();
|
||||
#endif
|
||||
|
||||
m_missingAssetLogger = AZStd::make_unique<AzFramework::MissingAssetLogger>();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -2786,10 +2625,6 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
GetIRemoteConsole()->RegisterConsoleVariables();
|
||||
|
||||
#ifdef ENABLE_LOADING_PROFILER
|
||||
CBootProfiler::GetInstance().RegisterCVars();
|
||||
#endif
|
||||
|
||||
if (!startupParams.bSkipConsole)
|
||||
{
|
||||
// Register system console variables.
|
||||
@@ -2827,7 +2662,7 @@ AZ_POP_DISABLE_WARNING
|
||||
m_env.pCryPak->OpenPack("@assets@", "Engine.pak");
|
||||
#if defined(AZ_PLATFORM_ANDROID) || defined(AZ_PLATFORM_IOS)
|
||||
MobileSysInspect::LoadDeviceSpecMapping();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
InitFileSystem_LoadEngineFolders(startupParams);
|
||||
|
||||
@@ -3472,10 +3307,6 @@ AZ_POP_DISABLE_WARNING
|
||||
MarkThisThreadForDebugging("Main");
|
||||
}
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CLoadingProfilerSystem::SaveTimeContainersToFile("EngineStart.crylp", 0.0, true);
|
||||
#endif
|
||||
|
||||
InlineInitializationProcessing("CSystem::Init End");
|
||||
|
||||
#if defined(IS_PROSDK)
|
||||
@@ -4188,7 +4019,7 @@ static void ScreenshotCmd(IConsoleCmdArgs* pParams)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to maintain backwards compatibility with our CVar but not force our new code to
|
||||
// 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)
|
||||
{
|
||||
@@ -4424,7 +4255,6 @@ void CSystem::CreateSystemVars()
|
||||
// Register DLL names as cvars before we load them
|
||||
//
|
||||
EVarFlags dllFlags = (EVarFlags)0;
|
||||
m_sys_game_folder = REGISTER_STRING("sys_game_folder", "EmptyTemplate", VF_READONLY, "Specifies the game folder to read all data from. Can be fully pathed for external folders or relative path for folders inside the root.");
|
||||
m_sys_dll_response_system = REGISTER_STRING("sys_dll_response_system", 0, dllFlags, "Specifies the DLL to load for the dynamic response system");
|
||||
|
||||
m_sys_initpreloadpacks = REGISTER_STRING("sys_initpreloadpacks", "", 0, "Specifies the paks for an engine initialization");
|
||||
@@ -4447,8 +4277,6 @@ void CSystem::CreateSystemVars()
|
||||
m_level_load_screen_minimum_time = REGISTER_FLOAT("level_load_screen_minimum_time", 0.0f, 0, "Minimum amount of time to show the level load screen. Important to prevent short loads from flashing the load screen. 0 means there is no limit.");
|
||||
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
|
||||
|
||||
m_cvGameName = REGISTER_STRING("sys_game_name", "Lumberyard", VF_DUMPTODISK, "Specifies the name to be displayed in the Launcher window title bar");
|
||||
|
||||
REGISTER_INT("cvDoVerboseWindowTitle", 0, VF_NULL, "");
|
||||
|
||||
m_pCVarQuit = REGISTER_INT("ExitOnQuit", 1, VF_NULL, "");
|
||||
@@ -4495,7 +4323,7 @@ void CSystem::CreateSystemVars()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
attachVariable("sys_PakReadSlice", &g_cvars.archiveVars.nReadSlice, "If non-0, means number of kilobytes to use to read files in portions. Should only be used on Win9x kernels");
|
||||
|
||||
attachVariable("sys_PakInMemorySizeLimit", &g_cvars.archiveVars.nInMemoryPerPakSizeLimit, "Individual pak size limit for being loaded into memory (MB)");
|
||||
@@ -4818,15 +4646,6 @@ void CSystem::CreateSystemVars()
|
||||
"e.g. LoadConfig lowspec.cfg\n"
|
||||
"Usage: LoadConfig <filename>");
|
||||
|
||||
REGISTER_CVAR(sys_ProfileLevelLoading, 0, VF_CHEAT,
|
||||
"Output level loading stats into log\n"
|
||||
"0 = Off\n"
|
||||
"1 = Output basic info about loading time per function\n"
|
||||
"2 = Output full statistics including loading time and memory allocations with call stack info");
|
||||
|
||||
REGISTER_CVAR_CB(sys_ProfileLevelLoadingDump, 0, VF_CHEAT, "Output level loading dump stats into log\n", OnLevelLoadingDump);
|
||||
|
||||
|
||||
assert(m_env.pConsole);
|
||||
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F12", "Screenshot");
|
||||
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F11", "RecordClip");
|
||||
@@ -4871,7 +4690,7 @@ void CSystem::CreateSystemVars()
|
||||
|
||||
// adding CVAR to toggle assert verbosity level
|
||||
const int defaultAssertValue = 1;
|
||||
REGISTER_CVAR2_CB("sys_asserts", &g_cvars.sys_asserts, defaultAssertValue, VF_CHEAT,
|
||||
REGISTER_CVAR2_CB("sys_asserts", &g_cvars.sys_asserts, defaultAssertValue, VF_CHEAT,
|
||||
"0 = Suppress Asserts\n"
|
||||
"1 = Log Asserts\n"
|
||||
"2 = Show Assert Dialog\n"
|
||||
@@ -4957,78 +4776,6 @@ void CSystem::AddCVarGroupDirectory(const string& sPath)
|
||||
gEnv->pCryPak->FindClose(handle);
|
||||
}
|
||||
|
||||
void CSystem::OutputLoadingTimeStats()
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
if (GetIConsole())
|
||||
{
|
||||
if (ICVar* pVar = GetIConsole()->GetCVar("sys_ProfileLevelLoading"))
|
||||
{
|
||||
CLoadingProfilerSystem::OutputLoadingTimeStats(GetILog(), pVar->GetIVal());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SLoadingTimeContainer* CSystem::StartLoadingSectionProfiling([[maybe_unused]] CLoadingTimeProfiler* pProfiler, [[maybe_unused]] const char* szFuncName)
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
return CLoadingProfilerSystem::StartLoadingSectionProfiling(pProfiler, szFuncName);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSystem::EndLoadingSectionProfiling([[maybe_unused]] CLoadingTimeProfiler* pProfiler)
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CLoadingProfilerSystem::EndLoadingSectionProfiling(pProfiler);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* CSystem::GetLoadingProfilerCallstack()
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
return CLoadingProfilerSystem::GetLoadingProfilerCallstack();
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
CBootProfilerRecord* CSystem::StartBootSectionProfiler([[maybe_unused]] const char* name, [[maybe_unused]] const char* args)
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CBootProfiler& profiler = CBootProfiler::GetInstance();
|
||||
return profiler.StartBlock(name, args);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSystem::StopBootSectionProfiler([[maybe_unused]] CBootProfilerRecord* record)
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CBootProfiler& profiler = CBootProfiler::GetInstance();
|
||||
profiler.StopBlock(record);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSystem::StartBootProfilerSessionFrames([[maybe_unused]] const char* pName)
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CBootProfiler& profiler = CBootProfiler::GetInstance();
|
||||
profiler.StartFrame(pName);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSystem::StopBootProfilerSessionFrames()
|
||||
{
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
CBootProfiler& profiler = CBootProfiler::GetInstance();
|
||||
profiler.StopFrame();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CSystem::RegisterErrorObserver(IErrorObserver* errorObserver)
|
||||
{
|
||||
return stl::push_back_unique(m_errorObservers, errorObserver);
|
||||
|
||||
@@ -92,13 +92,6 @@ static AZStd::vector<AZStd::string> GetModuleNames()
|
||||
moduleNames.push_back("CryFont" MODULE_EXTENSION);
|
||||
moduleNames.push_back("CrySystem" MODULE_EXTENSION);
|
||||
|
||||
if (gEnv && gEnv->pConsole)
|
||||
{
|
||||
string gameModuleNameRaw = gEnv->pConsole->GetCVar("sys_dll_game")->GetString();
|
||||
gameModuleNameRaw.append(MODULE_EXTENSION);
|
||||
moduleNames.push_back(gameModuleNameRaw.c_str());
|
||||
}
|
||||
|
||||
#undef MODULE_EXTENSION
|
||||
|
||||
# if defined(LINUX)
|
||||
@@ -1076,14 +1069,6 @@ void CSystem::FatalError(const char* format, ...)
|
||||
CryLogAlways("<CrySystem> Last System Error: %s", szSysErrorMessage);
|
||||
}
|
||||
|
||||
if (const char* pLoadingProfilerCallstack = GetLoadingProfilerCallstack())
|
||||
{
|
||||
if (pLoadingProfilerCallstack[0])
|
||||
{
|
||||
CryLogAlways("<CrySystem> LoadingProfilerCallstack: %s", pLoadingProfilerCallstack);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetUserCallback())
|
||||
{
|
||||
GetUserCallback()->OnError(szBuffer);
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
*/
|
||||
#include "CrySystem_precompiled.h"
|
||||
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzCore/UnitTest/UnitTest.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Memory/AllocatorScope.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <BootProfiler.h>
|
||||
|
||||
#if defined(ENABLE_LOADING_PROFILER)
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
using BootProfilerTestAllocatorScope = AZ::AllocatorScope<AZ::LegacyAllocator, CryStringAllocator>;
|
||||
class BootProfilerTest :
|
||||
public ::testing::Test,
|
||||
BootProfilerTestAllocatorScope,
|
||||
UnitTest::TraceBusRedirector
|
||||
{
|
||||
public:
|
||||
BootProfilerTest()
|
||||
{
|
||||
BootProfilerTestAllocatorScope::ActivateAllocators();
|
||||
UnitTest::TraceBusRedirector::BusConnect();
|
||||
}
|
||||
|
||||
~BootProfilerTest()
|
||||
{
|
||||
UnitTest::TraceBusRedirector::BusDisconnect();
|
||||
BootProfilerTestAllocatorScope::DeactivateAllocators();
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TEST_F(BootProfilerTest, BootProfilerTest_StartStopBlocksInThreads_Success)
|
||||
{
|
||||
CBootProfiler testProfiler;
|
||||
const char scopeName[] = "TestScope";
|
||||
const char blockArg[] = "TestArg";
|
||||
const int numAttempts = 1000;
|
||||
const int numThreads = 10;
|
||||
|
||||
auto switchSessionFunc = [&]() {
|
||||
for (int sessionNum = 0; sessionNum < numAttempts; ++sessionNum)
|
||||
{
|
||||
auto sessionName = AZStd::string::format("TestSession%d", sessionNum);
|
||||
testProfiler.StartSession(sessionName.c_str());
|
||||
testProfiler.StopSession(sessionName.c_str());
|
||||
}
|
||||
};
|
||||
auto testProfileFunc = [&]() {
|
||||
for (int blockNum = 0; blockNum < numAttempts; ++blockNum)
|
||||
{
|
||||
auto someBlock = testProfiler.StartBlock(scopeName, blockArg);
|
||||
testProfiler.StopBlock(someBlock);
|
||||
}
|
||||
};
|
||||
AZStd::thread threadArray[numThreads];
|
||||
|
||||
AZStd::thread sessionThread = AZStd::thread(switchSessionFunc);
|
||||
for (int i = 0; i < numThreads; ++i)
|
||||
{
|
||||
threadArray[i] = AZStd::thread(testProfileFunc);
|
||||
}
|
||||
for (int i = 0; i < numThreads; ++i)
|
||||
{
|
||||
threadArray[i].join();
|
||||
}
|
||||
sessionThread.join();
|
||||
}
|
||||
|
||||
class FrameTestBootProfiler : public CBootProfiler
|
||||
{
|
||||
public:
|
||||
FrameTestBootProfiler(int frameCount) : CBootProfiler()
|
||||
{
|
||||
SetFrameCount(frameCount);
|
||||
}
|
||||
};
|
||||
TEST_F(BootProfilerTest, BootProfilerTest_FrameStartStop_Success)
|
||||
{
|
||||
const int numTestFrames = 10;
|
||||
FrameTestBootProfiler testProfiler(numTestFrames);
|
||||
|
||||
for (int i = 0; i < numTestFrames; ++i)
|
||||
{
|
||||
testProfiler.StartFrame("TestFrame");
|
||||
|
||||
testProfiler.StopFrame();
|
||||
}
|
||||
}
|
||||
} // namespace UnitTests
|
||||
|
||||
#endif
|
||||
@@ -75,15 +75,10 @@ TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestPrefixes)
|
||||
TEST(CrySystemMaterialUtilsTests, MaterialUtilsTestGameName)
|
||||
{
|
||||
char tempBuffer[AZ_MAX_PATH_LEN];
|
||||
|
||||
ICVar* pGameNameCVar = nullptr;
|
||||
if ((gEnv)&&(gEnv->pConsole))
|
||||
{
|
||||
pGameNameCVar = gEnv->pConsole->GetCVar("sys_game_folder");
|
||||
}
|
||||
|
||||
azsnprintf(tempBuffer, AZ_MAX_PATH_LEN, ".\\%s\\materials\\blahblah.mat.mat.abc.test", pGameNameCVar ? pGameNameCVar->GetString() : "SamplesProject");
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace CryPakUnitTests
|
||||
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
|
||||
ASSERT_NE(nullptr, fileIo);
|
||||
|
||||
constexpr const char* testPakPath = "@cache@/archivecontainerlevel.pak";
|
||||
constexpr const char* testPakPath = "@usercache@/archivecontainerlevel.pak";
|
||||
|
||||
char resolvedArchivePath[AZ_MAX_PATH_LEN] = { 0 };
|
||||
EXPECT_TRUE(fileIo->ResolvePath(testPakPath, resolvedArchivePath, AZ_MAX_PATH_LEN));
|
||||
@@ -116,7 +116,7 @@ namespace CryPakUnitTests
|
||||
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds{ 100 });
|
||||
|
||||
// helper paths and strings
|
||||
AZStd::string gameFolder = fileIo->GetAlias("@cache@");
|
||||
AZStd::string gameFolder = fileIo->GetAlias("@usercache@");
|
||||
|
||||
AZStd::string testFile = "unittest.bin";
|
||||
AZStd::string testFilePath = gameFolder + "\\" + testFile;
|
||||
|
||||
@@ -297,7 +297,7 @@ void CVisRegTest::CaptureSample(const SCmd& cmd)
|
||||
if (m_cmdFreq == 1) // Final sample
|
||||
{
|
||||
// Screenshot
|
||||
stack_string filename("@cache@/TestResults/VisReg/"); // the default unaliased assets folder is read-only!
|
||||
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);
|
||||
|
||||
@@ -335,7 +335,7 @@ void CVisRegTest::Finish()
|
||||
|
||||
bool CVisRegTest::WriteResults()
|
||||
{
|
||||
stack_string filename("@cache@/TestResults/VisReg/");
|
||||
stack_string filename("@usercache@/TestResults/VisReg/");
|
||||
filename += m_testName + "/visreg_results.xml";
|
||||
|
||||
AZ::IO::HandleType fileHandle = fxopen(filename.c_str(), "wb");
|
||||
|
||||
@@ -26,7 +26,6 @@ set(FILES
|
||||
IDebugCallStack.cpp
|
||||
AsyncPakManager.cpp
|
||||
Log.cpp
|
||||
BootProfiler.cpp
|
||||
SystemRender.cpp
|
||||
NotificationNetwork.cpp
|
||||
PhysRenderer.cpp
|
||||
@@ -91,7 +90,6 @@ set(FILES
|
||||
WindowsConsole.h
|
||||
XConsole.h
|
||||
XConsoleVariable.h
|
||||
BootProfiler.h
|
||||
crash_face.bmp
|
||||
ImageHandler.h
|
||||
ImageHandler.cpp
|
||||
@@ -121,11 +119,9 @@ set(FILES
|
||||
XML/WriteXMLSource.cpp
|
||||
ZipFile.h
|
||||
ZipFileFormat_info.h
|
||||
LoadingProfiler.cpp
|
||||
PerfHUD.cpp
|
||||
ProfileLogSystem.cpp
|
||||
Sampler.cpp
|
||||
LoadingProfiler.h
|
||||
PerfHUD.h
|
||||
ProfileLogSystem.h
|
||||
Sampler.h
|
||||
|
||||
@@ -902,7 +902,7 @@ void ShadersOptimizeHelper(CallableT setupParserBin, const char* logString)
|
||||
{
|
||||
setupParserBin();
|
||||
CryLogAlways("\nStarting shaders optimizing for %s...", logString);
|
||||
AZStd::string str = "@cache@/" + gRenDev->m_cEF.m_ShadersCache;
|
||||
AZStd::string str = "@usercache@/" + gRenDev->m_cEF.m_ShadersCache;
|
||||
iLog->Log("Optimize shader cache folder: '%s'", gRenDev->m_cEF.m_ShadersCache.c_str());
|
||||
gRenDev->m_cEF.mfOptimiseShaders(str.c_str(), false);
|
||||
}
|
||||
@@ -2396,7 +2396,7 @@ void CRenderer::InitRenderer()
|
||||
|
||||
CV_r_ShaderCompilerFolderSuffix = REGISTER_STRING("r_ShaderCompilerFolderSuffix", "", VF_NULL,
|
||||
"Usage: r_ShaderCompilerFolderSuffix suffix \n"
|
||||
"Default is empty. Set to some other value to append this suffix to the sys_game_folder when compiling shaders");
|
||||
"Default is empty. Set to some other value to append this suffix to the project name when compiling shaders");
|
||||
|
||||
{
|
||||
const SFileVersion& ver = gEnv->pSystem->GetFileVersion();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <AzCore/Socket/AzSocket.h>
|
||||
#include <AzCore/NativeUI/NativeUIRequests.h>
|
||||
#include <AzCore/PlatformId/PlatformId.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzFramework/Network/SocketConnection.h>
|
||||
#include <AzFramework/Asset/AssetSystemTypes.h>
|
||||
|
||||
@@ -306,23 +307,20 @@ namespace NRemoteCompiler
|
||||
|
||||
m_RequestLineRootFolder = "";
|
||||
|
||||
ICVar* pGameFolder = gEnv->pConsole->GetCVar("sys_game_folder");
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
ICVar* pCompilerFolderSuffix = CRenderer::CV_r_ShaderCompilerFolderSuffix;
|
||||
|
||||
if (pGameFolder)
|
||||
if (!projectName.empty())
|
||||
{
|
||||
string folder = pGameFolder->GetString();
|
||||
folder.Trim();
|
||||
if (!folder.empty())
|
||||
if (pCompilerFolderSuffix)
|
||||
{
|
||||
if (pCompilerFolderSuffix)
|
||||
{
|
||||
string suffix = pCompilerFolderSuffix->GetString();
|
||||
suffix.Trim();
|
||||
folder.append(suffix);
|
||||
}
|
||||
m_RequestLineRootFolder = folder + string("/");
|
||||
string suffix = pCompilerFolderSuffix->GetString();
|
||||
suffix.Trim();
|
||||
projectName.append(suffix);
|
||||
}
|
||||
|
||||
projectName.append("/");
|
||||
m_RequestLineRootFolder.assign(projectName.c_str(), projectName.size());
|
||||
}
|
||||
|
||||
if (m_RequestLineRootFolder.empty())
|
||||
|
||||
@@ -13,16 +13,61 @@
|
||||
#include <AzTest/AzTest.h>
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Memory/AllocatorScope.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/UnitTest/UnitTest.h>
|
||||
#include "Mocks/IConsoleMock.h"
|
||||
#include "Mocks/ICVarMock.h"
|
||||
#include "Mocks/ISystemMock.h"
|
||||
#include "RemoteCompiler.h"
|
||||
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class SettingsRegistrySimpleMock;
|
||||
using NiceSettingsRegistrySimpleMock = ::testing::NiceMock<SettingsRegistrySimpleMock>;
|
||||
|
||||
class SettingsRegistrySimpleMock : public AZ::SettingsRegistryInterface
|
||||
{
|
||||
public:
|
||||
MOCK_CONST_METHOD1(GetType, Type(AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Visit, bool(Visitor&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Visit, bool(const VisitorCallback&, AZStd::string_view));
|
||||
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(const NotifyCallback&));
|
||||
MOCK_METHOD1(RegisterNotifier, NotifyEventHandler(NotifyCallback&&));
|
||||
|
||||
MOCK_CONST_METHOD2(Get, bool(bool&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Get, bool(s64&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Get, bool(u64&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Get, bool(double&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Get, bool(AZStd::string&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD2(Get, bool(FixedValueString&, AZStd::string_view));
|
||||
MOCK_CONST_METHOD3(GetObject, bool(void*, Uuid, AZStd::string_view));
|
||||
|
||||
MOCK_METHOD2(Set, bool(AZStd::string_view, bool));
|
||||
MOCK_METHOD2(Set, bool(AZStd::string_view, s64));
|
||||
MOCK_METHOD2(Set, bool(AZStd::string_view, u64));
|
||||
MOCK_METHOD2(Set, bool(AZStd::string_view, double));
|
||||
MOCK_METHOD2(Set, bool(AZStd::string_view, AZStd::string_view));
|
||||
MOCK_METHOD2(Set, bool(AZStd::string_view, const char*));
|
||||
MOCK_METHOD3(SetObject, bool(AZStd::string_view, const void*, Uuid));
|
||||
|
||||
MOCK_METHOD1(Remove, bool(AZStd::string_view));
|
||||
|
||||
MOCK_METHOD3(MergeCommandLineArgument, bool(AZStd::string_view, AZStd::string_view, const CommandLineArgumentSettings&));
|
||||
MOCK_METHOD2(MergeSettings, bool(AZStd::string_view, Format));
|
||||
MOCK_METHOD4(MergeSettingsFile, bool(AZStd::string_view, Format, AZStd::string_view, AZStd::vector<char>*));
|
||||
MOCK_METHOD5(
|
||||
MergeSettingsFolder,
|
||||
bool(AZStd::string_view, const Specializations&, AZStd::string_view, AZStd::string_view, AZStd::vector<char>*));
|
||||
};
|
||||
} // namespace AZ
|
||||
|
||||
|
||||
namespace NRemoteCompiler
|
||||
{
|
||||
using ::testing::NiceMock;
|
||||
using ::testing::Return;
|
||||
using ::testing::DoAll;
|
||||
|
||||
using SystemAllocatorScope = AZ::AllocatorScope<AZ::LegacyAllocator, CryStringAllocator>;
|
||||
|
||||
@@ -65,9 +110,12 @@ namespace NRemoteCompiler
|
||||
SystemAllocatorScope::ActivateAllocators();
|
||||
|
||||
m_priorEnv = gEnv;
|
||||
m_priorSettingsRegistry = AZ::SettingsRegistry::Get();
|
||||
|
||||
m_data.reset(new DataMembers);
|
||||
|
||||
AZ::SettingsRegistry::Register(&m_data->m_settings);
|
||||
|
||||
ON_CALL(m_data->m_console, GetCVar(_))
|
||||
.WillByDefault(Return(&m_data->m_cvarMock));
|
||||
|
||||
@@ -89,6 +137,11 @@ namespace NRemoteCompiler
|
||||
void TearDown() override
|
||||
{
|
||||
gEnv = m_priorEnv;
|
||||
AZ::SettingsRegistry::Unregister(&m_data->m_settings);
|
||||
if (m_priorSettingsRegistry)
|
||||
{
|
||||
AZ::SettingsRegistry::Register(m_priorSettingsRegistry);
|
||||
}
|
||||
m_data.reset();
|
||||
SystemAllocatorScope::DeactivateAllocators();
|
||||
AllocatorsTestFixture::TearDown();
|
||||
@@ -99,12 +152,14 @@ namespace NRemoteCompiler
|
||||
NiceMock<SystemMock> m_system;
|
||||
NiceMock<ConsoleMock> m_console;
|
||||
NiceMock<CVarMock> m_cvarMock;
|
||||
AZ::NiceSettingsRegistrySimpleMock m_settings;
|
||||
SSystemGlobalEnvironment m_stubEnv;
|
||||
};
|
||||
|
||||
AZStd::unique_ptr<DataMembers> m_data;
|
||||
|
||||
SSystemGlobalEnvironment* m_priorEnv = nullptr;
|
||||
AZ::SettingsRegistryInterface* m_priorSettingsRegistry = nullptr;
|
||||
};
|
||||
|
||||
// allow punch through to PRIVATE functions so that they do not need to be made PUBLIC.
|
||||
@@ -130,7 +185,9 @@ namespace NRemoteCompiler
|
||||
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_Constructor_WithNoGameName_Fails)
|
||||
{
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString());
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString regResult;
|
||||
EXPECT_CALL(m_data->m_settings, Get(regResult, _));
|
||||
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
@@ -140,8 +197,10 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_Constructor_WithValidGameName_Succeeds)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
}
|
||||
@@ -149,11 +208,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_EmptyData_Fails)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
std::vector<uint8> testVector;
|
||||
|
||||
@@ -165,11 +225,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_ValidData_EmptyServerList_Fails)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillRepeatedly(Return("")); // empty server list
|
||||
@@ -186,11 +247,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_EncapsulateRequestInEngineConnectionProtocol_ValidInputs_Succeeds)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
// After this, it will repeatedly call get cvar to get the server address:
|
||||
const char* testList = "10.20.30.40";
|
||||
@@ -207,11 +269,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_EmptyData_Fails)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
// After this, it will repeatedly call get cvar to get the server address:
|
||||
const char* testList = "10.20.30.40";
|
||||
@@ -221,7 +284,7 @@ namespace NRemoteCompiler
|
||||
std::vector<uint8> testVector;
|
||||
std::string testString("empty");
|
||||
|
||||
// test for empty data - recvfailed expected (error emitted)
|
||||
// test for empty data - RecvFailed expected (error emitted)
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
testString = "empty";
|
||||
testVector.assign(testString.begin(), testString.end());
|
||||
@@ -232,11 +295,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_IncompleteData_Fails)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
// After this, it will repeatedly call get cvar to get the server address:
|
||||
const char* testList = "10.20.30.40";
|
||||
@@ -247,7 +311,7 @@ namespace NRemoteCompiler
|
||||
std::string testString("incomplete");
|
||||
testVector.assign(testString.begin(), testString.end());
|
||||
|
||||
// test for incomplete data - recvfailed expected
|
||||
// test for incomplete data - RecvFailed expected
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESRecvFailed);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
@@ -256,11 +320,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_CorruptData_Fails)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
// After this, it will repeatedly call get cvar to get the server address:
|
||||
const char* testList = "10.20.30.40";
|
||||
@@ -271,7 +336,7 @@ namespace NRemoteCompiler
|
||||
std::string testString("corrupt");
|
||||
testVector.assign(testString.begin(), testString.end());
|
||||
|
||||
// test for incomplete data - recvfailed expected
|
||||
// test for incomplete data - RecvFailed expected
|
||||
AZ_TEST_START_TRACE_SUPPRESSION;
|
||||
EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESRecvFailed);
|
||||
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
|
||||
@@ -280,11 +345,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_CompileError_Fails_ReturnsText)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
// After this, it will repeatedly call get cvar to get the server address:
|
||||
const char* testList = "10.20.30.40";
|
||||
@@ -294,11 +360,11 @@ namespace NRemoteCompiler
|
||||
std::vector<uint8> testVector;
|
||||
std::string testString("corrupt");
|
||||
testVector.assign(testString.begin(), testString.end());
|
||||
// test for an actual compile error - decompressed compile erro rexpected to be attached.
|
||||
// test for an actual compile error - decompressed compile error expected to be attached.
|
||||
testString = "compile_failure";
|
||||
testVector.assign(testString.begin(), testString.end());
|
||||
EXPECT_EQ(srv.SendRequestViaEngineConnection(testVector), EServerError::ESCompileError);
|
||||
// validate hte compile erorr decompressed successfully
|
||||
// validate the compile error decompressed successfully
|
||||
const char* expected_decode = "decompressed_plaintext";
|
||||
EXPECT_EQ(testVector.size(), strlen(expected_decode));
|
||||
EXPECT_EQ(memcmp(testVector.data(), expected_decode, strlen(expected_decode)), 0);
|
||||
@@ -307,11 +373,12 @@ namespace NRemoteCompiler
|
||||
TEST_F(RemoteCompilerTest, CShaderSrv_SendRequestViaEngineConnection_ValidInput_Succeeds_ReturnsText)
|
||||
{
|
||||
// when we construct the server it calls get on the game name
|
||||
EXPECT_CALL(m_data->m_cvarMock, GetString())
|
||||
.WillOnce(Return("StarterGame"));
|
||||
using namespace ::testing;
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
EXPECT_CALL(m_data->m_settings, Get(projectName, _))
|
||||
.WillOnce(DoAll(testing::SetArgReferee<0>("StarterGame"), Return(true)));
|
||||
|
||||
ShaderSrvUnitTestAccessor srv;
|
||||
|
||||
|
||||
// After this, it will repeatedly call get cvar to get the server address:
|
||||
const char* testList = "10.20.30.40";
|
||||
|
||||
@@ -375,7 +375,7 @@ void CShaderMan::mfInitShadersCacheMissLog()
|
||||
// create valid path
|
||||
gEnv->pCryPak->MakeDir(g_szTestResults);
|
||||
|
||||
m_ShaderCacheMissPath = string("@cache@\\Shaders\\ShaderCacheMisses.txt"); // do we want this here, or maybe in @log@ ?
|
||||
m_ShaderCacheMissPath = string("@usercache@\\Shaders\\ShaderCacheMisses.txt"); // do we want this here, or maybe in @log@ ?
|
||||
|
||||
// load data which is already stored
|
||||
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
|
||||
@@ -2175,9 +2175,10 @@ void CShaderMan::mfOptimiseShaders(const char* szFolder, bool bForce)
|
||||
for (i = 0; i < Names.size(); i++)
|
||||
{
|
||||
const char* szName = Names[i].c_str();
|
||||
if (!strncmp(szName, "@cache@/", 7))
|
||||
constexpr AZStd::string_view userCache = "@usercache@/";
|
||||
if (szName == userCache)
|
||||
{
|
||||
szName += 7;
|
||||
szName += userCache.size();
|
||||
}
|
||||
pCache = CHWShader::mfInitCache(szName, NULL, false, 0, false);
|
||||
if (!pCache || !pCache->m_pRes[CACHE_USER])
|
||||
|
||||
@@ -1589,7 +1589,7 @@ void CShaderMan::mfInit (void)
|
||||
#else
|
||||
m_ShadersCache = CONCAT_PATHS(g_shaderCache, "D3D11");
|
||||
#endif
|
||||
m_szCachePath = "@cache@/";
|
||||
m_szCachePath = "@usercache@/";
|
||||
|
||||
if (CRenderer::CV_r_shadersImport == 3)
|
||||
{
|
||||
|
||||
@@ -162,7 +162,7 @@ bool CShaderSerialize::OpenSResource(const char* szName, SSShaderRes* pSR, CSha
|
||||
stack_string szReadOnly = szName;
|
||||
|
||||
// ShaderCacheGen behavior:
|
||||
// CACHE_READONLY is not really used when exporting the .fxb, so we append the @cache@ alias to the relative shader path
|
||||
// CACHE_READONLY is not really used when exporting the .fxb, so we append the @usercache@ alias to the relative shader path
|
||||
// here as well. We cannot just leave this as the relative Shaders/Cache/Foo.fxb value because then it creates a new
|
||||
// file in the asset cache as @assets@/Shaders/Cache/Foo.fxb, which is illegal (since only AP has the authority to write here)
|
||||
// Game runtime behavior:
|
||||
|
||||
@@ -3490,7 +3490,7 @@ void CHWShader_D3D::mfSaveCGFile(const char* scr, const char* path)
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(name, "@cache@/shaders/fxerror/%s(GL%llx)/(LT%x)(RT%llx)/(MD%x)(MDV%x)(PSS%llx)(ST%llx).cg", GetName(), m_pCurInst->m_Ident.m_GLMask, m_pCurInst->m_Ident.m_LightMask, m_pCurInst->m_Ident.m_RTMask, m_pCurInst->m_Ident.m_MDMask, m_pCurInst->m_Ident.m_MDVMask, m_pCurInst->m_Ident.m_pipelineState.opaque, m_pCurInst->m_Ident.m_STMask);
|
||||
sprintf_s(name, "@usercache@/shaders/fxerror/%s(GL%llx)/(LT%x)(RT%llx)/(MD%x)(MDV%x)(PSS%llx)(ST%llx).cg", GetName(), m_pCurInst->m_Ident.m_GLMask, m_pCurInst->m_Ident.m_LightMask, m_pCurInst->m_Ident.m_RTMask, m_pCurInst->m_Ident.m_MDMask, m_pCurInst->m_Ident.m_MDVMask, m_pCurInst->m_Ident.m_pipelineState.opaque, m_pCurInst->m_Ident.m_STMask);
|
||||
}
|
||||
|
||||
AZ::IO::HandleType fileHandle;
|
||||
@@ -4672,7 +4672,7 @@ bool CAsyncShaderTask::CompileAsyncShader(SShaderAsyncInfo* pAsync)
|
||||
CryFixedStringT<1024> hlslPath;
|
||||
|
||||
// Create a directory for this shader type, strip the .fxcb extension from the folder name
|
||||
shaderSourceOutputFolder.Format("@cache@/%s",pAsync->m_pShader->m_pDevCache->m_Name.c_str());
|
||||
shaderSourceOutputFolder.Format("@usercache@/%s",pAsync->m_pShader->m_pDevCache->m_Name.c_str());
|
||||
PathUtil::RemoveExtension(shaderSourceOutputFolder);
|
||||
gEnv->pFileIO->CreatePath(shaderSourceOutputFolder);
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#endif
|
||||
|
||||
#include "../Common/RenderCapabilities.h"
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#ifdef WIN32
|
||||
// Count monitors helper
|
||||
@@ -1634,8 +1635,8 @@ WIN_HWND CD3D9Renderer::Init([[maybe_unused]] int x, [[maybe_unused]] int y, int
|
||||
iLog->Log ("Direct3D driver is creating...");
|
||||
iLog->Log ("Crytek Direct3D driver version %4.2f (%s <%s>)", VERSION_D3D, __DATE__, __TIME__);
|
||||
|
||||
const char* sGameName = iConsole->GetCVar("sys_game_name")->GetString();
|
||||
cry_strcpy(m_WinTitle, sGameName);
|
||||
auto projectName = AZ::Utils::GetProjectName();
|
||||
cry_strcpy(m_WinTitle, projectName.c_str());
|
||||
|
||||
iLog->Log ("Creating window called '%s' (%dx%d)", m_WinTitle, width, height);
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
|
||||
#include <AzCore/Debug/LocalFileEventLogger.h>
|
||||
|
||||
#include <AzCore/Memory/AllocationRecords.h>
|
||||
|
||||
#include <AzCore/Memory/OverrunDetectionAllocator.h>
|
||||
@@ -99,6 +101,18 @@ namespace AZ
|
||||
return environment ? environment->Get() : nullptr;
|
||||
}
|
||||
|
||||
ComponentApplication::EventLoggerDeleter::EventLoggerDeleter() noexcept= default;
|
||||
ComponentApplication::EventLoggerDeleter::EventLoggerDeleter(bool skipDelete) noexcept
|
||||
: m_skipDelete{skipDelete}
|
||||
{}
|
||||
void ComponentApplication::EventLoggerDeleter::operator()(AZ::Debug::LocalFileEventLogger* ptr)
|
||||
{
|
||||
if (!m_skipDelete)
|
||||
{
|
||||
delete ptr;
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// ComponentApplication::Descriptor
|
||||
// [5/30/2012]
|
||||
@@ -159,6 +173,80 @@ namespace AZ
|
||||
return true;
|
||||
};
|
||||
|
||||
//! SettingsRegistry notifier handler which updates relevant registry settings based
|
||||
//! on an update to '/Amazon/AzCore/Bootstrap/project_path' key.
|
||||
struct UpdateProjectSettingsEventHandler
|
||||
{
|
||||
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry)
|
||||
: m_registry{ registry }
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
|
||||
{
|
||||
UpdateProjectSpecializationInRegistry(path);
|
||||
}
|
||||
|
||||
//! Add the project name as a specialization underneath the /Amazon/AzCore/Settings/Specializations path
|
||||
//! and remove the current project name specialization if one exists.
|
||||
void UpdateProjectSpecializationInRegistry(AZStd::string_view path)
|
||||
{
|
||||
auto projectPathKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
|
||||
+ "/project_path";
|
||||
if (path == projectPathKey)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString newProjectPath;
|
||||
if (m_registry.Get(newProjectPath, path) && !newProjectPath.empty())
|
||||
{
|
||||
// Make the path absolute by appending to app root, in case project path is relative.
|
||||
// If the project path is already absolute it will remain the same.
|
||||
// If we turn it from a relative path to an absolute path, write-back the absolute path to the registry.
|
||||
AZ::IO::FixedMaxPath projectPath = AZ::SettingsRegistryMergeUtils::FindEngineRoot(m_registry) / newProjectPath;
|
||||
if (projectPath.Compare(newProjectPath.c_str()))
|
||||
{
|
||||
m_registry.Set(path, projectPath.Native());
|
||||
}
|
||||
|
||||
// Merge the project.json file into settings registry under ProjectSettingsRootKey path.
|
||||
AZ::IO::FixedMaxPath projectMetadataFile{ projectPath };
|
||||
projectMetadataFile /= "project.json";
|
||||
m_registry.MergeSettingsFile(projectMetadataFile.Native(),
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch, AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey);
|
||||
|
||||
// Get the 'project_name' value from what was in the 'project.json' file...
|
||||
auto projectNameKey =
|
||||
AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey)
|
||||
+ "/project_name";
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectSpecialization;
|
||||
if (m_registry.Get(projectSpecialization, projectNameKey))
|
||||
{
|
||||
auto specializationKey = AZ::SettingsRegistryInterface::FixedValueString::format(
|
||||
"%s/%s", AZ::SettingsRegistryMergeUtils::SpecializationsRootKey, projectSpecialization.c_str());
|
||||
if (m_currentSpecialization != specializationKey)
|
||||
{
|
||||
m_registry.Set(specializationKey, true);
|
||||
if (!m_currentSpecialization.empty())
|
||||
{
|
||||
// Remove the previous Project Name from the specialization path if it was set.
|
||||
m_registry.Remove(m_currentSpecialization);
|
||||
}
|
||||
m_currentSpecialization = specializationKey;
|
||||
|
||||
// Update all the runtime file paths based on the new "project_path" value.
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
AZ::SettingsRegistryInterface::FixedValueString m_currentSpecialization;
|
||||
AZ::SettingsRegistryInterface& m_registry;
|
||||
};
|
||||
|
||||
void ComponentApplication::Descriptor::AllocatorRemapping::Reflect(ReflectContext* context, ComponentApplication* app)
|
||||
{
|
||||
(void)app;
|
||||
@@ -276,6 +364,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
ComponentApplication::ComponentApplication(int argC, char** argV)
|
||||
: m_eventLogger{}
|
||||
{
|
||||
if (argV)
|
||||
{
|
||||
@@ -284,11 +373,23 @@ namespace AZ
|
||||
}
|
||||
else
|
||||
{
|
||||
azstrcpy(m_commandLineBuffer, AZ_ARRAY_SIZE(m_commandLineBuffer), "no_argv_supplied");
|
||||
azstrcpy(m_commandLineBuffer, AZ_ARRAY_SIZE(m_commandLineBuffer), "no_argv_supplied");
|
||||
// use a "valid" value here. This is because Qt and potentially other third party libraries require
|
||||
// that ArgC be 'at least 1' and that (*argV)[0] be a valid pointer to a real null terminated string.
|
||||
m_argC = 1;
|
||||
m_argV = &m_commandLineBufferAddress;
|
||||
m_argC = 1;
|
||||
m_argV = &m_commandLineBufferAddress;
|
||||
}
|
||||
|
||||
// Create the Event logger if it doesn't exist, otherwise reuse the one registered
|
||||
// with the AZ::Interface
|
||||
if (AZ::Interface<AZ::Debug::IEventLogger>::Get() == nullptr)
|
||||
{
|
||||
m_eventLogger.reset(new AZ::Debug::LocalFileEventLogger);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_eventLogger = EventLoggerPtr(static_cast<AZ::Debug::LocalFileEventLogger*>(AZ::Interface<AZ::Debug::IEventLogger>::Get()),
|
||||
EventLoggerDeleter{ true });
|
||||
}
|
||||
|
||||
// Initializes the OSAllocator and SystemAllocator as soon as possible
|
||||
@@ -297,6 +398,7 @@ namespace AZ
|
||||
|
||||
// Now that the Allocators are initialized, the Command Line parameters can be parsed
|
||||
m_commandLine.Parse(m_argC, m_argV);
|
||||
ParseCommandLine(m_commandLine);
|
||||
|
||||
// Create the settings registry and register it with the AZ interface system
|
||||
// This is done after the AppRoot has been calculated so that the Bootstrap.cfg
|
||||
@@ -304,62 +406,34 @@ namespace AZ
|
||||
m_settingsRegistry = AZStd::make_unique<SettingsRegistryImpl>();
|
||||
|
||||
// Register the Settings Registry with the AZ Interface if there isn't one registered already
|
||||
if (AZ::SettingsRegistry::Get() == nullptr)
|
||||
if (SettingsRegistry::Get() == nullptr)
|
||||
{
|
||||
SettingsRegistry::Register(m_settingsRegistry.get());
|
||||
}
|
||||
|
||||
// Add the Command Line arguments into the SettingsRegistry
|
||||
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_StoreCommandLine(*m_settingsRegistry, m_commandLine);
|
||||
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
|
||||
|
||||
// Merge Command Line arguments
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
|
||||
|
||||
// Query for the Executable Path using OS specific functions
|
||||
CalculateExecutablePath();
|
||||
|
||||
// Determine the path to the engine
|
||||
CalculateEngineRoot();
|
||||
|
||||
// If the current platform returns an engaged optional from Utils::GetDefaultAppRootPath(), that is used
|
||||
// for the application root other the application root is found by scanning upwards from the Executable Directory
|
||||
// for a bootstrap.cfg file
|
||||
CalculateAppRoot(nullptr);
|
||||
// for the application root.
|
||||
CalculateAppRoot();
|
||||
|
||||
// Add a notifier to update the /Amazon/AzCore/Settings/Specializations
|
||||
// when the sys_game_folder property changes within the SettingsRegistry
|
||||
|
||||
// currentGameName is bound by value in order to allow the lambda to have a member variable that
|
||||
// can track the current game specialization before it changes
|
||||
AZ::SettingsRegistryInterface::FixedValueString currentGameSpecialization;
|
||||
auto GameProjectChanged = [currentGameSpecialization](AZStd::string_view path, AZ::SettingsRegistryInterface::Type type) mutable
|
||||
{
|
||||
constexpr auto projectKey = AZ::SettingsRegistryInterface::FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
|
||||
+ "/sys_game_folder";
|
||||
if (projectKey == path && type == AZ::SettingsRegistryInterface::Type::String)
|
||||
{
|
||||
auto registry = AZ::SettingsRegistry::Get();
|
||||
AZ::SettingsRegistryInterface::FixedValueString newGameName;
|
||||
if (registry && registry->Get(newGameName, path) && !newGameName.empty())
|
||||
{
|
||||
auto specializationKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/%s",
|
||||
AZ::SettingsRegistryMergeUtils::SpecializationsRootKey, newGameName.c_str());
|
||||
|
||||
if (currentGameSpecialization != specializationKey)
|
||||
{
|
||||
registry->Set(specializationKey, true);
|
||||
if (!currentGameSpecialization.empty())
|
||||
{
|
||||
// Remove the previous Game Name from the specialization path if it was set
|
||||
registry->Remove(currentGameSpecialization);
|
||||
}
|
||||
// Update the currentGameSpecialization
|
||||
currentGameSpecialization = specializationKey;
|
||||
|
||||
// Update all the runtime filepaths based on the new "sys_game_folder" value
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
m_gameProjectChangedHandler = m_settingsRegistry->RegisterNotifier(AZStd::move(GameProjectChanged));
|
||||
// when the 'project_path' property changes within the SettingsRegistry
|
||||
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry });
|
||||
|
||||
// Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created.
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry);
|
||||
|
||||
@@ -391,11 +465,11 @@ namespace AZ
|
||||
Destroy();
|
||||
}
|
||||
|
||||
// The m_gameProjectChangedHandler stores an AZStd::function internally
|
||||
// The m_projectChangedHandler stores an AZStd::function internally
|
||||
// which allocates using the AZ SystemAllocator
|
||||
// m_gameProjectChangedHandler is being default value initialized
|
||||
// m_projectChangedHandler is being default value initialized
|
||||
// to clear out the AZStd::function
|
||||
m_gameProjectChangedHandler = {};
|
||||
m_projectChangedHandler = {};
|
||||
|
||||
// Delete the AZ::IConsole if it was created by this application instance
|
||||
if (m_ownsConsole)
|
||||
@@ -412,6 +486,10 @@ namespace AZ
|
||||
}
|
||||
m_settingsRegistry.reset();
|
||||
|
||||
// Set AZ::CommandLine to an empty object to clear out allocated memory before the allocators
|
||||
// are destroyed
|
||||
m_commandLine = {};
|
||||
|
||||
DestroyAllocator();
|
||||
}
|
||||
|
||||
@@ -421,17 +499,6 @@ namespace AZ
|
||||
AZ_Assert(!m_isStarted, "Component application already started!");
|
||||
|
||||
m_startupParameters = startupParameters;
|
||||
// Invokes CalculateAppRoot() again this time with the appRootOverride startup parameter
|
||||
// supplied in order to allow overriding the AppRoot calculated in the constructor
|
||||
if (m_startupParameters.m_appRootOverride)
|
||||
{
|
||||
CalculateAppRoot(m_startupParameters.m_appRootOverride);
|
||||
// Re-check for the bootstrap.cfg file again using the appRoot override and update the file paths
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
|
||||
constexpr bool executeRegDumpCommands = false;
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(*m_settingsRegistry);
|
||||
}
|
||||
|
||||
m_descriptor = descriptor;
|
||||
|
||||
@@ -461,20 +528,14 @@ namespace AZ
|
||||
void ComponentApplication::CreateCommon()
|
||||
{
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString registryValue;
|
||||
m_settingsRegistry->Get(registryValue, AZ::SettingsRegistryMergeUtils::FilePathKey_DevWriteStorage);
|
||||
AZ::IO::FixedMaxPath outputPath{ registryValue };
|
||||
AZ::IO::FixedMaxPath outputPath;
|
||||
m_settingsRegistry->Get(outputPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_DevWriteStorage);
|
||||
outputPath /= "eventlogger";
|
||||
|
||||
registryValue.clear();
|
||||
|
||||
AZ::IO::FixedMaxPathString baseFileName{ "EventLog" }; // default name
|
||||
if (m_settingsRegistry->Get(registryValue, AZ::SettingsRegistryMergeUtils::BuildTargetNameKey))
|
||||
{
|
||||
baseFileName = registryValue;
|
||||
}
|
||||
m_settingsRegistry->Get(baseFileName, AZ::SettingsRegistryMergeUtils::BuildTargetNameKey);
|
||||
|
||||
m_eventLogger.Start(outputPath.c_str(), baseFileName.c_str());
|
||||
m_eventLogger->Start(outputPath.Native(), baseFileName);
|
||||
}
|
||||
|
||||
CreateDrillers();
|
||||
@@ -515,7 +576,9 @@ namespace AZ
|
||||
LoadModules();
|
||||
|
||||
// Execute user.cfg after modules have been loaded but before processing any command-line overrides
|
||||
m_console->ExecuteConfigFile("@root@/user.cfg");
|
||||
AZ::IO::FixedMaxPath platformCachePath;
|
||||
m_settingsRegistry->Get(platformCachePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder);
|
||||
m_console->ExecuteConfigFile((platformCachePath / "user.cfg").Native());
|
||||
|
||||
// Parse the command line parameters for console commands after modules have loaded
|
||||
m_console->ExecuteCommandLine(m_commandLine);
|
||||
@@ -601,7 +664,7 @@ namespace AZ
|
||||
m_drillerManager = nullptr;
|
||||
}
|
||||
|
||||
m_eventLogger.Stop();
|
||||
m_eventLogger->Stop();
|
||||
|
||||
// Clear the descriptor to deallocate all strings (owned by ModuleDescriptor)
|
||||
m_descriptor = Descriptor();
|
||||
@@ -775,6 +838,46 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::ParseCommandLine(const AZ::CommandLine& commandLine)
|
||||
{
|
||||
struct OptionKeyToRegsetKey
|
||||
{
|
||||
AZStd::string_view m_optionKey;
|
||||
AZStd::string m_regsetKey;
|
||||
};
|
||||
|
||||
// Provide overrides for the engine root, the project root and the project cache root
|
||||
AZStd::array commandOptions = {
|
||||
OptionKeyToRegsetKey{ "engine-path", AZStd::string::format("%s/engine_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) },
|
||||
OptionKeyToRegsetKey{ "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::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
|
||||
|
||||
for (auto&& [optionKey, regsetKey] : commandOptions)
|
||||
{
|
||||
if (size_t optionCount = commandLine.GetNumSwitchValues(optionKey); optionCount > 0)
|
||||
{
|
||||
// Use the last supplied command option value to override previous values
|
||||
auto overrideArg = AZStd::string::format(R"(--regset="%s=%s")", regsetKey.c_str(),
|
||||
commandLine.GetSwitchValue(optionKey, optionCount - 1).c_str());
|
||||
overrideArgs.emplace_back(AZStd::move(overrideArg));
|
||||
}
|
||||
}
|
||||
|
||||
if (!overrideArgs.empty())
|
||||
{
|
||||
// Dump the input command line, add the additional option overrides
|
||||
// and Parse the new command line into the Component Application command line
|
||||
AZ::CommandLine::ParamContainer commandLineArgs;
|
||||
commandLine.Dump(commandLineArgs);
|
||||
commandLineArgs.insert(commandLineArgs.end(), AZStd::make_move_iterator(overrideArgs.begin()),
|
||||
AZStd::make_move_iterator(overrideArgs.end()));
|
||||
m_commandLine.Parse(commandLineArgs);
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::MergeSettingsToRegistry(SettingsRegistryInterface& registry)
|
||||
{
|
||||
SettingsRegistryInterface::Specializations specializations;
|
||||
@@ -788,14 +891,14 @@ namespace AZ
|
||||
// In development builds apply the developer 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_DevRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_UserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, false);
|
||||
#endif
|
||||
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_DevRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_UserRegistry(registry, AZ_TRAIT_OS_PLATFORM_CODENAME, specializations, &scratchBuffer);
|
||||
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(registry, m_commandLine, true);
|
||||
#endif
|
||||
}
|
||||
@@ -1013,7 +1116,7 @@ namespace AZ
|
||||
struct GemModuleLoadData
|
||||
{
|
||||
AZ::OSString m_gemName;
|
||||
AZ::OSString m_dynamicLibraryPath;
|
||||
AZStd::vector<AZ::OSString> m_dynamicLibraryPaths;
|
||||
bool m_autoLoad{ true };
|
||||
};
|
||||
|
||||
@@ -1069,19 +1172,18 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view path, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, AZStd::string_view value) override
|
||||
void Visit(AZStd::string_view path, AZStd::string_view, AZ::SettingsRegistryInterface::Type, AZStd::string_view value) override
|
||||
{
|
||||
if (valueName == "Module" && !value.empty())
|
||||
// Remove last path segment and check if the key corresponds to the Modules array
|
||||
AZStd::optional<AZStd::string_view> moduleIndex = AZ::StringFunc::TokenizeLast(path, "/");
|
||||
if (path.ends_with("/Modules"))
|
||||
{
|
||||
// Strip off the Module entry from the path
|
||||
auto moduleKey = AZ::StringFunc::TokenizeLast(path, "/");
|
||||
if (!moduleKey)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Remove the "Modules" path segment to be at the GemName key
|
||||
AZ::StringFunc::TokenizeLast(path, "/");
|
||||
if (auto moduleLoadData = FindGemModuleEntry(path); moduleLoadData != nullptr)
|
||||
{
|
||||
moduleLoadData->m_dynamicLibraryPath = value;
|
||||
// Just use Json Serialization to load all the array elements
|
||||
moduleLoadData->m_dynamicLibraryPaths.emplace_back(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1111,30 +1213,41 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
|
||||
constexpr size_t RegistryKeySize = 64;
|
||||
auto gemModuleKey = AZStd::fixed_string<RegistryKeySize>::format("%s/Gems", AZ::SettingsRegistryMergeUtils::OrganizationRootKey);
|
||||
auto gemModuleKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/Gems", AZ::SettingsRegistryMergeUtils::OrganizationRootKey);
|
||||
ModuleDescriptorList gemModules;
|
||||
{
|
||||
GemModuleVisitor moduleVisitor;
|
||||
m_settingsRegistry->Visit(moduleVisitor, gemModuleKey);
|
||||
m_settingsRegistry->Visit(moduleVisitor, gemModuleKey);
|
||||
for (GemModuleLoadData& moduleLoadData : moduleVisitor.m_modulesLoadData)
|
||||
{
|
||||
// Add all auto loadable non-asset gems to the list of gem modules to load
|
||||
if (moduleLoadData.m_autoLoad && !moduleLoadData.m_dynamicLibraryPath.empty())
|
||||
if (!moduleLoadData.m_autoLoad)
|
||||
{
|
||||
gemModules.emplace_back(DynamicModuleDescriptor{ AZStd::move(moduleLoadData.m_dynamicLibraryPath) });
|
||||
break;
|
||||
}
|
||||
for (AZ::OSString& dynamicLibraryPath : moduleLoadData.m_dynamicLibraryPaths)
|
||||
{
|
||||
auto CompareDynamicModuleDescriptor = [&dynamicLibraryPath](const DynamicModuleDescriptor& entry)
|
||||
{
|
||||
return entry.m_dynamicLibraryPath.contains(dynamicLibraryPath);
|
||||
};
|
||||
if (auto moduleIter = AZStd::find_if(gemModules.begin(), gemModules.end(), CompareDynamicModuleDescriptor);
|
||||
moduleIter == gemModules.end())
|
||||
{
|
||||
gemModules.emplace_back(DynamicModuleDescriptor{ AZStd::move(dynamicLibraryPath) });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The settings registry in the settings registry are prioritized to load before the modules in the ComponetnApplication descriptor
|
||||
// The modules in the settings registry are prioritized to load before the modules in the ComponentApplication descriptor
|
||||
// in the order in which they were found
|
||||
for (auto&& moduleDescriptor : m_descriptor.m_modules)
|
||||
{
|
||||
// Append new dynamic library modules to the descriptor array
|
||||
auto CompareDynamicModuleDescriptor = [&moduleDescriptor](const DynamicModuleDescriptor& entry)
|
||||
{
|
||||
return entry.m_dynamicLibraryPath.find(moduleDescriptor.m_dynamicLibraryPath) != AZStd::string_view::npos;
|
||||
return entry.m_dynamicLibraryPath.contains(moduleDescriptor.m_dynamicLibraryPath);
|
||||
};
|
||||
if (auto foundModuleIter = AZStd::find_if(gemModules.begin(), gemModules.end(), CompareDynamicModuleDescriptor);
|
||||
foundModuleIter == gemModules.end())
|
||||
@@ -1260,17 +1373,8 @@ namespace AZ
|
||||
m_exeDirectory.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
}
|
||||
|
||||
void ComponentApplication::CalculateAppRoot(const char* appRootOverride)
|
||||
void ComponentApplication::CalculateAppRoot()
|
||||
{
|
||||
if (appRootOverride)
|
||||
{
|
||||
m_appRoot = appRootOverride;
|
||||
if (!m_appRoot.empty() && !m_appRoot.ends_with(AZ_CORRECT_FILESYSTEM_SEPARATOR))
|
||||
{
|
||||
m_appRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (AZStd::optional<AZ::StringFunc::Path::FixedString> appRootPath = Utils::GetDefaultAppRootPath(); appRootPath)
|
||||
{
|
||||
m_appRoot = AZStd::move(*appRootPath);
|
||||
@@ -1279,26 +1383,14 @@ namespace AZ
|
||||
m_appRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_appRoot = AZ::SettingsRegistryMergeUtils::GetAppRoot(m_settingsRegistry.get()).Native();
|
||||
m_appRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// CheckEngineMarkerFile
|
||||
//=========================================================================
|
||||
bool ComponentApplication::CheckPathForEngineMarker(const char* fullPath) const
|
||||
void ComponentApplication::CalculateEngineRoot()
|
||||
{
|
||||
static const char* engineMarkerFileName = "engine.json";
|
||||
char engineMarkerFullPathToCheck[AZ_MAX_PATH_LEN] = "";
|
||||
|
||||
azstrcpy(engineMarkerFullPathToCheck, AZ_ARRAY_SIZE(engineMarkerFullPathToCheck), fullPath);
|
||||
azstrcat(engineMarkerFullPathToCheck, AZ_ARRAY_SIZE(engineMarkerFullPathToCheck), "/");
|
||||
azstrcat(engineMarkerFullPathToCheck, AZ_ARRAY_SIZE(engineMarkerFullPathToCheck), engineMarkerFileName);
|
||||
|
||||
return AZ::IO::SystemFile::Exists(engineMarkerFullPathToCheck);
|
||||
if (m_engineRoot = AZ::SettingsRegistryMergeUtils::FindEngineRoot(*m_settingsRegistry).Native(); !m_engineRoot.empty())
|
||||
{
|
||||
m_engineRoot.push_back(AZ_CORRECT_FILESYSTEM_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentApplication::ResolveModulePath([[maybe_unused]] AZ::OSString& modulePath)
|
||||
|
||||
@@ -9,15 +9,13 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_COMPONENT_APPLICATION_H
|
||||
#define AZCORE_COMPONENT_APPLICATION_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzCore/Debug/ProfileModuleInit.h>
|
||||
#include <AzCore/Debug/LocalFileEventLogger.h>
|
||||
#include <AzCore/Memory/AllocationRecords.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/Module/DynamicModuleHandle.h>
|
||||
@@ -40,12 +38,15 @@ namespace AZ
|
||||
class IConsole;
|
||||
class Module;
|
||||
class ModuleManager;
|
||||
}
|
||||
namespace AZ::Debug
|
||||
{
|
||||
class DrillerManager;
|
||||
class LocalFileEventLogger;
|
||||
}
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
class DrillerManager;
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class ReflectionEnvironment
|
||||
{
|
||||
public:
|
||||
@@ -167,15 +168,6 @@ namespace AZ
|
||||
//! \note Dynamic AZ::Modules are specified in the ComponentApplication::Descriptor.
|
||||
CreateStaticModulesCallback m_createStaticModulesCallback = nullptr;
|
||||
|
||||
//! If set, this is used as the app root folder instead of it being calculated.
|
||||
const char* m_appRootOverride = nullptr;
|
||||
|
||||
//! The path to root of the asset cache folder. For instance: ./cache/<project>/pc
|
||||
const char* m_cacheRootPath = nullptr;
|
||||
|
||||
//! The path to the project in the asset cache folder. For instance: ./cache/<project>/pc/<project>
|
||||
const char* m_cacheProjectPath = nullptr;
|
||||
|
||||
//! Specifies which system components to create & activate. If no tags specified, all system components are used. Specify as comma separated list.
|
||||
const char* m_systemComponentTags = nullptr;
|
||||
|
||||
@@ -226,6 +218,8 @@ namespace AZ
|
||||
/// Returns the working root folder that has been registered with the app, if there is one.
|
||||
/// It's expected that derived applications will implement an application root.
|
||||
const char* GetAppRoot() const override { return m_appRoot.c_str(); }
|
||||
/// Returns the path to the engine.
|
||||
const char* GetEngineRoot() const override { return m_engineRoot.c_str(); }
|
||||
/// Returns the path to the folder the executable is in.
|
||||
const char* GetExecutableFolder() const override { return m_exeDirectory.c_str(); }
|
||||
|
||||
@@ -331,6 +325,9 @@ namespace AZ
|
||||
/// Create the drillers
|
||||
void CreateDrillers();
|
||||
|
||||
/// Parse ComponentApplication specific command line arguments
|
||||
void ParseCommandLine(const AZ::CommandLine& commandLine);
|
||||
|
||||
virtual void MergeSettingsToRegistry(SettingsRegistryInterface& registry);
|
||||
|
||||
//! Sets the specializations that will be used when loading the Settings Registry. Extend this in derived
|
||||
@@ -363,17 +360,11 @@ namespace AZ
|
||||
/// Calculates the directory the application executable comes from.
|
||||
void CalculateExecutablePath();
|
||||
|
||||
/// Calculates the directory where the bootstrap.cfg file resides.
|
||||
void CalculateAppRoot(const char* appRootOverride = {});
|
||||
/// Calculates the root directory of the engine.
|
||||
void CalculateEngineRoot();
|
||||
|
||||
/**
|
||||
* Check/verify a given path for the engine marker (file) so that we can identify that
|
||||
* a given path is the engine root. This is only valid for target platforms that are built
|
||||
* for the host platform and not deployable (ie windows, mac).
|
||||
* @param fullPath The full path to look for the engine marker
|
||||
* @return true if the input path contains the engine marker file, false if not
|
||||
*/
|
||||
virtual bool CheckPathForEngineMarker(const char* fullPath) const;
|
||||
/// Calculates the directory where the bootstrap.cfg file resides.
|
||||
void CalculateAppRoot();
|
||||
|
||||
template<typename Iterator>
|
||||
static void NormalizePath(Iterator begin, Iterator end, bool doLowercase = true)
|
||||
@@ -398,10 +389,11 @@ namespace AZ
|
||||
void* m_fixedMemoryBlock{ nullptr }; //!< Pointer to the memory block allocator, so we can free it OnDestroy.
|
||||
IAllocatorAllocate* m_osAllocator{ nullptr };
|
||||
EntitySetType m_entities;
|
||||
AZ::StringFunc::Path::FixedString m_exeDirectory;
|
||||
AZ::StringFunc::Path::FixedString m_appRoot;
|
||||
AZ::IO::FixedMaxPathString m_exeDirectory;
|
||||
AZ::IO::FixedMaxPathString m_engineRoot;
|
||||
AZ::IO::FixedMaxPathString m_appRoot;
|
||||
|
||||
AZ::SettingsRegistryInterface::NotifyEventHandler m_gameProjectChangedHandler;
|
||||
AZ::SettingsRegistryInterface::NotifyEventHandler m_projectChangedHandler;
|
||||
|
||||
// ConsoleFunctorHandle is responsible for unregistering the Settings Registry Console
|
||||
// from the m_console member when it goes out of scope
|
||||
@@ -427,9 +419,15 @@ namespace AZ
|
||||
// Created early to allow events to be logged before anything else. These will be kept in memory until
|
||||
// a file is associated with the logger. The internal buffer is limited to 64kb and once full unexpected
|
||||
// behavior may happen. The LocalFileEventLogger will register itself automatically with AZ::Interface<IEventLogger>.
|
||||
AZ::Debug::LocalFileEventLogger m_eventLogger;
|
||||
|
||||
struct EventLoggerDeleter
|
||||
{
|
||||
EventLoggerDeleter() noexcept;
|
||||
EventLoggerDeleter(bool skipDelete) noexcept;
|
||||
void operator()(AZ::Debug::LocalFileEventLogger* ptr);
|
||||
bool m_skipDelete{};
|
||||
};
|
||||
using EventLoggerPtr = AZStd::unique_ptr<AZ::Debug::LocalFileEventLogger, EventLoggerDeleter>;
|
||||
EventLoggerPtr m_eventLogger;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // AZCORE_COMPONENT_APPLICATION_H
|
||||
#pragma once
|
||||
|
||||
@@ -183,6 +183,11 @@ namespace AZ
|
||||
* @return A pointer to the name of the app's root folder, if a root folder was registered.
|
||||
*/
|
||||
virtual const char* GetAppRoot() const = 0;
|
||||
/**
|
||||
* Gets the path of the working engine folder that the app is a part of.
|
||||
* @return A pointer to the engine path.
|
||||
*/
|
||||
virtual const char* GetEngineRoot() const = 0;
|
||||
/**
|
||||
* Gets the path to the directory that contains the application's executable.
|
||||
* @return A pointer to the name of the path that contains the application's executable.
|
||||
|
||||
@@ -161,9 +161,11 @@ namespace AZ
|
||||
|
||||
void Console::ExecuteCommandLine(const AZ::CommandLine& commandLine)
|
||||
{
|
||||
for (const auto& [switchKey, switchValues] : commandLine.GetSwitchList())
|
||||
for (auto&& commandArgument : commandLine)
|
||||
{
|
||||
ConsoleCommandContainer commandArgs(switchValues.begin(), switchValues.end());
|
||||
const auto& switchKey = commandArgument.m_option;
|
||||
const auto& switchValue = commandArgument.m_value;
|
||||
ConsoleCommandContainer commandArgs{ switchValue };
|
||||
PerformCommand(switchKey, commandArgs, ConsoleSilentMode::NotSilent, ConsoleInvokedFrom::AzConsole, ConsoleFunctorFlags::Null, ConsoleFunctorFlags::Null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,25 +67,7 @@ namespace AZ
|
||||
return a != OpenMode::Invalid;
|
||||
}
|
||||
|
||||
inline OpenMode operator | (OpenMode a, OpenMode b)
|
||||
{
|
||||
return static_cast<OpenMode>(static_cast<AZ::u32>(a) | static_cast<AZ::u32>(b));
|
||||
}
|
||||
|
||||
inline OpenMode operator & (OpenMode a, OpenMode b)
|
||||
{
|
||||
return static_cast<OpenMode>(static_cast<AZ::u32>(a) & static_cast<AZ::u32>(b));
|
||||
}
|
||||
|
||||
inline OpenMode& operator |= (OpenMode& a, OpenMode b)
|
||||
{
|
||||
return a = a | b;
|
||||
}
|
||||
|
||||
inline OpenMode& operator &= (OpenMode& a, OpenMode b)
|
||||
{
|
||||
return a = a & b;
|
||||
}
|
||||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(OpenMode)
|
||||
|
||||
OpenMode GetOpenModeFromStringMode(const char* mode);
|
||||
|
||||
@@ -250,12 +232,14 @@ namespace AZ
|
||||
virtual bool ConvertToAlias(AZ::IO::FixedMaxPath& convertedPath, const AZ::IO::PathView& path) const = 0;
|
||||
AZStd::optional<AZ::IO::FixedMaxPath> ConvertToAlias(const AZ::IO::PathView& path) const;
|
||||
|
||||
/// ResolvePath - Replaces any aliases in path with their values and stores the result in resolvedPath,
|
||||
/// also ensures that the path is absolute
|
||||
/// returns true if path was resolved, false otherwise
|
||||
/// note that all of the above file-finding and opening functions automatically resolve the path before operating
|
||||
/// so you should not need to call this except in very exceptional circumstances where you absolutely need to
|
||||
/// hit a physical file and don't want to use SystemFile
|
||||
//! ResolvePath - Replaces any aliases in path with their values and stores the result in resolvedPath,
|
||||
//! also ensures that the path is absolute
|
||||
//! NOTE: If the path does not start with an alias then the resolved value of the @assets@ is used
|
||||
//! which has the effect of making the path relative to the @assets@/ folder
|
||||
//! returns true if path was resolved, false otherwise
|
||||
//! note that all of the above file-finding and opening functions automatically resolve the path before operating
|
||||
//! so you should not need to call this except in very exceptional circumstances where you absolutely need to
|
||||
//! hit a physical file and don't want to use SystemFile
|
||||
virtual bool ResolvePath(const char* path, char* resolvedPath, AZ::u64 resolvedPathSize) const = 0;
|
||||
|
||||
//! ResolvePath - Replaces any @ aliases in the supplied path with their the resolved alias values
|
||||
@@ -265,6 +249,11 @@ namespace AZ
|
||||
virtual bool ResolvePath(AZ::IO::FixedMaxPath& resolvedPath, const AZ::IO::PathView& path) const = 0;
|
||||
AZStd::optional<AZ::IO::FixedMaxPath> ResolvePath(const AZ::IO::PathView& path) const;
|
||||
|
||||
//! ReplaceAliases - If the path starts with an @...@ alias it is substituted with the alias value
|
||||
//! otherwise the path is copied as is to the resolvedAlias path value
|
||||
//! returns true if the resulting path can fit within AZ::IO::FixedMaxPath buffer
|
||||
virtual bool ReplaceAlias(AZ::IO::FixedMaxPath& replacedAliasPath, const AZ::IO::PathView& path) const = 0;
|
||||
|
||||
/// Divulge the filename used to originally open that handle.
|
||||
virtual bool GetFilename(HandleType fileHandle, char* filename, AZ::u64 filenameSize) const = 0;
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace AZ::IO
|
||||
//! Check whether the path is not absolute
|
||||
[[nodiscard]] constexpr bool IsRelative() const;
|
||||
//! Check whether the path is relative to the base path
|
||||
[[nodiscard]] constexpr bool IsRelativeTo(const PathView & base) const;
|
||||
[[nodiscard]] constexpr bool IsRelativeTo(const PathView& base) const;
|
||||
|
||||
//! Normalizes a path in a purely lexical manner.
|
||||
//! # Path separators are converted to their preferred path separator
|
||||
@@ -517,7 +517,7 @@ namespace AZ::IO
|
||||
//! Checks if the path has a root directory
|
||||
[[nodiscard]] constexpr bool HasRootDirectory() const;
|
||||
//! Checks whether the entire root path portion of the path is empty
|
||||
//! The root portion ofthe path is made up of root_name() / root_directory()
|
||||
//! The root portion of the path is made up of root_name() / root_directory()
|
||||
[[nodiscard]] constexpr bool HasRootPath() const;
|
||||
//! checks whether the relative part of path is empty
|
||||
//! (C:\\ lumberyard\dev\)
|
||||
@@ -539,8 +539,8 @@ namespace AZ::IO
|
||||
[[nodiscard]] constexpr bool IsAbsolute() const;
|
||||
//! Check whether the path is not absolute
|
||||
[[nodiscard]] constexpr bool IsRelative() const;
|
||||
//! Check whether the path is relative to the input path
|
||||
[[nodiscard]] constexpr bool IsRelativeTo() const;
|
||||
//! Check whether the path is relative to the base path
|
||||
[[nodiscard]] constexpr bool IsRelativeTo(const PathView& base) const;
|
||||
|
||||
// decomposition
|
||||
//! Given a windows path of "C:\lumberyard\foo\bar\name.txt" and a posix path of
|
||||
|
||||
@@ -1035,7 +1035,7 @@ namespace AZ::IO
|
||||
// move the parser from the end to a valid filename by decrementing
|
||||
for(--pathParserEnd, --patternParserEnd; pathParserEnd && patternParserEnd; --pathParserEnd, --patternParserEnd)
|
||||
{
|
||||
if (!AZStd::wildcard_match(*patternParserEnd, *pathParserEnd))
|
||||
if (!AZStd::wildcard_match_case(*patternParserEnd, *pathParserEnd))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1830,9 +1830,9 @@ namespace AZ::IO
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
[[nodiscard]] constexpr bool BasicPath<StringType>::IsRelativeTo() const
|
||||
[[nodiscard]] constexpr bool BasicPath<StringType>::IsRelativeTo(const PathView& base) const
|
||||
{
|
||||
return static_cast<PathView>(*this).IsRelative();
|
||||
return static_cast<PathView>(*this).IsRelativeTo(base);
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
|
||||
@@ -369,6 +369,7 @@ namespace AZ
|
||||
context.Serializer<JsonVector2Serializer>()->HandlesType<Vector2>();
|
||||
context.Serializer<JsonVector3Serializer>()->HandlesType<Vector3>();
|
||||
context.Serializer<JsonVector4Serializer>()->HandlesType<Vector4>();
|
||||
context.Serializer<JsonQuaternionSerializer>()->HandlesType<Quaternion>();
|
||||
}
|
||||
|
||||
void MathReflect(ReflectContext* context)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Vector4.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Math/MathVectorSerializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
@@ -238,4 +239,56 @@ namespace AZ
|
||||
{
|
||||
return JsonMathVectorSerializerInternal::Store<Vector4, 4>(outputValue, inputValue, defaultValue, valueTypeId, context);
|
||||
}
|
||||
|
||||
// Quaternion
|
||||
|
||||
AZ_CLASS_ALLOCATOR_IMPL(JsonQuaternionSerializer, SystemAllocator, 0);
|
||||
|
||||
JsonSerializationResult::Result JsonQuaternionSerializer::Load(void* outputValue, const Uuid& outputValueTypeId,
|
||||
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds.
|
||||
|
||||
// check for "yaw, pitch, roll" object
|
||||
if (inputValue.IsObject())
|
||||
{
|
||||
if (inputValue.GetObject().ObjectEmpty())
|
||||
{
|
||||
Quaternion* outQuaternion = reinterpret_cast<Quaternion*>(outputValue);
|
||||
*outQuaternion = Quaternion::CreateIdentity();
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Using identity quaternion for empty object.");
|
||||
}
|
||||
|
||||
AZ::BaseJsonSerializer* floatSerializer = context.GetRegistrationContext()->GetSerializerForType(azrtti_typeid<float>());
|
||||
if (!floatSerializer)
|
||||
{
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "Failed to find the json float serializer.");
|
||||
}
|
||||
|
||||
constexpr const char* names[3] = {"yaw", "pitch", "roll"};
|
||||
float values[3];
|
||||
int i = 0;
|
||||
for (auto itr = inputValue.MemberBegin(); itr != inputValue.MemberEnd(); ++i, ++itr)
|
||||
{
|
||||
ScopedContextPath subPath(context, names[i]);
|
||||
JSR::Result intermediate = floatSerializer->Load(values + i, azrtti_typeid<float>(), itr->value, context);
|
||||
if (intermediate.GetResultCode().GetProcessing() != JSR::Processing::Completed)
|
||||
{
|
||||
return intermediate;
|
||||
}
|
||||
}
|
||||
|
||||
auto eulerAnglesDegrees = Vector3::CreateFromFloat3(values);
|
||||
reinterpret_cast<Quaternion*>(outputValue)->SetFromEulerDegrees(eulerAnglesDegrees);
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read quaternion.");
|
||||
}
|
||||
|
||||
return JsonMathVectorSerializerInternal::Load<Quaternion, 4>(outputValue, outputValueTypeId, inputValue, context);
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonQuaternionSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
|
||||
const void* defaultValue, const Uuid& valueTypeId, JsonSerializerContext& context)
|
||||
{
|
||||
return JsonMathVectorSerializerInternal::Store<Quaternion, 4>(outputValue, inputValue, defaultValue, valueTypeId, context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,4 +51,16 @@ namespace AZ
|
||||
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
||||
const Uuid& valueTypeId, JsonSerializerContext& context) override;
|
||||
};
|
||||
|
||||
class JsonQuaternionSerializer
|
||||
: public BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(JsonQuaternionSerializer, "{18604375-3606-49AC-B366-0F6DF9149FF3}", 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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/AzCore_Traits_Platform.h>
|
||||
#include <AzCore/std/tuple.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -29,6 +29,21 @@ namespace AZ
|
||||
|
||||
return lowerStr;
|
||||
}
|
||||
|
||||
AZStd::string_view UnquoteArgument(AZStd::string_view arg)
|
||||
{
|
||||
if (arg.size() < 2)
|
||||
{
|
||||
return arg;
|
||||
}
|
||||
|
||||
return arg.front() == '"' && arg.back() == '"' ? AZStd::string_view{ arg.begin() + 1, arg.end() - 1 } : arg;
|
||||
}
|
||||
|
||||
AZStd::string QuoteArgument(AZStd::string_view arg)
|
||||
{
|
||||
return !arg.empty() ? AZStd::string::format(R"("%.*s")", aznumeric_cast<int>(arg.size()), arg.data()) : AZStd::string{ arg };
|
||||
}
|
||||
}
|
||||
|
||||
CommandLine::CommandLine()
|
||||
@@ -41,15 +56,62 @@ namespace AZ
|
||||
{
|
||||
}
|
||||
|
||||
void CommandLine::AddArgument(AZStd::string currentArg, AZStd::string& currentSwitch)
|
||||
void CommandLine::ParseOptionArgument(AZStd::string_view newOption, AZStd::string_view newValue,
|
||||
CommandArgument* inProgressArgument)
|
||||
{
|
||||
StringFunc::Strip(currentArg, " ", false, true, true);
|
||||
// Allow argument values wrapped in quotes at both ends to become the value within the quotes
|
||||
AZStd::string_view unquotedValue = UnquoteArgument(newValue);
|
||||
if (unquotedValue != newValue)
|
||||
{
|
||||
// Update the inProgressArgument before adding new arguments
|
||||
if(inProgressArgument)
|
||||
{
|
||||
inProgressArgument->m_value = unquotedValue;
|
||||
// Set the inProgressArgument to nullptr to indicate that the inProgressArgument has been fulfilled
|
||||
inProgressArgument = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_allValues.push_back({ newOption, unquotedValue });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZStd::vector<AZStd::string_view> tokens;
|
||||
auto splitArgument = [&tokens](AZStd::string_view token)
|
||||
{
|
||||
tokens.emplace_back(AZ::StringFunc::StripEnds(token));
|
||||
};
|
||||
AZ::StringFunc::TokenizeVisitor(newValue, splitArgument, ",;");
|
||||
|
||||
// we do it this way because you are allowed to do odd things like
|
||||
// -root=abc -root=hij,klm -root whee -root fun;days
|
||||
// and roots value should be { abc, hij, klm, whee, fun, days }
|
||||
for (AZStd::string_view optionValue : tokens)
|
||||
{
|
||||
if (inProgressArgument)
|
||||
{
|
||||
inProgressArgument->m_value = optionValue;
|
||||
// Set the inProgressArgument to nullptr to indicate that the inProgressArgument has been fulfilled
|
||||
inProgressArgument = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_allValues.push_back({ newOption, optionValue });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLine::AddArgument(AZStd::string_view currentArg, AZStd::string& currentSwitch)
|
||||
{
|
||||
currentArg = AZ::StringFunc::StripEnds(currentArg);
|
||||
if (!currentArg.empty())
|
||||
{
|
||||
if (AZStd::string_view(currentArg.begin(), currentArg.begin() + 1).find_first_of(m_commandLineOptionPrefix) != AZStd::string_view::npos)
|
||||
if (m_commandLineOptionPrefix.contains(currentArg.front()))
|
||||
{
|
||||
// its possible that its a key-value-pair like /blah=whatever
|
||||
// we support this too, for compatibilty.
|
||||
// its possible that its a key-value-pair like -blah=whatever
|
||||
// we support this too, for compatibility.
|
||||
|
||||
currentArg = currentArg.substr(1);
|
||||
if (currentArg[0] == '-') // for -- extra
|
||||
@@ -57,93 +119,41 @@ namespace AZ
|
||||
currentArg = currentArg.substr(1);
|
||||
}
|
||||
|
||||
AZStd::size_t foundPos = StringFunc::Find(currentArg.c_str(), '=');
|
||||
AZStd::size_t foundPos = AZ::StringFunc::Find(currentArg, "=");
|
||||
if (foundPos != AZStd::string::npos)
|
||||
{
|
||||
// Allow argument values wrapped in quotes at both ends to become the value within the quotes
|
||||
if (currentArg.length() > (foundPos + 2) && currentArg[foundPos + 1] == '"' && currentArg[currentArg.length() - 1] == '"')
|
||||
{
|
||||
AZStd::string argName = currentArg.substr(0, foundPos);
|
||||
argName = ToLower(argName);
|
||||
StringFunc::Strip(argName, " ", false, true, true);
|
||||
m_switches[argName].emplace_back(currentArg.substr(foundPos + 2, currentArg.length() - (foundPos + 2) - 1));
|
||||
currentSwitch.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// its in '=' format
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
StringFunc::Tokenize(currentArg.substr(foundPos + 1).c_str(), tokens, ",;");
|
||||
currentArg.resize(foundPos);
|
||||
currentArg = ToLower(currentArg);
|
||||
StringFunc::Strip(currentArg, " ", false, true, true);
|
||||
m_switches.insert_key(currentArg); // returns pair<iter, bool>
|
||||
// we do it this way because you are allowed to do odd things like
|
||||
// /root=abc /root=hij,klm /root whee /root fun;days
|
||||
// and roots value should be { abc, hij, klm, whee, fun, days }
|
||||
for (AZStd::string& switchValue : tokens)
|
||||
{
|
||||
StringFunc::Strip(switchValue, " ", false, true, true);
|
||||
m_switches[currentArg].push_back(switchValue);
|
||||
}
|
||||
AZStd::string_view argumentView{ currentArg };
|
||||
AZStd::string_view option = AZ::StringFunc::StripEnds(argumentView.substr(0, foundPos));
|
||||
AZStd::string_view value = AZ::StringFunc::StripEnds(argumentView.substr(foundPos + 1));
|
||||
ParseOptionArgument(ToLower(option), value, nullptr);
|
||||
currentSwitch.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// its in this format /switchName switchvalue
|
||||
// its in this format -switchName switchvalue
|
||||
// (no equals)
|
||||
currentSwitch = currentArg;
|
||||
currentSwitch = ToLower(currentSwitch);
|
||||
m_switches.insert_key(currentSwitch);
|
||||
currentSwitch = ToLower(currentArg);
|
||||
m_allValues.push_back({ currentSwitch, "" });
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (currentSwitch.empty())
|
||||
{
|
||||
m_miscValues.push_back(currentArg);
|
||||
m_allValues.push_back({ "", UnquoteArgument(currentArg) });
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allow argument values wrapped in quotes at both ends to become the value within the quotes
|
||||
if (currentArg[0] == '"' && currentArg.length() >= 2 && currentArg[currentArg.length() - 1] == '"')
|
||||
{
|
||||
m_switches[currentSwitch].emplace_back(currentArg.substr(1, currentArg.length() - 2));
|
||||
currentSwitch.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::vector<AZStd::string> tokens;
|
||||
StringFunc::Tokenize(currentArg.c_str(), tokens, ",;");
|
||||
for (AZStd::string& switchValue : tokens)
|
||||
{
|
||||
StringFunc::Strip(switchValue, " ", false, true, true);
|
||||
m_switches[currentSwitch].push_back(switchValue);
|
||||
}
|
||||
|
||||
ParseOptionArgument(currentSwitch, currentArg, &m_allValues.back());
|
||||
currentSwitch.clear();
|
||||
}
|
||||
|
||||
currentSwitch.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLine::Parse(const ParamContainer& commandLine)
|
||||
{
|
||||
m_switches.clear();
|
||||
m_miscValues.clear();
|
||||
|
||||
AZStd::string currentSwitch;
|
||||
for (int i = 1; i < commandLine.size(); ++i)
|
||||
{
|
||||
AddArgument(commandLine[i], currentSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLine::Parse(int argc, char** argv)
|
||||
{
|
||||
m_switches.clear();
|
||||
m_miscValues.clear();
|
||||
m_allValues.clear();
|
||||
|
||||
AZStd::string currentSwitch;
|
||||
// Start on 1 because 0 is the executable name
|
||||
@@ -157,91 +167,145 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
void CommandLine::Dump(ParamContainer& commandLineDumpOutput)
|
||||
void CommandLine::Parse(const ParamContainer& commandLine)
|
||||
{
|
||||
// Push back an empty argument as the Parse function always skips parsing the first argument
|
||||
commandLineDumpOutput.emplace_back(AZStd::string());
|
||||
for (const AZStd::string& miscValue : m_miscValues)
|
||||
{
|
||||
commandLineDumpOutput.push_back(miscValue);
|
||||
}
|
||||
m_allValues.clear();
|
||||
|
||||
if (!m_commandLineOptionPrefix.empty())
|
||||
// This version of Parse does not skip over 0th index
|
||||
AZStd::string currentSwitch;
|
||||
for (int i = 0; i < commandLine.size(); ++i)
|
||||
{
|
||||
for (const auto& [switchKey, switchValues] : m_switches)
|
||||
{
|
||||
AZStd::string prefixSwitchKey = m_commandLineOptionPrefix.front() + switchKey;
|
||||
if (switchValues.empty())
|
||||
{
|
||||
// There are no value for the switch so just push it back of the command line dump output
|
||||
commandLineDumpOutput.emplace_back(prefixSwitchKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& switchValue : switchValues)
|
||||
{
|
||||
commandLineDumpOutput.emplace_back(prefixSwitchKey);
|
||||
commandLineDumpOutput.emplace_back(switchValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
AddArgument(commandLine[i], currentSwitch);
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
void CommandLine::Dump(ParamContainer& commandLineDumpOutput) const
|
||||
{
|
||||
AZ_Error("CommandLine", !m_commandLineOptionPrefix.empty(),
|
||||
"Cannot dump command line switches from a command line with an empty option prefix");
|
||||
|
||||
for (const CommandArgument& argument : m_allValues)
|
||||
{
|
||||
AZ_Error("CommandLine", false, "Cannot dump command line switches from a command line with an empty option prefix");
|
||||
if (!argument.m_option.empty())
|
||||
{
|
||||
commandLineDumpOutput.emplace_back(m_commandLineOptionPrefix.front() + argument.m_option);
|
||||
}
|
||||
if (!argument.m_value.empty())
|
||||
{
|
||||
commandLineDumpOutput.emplace_back(QuoteArgument(argument.m_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CommandLine::HasSwitch(AZStd::string_view switchName) const
|
||||
{
|
||||
return m_switches.find(ToLower(switchName)) != m_switches.end();
|
||||
auto commandArgumentIter = AZStd::find_if(m_allValues.begin(), m_allValues.end(),
|
||||
[optionName = ToLower(switchName)](const CommandArgument& argument) { return argument.m_option == optionName; });
|
||||
return commandArgumentIter != m_allValues.end();
|
||||
}
|
||||
|
||||
AZStd::size_t CommandLine::GetNumSwitchValues(AZStd::string_view switchName) const
|
||||
{
|
||||
ParamMap::const_iterator switchFound = m_switches.find(ToLower(switchName));
|
||||
if (switchFound == m_switches.end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return switchFound->second.size();
|
||||
return AZStd::count_if(m_allValues.begin(), m_allValues.end(),
|
||||
[optionName = ToLower(switchName)](const CommandArgument& argument) { return argument.m_option == optionName; });
|
||||
}
|
||||
|
||||
const AZStd::string& CommandLine::GetSwitchValue(AZStd::string_view switchName, AZStd::size_t index) const
|
||||
{
|
||||
ParamMap::const_iterator switchFound = m_switches.find(ToLower(switchName));
|
||||
if (switchFound == m_switches.end())
|
||||
AZStd::string optionName = ToLower(switchName);
|
||||
size_t currentPosIndex{};
|
||||
auto findArgumentAt = [&optionName, index, ¤tPosIndex](const CommandArgument& argument)
|
||||
{
|
||||
if (argument.m_option == optionName)
|
||||
{
|
||||
return currentPosIndex++ == index;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
auto commandArgumentIter = AZStd::find_if(m_allValues.begin(), m_allValues.end(), findArgumentAt);
|
||||
if (!optionName.empty())
|
||||
{
|
||||
AZ_Assert(index < currentPosIndex, R"(Invalid Command line optional argument lookup of "%s" at index %zu)",
|
||||
optionName.c_str(), index);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(index < currentPosIndex, R"(Invalid Command line positional argument lookup at index %zu)", index);
|
||||
}
|
||||
if (commandArgumentIter == m_allValues.end())
|
||||
{
|
||||
return m_emptyValue;
|
||||
}
|
||||
|
||||
AZ_Assert(index < switchFound->second.size(), "Invalid Command line switch lookup");
|
||||
if (index >= switchFound->second.size())
|
||||
{
|
||||
return m_emptyValue;
|
||||
}
|
||||
|
||||
return switchFound->second.at(index);
|
||||
return commandArgumentIter->m_value;
|
||||
}
|
||||
|
||||
AZStd::size_t CommandLine::GetNumMiscValues() const
|
||||
{
|
||||
return m_miscValues.size();
|
||||
return GetNumSwitchValues("");
|
||||
}
|
||||
|
||||
const AZStd::string& CommandLine::GetMiscValue(AZStd::size_t index) const
|
||||
{
|
||||
AZ_Assert(index < m_miscValues.size(), "Invalid Command line lookup");
|
||||
if (index >= m_miscValues.size())
|
||||
{
|
||||
return m_emptyValue;
|
||||
}
|
||||
return m_miscValues[index];
|
||||
// Positional arguments option value is an empty string
|
||||
return GetSwitchValue("", index);
|
||||
}
|
||||
|
||||
const CommandLine::ParamMap& CommandLine::GetSwitchList() const
|
||||
[[nodiscard]] bool CommandLine::empty() const
|
||||
{
|
||||
return m_switches;
|
||||
return m_allValues.empty();
|
||||
}
|
||||
|
||||
auto CommandLine::size() const -> ArgumentVector::size_type
|
||||
{
|
||||
return m_allValues.size();
|
||||
}
|
||||
auto CommandLine::begin() -> ArgumentVector::iterator
|
||||
{
|
||||
return m_allValues.begin();
|
||||
}
|
||||
auto CommandLine::begin() const -> ArgumentVector::const_iterator
|
||||
{
|
||||
return m_allValues.begin();
|
||||
}
|
||||
auto CommandLine::cbegin() const -> ArgumentVector::const_iterator
|
||||
{
|
||||
return m_allValues.cbegin();
|
||||
}
|
||||
auto CommandLine::end() -> ArgumentVector::iterator
|
||||
{
|
||||
return m_allValues.end();
|
||||
}
|
||||
auto CommandLine::end() const -> ArgumentVector::const_iterator
|
||||
{
|
||||
return m_allValues.end();
|
||||
}
|
||||
auto CommandLine::cend() const -> ArgumentVector::const_iterator
|
||||
{
|
||||
return m_allValues.cend();
|
||||
}
|
||||
auto CommandLine::rbegin() -> ArgumentVector::reverse_iterator
|
||||
{
|
||||
return m_allValues.rbegin();
|
||||
}
|
||||
auto CommandLine::rbegin() const -> ArgumentVector::const_reverse_iterator
|
||||
{
|
||||
return m_allValues.rbegin();
|
||||
}
|
||||
auto CommandLine::crbegin() const -> ArgumentVector::const_reverse_iterator
|
||||
{
|
||||
return m_allValues.crbegin();
|
||||
}
|
||||
auto CommandLine::rend() -> ArgumentVector::reverse_iterator
|
||||
{
|
||||
return m_allValues.rend();
|
||||
}
|
||||
auto CommandLine::rend() const -> ArgumentVector::const_reverse_iterator
|
||||
{
|
||||
return m_allValues.rend();
|
||||
}
|
||||
auto CommandLine::crend() const -> ArgumentVector::const_reverse_iterator
|
||||
{
|
||||
return m_allValues.crend();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,36 +36,47 @@ namespace AZ
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(CommandLine, AZ::SystemAllocator, 0);
|
||||
|
||||
using ParamContainer = AZStd::vector<AZStd::string>;
|
||||
|
||||
struct CommandArgument
|
||||
{
|
||||
AZStd::string m_option;
|
||||
AZStd::string m_value;
|
||||
};
|
||||
using ArgumentVector = AZStd::vector<CommandArgument>;
|
||||
|
||||
CommandLine();
|
||||
|
||||
/**
|
||||
* Initializes a CommandLine instance which uses the provided commandLineOptionPreix for parsing switches
|
||||
*/
|
||||
CommandLine(AZStd::string_view commandLineOptionPrefix);
|
||||
|
||||
using ParamContainer = AZStd::vector<AZStd::string>;
|
||||
using ParamMap = AZStd::unordered_map<AZStd::string, ParamContainer>;
|
||||
/**
|
||||
* Construct a command line parser.
|
||||
* It will load parameters from the given ARGC/ARGV parameters instead of process command line.
|
||||
* Skips over the first parameter as it assumes it is the executable name
|
||||
*/
|
||||
void Parse(int argc, char** argv);
|
||||
/**
|
||||
* Parses each element of the command line as parameter.
|
||||
* Unlike the ARGC/ARGV version above, this function doesn't skip over the first parameter
|
||||
* It allows for round trip conversion with the Dump() method
|
||||
*/
|
||||
void Parse(const ParamContainer& commandLine);
|
||||
|
||||
/**
|
||||
* Will dump command line parameters from the CommandLine in a format such that switches
|
||||
* are prefixed with the option prefix followed by their value(s) which are comma separated
|
||||
* The result of this function can be supplied to Parse() to re-create an eqiuvlanet command line obect
|
||||
* The result of this function can be supplied to Parse() to re-create an equivalent command line object
|
||||
* Ex, If the command line has the current list of parsed miscellaneous values and switches of
|
||||
* MiscValue = ["Foo", "Bat"]
|
||||
* Switches = ["GameFolder" : [], "RemoteIp" : ["10.0.0.1"], "ScanFolders" : ["\a\b\c", "\d\e\f"]
|
||||
* CommandLineOptionPrefix = "-/"
|
||||
*
|
||||
* Then the resulting dumped value would be
|
||||
* Dump = ["", "Foo", "Bat", "-GameFolder", "-RemoteIp", "10.0.0.1", "-ScanFolders", "\a\b\c", "-ScanFolders", "\d\e\f"]
|
||||
* NOTE: The first parameter is always empty string as the Parse function skips over it
|
||||
* Dump = ["Foo", "Bat", "-GameFolder", "-RemoteIp", "10.0.0.1", "-ScanFolders", "\a\b\c", "-ScanFolders", "\d\e\f"]
|
||||
*/
|
||||
void Dump(ParamContainer& commandLineDumpOutput);
|
||||
void Dump(ParamContainer& commandLineDumpOutput) const;
|
||||
|
||||
/**
|
||||
* Determines whether a switch is present in the command line
|
||||
@@ -97,16 +108,28 @@ namespace AZ
|
||||
*/
|
||||
const AZStd::string& GetMiscValue(AZStd::size_t index) const;
|
||||
|
||||
/*
|
||||
* Return the list of parsed switches
|
||||
*/
|
||||
const ParamMap& GetSwitchList() const;
|
||||
|
||||
// Range accessors
|
||||
[[nodiscard]] bool empty() const;
|
||||
auto size() const -> ArgumentVector::size_type;
|
||||
auto begin() -> ArgumentVector::iterator;
|
||||
auto begin() const -> ArgumentVector::const_iterator;
|
||||
auto cbegin() const -> ArgumentVector::const_iterator;
|
||||
auto end() -> ArgumentVector::iterator;
|
||||
auto end() const -> ArgumentVector::const_iterator;
|
||||
auto cend() const -> ArgumentVector::const_iterator;
|
||||
auto rbegin() -> ArgumentVector::reverse_iterator;
|
||||
auto rbegin() const -> ArgumentVector::const_reverse_iterator;
|
||||
auto crbegin() const -> ArgumentVector::const_reverse_iterator;
|
||||
auto rend() -> ArgumentVector::reverse_iterator;
|
||||
auto rend() const -> ArgumentVector::const_reverse_iterator;
|
||||
auto crend() const -> ArgumentVector::const_reverse_iterator;
|
||||
|
||||
private:
|
||||
void AddArgument(AZStd::string currentArg, AZStd::string& currentSwitch);
|
||||
void AddArgument(AZStd::string_view currentArg, AZStd::string& currentSwitch);
|
||||
void ParseOptionArgument(AZStd::string_view newOption, AZStd::string_view newValue, CommandArgument* inProgressArgument);
|
||||
|
||||
ParamMap m_switches;
|
||||
ParamContainer m_miscValues;
|
||||
ArgumentVector m_allValues;
|
||||
AZStd::string m_emptyValue;
|
||||
|
||||
inline static constexpr size_t MaxCommandOptionPrefixes = 8;
|
||||
|
||||
@@ -173,7 +173,15 @@ namespace AZ
|
||||
path.remove_prefix(1); // Remove the leading slash as the StackedString will add this back in.
|
||||
jsonPath.Push(path);
|
||||
}
|
||||
Visit(visitor, jsonPath, "", *value);
|
||||
// Extract the last token of the JSON pointer to use as the valueName
|
||||
AZStd::string_view valueName;
|
||||
size_t pointerTokenCount = pointer.GetTokenCount();
|
||||
if (pointerTokenCount > 0)
|
||||
{
|
||||
const rapidjson::Pointer::Token& lastToken = pointer.GetTokens()[pointerTokenCount - 1];
|
||||
valueName = AZStd::string_view(lastToken.name, lastToken.length);
|
||||
}
|
||||
Visit(visitor, jsonPath, valueName, *value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,68 +41,197 @@ namespace AZ::Internal
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString GetEngineMonikerForProject(
|
||||
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectPath)
|
||||
{
|
||||
// projectPath needs to be an absolute path here.
|
||||
using namespace AZ::SettingsRegistryMergeUtils;
|
||||
bool projectJsonMerged = false;
|
||||
auto projectJsonPath = projectPath / "project.json";
|
||||
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
|
||||
{
|
||||
projectJsonMerged = settingsRegistry.MergeSettingsFile(
|
||||
projectJsonPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ProjectSettingsRootKey);
|
||||
}
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString engineMoniker;
|
||||
if (projectJsonMerged)
|
||||
{
|
||||
// In project.json look for the "engine" key.
|
||||
auto engineMonikerKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engine", ProjectSettingsRootKey);
|
||||
settingsRegistry.Get(engineMoniker, engineMonikerKey);
|
||||
}
|
||||
|
||||
return engineMoniker;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath ReconcileEngineRootFromProjectPath(SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectPath)
|
||||
{
|
||||
// Find the engine root via the engine manifest file and project.json
|
||||
// Locate the engine manifest file and merge it to settings registry.
|
||||
// Visit over the engine paths list and merge the engine.json files to settings registry.
|
||||
// Merge project.json to settings registry. That will give us an "engine" key.
|
||||
// When we find a match for "engine_name" value against the "engine" value from before, we can stop and use that engine root.
|
||||
// Finally set the BootstrapSettingsRootKey/engine_path setting so that subsequent calls to GetEngineRoot will use that
|
||||
// and avoid all this logic.
|
||||
|
||||
using namespace AZ::SettingsRegistryMergeUtils;
|
||||
|
||||
AZ::IO::FixedMaxPath engineRoot;
|
||||
if (auto engineManifestPath = AZ::Utils::GetEngineManifestPath(); !engineManifestPath.empty())
|
||||
{
|
||||
bool manifestLoaded{false};
|
||||
|
||||
if (AZ::IO::SystemFile::Exists(engineManifestPath.c_str()))
|
||||
{
|
||||
manifestLoaded = settingsRegistry.MergeSettingsFile(
|
||||
engineManifestPath, AZ::SettingsRegistryInterface::Format::JsonMergePatch, EngineManifestRootKey);
|
||||
}
|
||||
|
||||
struct EngineInfo
|
||||
{
|
||||
AZ::IO::FixedMaxPath m_path;
|
||||
AZ::SettingsRegistryInterface::FixedValueString m_moniker;
|
||||
};
|
||||
|
||||
struct EnginePathsVisitor : public AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
void Visit(
|
||||
[[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZStd::string_view valueName,
|
||||
[[maybe_unused]] AZ::SettingsRegistryInterface::Type type, AZStd::string_view value) override
|
||||
{
|
||||
m_enginePaths.emplace_back(EngineInfo{AZ::IO::FixedMaxPath{value}.LexicallyNormal(), {}});
|
||||
}
|
||||
|
||||
AZStd::vector<EngineInfo> m_enginePaths{};
|
||||
};
|
||||
|
||||
EnginePathsVisitor pathVisitor;
|
||||
if (manifestLoaded)
|
||||
{
|
||||
auto enginePathsKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engines", EngineManifestRootKey);
|
||||
settingsRegistry.Visit(pathVisitor, enginePathsKey);
|
||||
}
|
||||
|
||||
const auto engineMonikerKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engine_name", EngineSettingsRootKey);
|
||||
|
||||
for (EngineInfo& engineInfo : pathVisitor.m_enginePaths)
|
||||
{
|
||||
AZ::IO::FixedMaxPath engineSettingsPath{engineInfo.m_path};
|
||||
engineSettingsPath /= "engine.json";
|
||||
|
||||
if (AZ::IO::SystemFile::Exists(engineSettingsPath.c_str()))
|
||||
{
|
||||
if (settingsRegistry.MergeSettingsFile(
|
||||
engineSettingsPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, EngineSettingsRootKey))
|
||||
{
|
||||
settingsRegistry.Get(engineInfo.m_moniker, engineMonikerKey);
|
||||
}
|
||||
}
|
||||
|
||||
auto engineMoniker = Internal::GetEngineMonikerForProject(settingsRegistry, engineInfo.m_path / projectPath);
|
||||
if (!engineMoniker.empty() && engineMoniker == engineInfo.m_moniker)
|
||||
{
|
||||
engineRoot = engineInfo.m_path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return engineRoot;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath ScanUpRootLocator(AZStd::string_view rootFileToLocate)
|
||||
{
|
||||
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> executableDir;
|
||||
if (Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity()) == Utils::ExecutablePathResult::Success)
|
||||
{
|
||||
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string
|
||||
// stored within it
|
||||
executableDir.resize_no_construct(AZStd::char_traits<char>::length(executableDir.data()));
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath engineRootCandidate{ executableDir };
|
||||
|
||||
bool rootPathVisited = false;
|
||||
do
|
||||
{
|
||||
if (AZ::IO::SystemFile::Exists((engineRootCandidate / rootFileToLocate).c_str()))
|
||||
{
|
||||
return engineRootCandidate;
|
||||
}
|
||||
|
||||
// Note for posix filesystems the parent directory of '/' is '/' and for windows
|
||||
// the parent directory of 'C:\\' is 'C:\\'
|
||||
|
||||
// Validate that the parent directory isn't itself, that would imply
|
||||
// that it is the filesystem root path
|
||||
AZ::IO::PathView parentPath = engineRootCandidate.ParentPath();
|
||||
rootPathVisited = (engineRootCandidate == parentPath);
|
||||
// Recurse upwards one directory
|
||||
engineRootCandidate = AZStd::move(parentPath);
|
||||
|
||||
} while (!rootPathVisited);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace AZ::Internal
|
||||
|
||||
namespace AZ::SettingsRegistryMergeUtils
|
||||
{
|
||||
AZ::IO::FixedMaxPath GetAppRoot(SettingsRegistryInterface* settingsRegistry)
|
||||
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry)
|
||||
{
|
||||
constexpr size_t MaxAppRootPathsToScan = 16;
|
||||
AZStd::fixed_vector<AZStd::string_view, MaxAppRootPathsToScan> appRootScanPaths;
|
||||
AZ::IO::FixedMaxPath engineRoot;
|
||||
|
||||
// Check the commandLine for --app-root parameter
|
||||
// If it exist use that instead
|
||||
auto appRootOverrideKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/app-root", AZ::SettingsRegistryMergeUtils::CommandLineSwitchRootKey);
|
||||
if (settingsRegistry)
|
||||
// This is the 'external' engine root key, as in passed from command-line or .setreg files.
|
||||
auto engineRootKey = SettingsRegistryInterface::FixedValueString::format("%s/engine_path", BootstrapSettingsRootKey);
|
||||
if (settingsRegistry.Get(engineRoot.Native(), engineRootKey); !engineRoot.empty())
|
||||
{
|
||||
AZ::IO::FixedMaxPath appRootOverridePath;
|
||||
if (settingsRegistry->Get(appRootOverridePath.Native(), appRootOverrideKey))
|
||||
{
|
||||
return appRootOverridePath;
|
||||
}
|
||||
return engineRoot;
|
||||
}
|
||||
|
||||
AZStd::optional<AZStd::fixed_string<AZ::IO::MaxPathLength>> appRootPath = Utils::GetDefaultAppRootPath();
|
||||
if (appRootPath.has_value())
|
||||
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
|
||||
if (engineRoot = Internal::ScanUpRootLocator("engine.json"); !engineRoot.empty())
|
||||
{
|
||||
appRootScanPaths.push_back(*appRootPath);
|
||||
settingsRegistry.Set(engineRootKey, engineRoot.c_str());
|
||||
return engineRoot;
|
||||
}
|
||||
AZStd::fixed_string<AZ::IO::MaxPathLength> executableDir;
|
||||
AZ::Utils::ExecutablePathResult pathResult = Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity());
|
||||
if (pathResult == Utils::ExecutablePathResult::Success)
|
||||
|
||||
AZ::IO::FixedMaxPath projectRoot = FindProjectRoot(settingsRegistry);
|
||||
if (projectRoot.empty())
|
||||
{
|
||||
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string stored within it
|
||||
executableDir.resize_no_construct(AZStd::char_traits<char>::length(executableDir.data()));
|
||||
if (auto foundIt = AZStd::find(appRootScanPaths.begin(), appRootScanPaths.end(), executableDir);
|
||||
foundIt == appRootScanPaths.end())
|
||||
{
|
||||
appRootScanPaths.push_back(executableDir);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
for (AZStd::string_view appRootScanPath : appRootScanPaths)
|
||||
|
||||
// Use the project.json and engine manifest to locate the engine root.
|
||||
if (engineRoot = Internal::ReconcileEngineRootFromProjectPath(settingsRegistry, projectRoot); !engineRoot.empty())
|
||||
{
|
||||
AZ::IO::FixedMaxPath appRootCandidate{ appRootScanPath };
|
||||
|
||||
// Search for the application root
|
||||
bool rootPathVisited = false;
|
||||
do
|
||||
{
|
||||
if (AZ::IO::SystemFile::Exists((appRootCandidate / "bootstrap.cfg").c_str()))
|
||||
{
|
||||
return appRootCandidate;
|
||||
}
|
||||
|
||||
// Validate that the parent directory isn't itself, that would imply
|
||||
// that it is the root path
|
||||
AZ::IO::PathView parentPath = appRootCandidate.ParentPath();
|
||||
rootPathVisited = appRootCandidate == parentPath;
|
||||
// Recurse upwards one directory
|
||||
appRootCandidate = AZStd::move(parentPath);
|
||||
|
||||
} while (!rootPathVisited);
|
||||
// Note for posix filesystems the parent directory of '/' is '/' and for windows
|
||||
// the parent directory of 'C:\\' is 'C:\\'
|
||||
settingsRegistry.Set(engineRootKey, engineRoot.c_str());
|
||||
return engineRoot;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry)
|
||||
{
|
||||
AZ::IO::FixedMaxPath projectRoot;
|
||||
// This is the 'external' project root key, as in passed from command-line or .setreg files.
|
||||
auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
|
||||
{
|
||||
return projectRoot;
|
||||
}
|
||||
|
||||
if (projectRoot = Internal::ScanUpRootLocator("project.json"); !projectRoot.empty())
|
||||
{
|
||||
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
|
||||
return projectRoot;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -111,9 +240,9 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
constexpr AZStd::string_view commentPrefixes = ";#";
|
||||
for (char commentPrefix : commentPrefixes)
|
||||
{
|
||||
if (line.starts_with(commentPrefix))
|
||||
if (size_t commentOffset = line.find(commentPrefix); commentOffset != AZStd::string_view::npos)
|
||||
{
|
||||
return {};
|
||||
return line.substr(0, commentOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +252,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
AZStd::string_view ConfigParserSettings::DefaultSectionHeaderFilter(AZStd::string_view line)
|
||||
{
|
||||
AZStd::string_view sectionName;
|
||||
constexpr char sectionHeaderStart= '[';
|
||||
constexpr char sectionHeaderStart = '[';
|
||||
constexpr char sectionHeaderEnd = ']';
|
||||
if (line.starts_with(sectionHeaderStart) && line.ends_with(sectionHeaderEnd))
|
||||
{
|
||||
@@ -184,7 +313,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
|
||||
void QuerySpecializationsFromRegistry(SettingsRegistryInterface& registry, SettingsRegistryInterface::Specializations& specializations)
|
||||
{
|
||||
// Append any specializations stored in the registry
|
||||
// Append any specializations stored in the registry
|
||||
struct SpecializationsVisitor
|
||||
: AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
@@ -222,7 +351,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
bool MergeSettingsToRegistry_ConfigFile(SettingsRegistryInterface& registry, AZStd::string_view filePath,
|
||||
const ConfigParserSettings& configParserSettings)
|
||||
{
|
||||
auto configPath = GetAppRoot(®istry) / filePath;
|
||||
auto configPath = FindEngineRoot(registry) / filePath;
|
||||
IO::SystemFile configFile;
|
||||
if (!configFile.Open(configPath.c_str(), IO::SystemFile::OpenMode::SF_OPEN_READ_ONLY))
|
||||
{
|
||||
@@ -348,9 +477,13 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
ConfigParserSettings parserSettings;
|
||||
parserSettings.m_commentPrefixFunc = [](AZStd::string_view line) -> AZStd::string_view
|
||||
{
|
||||
if (line.starts_with("--") || line.starts_with(';') || line.starts_with('#'))
|
||||
constexpr AZStd::string_view commentPrefixes[]{ "--", ";","#" };
|
||||
for (AZStd::string_view commentPrefix : commentPrefixes)
|
||||
{
|
||||
return {};
|
||||
if (size_t commentOffset = line.find(commentPrefix); commentOffset != AZStd::string_view::npos)
|
||||
{
|
||||
return line.substr(0, commentOffset);
|
||||
}
|
||||
}
|
||||
return line;
|
||||
};
|
||||
@@ -365,71 +498,104 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
registry.Set(FilePathKey_BinaryFolder, path.LexicallyNormal().Native());
|
||||
|
||||
// Engine root folder - corresponds to the @engroot@ and @devroot@ aliases
|
||||
AZ::IO::FixedMaxPath appRoot = GetAppRoot(®istry);
|
||||
registry.Set(FilePathKey_EngineRootFolder, appRoot.LexicallyNormal().Native());
|
||||
AZ::IO::FixedMaxPath engineRoot = FindEngineRoot(registry);
|
||||
registry.Set(FilePathKey_EngineRootFolder, engineRoot.LexicallyNormal().Native());
|
||||
|
||||
constexpr size_t bufferSize = 64;
|
||||
auto buffer = AZStd::fixed_string<bufferSize>::format("%s/sys_game_folder", BootstrapSettingsRootKey);
|
||||
auto buffer = AZStd::fixed_string<bufferSize>::format("%s/project_path", BootstrapSettingsRootKey);
|
||||
|
||||
AZStd::string_view projectPath(buffer);
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectPathKey(buffer);
|
||||
SettingsRegistryInterface::FixedValueString projectPathValue;
|
||||
if (registry.Get(projectPathValue, projectPath))
|
||||
if (registry.Get(projectPathValue, projectPathKey))
|
||||
{
|
||||
// Cache folder
|
||||
// Get the name of the asset platform assigned by the bootstrap. First check for platform version such as "windows_assets"
|
||||
// and if that's missing just get "asset".
|
||||
// and if that's missing just get "assets".
|
||||
constexpr char platformName[] = AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER;
|
||||
|
||||
SettingsRegistryInterface::FixedValueString assetPlatform;
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/%s_assets", BootstrapSettingsRootKey, platformName);
|
||||
AZStd::string_view assetPlatformatPath(buffer);
|
||||
if (!registry.Get(assetPlatform, assetPlatformatPath))
|
||||
AZStd::string_view assetPlatformKey(buffer);
|
||||
if (!registry.Get(assetPlatform, assetPlatformKey))
|
||||
{
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/assets", BootstrapSettingsRootKey);
|
||||
assetPlatformatPath = AZStd::string_view(buffer);
|
||||
if (!registry.Get(assetPlatform, assetPlatformatPath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
assetPlatformKey = AZStd::string_view(buffer);
|
||||
registry.Get(assetPlatform, assetPlatformKey);
|
||||
}
|
||||
|
||||
// Source game folder - corresponds to the @devassets@ alias
|
||||
path = appRoot / projectPathValue;
|
||||
// Project path - corresponds to the @devassets@ alias
|
||||
// NOTE: Here we append to engineRoot, but if projectPathValue is absolute then engineRoot is discarded.
|
||||
path = engineRoot / projectPathValue;
|
||||
|
||||
AZ_Warning("SettingsRegistryMergeUtils", AZ::IO::SystemFile::Exists(path.c_str()),
|
||||
R"(Project Path "%s" does not exist. Is the "sys_game_folder" entry set to valid project folder?)"
|
||||
, path.c_str());
|
||||
registry.Set(FilePathKey_SourceGameFolder, path.LexicallyNormal().Native());
|
||||
R"(Project path "%s" does not exist. Is the "%.*s" registry setting set to valid absolute path?)"
|
||||
, path.c_str(), aznumeric_cast<int>(projectPathKey.size()), projectPathKey.data());
|
||||
|
||||
// Source game name - The filename of the project directory and the name of the project
|
||||
registry.Set(FilePathKey_SourceGameName, path.Filename().Native());
|
||||
AZ::IO::FixedMaxPath normalizedProjectPath = path.LexicallyNormal();
|
||||
registry.Set(FilePathKey_ProjectPath, normalizedProjectPath.Native());
|
||||
|
||||
// Cache root folder - corresponds to the @root@ alias
|
||||
#if AZ_TRAIT_USE_ASSET_CACHE_FOLDER
|
||||
path = appRoot / "Cache" / projectPathValue / assetPlatform;
|
||||
#else
|
||||
// Use the Engine Root/App Root as the Asset root directory in this case
|
||||
path = appRoot;
|
||||
#endif
|
||||
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
|
||||
|
||||
// check for a default write storage path, fall back to the cache root if not
|
||||
// Add an alias to the project "user" directory
|
||||
AZ::IO::FixedMaxPath projectUserPath = (normalizedProjectPath / "user").LexicallyNormal();
|
||||
registry.Set(FilePathKey_ProjectUserPath, projectUserPath.Native());
|
||||
// check for a default write storage path, fall back to the project's user/ directory if not
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> devWriteStorage = Utils::GetDevWriteStoragePath();
|
||||
registry.Set(FilePathKey_DevWriteStorage,
|
||||
devWriteStorage.has_value() ?
|
||||
devWriteStorage.value() :
|
||||
path.LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_DevWriteStorage, devWriteStorage.has_value()
|
||||
? devWriteStorage.value()
|
||||
: projectUserPath.Native());
|
||||
|
||||
// Cache game folder - corresponds to the @assets@ alias
|
||||
AZStd::to_lower(projectPathValue.begin(), projectPathValue.end());
|
||||
path /= projectPathValue;
|
||||
registry.Set(FilePathKey_CacheGameFolder, path.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)
|
||||
+ "/project_name";
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectName;
|
||||
if (!registry.Get(projectName, projectNameKey))
|
||||
{
|
||||
projectName = path.Filename().Native();
|
||||
registry.Set(projectNameKey, projectName);
|
||||
}
|
||||
|
||||
// Cache folders - sets up various paths in registry for the cache.
|
||||
// Make sure the asset platform is set before setting these cache paths.
|
||||
if (!assetPlatform.empty())
|
||||
{
|
||||
// Cache: project root - no corresponding fileIO alias, but this is where the asset database lives.
|
||||
// A registry override is accepted using the "project_cache_path" key.
|
||||
buffer = AZStd::fixed_string<bufferSize>::format("%s/project_cache_path", BootstrapSettingsRootKey);
|
||||
AZStd::string_view projectCacheRootOverrideKey(buffer);
|
||||
// Clear path to make sure that the `project_cache_path` value isn't concatenated to the project path
|
||||
path.clear();
|
||||
if (registry.Get(path.Native(), projectCacheRootOverrideKey))
|
||||
{
|
||||
registry.Set(FilePathKey_CacheProjectRootFolder, path.LexicallyNormal().Native());
|
||||
path /= assetPlatform;
|
||||
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cache: root - same as the @root@ alias, this is the starting path for cache files.
|
||||
path = normalizedProjectPath / "Cache";
|
||||
registry.Set(FilePathKey_CacheProjectRootFolder, path.LexicallyNormal().Native());
|
||||
path /= assetPlatform;
|
||||
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_TracePrintf("SettingsRegistryMergeUtils",
|
||||
R"(Current Project game folder "%.*s" isn't set in the Settings Registry. Project-related filepaths will not be set)" "\n",
|
||||
aznumeric_cast<int>(projectPath.size()), projectPath.data());
|
||||
R"(Project path isn't set in the Settings Registry at "%.*s". Project-related filepaths will not be set)" "\n",
|
||||
aznumeric_cast<int>(projectPathKey.size()), projectPathKey.data());
|
||||
}
|
||||
|
||||
#if !AZ_TRAIT_USE_ASSET_CACHE_FOLDER
|
||||
// Setup the cache and user paths for Platforms where the Asset Cache Folder isn't used
|
||||
path = engineRoot;
|
||||
registry.Set(FilePathKey_CacheProjectRootFolder, path.LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_CacheRootFolder, path.LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_DevWriteStorage, path.LexicallyNormal().Native());
|
||||
registry.Set(FilePathKey_ProjectUserPath, (path / "user").LexicallyNormal().Native());
|
||||
#endif // AZ_TRAIT_USE_ASSET_CACHE_FOLDER
|
||||
}
|
||||
|
||||
void MergeSettingsToRegistry_TargetBuildDependencyRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
@@ -535,7 +701,7 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString sourceGamePath;
|
||||
if (registry.Get(sourceGamePath, FilePathKey_SourceGameFolder))
|
||||
if (registry.Get(sourceGamePath, FilePathKey_ProjectPath))
|
||||
{
|
||||
AZ::IO::FixedMaxPath mergePath{ sourceGamePath };
|
||||
mergePath /= SettingsRegistryInterface::RegistryFolder;
|
||||
@@ -543,26 +709,41 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
}
|
||||
|
||||
void MergeSettingsToRegistry_DevRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
void MergeSettingsToRegistry_UserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer)
|
||||
{
|
||||
// Unlike other paths, the path can't be overwritten by the dev settings because that would create a circular dependency.
|
||||
auto mergePath = GetAppRoot(®istry);
|
||||
mergePath /= SettingsRegistryInterface::DevUserRegistryFolder;
|
||||
registry.MergeSettingsFolder(mergePath.Native(), specializations, platform, "", scratchBuffer);
|
||||
AZ::IO::FixedMaxPath projectUserPath;
|
||||
if (registry.Get(projectUserPath.Native(), FilePathKey_ProjectPath))
|
||||
{
|
||||
projectUserPath /= SettingsRegistryInterface::DevUserRegistryFolder;
|
||||
registry.MergeSettingsFolder(projectUserPath.Native(), specializations, platform, "", scratchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine, bool executeCommands)
|
||||
{
|
||||
const size_t regsetSwitchValues = commandLine.GetNumSwitchValues("regset");
|
||||
for (size_t regsetIndex = 0; regsetIndex < regsetSwitchValues; ++regsetIndex)
|
||||
// Iterate over all the command line options in order to parse the --regset and --regremove
|
||||
// arguments in the order they were supplied
|
||||
for (const CommandLine::CommandArgument& commandArgument : commandLine)
|
||||
{
|
||||
AZStd::string_view regsetValue = commandLine.GetSwitchValue("regset", regsetIndex);
|
||||
if (!registry.MergeCommandLineArgument(regsetValue, AZStd::string_view{}))
|
||||
if (commandArgument.m_option == "regset")
|
||||
{
|
||||
AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to parse argument for --regset with value of %.*s.",
|
||||
aznumeric_cast<int>(regsetValue.size()), regsetValue.data());
|
||||
continue;
|
||||
if (!registry.MergeCommandLineArgument(commandArgument.m_value, AZStd::string_view{}))
|
||||
{
|
||||
AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to parse argument for --regset with value of %s.",
|
||||
commandArgument.m_value.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (commandArgument.m_option == "regremove")
|
||||
{
|
||||
if (!registry.Remove(commandArgument.m_value))
|
||||
{
|
||||
AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to remove value at JSON Pointer %s for --regremove.",
|
||||
commandArgument.m_value.data());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,16 +766,8 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
DumpSettingsRegistryToStream(registry, regdumpValue, outputStream, dumperSettings);
|
||||
}
|
||||
|
||||
const size_t regdumpallSwitchValues = commandLine.GetNumSwitchValues("regdumpall");
|
||||
if (regdumpallSwitchValues > 0)
|
||||
if (commandLine.HasSwitch("regdumpall"))
|
||||
{
|
||||
AZStd::string_view regdumpallValue = commandLine.GetSwitchValue("regdumpall", 0);
|
||||
if (regdumpallValue.empty())
|
||||
{
|
||||
AZ_Warning("SettingsRegistryMergeUtils", false, "Unable to parse argument for --regdumpall with value of %.*s.",
|
||||
aznumeric_cast<int>(regdumpallValue.size()), regdumpallValue.data());
|
||||
}
|
||||
|
||||
DumperSettings dumperSettings{ prettifyOutput };
|
||||
AZ::IO::StdoutStream outputStream;
|
||||
DumpSettingsRegistryToStream(registry, "", outputStream, dumperSettings);
|
||||
@@ -602,85 +775,77 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
}
|
||||
}
|
||||
|
||||
void MergeSettingsToRegistry_StoreCommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine)
|
||||
void StoreCommandLineToRegistry(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine)
|
||||
{
|
||||
// Clear out any existing CommandLine settings
|
||||
registry.Remove(CommandLineRootKey);
|
||||
// Add the positional arguments into the Settings Registry
|
||||
AZ::SettingsRegistryInterface::FixedValueString miscValueKey{ CommandLineMiscValuesRootKey };
|
||||
size_t miscKeyRootSize = miscValueKey.size();
|
||||
for (size_t miscIndex = 0; miscIndex < commandLine.GetNumMiscValues(); ++miscIndex)
|
||||
{
|
||||
// Push an array for each positional entry
|
||||
miscValueKey += AZ::SettingsRegistryInterface::FixedValueString::format("/%zu", miscIndex);
|
||||
registry.Set(miscValueKey, commandLine.GetMiscValue(miscIndex));
|
||||
miscValueKey.resize(miscKeyRootSize);
|
||||
}
|
||||
// Add the option arguments into the SettingsRegistry
|
||||
for (const auto& [commandOption, value] : commandLine.GetSwitchList())
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString switchKey{ CommandLineSwitchRootKey };
|
||||
switchKey += '/';
|
||||
switchKey += commandOption;
|
||||
size_t switchKeyRootSize = switchKey.size();
|
||||
// Associate an empty array with the commandOption by default
|
||||
rapidjson::Document commandSwitchDocument;
|
||||
rapidjson::Pointer pointer(switchKey.c_str(), switchKey.length());
|
||||
pointer.Set(commandSwitchDocument, rapidjson::Value(rapidjson::kArrayType));;
|
||||
rapidjson::StringBuffer documentBuffer;
|
||||
rapidjson::Writer documentWriter(documentBuffer);
|
||||
commandSwitchDocument.Accept(documentWriter);
|
||||
registry.MergeSettings(AZStd::string_view{ documentBuffer.GetString(), documentBuffer.GetSize() },
|
||||
AZ::SettingsRegistryInterface::Format::JsonMergePatch);
|
||||
|
||||
for (size_t switchIndex = 0; switchIndex < value.size(); ++switchIndex)
|
||||
{
|
||||
// Push an array for each positional entry
|
||||
switchKey += AZ::SettingsRegistryInterface::FixedValueString::format("/%zu", switchIndex);
|
||||
registry.Set(switchKey, value[switchIndex]);
|
||||
switchKey.resize(switchKeyRootSize);
|
||||
}
|
||||
AZ::SettingsRegistryInterface::FixedValueString commandLinePath{ CommandLineRootKey };
|
||||
const size_t commandLineRootSize = commandLinePath.size();
|
||||
size_t argumentIndex{};
|
||||
for (const CommandLine::CommandArgument& commandArgument : commandLine)
|
||||
{
|
||||
commandLinePath += AZ::SettingsRegistryInterface::FixedValueString::format("/%zu", argumentIndex);
|
||||
registry.Set(commandLinePath + "/Option", commandArgument.m_option);
|
||||
registry.Set(commandLinePath + "/Value", commandArgument.m_value);
|
||||
++argumentIndex;
|
||||
commandLinePath.resize(commandLineRootSize);
|
||||
}
|
||||
}
|
||||
|
||||
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
|
||||
{
|
||||
struct CommandLineVisitor
|
||||
: AZ::SettingsRegistryInterface::Visitor
|
||||
{
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type
|
||||
, AZStd::string_view value) override
|
||||
{
|
||||
if (valueName == "Option" && !value.empty())
|
||||
{
|
||||
m_arguments.push_back(AZStd::string::format("--%.*s", aznumeric_cast<int>(value.size()), value.data()));
|
||||
}
|
||||
else if (valueName == "Value" && !value.empty())
|
||||
{
|
||||
m_arguments.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
// The first parameter is skipped by the ComamndLine::Parse function so initialize
|
||||
// the container with one empty element
|
||||
AZ::CommandLine::ParamContainer m_arguments{ 1 };
|
||||
};
|
||||
|
||||
CommandLineVisitor commandLineVisitor;
|
||||
if (!registry.Visit(commandLineVisitor, AZ::SettingsRegistryMergeUtils::CommandLineRootKey))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
commandLine.Parse(commandLineVisitor.m_arguments);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DumpSettingsRegistryToStream(SettingsRegistryInterface& registry, AZStd::string_view key,
|
||||
AZ::IO::GenericStream& stream, const DumperSettings& dumperSettings)
|
||||
{
|
||||
struct SettingsExportVisitor
|
||||
: SettingsRegistryInterface::Visitor
|
||||
{
|
||||
using SettingsWriter = AZStd::variant<
|
||||
rapidjson::PrettyWriter<AZ::IO::RapidJSONStreamWriter>,
|
||||
rapidjson::Writer<AZ::IO::RapidJSONStreamWriter>>;
|
||||
SettingsWriter m_writer;
|
||||
AZ::IO::RapidJSONStreamWriter m_rapidJsonStream;
|
||||
DumperSettings m_dumperSettings;
|
||||
AZStd::stack<bool> m_includeNameStack;
|
||||
bool m_includeName{};
|
||||
bool m_result{ true };
|
||||
|
||||
SettingsExportVisitor(AZ::IO::GenericStream& stream, const DumperSettings& dumperSettings)
|
||||
: m_rapidJsonStream{ &stream }
|
||||
, m_dumperSettings{ dumperSettings }
|
||||
, m_writer{ m_stringBuffer }
|
||||
{
|
||||
if (m_dumperSettings.m_prettifyOutput)
|
||||
{
|
||||
m_writer.emplace<rapidjson::PrettyWriter<AZ::IO::RapidJSONStreamWriter>>(m_rapidJsonStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_writer.emplace<rapidjson::Writer<AZ::IO::RapidJSONStreamWriter>>(m_rapidJsonStream);
|
||||
}
|
||||
}
|
||||
void WriteName(AZStd::string_view name)
|
||||
bool WriteName(AZStd::string_view name)
|
||||
{
|
||||
if (m_includeName)
|
||||
// Write the Key if the include name stack the top element is true
|
||||
if (!m_includeNameStack.empty() && m_includeNameStack.top())
|
||||
{
|
||||
AZStd::visit([&name](auto&& writer)
|
||||
{
|
||||
writer.Key(name.data(), aznumeric_caster(name.size()));
|
||||
}, m_writer);
|
||||
return m_writer.Key(name.data(), aznumeric_caster(name.size()), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
AZ::SettingsRegistryInterface::VisitResponse Traverse(
|
||||
AZStd::string_view path, AZStd::string_view valueName, AZ::SettingsRegistryInterface::VisitAction action,
|
||||
@@ -694,60 +859,43 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
|
||||
if (action == AZ::SettingsRegistryInterface::VisitAction::Begin)
|
||||
{
|
||||
AZ_Assert(type == AZ::SettingsRegistryInterface::Type::Object || type == AZ::SettingsRegistryInterface::Type::Array,
|
||||
"Unexpected type visited: %i.", type);
|
||||
WriteName(valueName);
|
||||
m_result = m_result && WriteName(valueName);
|
||||
if (type == AZ::SettingsRegistryInterface::Type::Object)
|
||||
{
|
||||
auto StartObject = [](auto&& writer)
|
||||
m_result = m_result && m_writer.StartObject();
|
||||
if (m_result)
|
||||
{
|
||||
return writer.StartObject();
|
||||
};
|
||||
m_result = m_result && AZStd::visit(StartObject, m_writer);
|
||||
m_includeNameStack.push(true);
|
||||
m_includeName = true;
|
||||
m_includeNameStack.push(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto StartArray = [](auto&& writer)
|
||||
m_result = m_result && m_writer.StartArray();
|
||||
if (m_result)
|
||||
{
|
||||
return writer.StartArray();
|
||||
};
|
||||
m_result = m_result && AZStd::visit(StartArray, m_writer);
|
||||
m_includeNameStack.push(false);
|
||||
m_includeName = false;
|
||||
m_includeNameStack.push(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (action == AZ::SettingsRegistryInterface::VisitAction::End)
|
||||
{
|
||||
if (type == AZ::SettingsRegistryInterface::Type::Object)
|
||||
{
|
||||
auto EndObject = [](auto&& writer)
|
||||
{
|
||||
return writer.EndObject();
|
||||
};
|
||||
m_result = m_result && AZStd::visit(EndObject, m_writer);
|
||||
m_result = m_result && m_writer.EndObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto EndArray = [](auto&& writer)
|
||||
{
|
||||
return writer.EndArray();
|
||||
};
|
||||
m_result = m_result && AZStd::visit(EndArray, m_writer);
|
||||
m_result = m_result && m_writer.EndArray();
|
||||
}
|
||||
AZ_Assert(!m_includeNameStack.empty(), "Attempting to close a json array or object that wasn't started.");
|
||||
m_includeNameStack.pop();
|
||||
m_includeName = !m_includeNameStack.empty() ? m_includeNameStack.top() : true;
|
||||
}
|
||||
else if (type == AZ::SettingsRegistryInterface::Type::Null)
|
||||
else
|
||||
{
|
||||
WriteName(valueName);
|
||||
auto WriteNull = [](auto&& writer)
|
||||
if (type == AZ::SettingsRegistryInterface::Type::Null)
|
||||
{
|
||||
return writer.Null();
|
||||
};
|
||||
m_result = m_result && AZStd::visit(WriteNull, m_writer);
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Null();
|
||||
}
|
||||
}
|
||||
|
||||
return m_result ?
|
||||
@@ -757,42 +905,27 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, bool value)
|
||||
{
|
||||
WriteName(valueName);
|
||||
auto WriteBool = [value](auto&& writer)
|
||||
{
|
||||
return writer.Bool(value);
|
||||
};
|
||||
m_result = m_result && AZStd::visit(WriteBool, m_writer);
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Bool(value);
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, AZ::s64 value)
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, AZ::s64 value) override
|
||||
{
|
||||
WriteName(valueName);
|
||||
auto WriteInt64 = [value](auto&& writer)
|
||||
{
|
||||
return writer.Int64(value);
|
||||
};
|
||||
m_result = m_result && AZStd::visit(WriteInt64, m_writer);
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Int64(value);
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, AZ::u64 value) override
|
||||
{
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Uint64(value);
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, double value)
|
||||
{
|
||||
WriteName(valueName);
|
||||
auto WriteDouble = [value](auto&& writer)
|
||||
{
|
||||
return writer.Double(value);
|
||||
};
|
||||
m_result = m_result && AZStd::visit(WriteDouble, m_writer);
|
||||
m_result = m_result && WriteName(valueName) && m_writer.Double(value);
|
||||
}
|
||||
|
||||
void Visit(AZStd::string_view, AZStd::string_view valueName, AZ::SettingsRegistryInterface::Type, AZStd::string_view value)
|
||||
{
|
||||
WriteName(valueName);
|
||||
auto WriteString = [&value](auto&& writer)
|
||||
{
|
||||
return writer.String(value.data(), aznumeric_caster(value.size()));
|
||||
};
|
||||
m_result = m_result && AZStd::visit(WriteString, m_writer);
|
||||
m_result = m_result && WriteName(valueName) && m_writer.String(value.data(), aznumeric_caster(value.size()));
|
||||
}
|
||||
|
||||
bool Finalize()
|
||||
@@ -802,8 +935,46 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
AZ_Assert(false, "m_includeNameStack is expected to be empty. This means that there was an object or array what wasn't closed.");
|
||||
return false;
|
||||
}
|
||||
return m_result;
|
||||
|
||||
// Root the JSON document underneath the JSON pointer prefix if non-empty
|
||||
// Parse non-anchored JSON data into a document and then re-root
|
||||
// that document under the prefix value
|
||||
rapidjson::Document document;
|
||||
document.Parse(m_stringBuffer.GetString(), m_stringBuffer.GetSize());
|
||||
|
||||
rapidjson::Document rootDocument;
|
||||
AZStd::string_view jsonPrefix{ m_dumperSettings.m_jsonPointerPrefix };
|
||||
if (!jsonPrefix.empty())
|
||||
{
|
||||
rapidjson::Pointer rootPointer(jsonPrefix.data(), jsonPrefix.size());
|
||||
rapidjson::SetValueByPointer(rootDocument, rootPointer, document);
|
||||
}
|
||||
else
|
||||
{
|
||||
rootDocument = AZStd::move(document);
|
||||
}
|
||||
|
||||
if (m_dumperSettings.m_prettifyOutput)
|
||||
{
|
||||
rapidjson::PrettyWriter settingsWriter(m_rapidJsonStream);
|
||||
rootDocument.Accept(settingsWriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
rapidjson::Writer settingsWriter(m_rapidJsonStream);
|
||||
rootDocument.Accept(settingsWriter);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
rapidjson::StringBuffer m_stringBuffer;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> m_writer;
|
||||
|
||||
AZ::IO::RapidJSONStreamWriter m_rapidJsonStream;
|
||||
DumperSettings m_dumperSettings;
|
||||
AZStd::stack<bool> m_includeNameStack;
|
||||
bool m_result{ true };
|
||||
};
|
||||
|
||||
SettingsExportVisitor visitor(stream, dumperSettings);
|
||||
|
||||
@@ -36,27 +36,45 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
inline static constexpr char FilePathsRootKey[] = "/Amazon/AzCore/Runtime/FilePaths";
|
||||
inline static constexpr char FilePathKey_BinaryFolder[] = "/Amazon/AzCore/Runtime/FilePaths/BinaryFolder";
|
||||
inline static constexpr char FilePathKey_EngineRootFolder[] = "/Amazon/AzCore/Runtime/FilePaths/EngineRootFolder";
|
||||
|
||||
//! Stores the absolute path to root of a project's cache. No asset platform in this path, this is where the asset database file lives.
|
||||
//! i.e. <ProjectPath>/Cache
|
||||
inline static constexpr char FilePathKey_CacheProjectRootFolder[] = "/Amazon/AzCore/Runtime/FilePaths/CacheProjectRootFolder";
|
||||
|
||||
//! Stores the absolute path to the cache root for an asset platform. This is the @root@ alias.
|
||||
//! i.e. <ProjectPath>/Cache/<assetplatform>
|
||||
inline static constexpr char FilePathKey_CacheRootFolder[] = "/Amazon/AzCore/Runtime/FilePaths/CacheRootFolder";
|
||||
inline static constexpr char FilePathKey_CacheGameFolder[] = "/Amazon/AzCore/Runtime/FilePaths/CacheGameFolder";
|
||||
inline static constexpr char FilePathKey_SourceGameFolder[] = "/Amazon/AzCore/Runtime/FilePaths/SourceGameFolder";
|
||||
//! Stores the filename of the Game Project Directory which is equivalent to the project name
|
||||
inline static constexpr char FilePathKey_SourceGameName[] = "/Amazon/AzCore/Runtime/FilePaths/SourceGameName";
|
||||
|
||||
//! Stores the absolute path of the Game Project Directory
|
||||
inline static constexpr char FilePathKey_ProjectPath[] = "/Amazon/AzCore/Runtime/FilePaths/SourceProjectPath";
|
||||
|
||||
//! Store the absolute path to the Projects "user" directory, which is a transient directory where per user
|
||||
//! project settings can be stored
|
||||
inline static constexpr char FilePathKey_ProjectUserPath[] = "/Amazon/AzCore/Runtime/FilePaths/SourceProjectUserPath";
|
||||
|
||||
//! 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";
|
||||
|
||||
//! Root key for where command line are stored at witin the settings registry
|
||||
//! Root key for where command line are stored at within the settings registry
|
||||
inline static constexpr char CommandLineRootKey[] = "/Amazon/AzCore/Runtime/CommandLine";
|
||||
//! Root key for command line switches(arguments that start with "-" or "--")
|
||||
inline static constexpr char CommandLineSwitchRootKey[] = "/Amazon/AzCore/Runtime/CommandLine/Switches";
|
||||
//! Root key for command line positional arguments
|
||||
inline static constexpr char CommandLineMiscValuesRootKey[] = "/Amazon/AzCore/Runtime/CommandLine/MiscValues";
|
||||
|
||||
//! Examines the Settings Registry for a "/Amazon/CommandLine/Switches/app-root" key
|
||||
//! to use as an override for the Application Root.
|
||||
//! If that key is not found, it then checks the AZ::Utils::GetDefaultAppRootPath and returns that if it is value
|
||||
//! Root key where raw project settings (project.json) file is merged to settings registry
|
||||
inline static constexpr char ProjectSettingsRootKey[] = "/Amazon/Project/Settings";
|
||||
|
||||
//! Root key where raw engine manifest (o3de_manifest.json) file is merged to settings registry
|
||||
inline static constexpr char EngineManifestRootKey[] = "/Amazon/Engine/Manifest";
|
||||
|
||||
//! Root key where raw engine settings (engine.json) file is merged to settings registry
|
||||
inline static constexpr char EngineSettingsRootKey[] = "/Amazon/Engine/Settings";
|
||||
|
||||
//! Examines the Settings Registry for a "${BootstrapSettingsRootKey}/engine_path" key
|
||||
//! to use as an override for the Engine Root.
|
||||
//! Otherwise a directory walk upwards from the executable directory is performed
|
||||
//! to find the boostrap.cfg file which will be used as the app root
|
||||
AZ::IO::FixedMaxPath GetAppRoot(SettingsRegistryInterface* settingsRegistry = nullptr);
|
||||
//! to find the engine.json file which will be used as the engine root
|
||||
//! If it's still not found, attempt to find the project (by similar means) then reconcile the
|
||||
//! engine root by inspecting project.json and the engine manifest file.
|
||||
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry);
|
||||
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry);
|
||||
|
||||
//! Query the specializations that will be used when loading the Settings Registry.
|
||||
//! The SpecializationsRootKey is visited to retrieve any specializations stored within that section of that registry
|
||||
@@ -151,16 +169,18 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
void MergeSettingsToRegistry_ProjectRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer = nullptr);
|
||||
|
||||
//! Adds the development settings added by individual users to the Settings Registry.
|
||||
//! Adds the development settings added by individual users of the project to the Settings Registry.
|
||||
//! Note that this function is only called in development builds and is compiled out in release builds.
|
||||
void MergeSettingsToRegistry_DevRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
void MergeSettingsToRegistry_UserRegistry(SettingsRegistryInterface& registry, const AZStd::string_view platform,
|
||||
const SettingsRegistryInterface::Specializations& specializations, AZStd::vector<char>* scratchBuffer = nullptr);
|
||||
|
||||
//! Adds the settings set through the command line to the Settings Registry. This will also execute any Settings
|
||||
//! Registry related arguments. Note that --set will be run first and all other commands are run afterwards and only
|
||||
//! if executeCommands is true. The following options are supported:
|
||||
//! Registry related arguments. Note that --regset and -regremove will run in the order in which they are parsed
|
||||
//! --regset <arg> Sets a value in the registry. See MergeCommandLineArgument for options for <arg>
|
||||
//! example: --regset "/My/String/Value=String value set"
|
||||
//! --regremove <arg> Removes a value in the registry
|
||||
//! example: --regremove "/My/String/Value"
|
||||
//! only when executeCommands is true are the following options supported:
|
||||
//! --regdump <path> Dumps the content of the key at path and all it's content/children to output.
|
||||
//! example: --regdump /My/Array/With/Objects
|
||||
//! --regdumpall Dumps the entire settings registry to output.
|
||||
@@ -169,7 +189,11 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
|
||||
//! Stores the command line settings into the Setting Registry
|
||||
//! The arguments can be used later anywhere the command line is needed
|
||||
void MergeSettingsToRegistry_StoreCommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine);
|
||||
void StoreCommandLineToRegistry(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine);
|
||||
|
||||
//! Query the command line settings from the Setting Registry and stores them
|
||||
//! into the AZ::CommandLine instance
|
||||
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine);
|
||||
|
||||
//! Structure for configuring how values should be dumped from the Settings Registry
|
||||
struct DumperSettings
|
||||
@@ -179,14 +203,25 @@ namespace AZ::SettingsRegistryMergeUtils
|
||||
//! Include filter which is used to indicate which paths of the Settings Registry
|
||||
//! should be traversed.
|
||||
//! If the include filter is empty then all paths underneath the JSON pointer path are included
|
||||
//! otherwise the include filter invoked and if it returns true does it proceed with traversal continues down the path
|
||||
//! otherwise the include filter invoked and if it returns true does it proceed with traversal down the path
|
||||
//! The supplied JSON pointer will be a complete path from the root of the registry
|
||||
AZStd::function<bool(AZStd::string_view path)> m_includeFilter;
|
||||
//! JSON pointer prefix to dump all settings underneath
|
||||
//! For example if the prefix is "/Amazon/Settings", then the dumped settings will be placed underneath
|
||||
//! an object at that path
|
||||
//! """
|
||||
//! {
|
||||
//! "Amazon":{
|
||||
//! "Settings":{ <Dumped values> }
|
||||
//! }
|
||||
//! }
|
||||
AZStd::string_view m_jsonPointerPrefix;
|
||||
};
|
||||
|
||||
//! Dumps supplied settings registry from the path specified by key if it exist the the AZ::IO::GenericStream
|
||||
//! key is a JSON pointer path to dumping settings recursively from
|
||||
//! stream is an AZ::IO::GenericStream that supports writing
|
||||
//! dumperSettings are used to determine how to format the dumped output
|
||||
//! @param key is a JSON pointer to recursively dump settings from
|
||||
//! @param stream is an AZ::IO::GenericStream that supports writing
|
||||
//! @param dumperSettings are used to determine how to format the dumped output
|
||||
bool DumpSettingsRegistryToStream(SettingsRegistryInterface& registry, AZStd::string_view key,
|
||||
AZ::IO::GenericStream& stream, const DumperSettings& dumperSettings);
|
||||
|
||||
|
||||
@@ -418,36 +418,37 @@ namespace AZ::StringFunc::Internal
|
||||
return Strip(inout, { &stripCharacter, 1 }, bCaseSensitive, bStripBeginning, bStripEnding);
|
||||
}
|
||||
|
||||
AZStd::string_view LStrip(AZStd::string_view in, AZStd::string_view stripCharacters)
|
||||
{
|
||||
if (size_t pos = in.find_first_not_of(stripCharacters); pos != AZStd::string_view::npos)
|
||||
{
|
||||
return in.substr(pos);
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
AZStd::string_view RStrip(AZStd::string_view in, AZStd::string_view stripCharacters)
|
||||
{
|
||||
if (size_t pos = in.find_last_not_of(stripCharacters); pos != AZStd::string_view::npos)
|
||||
{
|
||||
return in.substr(0, pos < in.size() ? pos + 1 : pos);
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
AZStd::string_view StripEnds(AZStd::string_view in, AZStd::string_view stripCharacters)
|
||||
{
|
||||
return LStrip(RStrip(in, stripCharacters), stripCharacters);
|
||||
};
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace StringFunc
|
||||
{
|
||||
AZStd::string_view LStrip(AZStd::string_view in, AZStd::string_view stripCharacters)
|
||||
{
|
||||
if (size_t pos = in.find_first_not_of(stripCharacters); pos != AZStd::string_view::npos)
|
||||
{
|
||||
return in.substr(pos);
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
AZStd::string_view RStrip(AZStd::string_view in, AZStd::string_view stripCharacters)
|
||||
{
|
||||
if (size_t pos = in.find_last_not_of(stripCharacters); pos != AZStd::string_view::npos)
|
||||
{
|
||||
return in.substr(0, pos < in.size() ? pos + 1 : pos);
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
AZStd::string_view StripEnds(AZStd::string_view in, AZStd::string_view stripCharacters)
|
||||
{
|
||||
return LStrip(RStrip(in, stripCharacters), stripCharacters);
|
||||
};
|
||||
|
||||
bool Equal(const char* inA, const char* inB, bool bCaseSensitive /*= false*/, size_t n /*= 0*/)
|
||||
{
|
||||
if (!inA || !inB)
|
||||
@@ -483,6 +484,14 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
}
|
||||
bool Equal(AZStd::string_view inA, AZStd::string_view inB, bool bCaseSensitive)
|
||||
{
|
||||
const size_t maxCharsToCompare = inA.size();
|
||||
|
||||
return inA.size() == inB.size() && (bCaseSensitive
|
||||
? strncmp(inA.data(), inB.data(), maxCharsToCompare) == 0
|
||||
: azstrnicmp(inA.data(), inB.data(), maxCharsToCompare) == 0);
|
||||
}
|
||||
|
||||
bool StartsWith(AZStd::string_view sourceValue, AZStd::string_view prefixValue, bool bCaseSensitive)
|
||||
{
|
||||
@@ -496,9 +505,18 @@ namespace AZ
|
||||
&& Equal(sourceValue.substr(sourceValue.size() - suffixValue.size(), AZStd::string_view::npos).data(), suffixValue.data(), bCaseSensitive, suffixValue.size());
|
||||
}
|
||||
|
||||
size_t Find(const char* in, char c, size_t pos /*= 0*/, bool bReverse /*= false*/, bool bCaseSensitive /*= false*/)
|
||||
bool Contains(AZStd::string_view in, char ch, bool bCaseSensitive)
|
||||
{
|
||||
if (!in)
|
||||
return Find(in, ch, 0, false, bCaseSensitive) != AZStd::string_view::npos;
|
||||
}
|
||||
bool Contains(AZStd::string_view in, AZStd::string_view sv, bool bCaseSensitive)
|
||||
{
|
||||
return Find(in, sv, 0, false, bCaseSensitive) != AZStd::string_view::npos;
|
||||
}
|
||||
|
||||
size_t Find(AZStd::string_view in, char c, size_t pos /*= 0*/, bool bReverse /*= false*/, bool bCaseSensitive /*= false*/)
|
||||
{
|
||||
if (in.empty())
|
||||
{
|
||||
return AZStd::string::npos;
|
||||
}
|
||||
@@ -508,7 +526,7 @@ namespace AZ
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
size_t inLen = strlen(in);
|
||||
size_t inLen = in.size();
|
||||
if (inLen < pos)
|
||||
{
|
||||
return AZStd::string::npos;
|
||||
@@ -557,7 +575,13 @@ namespace AZ
|
||||
|
||||
size_t Find(AZStd::string_view in, AZStd::string_view s, size_t offset /*= 0*/, bool bReverse /*= false*/, bool bCaseSensitive /*= false*/)
|
||||
{
|
||||
if (in.empty() || s.empty())
|
||||
// Formally an empty string matches at the offset if it is <= to the size of the input string
|
||||
if (s.empty() && offset <= in.size())
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
if (in.empty())
|
||||
{
|
||||
return AZStd::string::npos;
|
||||
}
|
||||
@@ -773,7 +797,7 @@ namespace AZ
|
||||
bool bIsSpaces = false;
|
||||
if (!bIsEmpty)
|
||||
{
|
||||
AZStd::string_view strippedNextToken = Internal::StripEnds(*nextToken, " ");
|
||||
AZStd::string_view strippedNextToken = StripEnds(*nextToken, " ");
|
||||
bIsSpaces = strippedNextToken.empty();
|
||||
}
|
||||
|
||||
@@ -805,7 +829,7 @@ namespace AZ
|
||||
bool bIsSpaces = false;
|
||||
if (!bIsEmpty)
|
||||
{
|
||||
AZStd::string_view strippedNextToken = Internal::StripEnds(*nextToken, " ");
|
||||
AZStd::string_view strippedNextToken = StripEnds(*nextToken, " ");
|
||||
bIsSpaces = strippedNextToken.empty();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/std/function/function_fwd.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
@@ -107,6 +108,22 @@ namespace AZ
|
||||
StringFunc::Equal("Hello World", "Hello", true, 3) = true
|
||||
*/
|
||||
bool Equal(const char* inA, const char* inB, bool bCaseSensitive = false, size_t n = 0);
|
||||
bool Equal(AZStd::string_view inA, AZStd::string_view inB, bool bCaseSensitive = false);
|
||||
|
||||
//! Contains
|
||||
/*! Checks if the supplied character or string is contained within the @in parameter
|
||||
*
|
||||
Example: Case Insensitive contains finds character
|
||||
StringFunc::Contains("Hello", 'L') == true
|
||||
Example: Case Sensitive contains finds character
|
||||
StringFunc::Contains("Hello", 'l', true) = true
|
||||
Example: Case Insensitive contains does not find string
|
||||
StringFunc::Contains("Well Hello", "Mello") == false
|
||||
Example: Case Sensitive contains does not find character
|
||||
StringFunc::Contains("HeLlo", 'h', true) == false
|
||||
*/
|
||||
bool Contains(AZStd::string_view in, char ch, bool bCaseSensitive = false);
|
||||
bool Contains(AZStd::string_view in, AZStd::string_view sv, bool bCaseSensitive = false);
|
||||
|
||||
//! Find
|
||||
/*! Find for non AZStd::strings. Ease of use to find the first or last occurrence of a character or substring in a c-string with case sensitivity.
|
||||
@@ -119,7 +136,7 @@ namespace AZ
|
||||
Example: Case Sensitive find first occurrence of substring "Hello" a in a c-string
|
||||
StringFunc::Find("Well Hello", "Hello", false, true) == 5
|
||||
*/
|
||||
size_t Find(const char* in, char c, size_t pos = 0, bool bReverse = false, bool bCaseSensitive = false);
|
||||
size_t Find(AZStd::string_view in, char c, size_t pos = 0, bool bReverse = false, bool bCaseSensitive = false);
|
||||
size_t Find(AZStd::string_view in, AZStd::string_view str, size_t pos = 0, bool bReverse = false, bool bCaseSensitive = false);
|
||||
|
||||
//! First and Last Character
|
||||
@@ -196,6 +213,33 @@ namespace AZ
|
||||
*/
|
||||
AZStd::string& TrimWhiteSpace(AZStd::string& value, bool leading, bool trailing);
|
||||
|
||||
//! LStrip
|
||||
/*! Strips leading characters in the stripCharacters set
|
||||
* Example
|
||||
* Example: Case Insensitive Strip leading 'a' characters
|
||||
* StringFunc::LStrip(s = "Abracadabra", 'a'); s == "bracadabra"
|
||||
* Example: Case Sensitive Strip leading 'a' characters
|
||||
* StringFunc::LStrip(s = "Abracadabra", 'a'); s == "Abracadabra"
|
||||
*/
|
||||
//! RStrip
|
||||
/*! Strips trailing characters in the stripCharacters set
|
||||
* Example
|
||||
* Example: Case Insensitive Strip trailing 'a' characters
|
||||
* StringFunc::RStrip(s = "AbracadabrA", 'a'); s == "Abracadabr"
|
||||
* Example: Case Sensitive Strip trailing 'a' characters
|
||||
* StringFunc::RStrip(s = "AbracadabrA", 'a'); s == "AbracadabrA"
|
||||
*/
|
||||
//! StripEnds
|
||||
/*! Strips leading and trailing characters in the stripCharacters set
|
||||
Example: Case Insensitive Strip all 'a' characters
|
||||
StringFunc::StripEnds(s = "Abracadabra", 'a'); s == "bracadabr"
|
||||
Example: Case Sensitive Strip all 'a' characters
|
||||
StringFunc::StripEnds(s = "Abracadabra", 'a'); s == "Abracadabr"
|
||||
*/
|
||||
AZStd::string_view LStrip(AZStd::string_view in, AZStd::string_view stripCharacters = " ");
|
||||
AZStd::string_view RStrip(AZStd::string_view in, AZStd::string_view stripCharacters = " ");
|
||||
AZStd::string_view StripEnds(AZStd::string_view in, AZStd::string_view stripCharacters = " ");
|
||||
|
||||
//! Strip
|
||||
/*! Strip away the leading, trailing or all character(s) or substring(s) in a AZStd::string with
|
||||
*! case sensitivity.
|
||||
@@ -669,8 +713,7 @@ namespace AZ
|
||||
*/
|
||||
namespace Path
|
||||
{
|
||||
inline constexpr size_t MaxPathLength = 1024;
|
||||
using FixedString = AZStd::fixed_string<MaxPathLength>;
|
||||
using FixedString = AZ::IO::FixedMaxPathString;
|
||||
//! Normalize
|
||||
/*! Normalizes a path and returns returns StringFunc::Path::IsValid()
|
||||
*! strips all AZ_FILESYSTEM_INVALID_CHARACTERS
|
||||
@@ -791,7 +834,7 @@ namespace AZ
|
||||
|
||||
//! StripFullName
|
||||
/*! gets rid of the full file name if it has one, returns if it removed one or not
|
||||
*! EX: StringFunc::Path::StripFullName(a="C:\\p4\\game\\info\\some.file") == true; a=="C:\\p4\\game\\info\\"
|
||||
*! EX: StringFunc::Path::StripFullName(a="C:\\p4\\game\\info\\some.file") == true; a=="C:\\p4\\game\\info"
|
||||
*/
|
||||
void StripFullName(AZStd::string& out);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace UnitTest
|
||||
MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ());
|
||||
MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ());
|
||||
MOCK_CONST_METHOD0(GetAppRoot, const char* ());
|
||||
MOCK_CONST_METHOD0(GetEngineRoot, const char* ());
|
||||
MOCK_CONST_METHOD0(GetExecutableFolder, const char* ());
|
||||
MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ());
|
||||
MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&));
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace AZ
|
||||
MOCK_CONST_METHOD2(ConvertToAlias, bool(AZ::IO::FixedMaxPath& aliasPath, const AZ::IO::PathView& path));
|
||||
MOCK_CONST_METHOD3(ResolvePath, bool(const char* path, char* resolvedPath, AZ::u64 resolvedPathSize));
|
||||
MOCK_CONST_METHOD2(ResolvePath, bool(AZ::IO::FixedMaxPath& resolvedPath, const AZ::IO::PathView& path));
|
||||
MOCK_CONST_METHOD2(ReplaceAlias, bool(AZ::IO::FixedMaxPath& replacedAliasPath, const AZ::IO::PathView& path));
|
||||
MOCK_CONST_METHOD3(GetFilename, bool(HandleType fileHandle, char* filename, AZ::u64 filenameSize));
|
||||
using FileIOBase::ConvertToAlias;
|
||||
using FileIOBase::ResolvePath;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
|
||||
namespace AZ::Utils
|
||||
@@ -40,6 +42,47 @@ namespace AZ::Utils
|
||||
return result.m_pathStored;
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString GetEnginePath()
|
||||
{
|
||||
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString settingsValue;
|
||||
if (registry->Get(settingsValue, AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder))
|
||||
{
|
||||
return AZ::IO::FixedMaxPathString{settingsValue};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
AZ::IO::FixedMaxPathString GetProjectPath()
|
||||
{
|
||||
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString settingsValue;
|
||||
if (registry->Get(settingsValue, AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectPath))
|
||||
{
|
||||
return AZ::IO::FixedMaxPathString{settingsValue};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
AZ::SettingsRegistryInterface::FixedValueString GetProjectName()
|
||||
{
|
||||
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
|
||||
{
|
||||
AZ::SettingsRegistryInterface::FixedValueString projectNameKey{ AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey };
|
||||
projectNameKey += "/project_name";
|
||||
AZ::SettingsRegistryInterface::FixedValueString settingsValue;
|
||||
if (registry->Get(settingsValue, projectNameKey))
|
||||
{
|
||||
return settingsValue;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> WriteFile(AZStd::string_view content, AZStd::string_view filePath)
|
||||
{
|
||||
AZ::IO::FixedMaxPath filePathFixed = filePath; // Because FileIOStream requires a null-terminated string
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <AzCore/base.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
@@ -24,9 +26,6 @@ namespace AZ
|
||||
{
|
||||
namespace Utils
|
||||
{
|
||||
// Common cross platform Utils go here
|
||||
inline constexpr size_t MaxPathLength = 1024;
|
||||
|
||||
//! Protects from allocating too much memory. The choice of a 1MB threshold is arbitrary.
|
||||
//! If you need to work with larger files, please use AZ::IO directly instead of these utility functions.
|
||||
inline constexpr size_t DefaultMaxFileSize = 1024 * 1024;
|
||||
@@ -77,10 +76,22 @@ namespace AZ
|
||||
//! @returns a result object that indicates if the executable directory was able to be stored within the buffer
|
||||
ExecutablePathResult GetExecutableDirectory(char* exeStorageBuffer, size_t exeStorageSize);
|
||||
|
||||
//! Retrieves the full path to the engine from settings registry
|
||||
AZ::IO::FixedMaxPathString GetEnginePath();
|
||||
|
||||
//! Retrieves the full path to the project from settings registry
|
||||
AZ::IO::FixedMaxPathString GetProjectPath();
|
||||
|
||||
//! Retrieves the project name from the settings registry
|
||||
AZ::SettingsRegistryInterface::FixedValueString GetProjectName();
|
||||
|
||||
//! Retrieves the full path where the manifest file lives, i.e. "<userhome>/.o3de/o3de_manifest.json"
|
||||
AZ::IO::FixedMaxPathString GetEngineManifestPath();
|
||||
|
||||
//! Retrieves the App root path to use on the current platform
|
||||
//! If the optional is not engaged the AppRootPath should be calculated based
|
||||
//! on the location of the bootstrap.cfg file
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> GetDefaultAppRootPath();
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> GetDefaultAppRootPath();
|
||||
|
||||
//! Retrieves the development write storage path to use on the current platform, may be considered
|
||||
//! temporary or cache storage
|
||||
@@ -88,7 +99,7 @@ namespace AZ
|
||||
|
||||
// Attempts the supplied path to an absolute path.
|
||||
//! Returns nullopt if path cannot be converted to an absolute path
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> ConvertToAbsolutePath(AZStd::string_view path);
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> ConvertToAbsolutePath(AZStd::string_view path);
|
||||
|
||||
//! Save a string to a file. Otherwise returns a failure with error message.
|
||||
AZ::Outcome<void, AZStd::string> WriteFile(AZStd::string_view content, AZStd::string_view filePath);
|
||||
|
||||
@@ -249,6 +249,11 @@ namespace AZStd
|
||||
|
||||
constexpr auto swap(basic_fixed_string& rhs) -> void;
|
||||
|
||||
// C++23 contains
|
||||
constexpr auto contains(const basic_fixed_string& other) const -> bool;
|
||||
constexpr auto contains(Element ch) const -> bool;
|
||||
constexpr auto contains(const_pointer s) const -> bool;
|
||||
|
||||
constexpr auto find(const basic_fixed_string& rhs, size_type offset = 0) const -> size_type;
|
||||
constexpr auto find(const_pointer ptr, size_type offset, size_type count) const -> size_type;
|
||||
constexpr auto find(const_pointer ptr, size_type offset = 0) const -> size_type;
|
||||
|
||||
@@ -1072,6 +1072,23 @@ namespace AZStd
|
||||
Traits::assign(rhs.m_buffer[rhs.m_size], Element{ 0 });
|
||||
}
|
||||
|
||||
// C++23 contains
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
inline constexpr auto basic_fixed_string<Element, MaxElementCount, Traits>::contains(const basic_fixed_string& other) const -> bool
|
||||
{
|
||||
return find(other) != npos;
|
||||
}
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
inline constexpr auto basic_fixed_string<Element, MaxElementCount, Traits>::contains(value_type c) const -> bool
|
||||
{
|
||||
return find(c) != npos;
|
||||
}
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
inline constexpr auto basic_fixed_string<Element, MaxElementCount, Traits>::contains(const_pointer s) const -> bool
|
||||
{
|
||||
return find(s) != npos;
|
||||
}
|
||||
|
||||
template<class Element, size_t MaxElementCount, class Traits>
|
||||
inline constexpr auto basic_fixed_string<Element, MaxElementCount, Traits>::find(const basic_fixed_string& rhs, size_type offset) const -> size_type
|
||||
{
|
||||
|
||||
@@ -961,6 +961,22 @@ namespace AZStd
|
||||
}
|
||||
}
|
||||
|
||||
// C++23 contains
|
||||
bool contains(const basic_string& other) const
|
||||
{
|
||||
return find(other) != npos;
|
||||
}
|
||||
|
||||
bool contains(value_type c) const
|
||||
{
|
||||
return find(c) != npos;
|
||||
}
|
||||
|
||||
bool contains(const_pointer s) const
|
||||
{
|
||||
return find(s) != npos;
|
||||
}
|
||||
|
||||
inline size_type find(const this_type& rhs, size_type offset = 0) const
|
||||
{
|
||||
const_pointer rhsData = SSO_BUF_SIZE <= rhs.m_capacity ? rhs.m_data : rhs.m_buffer;
|
||||
|
||||
@@ -669,6 +669,22 @@ namespace AZStd
|
||||
return ends_with(basic_string_view(suffix));
|
||||
}
|
||||
|
||||
// C++23 contains
|
||||
constexpr bool contains(basic_string_view other) const
|
||||
{
|
||||
return find(other) != npos;
|
||||
}
|
||||
|
||||
constexpr bool contains(value_type c) const
|
||||
{
|
||||
return find(c) != npos;
|
||||
}
|
||||
|
||||
constexpr bool contains(const_pointer s) const
|
||||
{
|
||||
return find(s) != npos;
|
||||
}
|
||||
|
||||
// find
|
||||
constexpr size_type find(basic_string_view other, size_type pos = 0) const
|
||||
{
|
||||
|
||||
@@ -52,10 +52,10 @@ namespace AZ
|
||||
// in non-release builds.
|
||||
// If a bootstrap.cfg file is not found in the public storage, it is then searched for
|
||||
// within the APK itself
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> GetDefaultAppRootPath()
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> GetDefaultAppRootPath()
|
||||
{
|
||||
const char* appRoot = AZ::Android::Utils::FindAssetsDirectory();
|
||||
return appRoot ? AZStd::make_optional<AZStd::fixed_string<MaxPathLength>>(appRoot) : AZStd::nullopt;
|
||||
return appRoot ? AZStd::make_optional<AZ::IO::FixedMaxPathString>(appRoot) : AZStd::nullopt;
|
||||
}
|
||||
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> GetDevWriteStoragePath()
|
||||
@@ -64,10 +64,10 @@ namespace AZ
|
||||
return writeStorage ? AZStd::make_optional<AZ::IO::FixedMaxPathString>(writeStorage) : AZStd::nullopt;
|
||||
}
|
||||
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> ConvertToAbsolutePath(AZStd::string_view path)
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> ConvertToAbsolutePath(AZStd::string_view path)
|
||||
{
|
||||
AZStd::fixed_string<MaxPathLength> absolutePath;
|
||||
AZStd::fixed_string<MaxPathLength> srcPath{ path };
|
||||
AZ::IO::FixedMaxPathString absolutePath;
|
||||
AZ::IO::FixedMaxPathString srcPath{ path };
|
||||
if (AZ::Android::Utils::IsApkPath(srcPath.c_str()))
|
||||
{
|
||||
return srcPath;
|
||||
|
||||
@@ -64,6 +64,7 @@ set(FILES
|
||||
AzCore/Socket/AzSocket_Platform.h
|
||||
../Common/UnixLike/AzCore/std/time_UnixLike.cpp
|
||||
AzCore/Utils/Utils_Android.cpp
|
||||
../Common/Unimplemented/AzCore/Utils/Utils_Unimplemented.cpp
|
||||
../../AzCore/Android/AndroidEnv.cpp
|
||||
../../AzCore/Android/AndroidEnv.h
|
||||
../../AzCore/Android/APKFileHandler.cpp
|
||||
|
||||
+22
@@ -0,0 +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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
namespace AZ::Utils
|
||||
{
|
||||
AZ::IO::FixedMaxPathString GetEngineManifestPath()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace AZ::Utils
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -25,10 +25,25 @@ namespace AZ
|
||||
|
||||
void NativeErrorMessageBox(const char*, const char*) {}
|
||||
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> ConvertToAbsolutePath(AZStd::string_view path)
|
||||
AZ::IO::FixedMaxPathString GetEngineManifestPath()
|
||||
{
|
||||
AZStd::fixed_string<MaxPathLength> absolutePath;
|
||||
AZStd::fixed_string<MaxPathLength> srcPath{ path };
|
||||
if (const char* homePath = std::getenv("HOME"); homePath != nullptr)
|
||||
{
|
||||
AZ::IO::FixedMaxPath path{homePath};
|
||||
if (!path.empty())
|
||||
{
|
||||
path /= ".o3de";
|
||||
path /= "o3de_manifest.json";
|
||||
}
|
||||
return path.Native();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> ConvertToAbsolutePath(AZStd::string_view path)
|
||||
{
|
||||
AZ::IO::FixedMaxPathString absolutePath;
|
||||
AZ::IO::FixedMaxPathString srcPath{ path };
|
||||
|
||||
if (char* result = realpath(srcPath.c_str(), absolutePath.data()); result)
|
||||
{
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace AZ
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> GetDefaultAppRootPath()
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> GetDefaultAppRootPath()
|
||||
{
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
@@ -57,10 +57,10 @@ namespace AZ
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> ConvertToAbsolutePath(AZStd::string_view path)
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> ConvertToAbsolutePath(AZStd::string_view path)
|
||||
{
|
||||
AZStd::fixed_string<MaxPathLength> absolutePath;
|
||||
AZStd::fixed_string<MaxPathLength> srcPath{ path };
|
||||
AZ::IO::FixedMaxPathString absolutePath;
|
||||
AZ::IO::FixedMaxPathString srcPath{ path };
|
||||
char* result = _fullpath(absolutePath.data(), srcPath.c_str(), absolutePath.capacity());
|
||||
// Force update of the fixed_string size() value
|
||||
absolutePath.resize_no_construct(AZStd::char_traits<char>::length(absolutePath.data()));
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace AZ
|
||||
return result;
|
||||
}
|
||||
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> GetDefaultAppRootPath()
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> GetDefaultAppRootPath()
|
||||
{
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
namespace AZ::Utils
|
||||
{
|
||||
AZStd::optional<AZStd::fixed_string<MaxPathLength>> GetDefaultAppRootPath()
|
||||
AZStd::optional<AZ::IO::FixedMaxPathString> GetDefaultAppRootPath()
|
||||
{
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user