Merge branch 'main' into LYN-1099

main
jjjoness 5 years ago
commit 26b8181cc1

@ -1,402 +0,0 @@
<!--
= Platform names =
(case insensitive)
"ANDROID"
"PROVO"
"PC"
"LINUX"
"MAC"
= Basic Layout =
<ThreadConfig>
<Platform name="XXX">
<ThreadDefault Affinity="XX" Priority="XX" StackSizeKB="XX">
<Thread name ="A" Affinity="XX" Priority="XX" StackSizeKB="XX">
<Thread name ="B" Affinity="XX" >
...
</Platform>
<Platform name="YYY">
...
</Platform>
</ThreadConfig>
= Parser Order for Platform =
1. PlatformName_Common (valid for all potential platform configurations. Can be overridden by concert platform configuration)
2. PlatformName or PlatformName_X (for platforms with unknown CPU count where X is the number of potential cores. The equal or next lower matching configuration for the identified core count at runtime will be taken)
Note: Overriding of thread configuration by later parsed configuration allowed.
= <ThreadDefault> and <Thread> XML attributes =
!!!
Note: Use "ignore" as value if you do not want the thread system to set the value specifically!
If a value is not defines the <ThreadDefault> value of the parameter will be used.
This is useful when dealing with 3rdParty threads where you are not in control of the parameter setup.
!!!
Name:
"x" (string) : Name of thread
"x*y" (string) : Name of thread with wildcard character
Affinity:
"-1" : Put SW thread affinity in the hands of the scheduler - (default) -
"x" : Run thread on specified core
"x, y, ..." : Run thread on specified cores
Priority:
"idle" : Hint to CryEngine to run thread with pre-set priority
"below_normal" : Hint to CryEngine to run thread with pre-set priority
"normal" : Hint to CryEngine to run thread with pre-set priority - (default) -
"above_normal" : Hint to CryEngine to run thread with pre-set priority
"highest" : Hint to CryEngine to run thread with pre-set priority
"time_critical" : Hint to CryEngine to run thread with pre-set priority
"x" (number) : User defined thread priority number
StackSizeKB:
"0" : Let platform decide on the stack size - (default) -
"x" : Create thread with "x" KB of stack size
DisablePriorityBoost:
"true" : Disable priority boosting - (default) -
"false" : Enable priority boosting
-->
<ThreadConfig>
<!-- ============= -->
<!-- === PROVO === -->
<!-- ============= -->
<Platform name="Provo">
<ThreadDefault Affinity="-1" Priority="Normal" StackSizeKB="64"/>
<!-- [PROCESS] -->
<Thread name ="Main" Affinity="0" Priority="Above_Normal"/>
<!-- [RenderDLL] -->
<Thread name ="RenderThread" Affinity="2" Priority="Highest" StackSizeKB="128"/>
<Thread name ="RenderLoadingThread" Affinity="1" Priority="Above_Normal" StackSizeKB="72"/>
<Thread name ="ShaderCompile"/>
<!-- [SYSTEM] -->
<Thread name ="GFxMeshCacheReset"/>
<Thread name ="MTrace NetPump" Priority="25"/>
<Thread name ="NotificationNetwork"/>
<Thread name ="ReplayRecord"/>
<Thread name ="ResourceActivator"/>
<Thread name ="StatoscopeDataWriter"/>
<Thread name ="RemoteCommandClient"/>
<Thread name ="RemoteCommandServer"/>
<Thread name ="ServiceNetwork"/>
<Thread name ="SysCrashTestOnThread"/>
<!-- [SYSTEM] - JobSystem -->
<Thread name ="JobSystem_Worker_0(Blocking)" Affinity="1"/>
<Thread name ="JobSystem_Worker_0(Regular)" Affinity="1" StackSizeKB="256"/>
<Thread name ="JobSystem_Worker_1(Regular)" Affinity="3" StackSizeKB="256"/>
<Thread name ="JobSystem_Worker_2(Regular)" Affinity="4" StackSizeKB="256"/>
<Thread name ="JobSystem_Worker_3(Regular)" Affinity="5" StackSizeKB="256"/>
<!-- [SYSTEM] - Physics -->
<Thread name ="Physics" StackSizeKB="128"/>
<Thread name ="PhysicsWorkerThread_*" StackSizeKB="128"/>
<!-- [SYSTEM] - Streaming -->
<Thread name ="Streaming File IO HDD" Priority="Above_Normal" Affinity="1"/>
<Thread name ="Streaming File IO Optical" Priority="Above_Normal" Affinity="1"/>
<Thread name ="Streaming File IO InMemory" Priority="Above_Normal" Affinity="1"/>
<Thread name ="Streaming AsyncCallback" Affinity="5"/>
<Thread name ="Streaming AsyncCallback Pak 0" Affinity="5"/>
<!-- [SYSTEM] - Console -->
<Thread name ="RemoteConsoleServer"/>
<Thread name ="RemoteConsoleClient"/>
<!-- [NETWORK] -->
<Thread name ="Network"/>
<Thread name ="ServerProbe"/>
<Thread name ="NetworkDebugKit"/>
<Thread name ="NetFileDownload"/>
<Thread name ="NetworkWatchdog"/>
<Thread name ="NetAddressSolver"/>
<!-- [AI] -->
<Thread name ="NavigationSystemBackgroundUpdate"/>
<!-- [AUDIO] -->
<Thread name ="MainAudioThread" Affinity="1,3,4,5" Priority="below_normal" StackSize="ignore"/>
<Thread name ="Wwise_Device" Affinity="5" Priority="ignore" StackSize="ignore"/>
<Thread name ="Wwise_BankManager" Affinity="5" Priority="ignore" StackSize="ignore"/>
<Thread name ="Wwise_LEngine" Affinity="5" Priority="ignore" StackSize="ignore"/>
<Thread name ="Wwise_Monitor" Affinity="5" Priority="ignore" StackSize="ignore"/>
<!-- [ACTION] -->
<Thread name ="NetworkStallTicker"/>
<Thread name ="ZLibCompressor" Priority="Normal"/>
<!-- [INPUT] -->
<Thread name ="InputWorker"/>
<Thread name ="Synergy"/>
<!-- [LIVE_CREATE]-->
<Thread name ="LiveCreate_Server"/>
<Thread name ="LiveCreate_FileSync"/>
<Thread name ="LiveCreatePlatformService"/>
<Thread name ="LiveCreateUtilityService"/>
<!-- [SCALEFORM][3rd Party] -->
<Thread name ="GFxVideo_SoundUpdate" Affinity="5" Priority="time_critical" DisablePriorityBoost="ignore" StackSizeKB="ignore"/>
<Thread name ="GFxVideo_Decoder" Affinity="4" Priority="highest" DisablePriorityBoost="ignore" StackSizeKB="ignore"/>
<Thread name ="GFxVideo_Reader" Affinity="5" Priority="highest" DisablePriorityBoost="ignore" StackSizeKB="ignore"/>
</Platform>
<!-- ============ -->
<!-- === PC_Common === -->
<!-- ============ -->
<Platform name="PC_Common">
<ThreadDefault Affinity="-1" Priority="Normal" StackSizeKB="32"/>
<!-- [PROCESS] -->
<Thread name ="Main" Affinity="-1" Priority="Normal"/>
<!-- [SYSTEM] - JobSystem -->
<Thread name ="JobSystem_Worker_*(Blocking)" StackSizeKB="32"/>
<Thread name ="JobSystem_Worker_*(Regular)" StackSizeKB="256"/>
<!-- [SYSTEM] - Physics -->
<Thread name ="Physics" StackSizeKB="128"/>
<Thread name ="PhysicsWorkerThread_*" StackSizeKB="128"/>
<!-- [RenderDLL] -->
<Thread name ="RenderThread" StackSizeKB="128"/>
<Thread name ="RenderLoadingThread" Priority="Above_Normal" StackSizeKB="72"/>
<Thread name ="ShaderCompile"/>
<!-- [SYSTEM] -->
<Thread name ="GFxMeshCacheReset"/>
<Thread name ="MTrace NetPump" Priority="25" StackSizeKB="64"/>
<Thread name ="NotificationNetwork"/>
<Thread name ="ReplayRecord"/>
<Thread name ="ResourceActivator"/>
<Thread name ="StatoscopeDataWriter"/>
<Thread name ="RemoteCommandClient"/>
<Thread name ="RemoteCommandServer"/>
<Thread name ="ServiceNetwork"/>
<Thread name ="SysCrashTestOnThread"/>
<!-- [SYSTEM] - Streaming -->
<Thread name ="Streaming File IO HDD" Priority="Above_Normal"/>
<Thread name ="Streaming File IO Optical" Priority="Above_Normal"/>
<Thread name ="Streaming File IO InMemory" Priority="Above_Normal"/>
<Thread name ="Streaming AsyncCallback"/>
<Thread name ="Streaming AsyncCallback Pak 0"/>
<!-- [SYSTEM] - Console -->
<Thread name ="RemoteConsoleServer"/>
<Thread name ="RemoteConsoleClient"/>
<Thread name ="WindowsConsoleInput"/>
<Thread name ="UNIXConsoleInput"/>
<!-- [NETWORK] -->
<Thread name ="Network"/>
<Thread name ="ServerProbe"/>
<Thread name ="NetworkDebugKit"/>
<Thread name ="NetFileDownload"/>
<Thread name ="NetworkWatchdog" StackSizeKB="8"/>
<Thread name ="NetAddressSolver" StackSizeKB="16"/>
<!-- [AUDIO] -->
<Thread name ="MainAudioThread" Affinity="ignore" Priority="below_normal" StackSize="ignore"/>
<Thread name ="Wwise_Device" Affinity="ignore" Priority="ignore" StackSize="ignore"/>
<Thread name ="Wwise_BankManager" Affinity="ignore" Priority="ignore" StackSize="ignore"/>
<Thread name ="Wwise_LEngine" Affinity="ignore" Priority="ignore" StackSize="ignore"/>
<Thread name ="Wwise_Monitor" Affinity="ignore" Priority="ignore" StackSize="ignore"/>
<!-- [AI] -->
<Thread name ="NavigationSystemBackgroundUpdate"/>
<!-- [ACTION] -->
<Thread name ="NetworkStallTicker"/>
<Thread name ="ZLibCompressor" Priority="Normal" StackSizeKB="32"/>
<!-- [INPUT] -->
<Thread name ="InputWorker"/>
<Thread name ="Synergy"/>
<!-- [LIVE_CREATE]-->
<Thread name ="LiveCreate_Server"/>
<Thread name ="LiveCreate_FileSync"/>
<Thread name ="LiveCreatePlatformService"/>
<Thread name ="LiveCreateUtilityService"/>
<!-- [SCALEFORM][3rd Party] -->
<Thread name ="GFxVideo_SoundUpdate" Affinity="ignore" Priority="highest" DisablePriorityBoost="ignore" StackSizeKB="16"/>
<!-- Special case, to add additional decoder threads add a threads with an increase incremental number. "GFxVideo_Decoder_0" sets thread priority for all other decoder threads-->
<Thread name ="GFxVideo_Decoder_0" Affinity="ignore" Priority="normal" DisablePriorityBoost="ignore" StackSizeKB="ignore"/>
<Thread name ="GFxVideo_Decoder_1" Affinity="ignore" Priority="normal" DisablePriorityBoost="ignore" StackSizeKB="ignore"/>
</Platform>
<!-- ============ -->
<!-- === PC_8 === -->
<!-- ============ -->
<Platform name="PC_8">
<!-- Empty Example - Extend for 8 core specific machines. May override Common settings -->
</Platform>
<!-- ============ -->
<!-- === MAC_Common === -->
<!-- ============ -->
<Platform name="MAC_Common">
<ThreadDefault Affinity="-1" Priority="Normal" StackSizeKB="32"/>
</Platform>
<!-- ============ -->
<!-- === LINUX_Common === -->
<!-- ============ -->
<Platform name="LINUX_Common">
<ThreadDefault Affinity="-1" Priority="Normal" StackSizeKB="64"/>
<!-- [PROCESS] -->
<Thread name ="Main" Affinity="-1" Priority="Above_Normal"/>
<!-- [SYSTEM] - JobSystem -->
<Thread name ="JobSystem_Worker_*(Blocking)" StackSizeKB="32"/>
<Thread name ="JobSystem_Worker_*(Regular)" StackSizeKB="256"/>
<!-- [SYSTEM] - Physics -->
<Thread name ="Physics" StackSizeKB="128"/>
<Thread name ="PhysicsWorkerThread_*" StackSizeKB="128"/>
<!-- [RenderDLL] -->
<Thread name ="RenderThread" Priority="Above_Normal" StackSizeKB="128"/>
<Thread name ="RenderLoadingThread" Priority="Above_Normal" StackSizeKB="72"/>
<Thread name ="ShaderCompile"/>
<!-- [SYSTEM] -->
<Thread name ="GFxMeshCacheReset"/>
<Thread name ="MTrace NetPump" Priority="25" StackSizeKB="64"/>
<Thread name ="NotificationNetwork"/>
<Thread name ="ReplayRecord"/>
<Thread name ="ResourceActivator"/>
<Thread name ="StatoscopeDataWriter"/>
<Thread name ="RemoteCommandClient"/>
<Thread name ="RemoteCommandServer"/>
<Thread name ="ServiceNetwork"/>
<Thread name ="SysCrashTestOnThread"/>
<!-- [SYSTEM] - Streaming -->
<Thread name ="Streaming File IO HDD" Priority="Above_Normal"/>
<Thread name ="Streaming File IO Optical" Priority="Above_Normal"/>
<Thread name ="Streaming File IO InMemory" Priority="Above_Normal"/>
<Thread name ="Streaming AsyncCallback"/>
<Thread name ="Streaming AsyncCallback Pak 0"/>
<!-- [SYSTEM] - Console -->
<Thread name ="RemoteConsoleServer"/>
<Thread name ="RemoteConsoleClient"/>
<Thread name ="UNIXConsoleInput"/>
<!-- [NETWORK] -->
<Thread name ="Network"/>
<Thread name ="ServerProbe"/>
<Thread name ="NetworkDebugKit"/>
<Thread name ="NetFileDownload"/>
<Thread name ="NetworkWatchdog" StackSizeKB="8"/>
<Thread name ="NetAddressSolver"/>
<!-- [AUDIO] -->
<Thread name ="MainAudioThread" Affinity="ignore" Priority="below_normal" StackSize="ignore"/>
<Thread name ="Wwise_Device" Affinity="ignore" Priority="99" StackSize="ignore"/>
<Thread name ="Wwise_BankManager" Affinity="ignore" Priority="50" StackSize="ignore"/>
<Thread name ="Wwise_LEngine" Affinity="ignore" Priority="99" StackSize="ignore"/>
<Thread name ="Wwise_Monitor" Affinity="ignore" Priority="99" StackSize="ignore"/>
<!-- [AI] -->
<Thread name ="NavigationSystemBackgroundUpdate"/>
<!-- [ACTION] -->
<Thread name ="NetworkStallTicker"/>
<Thread name ="ZLibCompressor" Priority="Normal" StackSizeKB="32"/>
<!-- [INPUT] -->
<Thread name ="InputWorker"/>
<Thread name ="Synergy"/>
</Platform>
<!-- ============ -->
<!-- === ANDROID_Common === -->
<!-- ============ -->
<Platform name="ANDROID_Common">
<ThreadDefault Affinity="-1" Priority="Normal" StackSizeKB="32"/>
<!-- [PROCESS] -->
<Thread name ="Main" Priority="Above_Normal"/>
<!-- [SYSTEM] - JobSystem -->
<Thread name ="JobSystem_Worker_*(Blocking)" StackSizeKB="32"/>
<Thread name ="JobSystem_Worker_*(Regular)" StackSizeKB="256"/>
<!-- [SYSTEM] - Physics -->
<Thread name ="Physics" StackSizeKB="128"/>
<Thread name ="PhysicsWorkerThread_*" StackSizeKB="128"/>
<!-- [RenderDLL] -->
<Thread name ="RenderThread" Affinity="ignore" Priority="Above_Normal" StackSizeKB="128"/>
<Thread name ="RenderLoadingThread" Affinity="ignore" Priority="Above_Normal" StackSizeKB="72"/>
<Thread name ="ShaderCompile"/>
<!-- [SYSTEM] -->
<Thread name ="GFxMeshCacheReset"/>
<Thread name ="MTrace NetPump" Priority="25" StackSizeKB="64"/>
<Thread name ="NotificationNetwork"/>
<Thread name ="ReplayRecord"/>
<Thread name ="ResourceActivator"/>
<Thread name ="StatoscopeDataWriter"/>
<Thread name ="RemoteCommandClient"/>
<Thread name ="RemoteCommandServer"/>
<Thread name ="ServiceNetwork"/>
<Thread name ="SysCrashTestOnThread"/>
<!-- [AUDIO] -->
<Thread name ="MainAudioThread" Affinity="ignore" Priority="below_normal" StackSize="ignore"/>
<Thread name ="Wwise_Device" Affinity="ignore" Priority="99" StackSize="ignore"/>
<Thread name ="Wwise_BankManager" Affinity="ignore" Priority="50" StackSize="ignore"/>
<Thread name ="Wwise_LEngine" Affinity="ignore" Priority="99" StackSize="ignore"/>
<Thread name ="Wwise_Monitor" Affinity="ignore" Priority="99" StackSize="ignore"/>
<!-- [SYSTEM] - Streaming -->
<Thread name ="Streaming File IO HDD" Priority="Above_Normal"/>
<Thread name ="Streaming File IO Optical" Priority="Above_Normal"/>
<Thread name ="Streaming File IO InMemory" Priority="Above_Normal"/>
<Thread name ="Streaming AsyncCallback"/>
<Thread name ="Streaming AsyncCallback Pak 0"/>
<!-- [SYSTEM] - Console -->
<Thread name ="RemoteConsoleServer"/>
<!-- [NETWORK] -->
<Thread name ="Network"/>
<Thread name ="ServerProbe"/>
<Thread name ="NetworkDebugKit"/>
<Thread name ="NetFileDownload"/>
<Thread name ="NetworkWatchdog" StackSizeKB="8"/>
<Thread name ="NetAddressSolver" StackSizeKB="16"/>
<!-- [ACTION] -->
<Thread name ="NetworkStallTicker"/>
<Thread name ="ZLibCompressor" Affinity="ignore" Priority="Above_Normal" StackSizeKB="32"/>
</Platform>
</ThreadConfig>

@ -1,128 +0,0 @@
<!--
= Platform names =
(case insensitive)
"ANDROID"
"PROVO"
"PC"
"MAC"
= Basic Layout =
<ThreadConfig>
<Platform name="XXX">
<ThreadDefault Affinity="XX" Priority="XX" StackSizeKB="XX">
<Thread name ="A" Affinity="XX" Priority="XX" StackSizeKB="XX">
<Thread name ="B" Affinity="XX" >
...
</Platform>
<Platform name="YYY">
...
</Platform>
</ThreadConfig>
= Parser Order for Platform =
1. PlatformName_Common (valid for all potential platform configurations. Can be overridden by concert platform configuration)
2. PlatformName or PlatformName_X (for platforms with unknown CPU count where X is the number of potential cores. The equal or next lower matching configuration for the identified core count at runtime will be taken)
Note: Overriding of thread configuration by later parsed configuration allowed.
= <ThreadDefault> and <Thread> XML attributes =
!!!
Note: Use "ignore" as value if you do not want the thread system to set the value specifically!
If a value is not defines the <ThreadDefault> value of the parameter will be used.
This is useful when dealing with 3rdParty threads where you are not in control of the parameter setup.
!!!
Name:
"x" (string) : Name of thread
"x*y" (string) : Name of thread with wildcard character
Affinity:
"-1" : Put SW thread affinity in the hands of the scheduler - (default) -
"x" : Run thread on specified core
"x, y, ..." : Run thread on specified cores
Priority:
"idle" : Hint to CryEngine to run thread with pre-set priority
"below_normal" : Hint to CryEngine to run thread with pre-set priority
"normal" : Hint to CryEngine to run thread with pre-set priority - (default) -
"above_normal" : Hint to CryEngine to run thread with pre-set priority
"highest" : Hint to CryEngine to run thread with pre-set priority
"time_critical" : Hint to CryEngine to run thread with pre-set priority
"x" (number) : User defined thread priority number
StackSizeKB:
"0" : Let platform decide on the stack size - (default) -
"x" : Create thread with "x" KB of stack size
DisablePriorityBoost:
"true" : Disable priority boosting - (default) -
"false" : Enable priority boosting
-->
<ThreadConfig>
<!-- ============ -->
<!-- === PC_Common === -->
<!-- ============ -->
<Platform name="PC_Common">
<ThreadDefault Affinity="-1" Priority="Normal" StackSizeKB="32"/>
<!-- [SANDBOX] -->
<Thread name ="TextureViewer"/>
<Thread name ="TextureDatabaseCreator"/>
<Thread name ="MaterialFilesScanning"/>
<Thread name ="FileChangeMonitor"/>
<Thread name ="FileSystemSearcher"/>
<Thread name ="BackgroundTask_IO"/>
<Thread name ="BackgroundTask_*"/>
<!-- [SANDBOX] - Dialogues -->
<Thread name ="ResourceCompilerDialog"/>
<!-- [SANDBOX] - Telemetry -->
<Thread name ="TelemetryPipeThread"/>
<!-- [SANDBOX] - Asset Browser -->
<Thread name ="AssetMetaDataFileDB_CachingInfo"/>
<Thread name ="AssetMetaDataFileDB_LoadAndUpdate"/>
<!-- [SANDBOX] - Console -->
<Thread name ="ConsoleHotUpdate"/>
<Thread name ="Console Synchronization"/>
<!-- [SANDBOX] - LiveCreate -->
<Thread name ="LiveCreate_PeerComm"/>
<Thread name ="LiveCreate_SyncFiles"/>
<Thread name ="LiveCreate_CheckPowerOn"/>
<!-- [SANDBOX] - Plug-ins -->
<Thread name ="PerforcePlugin"/>
<!-- [SANDBOX] - Utility -->
<Thread name ="FileIndexing"/>
<Thread name ="LODChainGenerateThread"/>
<Thread name ="VisualChangeCalculatorView"/>
<!-- [SANDBOX] - Segmented World -->
<Thread name ="SegWorld_MapUpdater"/>
<Thread name ="SegWorld_WorldUpdater"/>
<Thread name ="SegWorld_ExportSurfaceTexture_*"/>
<!-- [SANDBOX] - Indirect Lighting -->
<Thread name ="SHLighting_*" StackSizeKB="1024"/>
<Thread name ="SHLighting_TriRaster" StackSizeKB="1024"/>
</Platform>
<!-- ============ -->
<!-- === PC_8 === -->
<!-- ============ -->
<Platform name="PC_8">
<!-- Empty Example - Extend for 8 core specific machines. May override Common settings -->
</Platform>
</ThreadConfig>

@ -123,6 +123,21 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
)
endif()
## Prefab ##
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME AutomatedTesting::PrefabTests
TEST_SUITE main
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Main.py
TIMEOUT 1500
RUNTIME_DEPENDENCIES
Legacy::Editor
AZ::AssetProcessor
AutomatedTesting.Assets
)
endif()
## Editor Python Bindings ##
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(

@ -0,0 +1,76 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# fmt:off
class Tests():
find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level")
empty_entity_pos = ("'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position")
find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level")
pxentity_component = ("Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' does *not* have a Physx Collider")
# fmt:on
def PrefabLevel_OpensLevelWithEntities():
"""
Opens the level that contains 2 entities, "EmptyEntity" and "EntityWithPxCollider".
This test makes sure that both entities exist after opening the level and that:
- EmptyEntity is at Position: (10, 20, 30)
- EntityWithPxCollider has a PhysXCollider component
"""
import os
import sys
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
import editor_python_test_tools.hydra_editor_utils as hydra
import azlmbr.entity as entity
import azlmbr.bus as bus
from azlmbr.math import Vector3
EXPECTED_EMPTY_ENTITY_POS = Vector3(10.00, 20.0, 30.0)
helper.init_idle()
helper.open_level("prefab", "PrefabLevel_OpensLevelWithEntities")
def find_entity(entity_name):
searchFilter = entity.SearchFilter()
searchFilter.names = [entity_name]
entityIds = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
if entityIds[0].IsValid():
return entityIds[0]
return None
#Checks for an entity called "EmptyEntity"
helper.wait_for_condition(lambda: find_entity("EmptyEntity").IsValid(), 5.0)
empty_entity_id = find_entity("EmptyEntity")
Report.result(Tests.find_empty_entity, empty_entity_id.IsValid())
# Checks if the EmptyEntity is in the correct position and if it fails, it will provide the expected postion and the actual postion of the entity in the Editor log
empty_entity_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", empty_entity_id)
is_at_position = empty_entity_pos.IsClose(EXPECTED_EMPTY_ENTITY_POS)
Report.result(Tests.empty_entity_pos, is_at_position)
if not is_at_position:
Report.info(f'Expected position: {EXPECTED_EMPTY_ENTITY_POS.ToString()}, actual position: {empty_entity_pos.ToString()}')
#Checks for an entity called "EntityWithPxCollider" and if it has the PhysX Collider component
pxentity = find_entity("EntityWithPxCollider")
Report.result(Tests.find_pxentity, pxentity.IsValid())
pxcollider_id = hydra.get_component_type_id("PhysX Collider")
hasComponent = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'HasComponentOfType', pxentity, pxcollider_id)
Report.result(Tests.pxentity_component, hasComponent)
if __name__ == "__main__":
from editor_python_test_tools.utils import Report
Report.start_test (PrefabLevel_OpensLevelWithEntities)

@ -0,0 +1,35 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# This suite consists of all test cases that are passing and have been verified.
import pytest
import os
import sys
from ly_test_tools import LAUNCHERS
sys.path.append (os.path.dirname (os.path.abspath (__file__)) + '/../automatedtesting_shared')
from base import TestAutomationBase
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
def _run_prefab_test(self, request, workspace, editor, test_module):
self._run_test(request, workspace, editor, test_module, ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"])
def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform):
from . import PrefabLevel_OpensLevelWithEntities as test_module
self._run_prefab_test(request, workspace, editor, test_module)

@ -0,0 +1,10 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""

@ -0,0 +1,117 @@
"""
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
its licensors.
For complete copyright and license terms please see the LICENSE at the root of this
distribution (the "License"). All use of this software is governed by the License,
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
# fmt: off
class Tests():
node_duplicated = ("Successfully duplicated node", "Failed to duplicate the node")
# fmt: on
def Node_HappyPath_DuplicateNode():
"""
Summary:
Duplicating node in graph
Expected Behavior:
Upon selecting a node and pressing Ctrl+D, the node will be duplicated
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
2) Open a new graph
3) Add node to graph
4) Duplicate node
5) Verify the node was duplicated6) Verify the node was duplicated
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
from PySide2 import QtWidgets, QtTest
from PySide2.QtCore import Qt
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
import editor_python_test_tools.pyside_utils as pyside_utils
import azlmbr.legacy.general as general
WAIT_FRAMES = 200
NODE_NAME = "Print"
NODE_CATEGORY = "Debug"
EXPECTED_STRING = f"{NODE_NAME} - {NODE_CATEGORY} (2 Selected)"
def command_line_input(command_str):
cmd_action = pyside_utils.find_child_by_pattern(
sc_main, {"objectName": "action_ViewCommandLine", "type": QtWidgets.QAction}
)
cmd_action.trigger()
textbox = sc.findChild(QtWidgets.QLineEdit, "commandText")
QtTest.QTest.keyClicks(textbox, command_str)
QtTest.QTest.keyClick(textbox, Qt.Key_Enter, Qt.NoModifier)
def grab_title_text():
scroll_area = node_inspector.findChild(QtWidgets.QScrollArea, "")
QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES)
background = scroll_area.findChild(QtWidgets.QFrame, "Background")
title = background.findChild(QtWidgets.QLabel, "Title")
text = title.findChild(QtWidgets.QLabel, "Title")
return text.text()
# 1) Open Script Canvas window (Tools > Script Canvas)
general.idle_enable(True)
general.open_pane("Script Canvas")
helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0)
# 2) Open a new graph
editor_window = pyside_utils.get_editor_main_window()
sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
sc_main = sc.findChild(QtWidgets.QMainWindow)
create_new_graph = pyside_utils.find_child_by_pattern(
sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction}
)
if sc.findChild(QtWidgets.QDockWidget, "NodeInspector") is None:
action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Inspector", "type": QtWidgets.QAction})
action.trigger()
node_inspector = sc.findChild(QtWidgets.QDockWidget, "NodeInspector")
create_new_graph.trigger()
# 3) Add node
command_line_input("add_node Print")
# 4) Duplicate node
graph_view = sc.findChild(QtWidgets.QFrame, "graphicsViewFrame")
graph = graph_view.findChild(QtWidgets.QWidget, "")
# There are currently no utilities available to directly duplicate the node,
# therefore the node is selected using CTRL+A on the graph to select
# it and then CTRL+D to duplicate
sc_main.activateWindow()
QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES)
QtTest.QTest.keyClick(graph, "d", Qt.ControlModifier, WAIT_FRAMES)
# 5) Verify the node was duplicated
# As direct interaction with node is not available the text on the label
# inside the Node Inspector is validated showing two nodes exist
after_dup = grab_title_text()
Report.result(Tests.node_duplicated, after_dup == EXPECTED_STRING)
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(Node_HappyPath_DuplicateNode)

@ -84,7 +84,7 @@ class TestAutomation(TestAutomationBase):
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import OnEntityActivatedDeactivated_PrintMessage as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92562993")
def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project):
from . import NodePalette_ClearSelection as test_module
@ -122,7 +122,7 @@ class TestAutomation(TestAutomationBase):
def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project):
from . import NodeInspector_RenameVariable as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92569137")
def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project):
from . import Debugging_TargetMultipleGraphs as test_module
@ -195,7 +195,7 @@ class TestAutomation(TestAutomationBase):
def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform):
from . import NodeCategory_ExpandOnClick as test_module
self._run_test(request, workspace, editor, test_module)
def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform):
from . import NodePalette_SearchText_Deletion as test_module
self._run_test(request, workspace, editor, test_module)
@ -204,6 +204,10 @@ class TestAutomation(TestAutomationBase):
from . import VariableManager_UnpinVariableType_Works as test_module
self._run_test(request, workspace, editor, test_module)
def test_Node_HappyPath_DuplicateNode(self, request, workspace, editor, launcher_platform):
from . import Node_HappyPath_DuplicateNode as test_module
self._run_test(request, workspace, editor, test_module)
# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method
# fails because of pyside_utils import
@pytest.mark.SUITE_periodic

@ -0,0 +1,171 @@
{
"Source": "Levels/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab",
"ContainerEntity": {
"Id": "Entity_[403811863694]",
"Name": "Level",
"Components": {
"Component_[10582285743525614098]": {
"$type": "SelectionComponent",
"Id": 10582285743525614098
},
"Component_[12253783095375428046]": {
"$type": "EditorInspectorComponent",
"Id": 12253783095375428046
},
"Component_[13764860261821571747]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 13764860261821571747,
"Parent Entity": ""
},
"Component_[15844324401733835865]": {
"$type": "EditorEntitySortComponent",
"Id": 15844324401733835865
},
"Component_[1605854641405361768]": {
"$type": "EditorLockComponent",
"Id": 1605854641405361768
},
"Component_[17698173984524983803]": {
"$type": "EditorOnlyEntityComponent",
"Id": 17698173984524983803
},
"Component_[3444251662966224826]": {
"$type": "EditorPendingCompositionComponent",
"Id": 3444251662966224826
},
"Component_[4231768881195179982]": {
"$type": "EditorVisibilityComponent",
"Id": 4231768881195179982
},
"Component_[4722360315410084479]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 4722360315410084479
},
"Component_[7614719100624882952]": {
"$type": "EditorPrefabComponent",
"Id": 7614719100624882952
},
"Component_[9585901769691795481]": {
"$type": "EditorEntityIconComponent",
"Id": 9585901769691795481
}
},
"IsDependencyReady": true
},
"Entities": {
"Entity_[438171602062]": {
"Id": "Entity_[438171602062]",
"Name": "EntityWithPxCollider",
"Components": {
"Component_[11161653124805884473]": {
"$type": "EditorPendingCompositionComponent",
"Id": 11161653124805884473
},
"Component_[13116773315299882093]": {
"$type": "EditorOnlyEntityComponent",
"Id": 13116773315299882093
},
"Component_[15820915681461536711]": {
"$type": "EditorVisibilityComponent",
"Id": 15820915681461536711
},
"Component_[2222061938345834243]": {
"$type": "SelectionComponent",
"Id": 2222061938345834243
},
"Component_[3861913165076405600]": {
"$type": "EditorEntitySortComponent",
"Id": 3861913165076405600
},
"Component_[7118587015611303204]": {
"$type": "EditorLockComponent",
"Id": 7118587015611303204
},
"Component_[7751174327125555504]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 7751174327125555504
},
"Component_[8304730147756374057]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 8304730147756374057,
"Parent Entity": "Entity_[403811863694]",
"Transform Data": {
"Translate": [
0.0,
20.0,
34.0
]
}
},
"Component_[8866353210615920259]": {
"$type": "EditorEntityIconComponent",
"Id": 8866353210615920259
},
"Component_[8988181228601932779]": {
"$type": "EditorInspectorComponent",
"Id": 8988181228601932779
},
"Component_[7103333782129541775]": {
"$type": "EditorColliderComponent",
"Id": 7103333782129541775
}
},
"IsDependencyReady": true
},
"Entity_[532660882574]": {
"Id": "Entity_[532660882574]",
"Name": "EmptyEntity",
"Components": {
"Component_[16437814751543997955]": {
"$type": "EditorEntitySortComponent",
"Id": 16437814751543997955
},
"Component_[16751517102089557119]": {
"$type": "EditorPendingCompositionComponent",
"Id": 16751517102089557119
},
"Component_[16773275259304187949]": {
"$type": "EditorInspectorComponent",
"Id": 16773275259304187949
},
"Component_[17283539636910567200]": {
"$type": "SelectionComponent",
"Id": 17283539636910567200
},
"Component_[250004123617033400]": {
"$type": "EditorLockComponent",
"Id": 250004123617033400
},
"Component_[2791138963683667073]": {
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
"Id": 2791138963683667073,
"Parent Entity": "Entity_[403811863694]",
"Transform Data": {
"Translate": [
10.0,
20.0,
30.0
]
}
},
"Component_[3296942400051129145]": {
"$type": "EditorEntityIconComponent",
"Id": 3296942400051129145
},
"Component_[3422076964671342434]": {
"$type": "EditorOnlyEntityComponent",
"Id": 3422076964671342434
},
"Component_[3431895414183121731]": {
"$type": "EditorVisibilityComponent",
"Id": 3431895414183121731
},
"Component_[7072085777705148766]": {
"$type": "EditorDisabledCompositionComponent",
"Id": 7072085777705148766
}
},
"IsDependencyReady": true
}
}
}

@ -32,41 +32,6 @@ ly_add_target(
AZ::AzFramework
)
ly_add_target(
NAME CryCommon.EngineSettings.Static STATIC
NAMESPACE Legacy
FILES_CMAKE
crycommon_enginesettings_files.cmake
${pal_dir}/crycommon_enginesettings_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
.
${pal_dir}
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
AZ::AzFramework
)
ly_add_target(
NAME CryCommon.EngineSettings.RC.Static STATIC
NAMESPACE Legacy
FILES_CMAKE
crycommon_enginesettings_files.cmake
${pal_dir}/crycommon_enginesettings_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PUBLIC
.
${pal_dir}
COMPILE_DEFINITIONS
PRIVATE
RESOURCE_COMPILER
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
AZ::AzFramework
)
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_target(

@ -31,7 +31,7 @@ void CryAssertTrace(const char* szFormat, ...)
return;
}
if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting)
if (!gEnv->bIgnoreAllAsserts)
{
if (szFormat == NULL)
{

@ -34,7 +34,7 @@ void CryAssertTrace(const char* szFormat, ...)
return;
}
if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting)
if (!gEnv->bIgnoreAllAsserts)
{
if (szFormat == NULL)
{

@ -30,7 +30,7 @@ void CryAssertTrace(const char* szFormat, ...)
return;
}
if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting)
if (!gEnv->bIgnoreAllAsserts)
{
if (szFormat == NULL)
{

@ -31,7 +31,7 @@ void CryAssertTrace(const char* szFormat, ...)
return;
}
if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting)
if (!gEnv->bIgnoreAllAsserts)
{
if (szFormat == NULL)
{

@ -305,7 +305,7 @@ void CryAssertTrace(const char* _pszFormat, ...)
{
return;
}
if (!gEnv->bIgnoreAllAsserts || gEnv->bTesting)
if (!gEnv->bIgnoreAllAsserts)
{
if (NULL == _pszFormat)
{

@ -49,12 +49,6 @@ public:
//! ISystem has shut down.
virtual void OnCrySystemPostShutdown() {}
//! Engine pre physics update.
virtual void OnCrySystemPrePhysicsUpdate() {}
//! Engine post physics update.
virtual void OnCrySystemPostPhysicsUpdate() {}
//! Sent when a new level is being created.
virtual void OnCryEditorBeginCreate() {}

@ -37,9 +37,6 @@ enum CryLockType
#define CRYLOCK_HAVE_FASTLOCK 1
void CryThreadSetName(threadID nThreadId, const char* sThreadName);
const char* CryThreadGetName(threadID nThreadId);
/////////////////////////////////////////////////////////////////////////////
//
// Primitive locks and conditions.

@ -31,22 +31,3 @@
#else
// Put other platform specific includes here!
#endif
#include <IThreadTask.h>
void CryThreadSetName(threadID dwThreadId, const char* sThreadName)
{
if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager())
{
gEnv->pSystem->GetIThreadTaskManager()->SetThreadName(dwThreadId, sThreadName);
}
}
const char* CryThreadGetName(threadID dwThreadId)
{
if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIThreadTaskManager())
{
return gEnv->pSystem->GetIThreadTaskManager()->GetThreadName(dwThreadId);
}
return "";
}

@ -13,8 +13,6 @@
#pragma once
//#include <IThreadTask.h>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

@ -249,10 +249,6 @@ public:
void SetName(const char* Name)
{
m_name = Name;
if (m_threadId)
{
CryThreadSetName(m_threadId, m_name);
}
}
const char* GetName() { return m_name; }
@ -289,11 +285,6 @@ private:
self->m_bIsStarted = true;
self->m_bIsRunning = true;
if (!self->m_name.empty())
{
CryThreadSetName(-1, self->m_name);
}
self->m_Runnable->Run();
self->m_bIsRunning = false;
self->m_bCreatedThread = false;
@ -311,11 +302,6 @@ private:
self->m_bIsStarted = true;
self->m_bIsRunning = true;
if (!self->m_name.empty())
{
CryThreadSetName(-1, self->m_name);
}
self->Run();
self->m_bIsRunning = false;
self->m_bCreatedThread = false;

@ -1,34 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EngineSettingsBackend.h"
#ifdef CRY_ENABLE_RC_HELPER
CEngineSettingsBackend::CEngineSettingsBackend(CEngineSettingsManager* parent, const wchar_t* moduleName)
: m_parent(parent)
, m_moduleName()
{
if (moduleName != nullptr)
{
m_moduleName = moduleName;
}
}
CEngineSettingsBackend::~CEngineSettingsBackend()
{
}
#endif // CRY_ENABLE_RC_HELPER

@ -1,65 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H
#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H
#pragma once
#include "ProjectDefines.h"
#ifdef CRY_ENABLE_RC_HELPER
#include "SettingsManagerHelpers.h"
#include <string>
class CEngineSettingsManager;
class CEngineSettingsBackend
{
public:
CEngineSettingsBackend(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL);
virtual ~CEngineSettingsBackend();
virtual std::wstring GetModuleFilePath() const = 0;
virtual bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) = 0;
virtual bool GetModuleSpecificIntEntry(const char* key, int& value) = 0;
virtual bool GetModuleSpecificBoolEntry(const char* key, bool& value) = 0;
virtual bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) = 0;
virtual bool SetModuleSpecificIntEntry(const char* key, const int& value) = 0;
virtual bool SetModuleSpecificBoolEntry(const char* key, const bool& value) = 0;
virtual bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) = 0;
virtual void LoadEngineSettingsFromRegistry() = 0;
virtual bool StoreEngineSettingsToRegistry() = 0;
protected:
CEngineSettingsManager* parent() const
{
return m_parent;
}
const std::wstring& moduleName() const
{
return m_moduleName;
}
private:
std::wstring m_moduleName;
CEngineSettingsManager* m_parent;
};
#endif // CRY_ENABLE_RC_HELPER
#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKEND_H

@ -1,486 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EngineSettingsBackendApple.h"
#ifdef CRY_ENABLE_RC_HELPER
#include "AzCore/PlatformDef.h"
#if AZ_TRAIT_OS_PLATFORM_APPLE
#include "EngineSettingsManager.h"
#include "SettingsManagerHelpers.h"
#include "platform.h"
#include <dlfcn.h>
#include <mach-o/dyld.h>
#include <mach-o/nlist.h>
#include <cassert>
#include <codecvt>
#include <cstdlib>
#include <fstream>
#include <map>
#include <string>
using namespace SettingsManagerHelpers;
static const char gDefaultRegistryLocation[] = "/EngineSettings.reg";
#define REG_SOFTWARE L"Software\\"
#define REG_COMPANY_NAME L"Amazon\\"
#define REG_PRODUCT_NAME L"Lumberyard\\"
#define REG_SETTING L"Settings\\"
#define REG_BASE_SETTING_KEY REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME REG_SETTING
//////////////////////////////////////////////////////////////////////////
class SimpleRegistry
{
typedef std::map< std::wstring, std::wstring > WStringMap;
std::map< std::wstring, WStringMap * > m_modules;
public:
SimpleRegistry();
~SimpleRegistry();
void setBoolValue(const std::wstring& module, const std::wstring& key, bool value);
void setIntValue(const std::wstring& module, const std::wstring& key, int value);
void setStrValue(const std::wstring& module, const std::wstring& key, const std::wstring& value);
bool getBoolValue(const std::wstring& module, const std::wstring& key, bool& value);
bool getIntValue(const std::wstring& module, const std::wstring& key, int& value);
bool getStrValue(const std::wstring& module, const std::wstring& key, std::wstring& value);
bool loadFromFile(const char* fileName);
bool saveToFile(const char* fileName);
protected:
void clear();
private:
static const wchar_t gSimpleMagic[];
static const size_t gMetaCharCount;
};
const wchar_t SimpleRegistry::gSimpleMagic[] = L"FR0";
const size_t SimpleRegistry::gMetaCharCount = sizeof(size_t) / sizeof(wchar_t);
SimpleRegistry::SimpleRegistry()
{
}
SimpleRegistry::~SimpleRegistry()
{
clear();
}
void SimpleRegistry::setBoolValue(const std::wstring& module, const std::wstring& key, bool value)
{
return setStrValue(module, key, value ? L"true" : L"false");
}
void SimpleRegistry::setIntValue(const std::wstring& module, const std::wstring& key, int value)
{
return setStrValue(module, key, std::to_wstring(value));
}
void SimpleRegistry::setStrValue(const std::wstring& module, const std::wstring& key, const std::wstring& value)
{
WStringMap *map = nullptr;
auto i = m_modules.find(module);
if (i == m_modules.end())
{
map = new WStringMap;
m_modules.emplace(module, map);
}
else
{
map = i->second;
}
assert(map);
(*map)[key] = value;
}
bool SimpleRegistry::getBoolValue(const std::wstring& module, const std::wstring& key, bool& value)
{
std::wstring str;
if (!getStrValue(module, key, str))
{
return false;
}
value = (0 == str.compare(L"true"));
return true;
}
bool SimpleRegistry::getIntValue(const std::wstring& module, const std::wstring& key, int& value)
{
std::wstring str;
if (!getStrValue(module, key, str))
{
return false;
}
value = std::stoi(str);
return true;
}
bool SimpleRegistry::getStrValue(const std::wstring& module, const std::wstring& key, std::wstring& value)
{
WStringMap *map = nullptr;
auto mi = m_modules.find(module);
if (mi == m_modules.end())
{
return false;
}
map = mi->second;
assert(map);
auto ki = map->find(key);
if (ki == map->end())
{
return false;
}
value = ki->second;
return true;
}
bool SimpleRegistry::loadFromFile(const char* fileName)
{
clear();
std::wifstream file(fileName, std::ios_base::in|std::ios_base::binary);
file.imbue(std::locale(file.getloc(), new std::codecvt_utf16<wchar_t>));
if (!file.is_open())
{
AZ_Warning("EngineSettings", false, "Failed to open registry settings file: %s", fileName);
return false;
}
std::wstring module;
std::wstring key;
std::wstring value;
wchar_t buffer[512];
size_t size;
wchar_t meta[gMetaCharCount];
/* magic number */
if(!file.read(buffer, sizeof(gSimpleMagic) / sizeof(wchar_t)) ||
wcsncmp(gSimpleMagic, buffer, sizeof(gSimpleMagic) / sizeof(wchar_t)) != 0)
{
file.close();
AZ_Warning("EngineSettings", false, "Failed to load registry settings from file: %s", fileName);
return false;
}
while (file.good())
{
file.read(meta, gMetaCharCount);
if (!file.good())
{
break;
}
memcpy(&size, meta, sizeof(size));
file.read(buffer, size);
buffer[file.gcount()] = L'\0';
module = buffer;
file.read(meta, gMetaCharCount);
memcpy(&size, meta, sizeof(size));
file.read(buffer, size);
buffer[file.gcount()] = L'\0';
key = buffer;
file.read(meta, gMetaCharCount);
memcpy(&size, meta, sizeof(size));
file.read(buffer, size);
buffer[file.gcount()] = L'\0';
value = buffer;
setStrValue(module, key, value);
}
file.close();
return true;
}
bool SimpleRegistry::saveToFile(const char* fileName)
{
std::wofstream file(fileName, std::ios_base::out|std::ios_base::trunc|std::ios_base::binary);
file.imbue(std::locale(file.getloc(), new std::codecvt_utf16<wchar_t>));
if (!file.is_open())
{
return false;
}
std::wstring module;
size_t size;
wchar_t meta[gMetaCharCount];
/* magic number */
file.write(gSimpleMagic, sizeof(gSimpleMagic) / sizeof(wchar_t));
for (auto j : m_modules)
{
module = j.first;
for (auto i : *j.second)
{
size = module.size();
memcpy(meta, &size, sizeof(meta));
file.write(meta, gMetaCharCount);
file.write(module.c_str(), size);
size = i.first.size();
memcpy(meta, &size, sizeof(meta));
file.write(meta, gMetaCharCount);
file.write(i.first.c_str(), size);
size = i.second.size();
memcpy(meta, &size, sizeof(meta));
file.write(meta, gMetaCharCount);
file.write(i.second.c_str(), size);
}
}
file.close();
return true;
}
void SimpleRegistry::clear()
{
for (auto pair : m_modules)
{
delete pair.second;
}
m_modules.clear();
}
//////////////////////////////////////////////////////////////////////////
CEngineSettingsBackendApple::CEngineSettingsBackendApple(CEngineSettingsManager* parent, const wchar_t* moduleName)
: CEngineSettingsBackend(parent, moduleName)
, m_registry(new SimpleRegistry)
, m_registryFilePath()
{
std::string rootValue = gEnv->pFileIO->GetAlias("@root@");
if (rootValue.empty())
{
AZ_Warning("EngineSettings", false, "Could not get engine root.");
return;
}
rootValue.append(gDefaultRegistryLocation);
m_registryFilePath = rootValue;
}
CEngineSettingsBackendApple::~CEngineSettingsBackendApple()
{
delete m_registry, m_registry = nullptr;
}
std::wstring CEngineSettingsBackendApple::GetModuleFilePath() const
{
std::string path;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::string module = converter.to_bytes(moduleName());
void* handle = ::dlopen(module.c_str(), RTLD_LAZY);
if (handle)
{
const int c = _dyld_image_count();
for (int i = 0; i < c; ++i)
{
const char* image = _dyld_get_image_name(i);
const void* altHandle = dlopen(image, RTLD_LAZY);
if (handle == altHandle)
{
char absImage[PATH_MAX];
realpath(image, absImage);
char *ext = rindex(absImage, '.');
if (ext)
{
*ext = '\0';
}
path.append(absImage);
path.append(".ini");
break;
}
}
}
return converter.from_bytes(path);
}
bool CEngineSettingsBackendApple::GetModuleSpecificStringEntryUtf16(const char* key, CWCharBuffer wbuffer)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wkey = converter.from_bytes(key);
std::wstring str;
if (!m_registry->getStrValue(moduleName(), wkey, str))
{
return false;
}
std::wcscpy(wbuffer.getPtr(), str.c_str());
return true;
}
bool CEngineSettingsBackendApple::GetModuleSpecificIntEntry(const char* key, int& value)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wkey = converter.from_bytes(key);
return m_registry->getIntValue(moduleName(), wkey, value);
}
bool CEngineSettingsBackendApple::GetModuleSpecificBoolEntry(const char* key, bool& value)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wkey = converter.from_bytes(key);
return m_registry->getBoolValue(moduleName(), wkey, value);
}
bool CEngineSettingsBackendApple::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wkey = converter.from_bytes(key);
m_registry->setStrValue(moduleName(), wkey, str);
return true;
}
bool CEngineSettingsBackendApple::SetModuleSpecificIntEntry(const char* key, const int& value)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wkey = converter.from_bytes(key);
m_registry->setIntValue(moduleName(), wkey, value);
return true;
}
bool CEngineSettingsBackendApple::SetModuleSpecificBoolEntry(const char* key, const bool& value)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wkey = converter.from_bytes(key);
m_registry->setBoolValue(moduleName(), wkey, value);
return true;
}
bool CEngineSettingsBackendApple::GetInstalledBuildRootPathUtf16(const int index, CWCharBuffer name, CWCharBuffer path)
{
return false;
}
bool CEngineSettingsBackendApple::StoreEngineSettingsToRegistry()
{
bool bRet = true;
wchar_t buffer[1024];
// ResourceCompiler Specific
if (parent()->GetValueByRef("RC_ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
const bool b = wcscmp(buffer, L"true") == 0;
m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_ShowWindow", b);
}
if (parent()->GetValueByRef("RC_HideCustom", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
const bool b = wcscmp(buffer, L"true") == 0;
m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_HideCustom", b);
}
if (parent()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
m_registry->setStrValue(REG_BASE_SETTING_KEY, L"RC_Parameters", buffer);
}
if (parent()->GetValueByRef("RC_EnableSourceControl", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
const bool b = wcscmp(buffer, L"true") == 0;
m_registry->setBoolValue(REG_BASE_SETTING_KEY, L"RC_EnableSourceControl", b);
}
bRet &= m_registry->saveToFile(m_registryFilePath.c_str());
return bRet;
}
void CEngineSettingsBackendApple::LoadEngineSettingsFromRegistry()
{
if (!m_registry->loadFromFile(m_registryFilePath.c_str()))
{
return;
}
std::wstring wStrResult;
bool bResult;
if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"RootPath", wStrResult))
{
parent()->SetKey("ENG_RootPath", wStrResult.c_str());
}
// Engine Specific
if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"ENG_RootPath", wStrResult))
{
parent()->SetKey("ENG_RootPath", wStrResult.c_str());
}
// ResourceCompiler Specific
if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_ShowWindow", bResult))
{
parent()->SetKey("RC_ShowWindow", bResult);
}
if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_HideCustom", bResult))
{
parent()->SetKey("RC_HideCustom", bResult);
}
if (m_registry->getStrValue(REG_BASE_SETTING_KEY, L"RC_Parameters", wStrResult))
{
parent()->SetKey("RC_Parameters", wStrResult.c_str());
}
if (m_registry->getBoolValue(REG_BASE_SETTING_KEY, L"RC_EnableSourceControl", bResult))
{
parent()->SetKey("RC_EnableSourceControl", bResult);
}
}
#endif // AZ_TRAIT_OS_PLATFORM_APPLE
#endif // CRY_ENABLE_RC_HELPER

@ -1,51 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H
#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H
#pragma once
#include "EngineSettingsBackend.h"
#ifdef CRY_ENABLE_RC_HELPER
class CEngineSettingsManager;
class SimpleRegistry;
class CEngineSettingsBackendApple : public CEngineSettingsBackend
{
public:
CEngineSettingsBackendApple(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL);
~CEngineSettingsBackendApple();
std::wstring GetModuleFilePath() const override;
bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) override;
bool GetModuleSpecificIntEntry(const char* key, int& value) override;
bool GetModuleSpecificBoolEntry(const char* key, bool& value) override;
bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) override;
bool SetModuleSpecificIntEntry(const char* key, const int& value) override;
bool SetModuleSpecificBoolEntry(const char* key, const bool& value) override;
bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) override;
void LoadEngineSettingsFromRegistry() override;
bool StoreEngineSettingsToRegistry() override;
private:
SimpleRegistry *m_registry;
std::string m_registryFilePath;
};
#endif // CRY_ENABLE_RC_HELPER
#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDAPPLE_H

@ -1,431 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "EngineSettingsBackendWin32.h"
#ifdef CRY_ENABLE_RC_HELPER
#include "AzCore/PlatformDef.h"
#ifdef AZ_PLATFORM_WINDOWS
#include "EngineSettingsManager.h"
#include "platform.h"
#include <windows.h>
#define REG_SOFTWARE L"Software\\"
#define REG_COMPANY_NAME L"Amazon\\"
#define REG_PRODUCT_NAME L"Open 3D Engine\\"
#define REG_SETTING L"Settings\\"
#define REG_BASE_SETTING_KEY REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME REG_SETTING
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
using namespace SettingsManagerHelpers;
static bool g_bWindowQuit;
static CEngineSettingsManager* g_pThis = 0;
static const unsigned int IDC_hEditRootPath = 100;
static const unsigned int IDC_hBtnBrowse = 101;
namespace
{
class RegKey
{
public:
RegKey(const wchar_t* key, bool writeable);
~RegKey();
void* pKey;
};
RegKey::RegKey(const wchar_t* key, bool writeable)
{
HKEY hKey;
LONG result;
if (writeable)
{
result = RegCreateKeyExW(HKEY_CURRENT_USER, key, 0, 0, 0, KEY_WRITE, 0, &hKey, 0);
}
else
{
result = RegOpenKeyExW(HKEY_CURRENT_USER, key, 0, KEY_READ, &hKey);
}
pKey = hKey;
}
RegKey::~RegKey()
{
RegCloseKey((HKEY)pKey);
}
}
CEngineSettingsBackendWin32::CEngineSettingsBackendWin32(CEngineSettingsManager* parent, const wchar_t* moduleName)
: CEngineSettingsBackend(parent, moduleName)
{
}
std::wstring CEngineSettingsBackendWin32::GetModuleFilePath() const
{
wchar_t szFilename[_MAX_PATH];
GetModuleFileNameW((HINSTANCE)&__ImageBase, szFilename, _MAX_PATH);
wchar_t drive[_MAX_DRIVE];
wchar_t dir[_MAX_DIR];
wchar_t fname[_MAX_FNAME];
wchar_t ext[1] = L"";
_wsplitpath_s(szFilename, drive, dir, fname, ext);
_wmakepath_s(szFilename, drive, dir, fname, L"ini");
return szFilename;
}
bool CEngineSettingsBackendWin32::GetModuleSpecificStringEntryUtf16(const char* key, CWCharBuffer wbuffer)
{
CFixedString<wchar_t, 256> s = REG_BASE_SETTING_KEY;
s.append(moduleName().c_str());
RegKey superKey(s.c_str(), false);
if (!superKey.pKey)
{
wbuffer[0] = 0;
return false;
}
if (!GetRegValue(superKey.pKey, key, wbuffer))
{
wbuffer[0] = 0;
return false;
}
return true;
}
bool CEngineSettingsBackendWin32::GetModuleSpecificIntEntry(const char* key, int& value)
{
CFixedString<wchar_t, 256> s = REG_BASE_SETTING_KEY;
s.append(moduleName().c_str());
RegKey superKey(s.c_str(), false);
if (!superKey.pKey)
{
return false;
}
if (!GetRegValue(superKey.pKey, key, value))
{
value = 0;
return false;
}
return true;
}
bool CEngineSettingsBackendWin32::GetModuleSpecificBoolEntry(const char* key, bool& value)
{
CFixedString<wchar_t, 256> s = REG_BASE_SETTING_KEY;
s.append(moduleName().c_str());
RegKey superKey(s.c_str(), false);
if (!superKey.pKey)
{
return false;
}
if (!GetRegValue(superKey.pKey, key, value))
{
value = false;
return false;
}
return true;
}
bool CEngineSettingsBackendWin32::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str)
{
CFixedString<wchar_t, 256> s = REG_BASE_SETTING_KEY;
s.append(moduleName().c_str());
RegKey superKey(s.c_str(), true);
if (superKey.pKey)
{
return SetRegValue(superKey.pKey, key, str);
}
return false;
}
bool CEngineSettingsBackendWin32::SetModuleSpecificIntEntry(const char* key, const int& value)
{
CFixedString<wchar_t, 256> s = REG_BASE_SETTING_KEY;
s.append(moduleName().c_str());
RegKey superKey(s.c_str(), true);
if (superKey.pKey)
{
return SetRegValue(superKey.pKey, key, value);
}
return false;
}
bool CEngineSettingsBackendWin32::SetModuleSpecificBoolEntry(const char* key, const bool& value)
{
CFixedString<wchar_t, 256> s = REG_BASE_SETTING_KEY;
s.append(moduleName().c_str());
RegKey superKey(s.c_str(), true);
if (superKey.pKey)
{
return SetRegValue(superKey.pKey, key, value);
}
return false;
}
bool CEngineSettingsBackendWin32::GetInstalledBuildRootPathUtf16(const int index, CWCharBuffer name, CWCharBuffer path)
{
RegKey key(REG_BASE_SETTING_KEY L"O3DEExport\\ProjectBuilds", false);
if (key.pKey)
{
DWORD type;
DWORD nameSizeInBytes = DWORD(name.getSizeInBytes());
DWORD pathSizeInBytes = DWORD(path.getSizeInBytes());
LONG result = RegEnumValueW((HKEY)key.pKey, index, name.getPtr(), &nameSizeInBytes, NULL, &type, (BYTE*)path.getPtr(), &pathSizeInBytes);
if (result == ERROR_SUCCESS)
{
return true;
}
}
return false;
}
bool CEngineSettingsBackendWin32::StoreEngineSettingsToRegistry()
{
// make sure the path in registry exists
{
RegKey key0(REG_SOFTWARE REG_COMPANY_NAME, true);
if (!key0.pKey)
{
RegKey software(REG_SOFTWARE, true);
HKEY hKey;
RegCreateKeyW((HKEY)software.pKey, REG_COMPANY_NAME, &hKey);
if (!hKey)
{
return false;
}
}
RegKey key1(REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME, true);
if (!key1.pKey)
{
RegKey softwareCompany(REG_SOFTWARE REG_COMPANY_NAME, true);
HKEY hKey;
RegCreateKeyW((HKEY)softwareCompany.pKey, REG_COMPANY_NAME, &hKey);
if (!hKey)
{
return false;
}
}
RegKey key2(REG_BASE_SETTING_KEY, true);
if (!key2.pKey)
{
RegKey softwareCompanyProduct(REG_SOFTWARE REG_COMPANY_NAME REG_PRODUCT_NAME, true);
HKEY hKey;
RegCreateKeyW((HKEY)key2.pKey, REG_SETTING, &hKey);
if (!hKey)
{
return false;
}
}
}
bool bRet = true;
RegKey key(REG_BASE_SETTING_KEY, true);
if (!key.pKey)
{
bRet = false;
}
else
{
wchar_t buffer[1024];
// ResourceCompiler Specific
if (parent()->GetValueByRef("RC_ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
const bool b = wcscmp(buffer, L"true") == 0;
SetRegValue(key.pKey, "RC_ShowWindow", b);
}
if (parent()->GetValueByRef("RC_HideCustom", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
const bool b = wcscmp(buffer, L"true") == 0;
SetRegValue(key.pKey, "RC_HideCustom", b);
}
if (parent()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
SetRegValue(key.pKey, "RC_Parameters", buffer);
}
if (parent()->GetValueByRef("RC_EnableSourceControl", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
const bool b = wcscmp(buffer, L"true") == 0;
SetRegValue(key.pKey, "RC_EnableSourceControl", b);
}
}
return bRet;
}
void CEngineSettingsBackendWin32::LoadEngineSettingsFromRegistry()
{
wchar_t buffer[1024];
bool bResult;
// Engine Specific (Deprecated value)
RegKey key(REG_BASE_SETTING_KEY, false);
if (key.pKey)
{
if (GetRegValue(key.pKey, "RootPath", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
parent()->SetKey("ENG_RootPath", buffer);
}
// Engine Specific
if (GetRegValue(key.pKey, "ENG_RootPath", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
parent()->SetKey("ENG_RootPath", buffer);
}
// ResourceCompiler Specific
if (GetRegValue(key.pKey, "RC_ShowWindow", bResult))
{
parent()->SetKey("RC_ShowWindow", bResult);
}
if (GetRegValue(key.pKey, "RC_HideCustom", bResult))
{
parent()->SetKey("RC_HideCustom", bResult);
}
if (GetRegValue(key.pKey, "RC_Parameters", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
parent()->SetKey("RC_Parameters", buffer);
}
if (GetRegValue(key.pKey, "RC_EnableSourceControl", bResult))
{
parent()->SetKey("RC_EnableSourceControl", bResult);
}
}
}
bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, const wchar_t* value)
{
CFixedString<wchar_t, 256> name;
name.appendAscii(valueName);
size_t const sizeInBytes = (wcslen(value) + 1) * sizeof(value[0]);
return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_SZ, (BYTE*)value, DWORD(sizeInBytes)));
}
bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, bool value)
{
CFixedString<wchar_t, 256> name;
name.appendAscii(valueName);
DWORD dwVal = value;
return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_DWORD, (BYTE*)&dwVal, sizeof(dwVal)));
}
bool CEngineSettingsBackendWin32::SetRegValue(void* key, const char* valueName, int value)
{
CFixedString<wchar_t, 256> name;
name.appendAscii(valueName);
DWORD dwVal = value;
return (ERROR_SUCCESS == RegSetValueExW((HKEY)key, name.c_str(), 0, REG_DWORD, (BYTE*)&dwVal, sizeof(dwVal)));
}
bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, CWCharBuffer wbuffer)
{
if (wbuffer.getSizeInElements() <= 0)
{
return false;
}
CFixedString<wchar_t, 256> name;
name.appendAscii(valueName);
DWORD type;
DWORD sizeInBytes = DWORD(wbuffer.getSizeInBytes());
if (ERROR_SUCCESS != RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)wbuffer.getPtr(), &sizeInBytes))
{
wbuffer[0] = 0;
return false;
}
const size_t sizeInElements = sizeInBytes / sizeof(wbuffer[0]);
if (sizeInElements > wbuffer.getSizeInElements()) // paranoid check
{
wbuffer[0] = 0;
return false;
}
// According to MSDN documentation for RegQueryValueEx(), strings returned by the function
// are not zero-terminated sometimes, so we need to terminate them by ourselves.
if (wbuffer[sizeInElements - 1] != 0)
{
if (sizeInElements >= wbuffer.getSizeInElements())
{
// No space left to put terminating zero character
wbuffer[0] = 0;
return false;
}
wbuffer[sizeInElements] = 0;
}
return true;
}
bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, bool& value)
{
CFixedString<wchar_t, 256> name;
name.appendAscii(valueName);
// Open the appropriate registry key
DWORD type, dwVal = 0, size = sizeof(dwVal);
bool res = (ERROR_SUCCESS == RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)&dwVal, &size));
if (res)
{
value = (dwVal != 0);
}
else
{
wchar_t buffer[100];
res = GetRegValue(key, valueName, CWCharBuffer(buffer, sizeof(buffer)));
if (res)
{
value = (wcscmp(buffer, L"true") == 0);
}
}
return res;
}
bool CEngineSettingsBackendWin32::GetRegValue(void* key, const char* valueName, int& value)
{
CFixedString<wchar_t, 256> name;
name.appendAscii(valueName);
// Open the appropriate registry key
DWORD type, dwVal = 0, size = sizeof(dwVal);
bool res = (ERROR_SUCCESS == RegQueryValueExW((HKEY)key, name.c_str(), NULL, &type, (BYTE*)&dwVal, &size));
if (res)
{
value = dwVal;
}
return res;
}
#endif // AZ_PLATFORM_WINDOWS
#endif // CRY_ENABLE_RC_HELPER

@ -1,53 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H
#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H
#pragma once
#include "EngineSettingsBackend.h"
#ifdef CRY_ENABLE_RC_HELPER
class CEngineSettingsManager;
class CEngineSettingsBackendWin32 : public CEngineSettingsBackend
{
public:
CEngineSettingsBackendWin32(CEngineSettingsManager* parent, const wchar_t* moduleName = NULL);
std::wstring GetModuleFilePath() const override;
bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) override;
bool GetModuleSpecificIntEntry(const char* key, int& value) override;
bool GetModuleSpecificBoolEntry(const char* key, bool& value) override;
bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str) override;
bool SetModuleSpecificIntEntry(const char* key, const int& value) override;
bool SetModuleSpecificBoolEntry(const char* key, const bool& value) override;
bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path) override;
void LoadEngineSettingsFromRegistry() override;
bool StoreEngineSettingsToRegistry() override;
protected:
bool SetRegValue(void* key, const char* valueName, const wchar_t* value);
bool SetRegValue(void* key, const char* valueName, bool value);
bool SetRegValue(void* key, const char* valueName, int value);
bool GetRegValue(void* key, const char* valueName, SettingsManagerHelpers::CWCharBuffer wbuffer);
bool GetRegValue(void* key, const char* valueName, bool& value);
bool GetRegValue(void* key, const char* valueName, int& value);
};
#endif // CRY_ENABLE_RC_HELPER
#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSBACKENDWIN32_H

@ -1,479 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "ProjectDefines.h"
#include "EngineSettingsManager.h"
#if defined(CRY_ENABLE_RC_HELPER)
#include <assert.h> // assert()
#include "EngineSettingsBackend.h"
#include "AzCore/PlatformDef.h"
#include "platform.h"
#if defined(AZ_PLATFORM_WINDOWS)
#include "EngineSettingsBackendWin32.h"
#include <AzCore/PlatformIncl.h>
#elif AZ_TRAIT_OS_PLATFORM_APPLE
#include "EngineSettingsBackendApple.h"
#endif
#include <climits>
#include <cstdio>
#define INFOTEXT L"Please specify the directory of your CryENGINE installation (RootPath):"
using namespace SettingsManagerHelpers;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
CEngineSettingsManager::CEngineSettingsManager(const wchar_t* moduleName, const wchar_t* iniFileName)
: m_hWndParent(0)
, m_backend(NULL)
{
m_sModuleName.clear();
#if defined(AZ_PLATFORM_WINDOWS)
m_backend = new CEngineSettingsBackendWin32(this, moduleName);
#elif AZ_TRAIT_OS_PLATFORM_APPLE
m_backend = new CEngineSettingsBackendApple(this, moduleName);
#endif
assert(m_backend);
// std initialization
RestoreDefaults();
// try to load content from INI file
if (moduleName != NULL)
{
m_sModuleName = moduleName;
if (iniFileName == NULL)
{
// find INI filename located in module path
m_sModuleFileName = m_backend->GetModuleFilePath().c_str();
}
else
{
m_sModuleFileName = iniFileName;
}
if (LoadValuesFromConfigFile(m_sModuleFileName.c_str()))
{
m_bGetDataFromBackend = false;
return;
}
}
m_bGetDataFromBackend = true;
// load basic content from registry
LoadEngineSettingsFromRegistry();
}
//////////////////////////////////////////////////////////////////////////
CEngineSettingsManager::~CEngineSettingsManager()
{
delete m_backend, m_backend = NULL;
}
//////////////////////////////////////////////////////////////////////////
void CEngineSettingsManager::RestoreDefaults()
{
// Engine
SetKey("ENG_RootPath", L"");
// RC
SetKey("RC_ShowWindow", false);
SetKey("RC_HideCustom", false);
SetKey("RC_Parameters", L"");
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer)
{
if (wbuffer.getSizeInElements() <= 0)
{
return false;
}
if (!m_bGetDataFromBackend)
{
if (!HasKey(key))
{
wbuffer[0] = 0;
return false;
}
if (!GetValueByRef(key, wbuffer))
{
wbuffer[0] = 0;
return false;
}
}
else
{
assert(m_backend);
return m_backend->GetModuleSpecificStringEntryUtf16(key, wbuffer);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::GetModuleSpecificStringEntryUtf8(const char* key, SettingsManagerHelpers::CCharBuffer buffer)
{
if (buffer.getSizeInElements() <= 0)
{
return false;
}
wchar_t wBuffer[1024];
if (!GetModuleSpecificStringEntryUtf16(key, SettingsManagerHelpers::CWCharBuffer(wBuffer, sizeof(wBuffer))))
{
buffer[0] = 0;
return false;
}
SettingsManagerHelpers::ConvertUtf16ToUtf8(wBuffer, buffer);
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::GetModuleSpecificIntEntry(const char* key, int& value)
{
value = 0;
if (!m_bGetDataFromBackend)
{
if (!HasKey(key))
{
return false;
}
if (!GetValueByRef(key, value))
{
return false;
}
}
else
{
assert(m_backend);
return m_backend->GetModuleSpecificIntEntry(key, value);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::GetModuleSpecificBoolEntry(const char* key, bool& value)
{
value = false;
if (!m_bGetDataFromBackend)
{
if (!HasKey(key))
{
return false;
}
if (!GetValueByRef(key, value))
{
return false;
}
}
else
{
assert(m_backend);
return m_backend->GetModuleSpecificBoolEntry(key, value);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str)
{
SetKey(key, str);
if (!m_bGetDataFromBackend)
{
return StoreData();
}
assert(m_backend);
return m_backend->SetModuleSpecificStringEntryUtf16(key, str);
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::SetModuleSpecificIntEntry(const char* key, const int& value)
{
SetKey(key, value);
if (!m_bGetDataFromBackend)
{
return StoreData();
}
assert(m_backend);
return m_backend->SetModuleSpecificIntEntry(key, value);
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::SetModuleSpecificBoolEntry(const char* key, const bool& value)
{
SetKey(key, value);
if (!m_bGetDataFromBackend)
{
return StoreData();
}
assert(m_backend);
return m_backend->SetModuleSpecificBoolEntry(key, value);
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::SetModuleSpecificStringEntryUtf8(const char* key, const char* str)
{
wchar_t wbuffer[512];
SettingsManagerHelpers::ConvertUtf8ToUtf16(str, SettingsManagerHelpers::CWCharBuffer(wbuffer, sizeof(wbuffer)));
return SetModuleSpecificStringEntryUtf16(key, wbuffer);
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::HasKey(const char* key)
{
return m_keyValueArray.find(key) != 0;
}
//////////////////////////////////////////////////////////////////////////
void CEngineSettingsManager::SetKey(const char* key, const wchar_t* value)
{
m_keyValueArray.set(key, value);
}
//////////////////////////////////////////////////////////////////////////
void CEngineSettingsManager::SetKey(const char* key, bool value)
{
m_keyValueArray.set(key, (value ? L"true" : L"false"));
}
//////////////////////////////////////////////////////////////////////////
void CEngineSettingsManager::SetKey(const char* key, int value)
{
m_keyValueArray.set(key, std::to_wstring(value).c_str());
}
bool CEngineSettingsManager::GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path)
{
assert(m_backend);
return m_backend->GetInstalledBuildRootPathUtf16(index, name, path);
}
//////////////////////////////////////////////////////////////////////////
void CEngineSettingsManager::SetParentDialog(size_t window)
{
m_hWndParent = window;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::StoreData()
{
if (m_bGetDataFromBackend)
{
bool res = StoreEngineSettingsToRegistry();
if (!res)
{
#ifdef AZ_PLATFORM_WINDOWS
MessageBoxA(reinterpret_cast<HWND>(m_hWndParent), "Could not store data to registry.", "Error", MB_OK | MB_ICONERROR);
#endif
}
return res;
}
// store data to INI file
FILE* file;
#ifdef AZ_PLATFORM_WINDOWS
_wfopen_s(&file, m_sModuleFileName.c_str(), L"wb");
#else
char fname[MAX_PATH];
memset(fname, 0, MAX_PATH);
wcstombs(fname, m_sModuleFileName.c_str(), MAX_PATH);
file = fopen(fname, "wb");
#endif
if (file == NULL)
{
return false;
}
char buffer[2048];
for (size_t i = 0; i < m_keyValueArray.size(); ++i)
{
const SKeyValue& kv = m_keyValueArray[i];
fprintf_s(file, kv.key.c_str());
fprintf_s(file, " = ");
if (kv.value.length() > 0)
{
SettingsManagerHelpers::ConvertUtf16ToUtf8(kv.value.c_str(), SettingsManagerHelpers::CCharBuffer(buffer, sizeof(buffer)));
fprintf_s(file, "%s", buffer);
}
fprintf_s(file, "\r\n");
}
fclose(file);
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::LoadValuesFromConfigFile(const wchar_t* szFileName)
{
m_keyValueArray.clear();
// read file to memory
FILE* file;
#ifdef AZ_PLATFORM_WINDOWS
_wfopen_s(&file, szFileName, L"rb");
#else
char fname[MAX_PATH];
memset(fname, 0, MAX_PATH);
wcstombs(fname, szFileName, MAX_PATH);
file = fopen(fname, "rb");
#endif
if (file == NULL)
{
return false;
}
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
char* data = new char[size + 1];
fread_s(data, size, 1, size, file);
fclose(file);
wchar_t wBuffer[1024];
// parse file for root path
int start = 0, end = 0;
while (end < size)
{
while (end < size && data[end] != '\n')
{
end++;
}
memcpy(data, &data[start], end - start);
data[end - start] = 0;
start = end = end + 1;
CFixedString<char, 2048> line(data);
size_t equalsOfs;
for (equalsOfs = 0; equalsOfs < line.length(); ++equalsOfs)
{
if (line[equalsOfs] == '=')
{
break;
}
}
if (equalsOfs < line.length())
{
CFixedString<char, 256> key;
CFixedString<wchar_t, 1024> value;
key.appendAscii(line.c_str(), equalsOfs);
key.trim();
SettingsManagerHelpers::ConvertUtf8ToUtf16(line.c_str() + equalsOfs + 1, SettingsManagerHelpers::CWCharBuffer(wBuffer, sizeof(wBuffer)));
value.append(wBuffer);
value.trim();
m_keyValueArray.set(key.c_str(), value.c_str());
}
}
delete[] data;
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::StoreEngineSettingsToRegistry()
{
assert(m_backend);
return m_backend->StoreEngineSettingsToRegistry();
}
//////////////////////////////////////////////////////////////////////////
void CEngineSettingsManager::LoadEngineSettingsFromRegistry()
{
assert(m_backend);
m_backend->LoadEngineSettingsFromRegistry();
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::GetValueByRef(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) const
{
if (wbuffer.getSizeInElements() <= 0)
{
return false;
}
const SKeyValue* p = m_keyValueArray.find(key);
if (!p || (p->value.length() + 1) > wbuffer.getSizeInElements())
{
wbuffer[0] = 0;
return false;
}
azwcscpy(wbuffer.getPtr(), wbuffer.getSizeInElements(), p->value.c_str());
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::GetValueByRef(const char* key, bool& value) const
{
wchar_t buffer[100];
if (!GetValueByRef(key, SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
return false;
}
value = (wcscmp(buffer, L"true") == 0);
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CEngineSettingsManager::GetValueByRef(const char* key, int& value) const
{
wchar_t buffer[100];
if (!GetValueByRef(key, SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer))))
{
return false;
}
value = wcstol(buffer, 0, 10);
return true;
}
#endif //(CRY_ENABLE_RC_HELPER)

@ -1,89 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H
#define CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H
#pragma once
#include "ProjectDefines.h"
#if defined(CRY_ENABLE_RC_HELPER)
#include "SettingsManagerHelpers.h"
class CEngineSettingsBackend;
//////////////////////////////////////////////////////////////////////////
// Manages storage and loading of all information for tools and CryENGINE, by either registry or an INI file.
// Information can be read and set by key-to-value functions.
// Specific information can be set by a dialog application called by this class.
// If the engine root path is not found, a fall-back dialog is opened.
class CEngineSettingsManager
{
public:
// prepares CEngineSettingsManager to get requested information either from registry or an INI file,
// if existent as a file with name an directory equal to the module, or from registry.
CEngineSettingsManager(const wchar_t* moduleName = NULL, const wchar_t* iniFileName = NULL);
~CEngineSettingsManager();
void RestoreDefaults();
// stores/loads user specific information for modules to/from registry or INI file
bool GetModuleSpecificStringEntryUtf16(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer);
bool GetModuleSpecificStringEntryUtf8(const char* key, SettingsManagerHelpers::CCharBuffer buffer);
bool GetModuleSpecificIntEntry(const char* key, int& value);
bool GetModuleSpecificBoolEntry(const char* key, bool& value);
bool SetModuleSpecificStringEntryUtf16(const char* key, const wchar_t* str);
bool SetModuleSpecificStringEntryUtf8(const char* key, const char* str);
bool SetModuleSpecificIntEntry(const char* key, const int& value);
bool SetModuleSpecificBoolEntry(const char* key, const bool& value);
bool GetValueByRef(const char* key, SettingsManagerHelpers::CWCharBuffer wbuffer) const;
bool GetValueByRef(const char* key, bool& value) const;
bool GetValueByRef(const char* key, int& value) const;
void SetKey(const char* key, const wchar_t* value);
void SetKey(const char* key, bool value);
void SetKey(const char* key, int value);
bool StoreData();
bool GetInstalledBuildRootPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path);
void SetParentDialog(size_t window);
private:
bool HasKey(const char* key);
void LoadEngineSettingsFromRegistry();
bool StoreEngineSettingsToRegistry();
// parses a file and stores all flags in a private key-value-map
bool LoadValuesFromConfigFile(const wchar_t* szFileName);
private:
CEngineSettingsBackend *m_backend;
SettingsManagerHelpers::CFixedString<wchar_t, 256> m_sModuleName; // name to store key-value pairs of modules in (registry) or to identify INI file
SettingsManagerHelpers::CFixedString<wchar_t, 256> m_sModuleFileName; // used in case of data being loaded from INI file
bool m_bGetDataFromBackend;
SettingsManagerHelpers::CKeyValueArray<30> m_keyValueArray;
void* m_hBtnBrowse;
size_t m_hWndParent;
};
#endif // CRY_ENABLE_RC_HELPER
#endif // CRYINCLUDE_CRYCOMMON_ENGINESETTINGSMANAGER_H

@ -1,228 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_IFLARES_H
#define CRYINCLUDE_CRYCOMMON_IFLARES_H
#pragma once
#include <IFuncVariable.h> // <> required for Interfuscator
#include <IXml.h> // <> required for Interfuscator
#include "smartptr.h"
struct IShader;
class CCamera;
class __MFPA
{
};
class __MFPB
{
};
#define MFP_SIZE_ENFORCE : public __MFPA, public __MFPB
enum EFlareType
{
eFT__Base__,
eFT_Root,
eFT_Group,
eFT_Ghost,
eFT_MultiGhosts,
eFT_Glow,
eFT_ChromaticRing,
eFT_IrisShafts,
eFT_CameraOrbs,
eFT_ImageSpaceShafts,
eFT_Streaks,
eFT_Reference,
eFT_Proxy,
eFT_Max
};
#define FLARE_LIBS_PATH "libs/flares/"
#define FLARE_EXPORT_FILE "LensFlareList.xml"
#define FLARE_EXPORT_FILE_VERSION "1"
struct FlareInfo
{
EFlareType type;
const char* name;
#if defined(FLARES_SUPPORT_EDITING)
const char* imagename;
#endif
};
#if defined(FLARES_SUPPORT_EDITING)
# define ADD_FLARE_INFO(type, name, imagename) {type, name, imagename}
#else
# define ADD_FLARE_INFO(type, name, imagename) {type, name}
#endif
class FlareInfoArray
{
public:
struct Props
{
const FlareInfo* p;
size_t size;
};
static const Props Get()
{
static const FlareInfo flareInfoArray[] =
{
ADD_FLARE_INFO(eFT__Base__, "__Base__", NULL),
ADD_FLARE_INFO(eFT_Root, "Root", NULL),
ADD_FLARE_INFO(eFT_Group, "Group", NULL),
ADD_FLARE_INFO(eFT_Ghost, "Ghost", "EngineAssets/Textures/flares/icons/ghost.dds"),
ADD_FLARE_INFO(eFT_MultiGhosts, "Multi Ghost", "EngineAssets/Textures/flares/icons/multi_ghost.dds"),
ADD_FLARE_INFO(eFT_Glow, "Glow", "EngineAssets/Textures/flares/icons/glow.dds"),
ADD_FLARE_INFO(eFT_ChromaticRing, "ChromaticRing", "EngineAssets/Textures/flares/icons/ring.dds"),
ADD_FLARE_INFO(eFT_IrisShafts, "IrisShafts", "EngineAssets/Textures/flares/icons/iris_shafts.dds"),
ADD_FLARE_INFO(eFT_CameraOrbs, "CameraOrbs", "EngineAssets/Textures/flares/icons/orbs.dds"),
ADD_FLARE_INFO(eFT_ImageSpaceShafts, "Vol Shafts", "EngineAssets/Textures/flares/icons/vol_shafts.dds"),
ADD_FLARE_INFO(eFT_Streaks, "Streaks", "EngineAssets/Textures/flares/icons/iris_shafts.dds")
};
Props ret;
ret.p = flareInfoArray;
ret.size = sizeof(flareInfoArray) / sizeof(flareInfoArray[0]);
return ret;
}
private:
FlareInfoArray();
~FlareInfoArray();
};
struct SLensFlareRenderParam
{
SLensFlareRenderParam()
: pCamera(NULL)
, pShader(NULL)
{
}
~SLensFlareRenderParam(){}
bool IsValid() const
{
return pCamera && pShader;
}
CCamera* pCamera;
IShader* pShader;
};
class ISoftOcclusionQuery
{
public:
// <interfuscator:shuffle>
virtual ~ISoftOcclusionQuery() {}
virtual void AddRef() = 0;
virtual void Release() = 0;
// </interfuscator:shuffle>
};
class IOpticsElementBase MFP_SIZE_ENFORCE
{
public:
IOpticsElementBase()
: m_nRefCount(0)
{
}
void AddRef()
{
CryInterlockedIncrement(&m_nRefCount);
}
void Release()
{
if (CryInterlockedDecrement(&m_nRefCount) <= 0)
{
delete this;
}
}
// <interfuscator:shuffle>
virtual EFlareType GetType() = 0;
virtual bool IsGroup() const = 0;
virtual string GetName() const = 0;
virtual void SetName(const char* ch_name) = 0;
virtual void Load(IXmlNode* pNode) = 0;
virtual IOpticsElementBase* GetParent() const = 0;
virtual ~IOpticsElementBase() {
}
virtual bool IsEnabled() const = 0;
virtual void AddElement(IOpticsElementBase* pElement) = 0;
virtual void InsertElement(int nPos, IOpticsElementBase* pElement) = 0;
virtual void Remove(int i) = 0;
virtual void RemoveAll() = 0;
virtual int GetElementCount() const = 0;
virtual IOpticsElementBase* GetElementAt(int i) const = 0;
virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0;
virtual void Invalidate() = 0;
virtual void Render(SLensFlareRenderParam* pParam, const Vec3& vPos) = 0;
virtual void SetOpticsReference([[maybe_unused]] IOpticsElementBase* pReference) {}
virtual IOpticsElementBase* GetOpticsReference() const { return NULL; }
// </interfuscator:shuffle>
#if defined(FLARES_SUPPORT_EDITING)
virtual AZStd::vector<FuncVariableGroup> GetEditorParamGroups() = 0;
#endif
///Basic Setters///////////////////////////////////////////////////////////////
virtual void SetEnabled(bool enabled) { (void)enabled; }
virtual void SetSize(float size) { (void)size; }
virtual void SetPerspectiveFactor(float perspectiveFactor) { (void)perspectiveFactor; }
virtual void SetDistanceFadingFactor(float distanceFadingFactor) { (void)distanceFadingFactor; }
virtual void SetBrightness(float brightness) { (void)brightness; }
virtual void SetColor(ColorF color) { (void)color; }
virtual void SetMovement(Vec2 movement) { (void)movement; }
virtual void SetTransform(const Matrix33& xform) { (void)xform; }
virtual void SetOccBokehEnabled(bool occBokehEnabled) { (void)occBokehEnabled; }
virtual void SetOrbitAngle(float orbitAngle) { (void)orbitAngle; }
virtual void SetSensorSizeFactor(float sizeFactor) { (void)sizeFactor; }
virtual void SetSensorBrightnessFactor(float brightnessFactor) { (void)brightnessFactor; }
virtual void SetAutoRotation(bool autoRotation) { (void)autoRotation; }
virtual void SetAspectRatioCorrection(bool aspectRatioCorrection) { (void)aspectRatioCorrection; }
////////////////////////////////////////////////////////////////////////////////
private:
volatile int m_nRefCount;
};
class IOpticsManager
{
public:
// <interfuscator:shuffle>
virtual ~IOpticsManager(){}
virtual void Reset() = 0;
virtual IOpticsElementBase* Create(EFlareType type) const = 0;
virtual bool Load(const char* fullFlareName, int& nOutIndex, bool forceReload = false) = 0;
virtual bool Load(XmlNodeRef& rootNode, int& nOutIndex) = 0;
virtual IOpticsElementBase* GetOptics(int nIndex) = 0;
virtual bool AddOptics(IOpticsElementBase* pOptics, const char* name, int& nOutNewIndex, bool allowReplace = false) = 0;
virtual bool Rename(const char* fullFlareName, const char* newFullFlareName) = 0;
virtual void GetMemoryUsage(ICrySizer* pSizer) const = 0;
virtual void Invalidate() = 0;
// </interfuscator:shuffle>
};
typedef _smart_ptr<IOpticsElementBase> IOpticsElementBasePtr;
#endif // CRYINCLUDE_CRYCOMMON_IFLARES_H

@ -1,504 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Interface to the Material Effects System
#ifndef CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H
#define CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H
#pragma once
#if !defined(_RELEASE)
#define MATERIAL_EFFECTS_DEBUG
#endif
#include "CryFixedArray.h"
struct IRenderNode;
struct ISurfaceType;
//////////////////////////////////////////////////////////////////////////
enum EMFXPlayFlags
{
eMFXPF_Disable_Delay = BIT(0),
eMFXPF_Audio = BIT(1),
eMFXPF_Decal = BIT(2),
eMFXPF_Particles = BIT(3),
eMFXPF_Deprecated0 = BIT(4), // formerly eMFXPF_Flowgraph
eMFXPF_ForceFeedback = BIT(5),
eMFXPF_All = (eMFXPF_Audio | eMFXPF_Decal | eMFXPF_Particles | eMFXPF_Deprecated0 | eMFXPF_ForceFeedback),
};
#define MFX_INVALID_ANGLE (gf_PI2 + 1)
//////////////////////////////////////////////////////////////////////////
struct SMFXAudioEffectRtpc
{
SMFXAudioEffectRtpc()
{
rtpcName = "";
rtpcValue = 0.0f;
}
const char* rtpcName;
float rtpcValue;
};
//////////////////////////////////////////////////////////////////////////
struct SMFXRunTimeEffectParams
{
static const int MAX_AUDIO_RTPCS = 4;
SMFXRunTimeEffectParams()
: playSoundFP(false)
, playflags(eMFXPF_All)
, fLastTime(0.0f)
, srcSurfaceId(0)
, trgSurfaceId(0)
, srcRenderNode(0)
, trgRenderNode(0)
, partID(0)
, pos(ZERO)
, decalPos(ZERO)
, normal(0.0f, 0.0f, 1.0f)
, angle(MFX_INVALID_ANGLE)
, scale(1.0f)
, audioComponentOffset(ZERO)
, numAudioRtpcs(0)
, fDecalPlacementTestMaxSize(1000.f)
{
dir[0].Set(0.0f, 0.0f, -1.0f);
dir[1].Set(0.0f, 0.0f, 1.0f);
}
bool AddAudioRtpc(const char* name, float val)
{
if (numAudioRtpcs < MAX_AUDIO_RTPCS)
{
audioRtpcs[numAudioRtpcs].rtpcName = name;
audioRtpcs[numAudioRtpcs].rtpcValue = val;
++numAudioRtpcs;
return true;
}
return false;
}
void ResetAudioRtpcs()
{
numAudioRtpcs = 0;
}
public:
uint16 playSoundFP; // Sets 1p/3p audio switch
uint16 playflags; // See EMFXPlayFlags
float fLastTime; // Last time this effect was played
float fDecalPlacementTestMaxSize;
int srcSurfaceId;
int trgSurfaceId;
IRenderNode* srcRenderNode;
IRenderNode* trgRenderNode;
int partID;
Vec3 pos;
Vec3 decalPos;
Vec3 dir[2];
Vec3 normal;
float angle;
float scale;
// audio related
Vec3 audioComponentOffset; // in case of audio component, uses this offset
SMFXAudioEffectRtpc audioRtpcs[MAX_AUDIO_RTPCS];
uint32 numAudioRtpcs;
};
struct SMFXBreakageParams
{
enum EBreakageRequestFlags
{
eBRF_Matrix = BIT(0),
eBRF_HitPos = BIT(1),
eBRF_HitImpulse = BIT(2),
eBRF_Velocity = BIT(3),
eBRF_ExplosionImpulse = BIT(4),
eBRF_Mass = BIT(5),
eBFR_Entity = BIT(6),
};
SMFXBreakageParams()
: m_flags(0)
, m_worldTM(IDENTITY)
, m_vHitPos(ZERO)
, m_vHitImpulse(IDENTITY)
, m_vVelocity(ZERO)
, m_fExplosionImpulse(1.0f)
, m_fMass(0.0f)
{
}
// Matrix
void SetMatrix(const Matrix34& worldTM)
{
m_worldTM = worldTM;
SetFlag(eBRF_Matrix);
}
const Matrix34& GetMatrix() const
{
return m_worldTM;
}
// HitPos
void SetHitPos(const Vec3& vHitPos)
{
m_vHitPos = vHitPos;
SetFlag(eBRF_HitPos);
}
const Vec3& GetHitPos() const
{
return m_vHitPos;
}
// HitImpulse
void SetHitImpulse(const Vec3& vHitImpulse)
{
m_vHitImpulse = vHitImpulse;
SetFlag(eBRF_HitImpulse);
}
const Vec3& GetHitImpulse() const
{
return m_vHitImpulse;
}
// Velocity
void SetVelocity(const Vec3& vVelocity)
{
m_vVelocity = vVelocity;
SetFlag(eBRF_Velocity);
}
const Vec3& GetVelocity() const
{
return m_vVelocity;
}
// Explosion Impulse
void SetExplosionImpulse(float fExplosionImpulse)
{
m_fExplosionImpulse = fExplosionImpulse;
SetFlag(eBRF_ExplosionImpulse);
}
float GetExplosionImpulse() const
{
return m_fExplosionImpulse;
}
// Mass
void SetMass(float fMass)
{
m_fMass = fMass;
SetFlag(eBRF_Mass);
}
float GetMass() const
{
return m_fMass;
}
// Checking for flags
bool CheckFlag(EBreakageRequestFlags flag) const
{
return (m_flags & flag) != 0;
}
protected:
void SetFlag(EBreakageRequestFlags flag)
{
m_flags |= flag;
}
void ClearFlag(EBreakageRequestFlags flag)
{
m_flags &= ~flag;
}
uint32 m_flags;
Matrix34 m_worldTM;
Vec3 m_vHitPos;
Vec3 m_vHitImpulse;
Vec3 m_vVelocity;
float m_fExplosionImpulse;
float m_fMass;
};
class IMFXParticleParams
{
public:
IMFXParticleParams()
: name(NULL)
, userdata(NULL)
, scale(1.0f)
{
}
const char* name;
const char* userdata;
float scale;
};
class SMFXParticleListNode
{
public:
static SMFXParticleListNode* Create();
void Destroy();
static void FreePool();
IMFXParticleParams m_particleParams;
SMFXParticleListNode* pNext;
private:
SMFXParticleListNode()
{
pNext = NULL;
}
~SMFXParticleListNode() {}
};
class IMFXAudioParams
{
const static uint MAX_SWITCH_DATA_ELEMENTS = 4;
public:
struct SSwitchData
{
SSwitchData()
: switchName(NULL)
, switchStateName(NULL)
{
}
const char* switchName;
const char* switchStateName;
};
IMFXAudioParams()
: triggerName(NULL)
{
}
const char* triggerName;
CryFixedArray<SSwitchData, MAX_SWITCH_DATA_ELEMENTS> triggerSwitches;
};
class SMFXAudioListNode
{
public:
static SMFXAudioListNode* Create();
void Destroy();
static void FreePool();
IMFXAudioParams m_audioParams;
SMFXAudioListNode* pNext;
private:
SMFXAudioListNode()
: pNext(NULL)
{
}
~SMFXAudioListNode()
{
}
};
class IMFXDecalParams
{
public:
IMFXDecalParams()
{
filename = 0;
material = 0;
minscale = 1.f;
maxscale = 1.f;
rotation = -1.f;
lifetime = 10.0f;
assemble = false;
forceedge = false;
}
const char* filename;
const char* material;
float minscale;
float maxscale;
float rotation;
float lifetime;
bool assemble;
bool forceedge;
};
class SMFXDecalListNode
{
public:
static SMFXDecalListNode* Create();
void Destroy();
static void FreePool();
IMFXDecalParams m_decalParams;
SMFXDecalListNode* pNext;
private:
SMFXDecalListNode()
{
pNext = 0;
}
~SMFXDecalListNode() {}
};
class IMFXForceFeedbackParams
{
public:
IMFXForceFeedbackParams()
: forceFeedbackEventName (NULL)
, intensityFallOffMinDistanceSqr(0.0f)
, intensityFallOffMaxDistanceSqr(0.0f)
{
}
const char* forceFeedbackEventName;
float intensityFallOffMinDistanceSqr;
float intensityFallOffMaxDistanceSqr;
};
class SMFXForceFeedbackListNode
{
public:
static SMFXForceFeedbackListNode* Create();
void Destroy();
static void FreePool();
IMFXForceFeedbackParams m_forceFeedbackParams;
SMFXForceFeedbackListNode* pNext;
private:
SMFXForceFeedbackListNode()
: pNext(NULL)
{
}
~SMFXForceFeedbackListNode() {}
};
struct SMFXResourceList;
typedef _smart_ptr<SMFXResourceList> SMFXResourceListPtr;
struct SMFXResourceList
{
public:
SMFXParticleListNode* m_particleList;
SMFXAudioListNode* m_audioList;
SMFXDecalListNode* m_decalList;
SMFXForceFeedbackListNode* m_forceFeedbackList;
void AddRef() { ++m_refs; }
void Release()
{
if (--m_refs <= 0)
{
Destroy();
}
}
static SMFXResourceListPtr Create();
static void FreePool();
private:
int m_refs;
virtual void Destroy();
SMFXResourceList()
: m_refs(0)
{
m_particleList = 0;
m_audioList = 0;
m_decalList = 0;
m_forceFeedbackList = 0;
}
virtual ~SMFXResourceList()
{
while (m_particleList != 0)
{
SMFXParticleListNode* next = m_particleList->pNext;
m_particleList->Destroy();
m_particleList = next;
}
while (m_audioList != 0)
{
SMFXAudioListNode* next = m_audioList->pNext;
m_audioList->Destroy();
m_audioList = next;
}
while (m_decalList != 0)
{
SMFXDecalListNode* next = m_decalList->pNext;
m_decalList->Destroy();
m_decalList = next;
}
while (m_forceFeedbackList != 0)
{
SMFXForceFeedbackListNode* next = m_forceFeedbackList->pNext;
m_forceFeedbackList->Destroy();
m_forceFeedbackList = next;
}
}
};
typedef uint16 TMFXEffectId;
static const TMFXEffectId InvalidEffectId = 0;
struct SMFXCustomParamValue
{
float fValue;
};
//////////////////////////////////////////////////////////////////////////
struct IMaterialEffects
{
// <interfuscator:shuffle>
virtual ~IMaterialEffects(){}
virtual void LoadFXLibraries() = 0;
virtual void Reset(bool bCleanup) = 0;
virtual void ClearDelayedEffects() = 0;
virtual TMFXEffectId GetEffectIdByName(const char* libName, const char* effectName) = 0;
virtual TMFXEffectId GetEffectId(int surfaceIndex1, int surfaceIndex2) = 0;
virtual TMFXEffectId GetEffectId(const char* customName, int surfaceIndex2) = 0;
virtual SMFXResourceListPtr GetResources(TMFXEffectId effectId) const = 0;
virtual void PreLoadAssets() = 0;
virtual bool ExecuteEffect(TMFXEffectId effectId, SMFXRunTimeEffectParams& runtimeParams) = 0;
virtual int GetDefaultSurfaceIndex() = 0;
virtual int GetDefaultCanopyIndex() = 0;
virtual bool PlayBreakageEffect(ISurfaceType* pSurfaceType, const char* breakageType, const SMFXBreakageParams& mfxBreakageParams) = 0;
virtual void SetCustomParameter(TMFXEffectId effectId, const char* customParameter, const SMFXCustomParamValue& customParameterValue) = 0;
virtual void CompleteInit() = 0;
// </interfuscator:shuffle>
};
#endif // CRYINCLUDE_CRYCOMMON_IMATERIALEFFECTS_H

@ -1,147 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H
#define CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H
#pragma once
// Constants
#define NN_CHANNEL_NAME_LENGTH_MAX 16
struct INotificationNetworkClient;
// User Interfaces
struct INotificationNetworkListener
{
// <interfuscator:shuffle>
virtual ~INotificationNetworkListener(){}
// Called upon receiving data from the Channel the Listener is binded to.
virtual void OnNotificationNetworkReceive(const void* pBuffer, size_t length) = 0;
// </interfuscator:shuffle>
};
struct INotificationNetworkConnectionCallback
{
// <interfuscator:shuffle>
virtual ~INotificationNetworkConnectionCallback(){}
virtual void OnConnect(INotificationNetworkClient* pClient, bool bSucceeded) = 0;
virtual void OnDisconnected(INotificationNetworkClient* pClient) = 0;
// </interfuscator:shuffle>
};
// Interfaces
struct INotificationNetworkClient
{
// <interfuscator:shuffle>
virtual ~INotificationNetworkClient(){}
virtual void Release() = 0;
// Binds a Listener to the given Notification Channel.
// Each Listener can be binded only to one Channel, calling the method
// again with an already added Listener and a different Channel will rebind it.
// The Channel name cannot exceed NN_CHANNEL_NAME_LENGTH_MAX chars.
virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener) = 0;
// If it exist, removes the given Listener form the Notification Network.
virtual bool ListenerRemove(INotificationNetworkListener* pListener) = 0;
// Sends arbitrary data to the Notification Network the Client is connected to.
virtual bool Send(const char* channelName, const void* pBuffer, size_t length) = 0;
// Checks if the current client is connected.
// Returns true if it is connected, false otherwise.
virtual bool IsConnected() = 0;
// Checks if the connection attempt failed.
// Returns true if it failed to connect by any reason (such as timeout).
virtual bool IsFailedToConnect() const = 0;
// Start the connection request for this particular client.
// Parameters:
// address - Is the host name or ipv4 (for now) address string to which
// we want to connect.
// port - Is the TCP port to which we want to connect.
// Remarks: Port 9432 is being used by the live preview already.
virtual bool Connect(const char* address, uint16 port) = 0;
// Tries to register a callback listener object.
// A callback listener object will receive events from the client element,
// such as connection result information.
// Parameters:
// - pConnectionCallback - Is a pointer to an object implementing interface
// INotificationNetworkConnectionCallback which will be called when
// the events happen, such as connection, disconnection and failed attempt
// to connect.
// Return Value:
// - It will return true if registered the callback object successfully.
// - It will return false when there the callback object is already
// registered.
virtual bool RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) = 0;
// Tries to unregister a callback listener object.
// A callback listener object will receive events from the client element,
// such as connection result information.
// Parameters:
// - pConnectionCallback - Is a pointer to an object implementing interface
// INotificationNetworkConnectionCallback which will be called when
// the events happen, such as connection, disconnection and failed attempt
// to connect and that we want to unregister.
// Return Value:
// - It will return true if unregistered the callback object successfully.
// - It will return false when no object matching the one requested is found
// int the object.
virtual bool UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback) = 0;
// </interfuscator:shuffle>
};
struct INotificationNetwork
{
// <interfuscator:shuffle>
virtual ~INotificationNetwork(){}
virtual void Release() = 0;
// Creates a disconnected client.
virtual INotificationNetworkClient* CreateClient() = 0;
// Attempts to connect to the Notification Network at the given address,
// returns a Client interface if communication is possible.
virtual INotificationNetworkClient* Connect(const char* address, uint16 port) = 0;
// Returns the Connection count of the given Channel. If NULL is passed
// instead of a valid Channel name the total count of all Connections is
// returned.
virtual size_t GetConnectionCount(const char* channelName = NULL) = 0;
// Has to be called from the main thread to process received notifications.
virtual void Update() = 0;
// Binds a Listener to the given Notification Channel.
// Each Listener can be binded only to one Channel, calling the method
// again with an already added Listener and a different Channel will rebind it.
// The Channel name cannot exceed NN_CHANNEL_NAME_LENGTH_MAX chars.
virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener) = 0;
// If it exist, removes the given Listener form the Notification Network.
virtual bool ListenerRemove(INotificationNetworkListener* pListener) = 0;
// Sends arbitrary data to all the Connections listening to the given Channel.
virtual uint32 Send(const char* channel, const void* pBuffer, size_t length) = 0;
// </interfuscator:shuffle>
};
#endif // CRYINCLUDE_CRYCOMMON_INOTIFICATIONNETWORK_H

@ -16,12 +16,12 @@
#include "Cry_Geo.h"
#include "Cry_Camera.h"
#include "ITexture.h"
#include <IFlares.h> // <> required for Interfuscator
#include <IFuncVariable.h> // <> required for Interfuscator
#include <IXml.h> // <> required for Interfuscator
#include "smartptr.h"
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/std/containers/intrusive_slist.h>
#include "IResourceCompilerHelper.h" // for IResourceCompilerHelper::ERcCallResult
// forward declarations
struct SRenderingPassInfo;
struct SRTStack;
@ -95,7 +95,6 @@ struct IFFont;
struct IFFont_RenderProxy;
struct STextDrawContext;
struct IRenderMesh;
class IOpticsManager;
struct ShadowFrustumMGPUCache;
struct IAsyncTextureCompileListener;
struct IClipVolume;
@ -955,25 +954,6 @@ protected:
virtual ~ITextureStreamListener() {}
};
#if defined(CRY_ENABLE_RC_HELPER)
////////////////////////////////////////////////////////////////////////////
// Listener for asynchronous texture compilation.
// Connects the listener to the task-queue of pending compilation requests.
enum ERcExitCode;
struct IAsyncTextureCompileListener
{
public:
virtual void OnCompilationStarted(const char* source, const char* target, int nPending) = 0;
virtual void OnCompilationFinished(const char* source, const char* target, IResourceCompilerHelper::ERcCallResult nReturnCode) = 0;
virtual void OnCompilationQueueTriggered(int nPending) = 0;
virtual void OnCompilationQueueDepleted() = 0;
protected:
virtual ~IAsyncTextureCompileListener() {}
};
#endif
enum eDolbyVisionMode
{
eDVM_Disabled,
@ -1869,8 +1849,6 @@ struct IRenderer
virtual SDepthTexture* CreateDepthSurface(int nWidth, int nHeight, bool shaderResourceView = false) = 0;
virtual void DestroyDepthSurface(SDepthTexture* pDepthSurf) = 0;
virtual IOpticsElementBase* CreateOptics(EFlareType type) const = 0;
// Note:
// Used for pausing timer related stuff.
// Example:

@ -1,378 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "IResourceCompilerHelper.h"
#include <AzCore/base.h>
// DO NOT USE AZSTD.
#include <string> // std string used here.
#include <memory>
#include <cstring>
// the following block is for _mkdir on windows and mkdir on other platforms.
#if defined(_WIN32)
# include <direct.h>
#else
# include <sys/stat.h>
# include <sys/types.h>
#endif
namespace RCPathUtil
{
const char* GetExt(const char* filepath)
{
const char* str = filepath;
size_t len = strlen(filepath);
for (const char* p = str + len - 1; p >= str; --p)
{
switch (*p)
{
case ':':
case '/':
case '\\':
// we've reached a path separator - it means there's no extension in this name
return "";
case '.':
// there's an extension in this file name
return p + 1;
}
}
return "";
}
const char* GetFile(const char* filepath)
{
const size_t len = strlen(filepath);
for (const char* p = filepath + len - 1; p >= filepath; --p)
{
switch (*p)
{
case ':':
case '/':
case '\\':
return p + 1;
}
}
return filepath;
}
//! Replace extension for given file.
std::string RemoveExtension(const char* filepath)
{
std::string filepathstr = filepath;
const char* str = filepathstr.c_str();
for (const char* p = str + filepathstr.length() - 1; p >= str; --p)
{
switch (*p)
{
case ':':
case '/':
case '\\':
// we've reached a path separator - it means there's no extension in this name
return filepathstr;
case '.':
// there's an extension in this file name
filepathstr.erase(p - str);
return filepathstr;
}
}
// it seems the file name is a pure name, without path or extension
return filepathstr;
}
std::string ReplaceExtension(const char* filepath, const char* ext)
{
std::string str = filepath;
if (ext != 0)
{
str = RemoveExtension(str.c_str());
if (ext[0] != 0 && ext[0] != '.')
{
str += ".";
}
str += ext;
}
return str;
}
std::string GetPath(const char* filepath)
{
std::string filepathstr = filepath;
const char* str = filepathstr.c_str();
for (const char* p = str + filepathstr.length() - 1; p >= str; --p)
{
switch (*p)
{
case ':':
case '/':
case '\\':
// we've reached a path separator - it means there's no extension in this name
return filepathstr.substr(0, p - str);
}
}
// it seems the file name is a pure name, without path
return "";
}
//////////////////////////////////////////////////////////////////////////
bool IsRelativePath(const char* p)
{
if (!p || !p[0])
{
return true;
}
return p[0] != '/' && p[0] != '\\' && !strchr(p, ':');
}
}
const char* IResourceCompilerHelper::SourceImageFormatExts[NUM_SOURCE_IMAGE_TYPE] = { "tif", "bmp", "gif", "jpg", "jpeg", "jpe", "tga", "png" };
const char* IResourceCompilerHelper::SourceImageFormatExtsWithDot[NUM_SOURCE_IMAGE_TYPE] = { ".tif", ".bmp", ".gif", ".jpg", ".jpeg", ".jpe", ".tga", ".png" };
const char* IResourceCompilerHelper::EngineImageFormatExts[NUM_ENGINE_IMAGE_TYPE] = { "dds" };
const char* IResourceCompilerHelper::EngineImageFormatExtsWithDot[NUM_ENGINE_IMAGE_TYPE] = { ".dds" };
IResourceCompilerHelper::ERcCallResult IResourceCompilerHelper::ConvertResourceCompilerExitCodeToResultCode(int exitCode)
{
switch (exitCode)
{
case eRcExitCode_Success:
case eRcExitCode_UserFixing:
return eRcCallResult_success;
case eRcExitCode_Error:
return eRcCallResult_error;
case eRcExitCode_FatalError:
return eRcCallResult_error;
case eRcExitCode_Crash:
return eRcCallResult_crash;
}
return eRcCallResult_error;
}
//////////////////////////////////////////////////////////////////////////
const char* IResourceCompilerHelper::GetCallResultDescription(IResourceCompilerHelper::ERcCallResult result)
{
switch (result)
{
case eRcCallResult_success:
return "Success.";
case eRcCallResult_notFound:
return "ResourceCompiler executable was not found.";
case eRcCallResult_error:
return "ResourceCompiler exited with an error.";
case eRcCallResult_crash:
return "ResourceCompiler crashed! Please report this. Include source asset and this log in the report.";
default:
return "Unexpected failure in ResultCompilerHelper.";
}
}
// Arguments:
// szFilePath - could be source or destination filename
void IResourceCompilerHelper::GetOutputFilename(const char* szFilePath, char* buffer, size_t bufferSizeInBytes)
{
if (IResourceCompilerHelper::IsSourceImageFormatSupported(szFilePath))
{
std::string newString = RCPathUtil::ReplaceExtension(szFilePath, "dds");
azstrncpy(buffer, bufferSizeInBytes, newString.c_str(), bufferSizeInBytes - 1);
return;
}
azstrncpy(buffer, bufferSizeInBytes, szFilePath, bufferSizeInBytes - 1);
}
IResourceCompilerHelper::ERcCallResult IResourceCompilerHelper::InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog)
{
const char* szDstFileName = RCPathUtil::GetFile(szDstFilePath);
std::string pathOnly = RCPathUtil::GetPath(szDstFilePath);
const int maxStringSize = 512;
char szRemoteCmdLine[maxStringSize] = { 0 };
char szFullPathToSourceFile[maxStringSize] = { 0 };
if (RCPathUtil::IsRelativePath(szSrcFilePath))
{
azstrcat(szFullPathToSourceFile, maxStringSize, "#ENGINEROOT#");
azstrcat(szFullPathToSourceFile, maxStringSize, "\\");
}
azstrcat(szFullPathToSourceFile, maxStringSize, szSrcFilePath);
azstrcat(szRemoteCmdLine, maxStringSize, " /targetroot=\"");
azstrcat(szRemoteCmdLine, maxStringSize, pathOnly.c_str());
azstrcat(szRemoteCmdLine, maxStringSize, "\"");
azstrcat(szRemoteCmdLine, maxStringSize, " /overwritefilename=\"");
azstrcat(szRemoteCmdLine, maxStringSize, szDstFileName);
azstrcat(szRemoteCmdLine, maxStringSize, "\"");
return CallResourceCompiler(szFullPathToSourceFile, szRemoteCmdLine, nullptr, true, false, !bUserDialog);
}
unsigned int IResourceCompilerHelper::GetNumSourceImageFormats()
{
return NUM_SOURCE_IMAGE_TYPE;
}
const char* IResourceCompilerHelper::GetSourceImageFormat(unsigned int index, bool bWithDot)
{
if (index >= GetNumSourceImageFormats())
{
return nullptr;
}
if (bWithDot)
{
return SourceImageFormatExtsWithDot[index];
}
else
{
return SourceImageFormatExts[index];
}
}
unsigned int IResourceCompilerHelper::GetNumEngineImageFormats()
{
return NUM_ENGINE_IMAGE_TYPE;
}
const char* IResourceCompilerHelper::GetEngineImageFormat(unsigned int index, bool bWithDot)
{
if (index >= GetNumEngineImageFormats())
{
return nullptr;
}
if (bWithDot)
{
return EngineImageFormatExtsWithDot[index];
}
else
{
return EngineImageFormatExts[index];
}
}
bool IResourceCompilerHelper::IsSourceImageFormatSupported(const char* szFileNameOrExtension)
{
if (!szFileNameOrExtension) // if this hits, might want to check the call site
{
return false;
}
//check the string length
size_t len = strlen(szFileNameOrExtension);
if (len < 3)//no point in going on if the smallest valid ext is 3 characters
{
return false;
}
//find the ext by starting at the last character and moving backward to first he first '.'
const char* szExtension = nullptr;
size_t cur = len - 1;
while (cur && !szExtension)
{
if (szFileNameOrExtension[cur] == '.')
{
szExtension = &szFileNameOrExtension[cur];
}
cur--;
}
if (len - cur < 3)//no point in going on if the smallest valid ext is 3 characters
{
return false;
}
//if we didn't find a '.' it could still be valid, they may not have
//passed it in. i.e. "dds" instead of ".dds" which is still valid
if (!szExtension)
{
//with no '.' the largest ext is currently 4 characters
//no point in going on if it is larger
if (len > 4)
{
return false;
}
szExtension = szFileNameOrExtension;
}
//loop over all the valid exts and see if it is one of them
for (unsigned int i = 0; i < GetNumSourceImageFormats(); ++i)
{
if (!azstricmp(szExtension, GetSourceImageFormat(i, szExtension[0] == '.')))
{
return true;
}
}
return false;
}
bool IResourceCompilerHelper::IsGameImageFormatSupported(const char* szFileNameOrExtension)
{
if (!szFileNameOrExtension) // if this hits, might want to check the call site
{
return false;
}
//check the string length
size_t len = strlen(szFileNameOrExtension);
if (len < 3)//no point in going on if the smallest valid ext is 3 characters
{
return false;
}
//find the ext by starting at the last character and moving backward to first he first '.'
const char* szExtension = nullptr;
size_t cur = len - 1;
while (cur && !szExtension)
{
if (szFileNameOrExtension[cur] == '.')
{
szExtension = &szFileNameOrExtension[cur];
}
cur--;
}
if (len - cur < 3)//no point in going on if the smallest valid ext is 3 characters
{
return false;
}
//if we didn't find a '.' it could still be valid, they may not have
//passed it in. i.e. "dds" instead of ".dds" which is still valid
if (!szExtension)
{
//with no '.' the largest ext is currently 4 characters
//no point in going on if it is larger
if (len > 4)
{
return false;
}
szExtension = szFileNameOrExtension;
}
//loop over all the valid exts and see if it is one of them
for (unsigned int i = 0; i < GetNumEngineImageFormats(); ++i)
{
if (!azstricmp(szExtension, GetEngineImageFormat(i, szExtension[0] == '.')))
{
return true;
}
}
return false;
}

@ -1,167 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H
#define CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H
#pragma once
// DO NOT USE AZSTD
#include <string>
// IResourceCompilerHelper exists to define an interface that allows
// remote or local compilation of resources through the "resource Compiler" executable
// in most tools it will be implemented as a local execution. However, in the engine
// it will be substituted for a remote RC invocation through the Asset Processor if
// that system is enabled (via con var and define)
// DO NOT USE CRYSTRING or CRY ALLOCATORS HERE. This is used in maya plugins, that kind of thing.
// the following path utils are special versions of these functions which take pains
// to not use crystring.
// the functions in this interface must be cross platform.
namespace RCPathUtil
{
// given a full path, return the extension (it will be a pointer into the existing string)
const char* GetExt(const char* filepath);
// given a full path, return the file only (it will be a pointer into the existing string)
const char* GetFile(const char* filepath);
// given a filepath, get only the path.
std::string GetPath(const char* filepath);
std::string ReplaceExtension(const char* filepath, const char* ext);
bool IsRelativePath(const char* p);
}
class IResourceCompilerListener;
enum ERcExitCode
{
eRcExitCode_Success = 0, // must be 0
eRcExitCode_Error = 1,
eRcExitCode_FatalError = 100,
eRcExitCode_Crash = 101,
eRcExitCode_UserFixing = 200,
eRcExitCode_Pending = 666,
};
/// A pure virtual interface to the RC Helper system
/// the RC helper system allows you to make requests to a remote process in order to process
/// an asset for you.
class IResourceCompilerHelper
{
public:
virtual ~IResourceCompilerHelper() {}
// defines the result of a call via this API to the RC system
enum ERcCallResult
{
eRcCallResult_success, // everything is OK
eRcCallResult_notFound, // the RC executable is not found
eRcCallResult_error, // the RC executable returned an error
eRcCallResult_crash, // the RC executable did not finish
};
//
// Arguments:
// szFileName null terminated ABSOLUTE file path or 0 can be used to test for rc.exe existence
// relative path needs to be relative to rc_plugins directory
// szAdditionalSettings - 0 or e.g. "/refresh" or "/refresh /xyz=56"
//
// this is a SYNCHRONOUS, BLOCKING call and will return once the process is complete
virtual ERcCallResult CallResourceCompiler(
const char* szFileName = 0,
const char* szAdditionalSettings = 0,
IResourceCompilerListener* listener = 0,
bool bMayShowWindow = true,
bool bSilent = false,
bool bNoUserDialog = false,
const wchar_t* szWorkingDirectory = 0,
const wchar_t* szRootPath = 0) = 0;
// InvokeResourceCompiler - a utility that calls the above CallResourceCompiler function
// but generates appropriate settings so you don't have to specify each option.
// This is a BLOCKING call
// the srcFile can be relative to the project root or an absolute path
// the dstFilePath MUST be relative to the same folder as the Src File path
// this will output dstFilePath in the same folder as srcFile.
virtual ERcCallResult InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog);
// --------------------- utility functions ---------------------------------
// given a RC.EXE process exit code like 101, convert it to the above ERcCallResult
ERcCallResult ConvertResourceCompilerExitCodeToResultCode(int exitCode);
// given a ERcCallResult, convert it to a simple english string for debugging.
static const char* GetCallResultDescription(ERcCallResult result);
// given a filename such as "blah.tif" convert it to the appropriate output name "blah.dds" for example
static void GetOutputFilename(const char* szFilePath, char* buffer, size_t bufferSizeInBytes);
//////////////////////////////////////////////////////////////////////////
enum SourceImageTypes
{
SOURCE_IMAGE_TYPE_TIF,
SOURCE_IMAGE_TYPE_BMP,
SOURCE_IMAGE_TYPE_GIF,
SOURCE_IMAGE_TYPE_JPG,
SOURCE_IMAGE_TYPE_JPEG,
SOURCE_IMAGE_TYPE_JPE,
SOURCE_IMAGE_TYPE_TGA,
SOURCE_IMAGE_TYPE_PNG,
NUM_SOURCE_IMAGE_TYPE
};
enum EngineImageTypes
{
ENGINE_IMAGE_TYPE_DDS,
NUM_ENGINE_IMAGE_TYPE
};
private:
static const char* SourceImageFormatExts[NUM_SOURCE_IMAGE_TYPE];
static const char* SourceImageFormatExtsWithDot[NUM_SOURCE_IMAGE_TYPE];
static const char* EngineImageFormatExts[NUM_ENGINE_IMAGE_TYPE];
static const char* EngineImageFormatExtsWithDot[NUM_ENGINE_IMAGE_TYPE];
public:
static unsigned int GetNumSourceImageFormats();
static const char* GetSourceImageFormat(unsigned int index, bool bWithDot);
static unsigned int GetNumEngineImageFormats();
static const char* GetEngineImageFormat(unsigned int index, bool bWithDot);
static bool IsSourceImageFormatSupported(const char* szExtension);
static bool IsGameImageFormatSupported(const char* szExtension);
};
////////////////////////////////////////////////////////////////////////////
// Listener for synchronous resource-compilation.
// Connects the listener to the output of the RC process.
class IResourceCompilerListener
{
public:
// FbxImportDialog relies on this enum being in the order from most verbose to least verbose
enum MessageSeverity
{
MessageSeverity_Debug = 0,
MessageSeverity_Info,
MessageSeverity_Warning,
MessageSeverity_Error
};
virtual void OnRCMessage(MessageSeverity /*severity*/, const char* /*text*/) {}
virtual ~IResourceCompilerListener() {}
};
#endif // CRYINCLUDE_CRYCOMMON_IRESOURCECOMPILERHELPER_H

@ -24,7 +24,9 @@
#endif
#include "smartptr.h"
#include <IFlares.h> // <> required for Interfuscator
#include <IFuncVariable.h> // <> required for Interfuscator
#include <IXml.h> // <> required for Interfuscator
#include "smartptr.h"
#include "VertexFormats.h"
#include <Vertex.h>
#include <AzCore/Casting/numeric_cast.h>
@ -2828,7 +2830,6 @@ struct SRenderLight
m_ObjMatrix.SetIdentity();
m_BaseObjMatrix.SetIdentity();
m_sName = "";
m_pSoftOccQuery = NULL;
m_pLightAnim = NULL;
m_fAreaWidth = 1;
m_fAreaHeight = 1;
@ -2884,11 +2885,6 @@ struct SRenderLight
return m_pLightImage ? m_pLightImage : NULL;
}
IOpticsElementBase* GetLensOpticsElement() const
{
return m_pLensOpticsElement;
}
void SetOpticsParams(const SOpticsInstanceParameters& params)
{
m_opticsParams = params;
@ -2899,24 +2895,6 @@ struct SRenderLight
return m_opticsParams;
}
void SetLensOpticsElement(IOpticsElementBase* pOptics)
{
if (m_pLensOpticsElement == pOptics)
{
return;
}
if (pOptics && pOptics->GetType() != eFT_Root)
{
return;
}
SAFE_RELEASE(m_pLensOpticsElement);
m_pLensOpticsElement = pOptics;
if (m_pLensOpticsElement)
{
m_pLensOpticsElement->AddRef();
}
}
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const { /*LATER*/}
void AcquireResources()
@ -2937,14 +2915,6 @@ struct SRenderLight
{
m_pSpecularCubemap->AddRef();
}
if (m_pLensOpticsElement)
{
m_pLensOpticsElement->AddRef();
}
if (m_pSoftOccQuery)
{
m_pSoftOccQuery->AddRef();
}
if (m_pLightAnim)
{
m_pLightAnim->AddRef();
@ -2961,8 +2931,6 @@ struct SRenderLight
SAFE_RELEASE(m_pLightImage);
SAFE_RELEASE(m_pDiffuseCubemap);
SAFE_RELEASE(m_pSpecularCubemap);
SAFE_RELEASE(m_pLensOpticsElement);
SAFE_RELEASE(m_pSoftOccQuery);
SAFE_RELEASE(m_pLightAnim);
SAFE_RELEASE(m_pLightAttenMap);
}
@ -3046,8 +3014,6 @@ struct SRenderLight
const char* m_sName; // Optional name of the light source.
SShaderItem m_Shader; // Shader item
CRenderObject* m_pObject[MAX_RECURSION_LEVELS]; // Object for light coronas and light flares.
IOpticsElementBase* m_pLensOpticsElement; // Optics element for this shader instance
ISoftOcclusionQuery* m_pSoftOccQuery;
ILightAnimWrapper* m_pLightAnim;
Matrix34 m_BaseObjMatrix;
@ -3146,9 +3112,7 @@ public:
m_fShadowSlopeBias = dl.m_fShadowSlopeBias;
m_fShadowResolutionScale = dl.m_fShadowResolutionScale;
m_fHDRDynamic = dl.m_fHDRDynamic;
m_pLensOpticsElement = dl.m_pLensOpticsElement;
m_LensOpticsFrustumAngle = dl.m_LensOpticsFrustumAngle;
m_pSoftOccQuery = dl.m_pSoftOccQuery;
m_fLightFrustumAngle = dl.m_fLightFrustumAngle;
m_fProjectorNearPlane = dl.m_fProjectorNearPlane;
m_Flags = dl.m_Flags;

@ -1,276 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Interface to manage SoftCode module loading and patching
#ifndef CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H
#define CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H
#pragma once
// Provides the generic interface for exchanging member values between SoftCode modules,
struct IExchangeValue
{
// <interfuscator:shuffle>
virtual ~IExchangeValue() {}
// Allocates a new IExchangeValue with the underlying type
virtual IExchangeValue* Clone() const = 0;
// Returns the size of the underlying type (to check compatibility)
virtual size_t GetSizeOf() const = 0;
// </interfuscator:shuffle>
};
template <typename T>
struct ExchangeValue
: public IExchangeValue
{
ExchangeValue(T& value)
: m_value(value)
{}
virtual IExchangeValue* Clone() const { return new ExchangeValue(*this); }
virtual size_t GetSizeOf() const { return sizeof(m_value); }
T m_value;
};
template <typename T, size_t S>
struct ExchangeArray
: public IExchangeValue
{
ExchangeArray(T* pArr)
{
for (size_t i = 0; i < S; ++i)
{
m_array[i] = pArr[i];
}
}
virtual IExchangeValue* Clone() const { return new ExchangeArray(*this); }
virtual size_t GetSizeOf() const { return sizeof(m_array); }
T m_array[S];
};
/*
This is a non-intrusive support function for types where default construction does no initialization.
SoftCoding relies on default construction to initialize object state correctly.
For most types this works as expected but for some types (typically things like vectors or matrices)
default initialization would be too costly and is therefore not implemented.
This function allows a specialized implementation to be used for such types that will perform
initialization on the newly constructed instance. For example:
inline void DefaultInitialize(Matrix34& matrix)
{
matrix.SetIdentity();
}
*/
template <typename T>
void DefaultInitialize(T& t)
{
t = T();
}
// Vector support
template<class F>
struct Vec2_tpl;
template<typename T>
struct Vec3_tpl;
template <class F>
void DefaultInitialize(Vec2_tpl<F>& vec) { vec.zero(); }
template <typename T>
void DefaultInitialize(Vec3_tpl<T>& vec) { vec.zero(); }
// Matrix support
template<typename F>
struct Matrix33_tpl;
template<typename F>
struct Matrix34_tpl;
template<typename F>
struct Matrix44_tpl;
template <typename F>
void DefaultInitialize(Matrix33_tpl<F>& matrix) { matrix.SetIdentity(); }
template <typename F>
void DefaultInitialize(Matrix34_tpl<F>& matrix) { matrix.SetIdentity(); }
template <typename F>
void DefaultInitialize(Matrix44_tpl<F>& matrix) { matrix.SetIdentity(); }
// Quat support
template <typename F>
struct Quat_tpl;
template <typename F>
void DefaultInitialize(Quat_tpl<F>& quat) { quat.SetIdentity(); }
// Interface for performing an exchange of instance data
struct IExchanger
{
// <interfuscator:shuffle>
virtual ~IExchanger() {}
// True if data is being read from instance members
virtual bool IsLoading() const = 0;
virtual size_t InstanceCount() const = 0;
virtual bool BeginInstance(void* pInstance) = 0;
virtual bool SetValue(const char* name, IExchangeValue& value) = 0;
virtual IExchangeValue* GetValue(const char* name, void* pTarget, size_t targetSize) = 0;
// </interfuscator:shuffle>
template <typename T>
void Visit(const char* name, T& instance);
template <typename T, size_t S>
void Visit(const char* name, T (&arr)[S]);
};
template <typename T>
void IExchanger::Visit(const char* name, T& value)
{
if (IsLoading())
{
IExchangeValue* pValue = GetValue(name, &value, sizeof(value));
if (pValue)
{
ExchangeValue<T>* pTypedValue = static_cast<ExchangeValue<T>*>(pValue);
value = pTypedValue->m_value;
}
}
else // Saving
{
// If this member is stored
if (SetValue(name, ExchangeValue<T>(value)))
{
// Set the original value to the default state (to allow safe destruction)
DefaultInitialize(value);
}
}
}
template <typename T, size_t S>
void IExchanger::Visit(const char* name, T (&arr)[S])
{
if (IsLoading())
{
IExchangeValue* pValue = GetValue(name, &arr, sizeof(arr));
if (pValue)
{
ExchangeArray<T, S>* pTypedArray = static_cast<ExchangeArray<T, S>*>(pValue);
// TODO: Accommodate array resizing? Complex however...
for (size_t i = 0; i < S; ++i)
{
arr[i] = pTypedArray->m_array[i];
}
}
}
else // Saving
{
// If this member is stored
if (SetValue(name, ExchangeArray<T, S>(arr)))
{
T defaultValue;
DefaultInitialize(defaultValue);
// Set the original value to the default value (to allow safe destruction)
for (size_t i = 0; i < S; ++i)
{
arr[i] = defaultValue;
}
}
}
}
struct InstanceTracker;
struct ITypeRegistrar
{
// <interfuscator:shuffle>
virtual ~ITypeRegistrar() {}
virtual const char* GetName() const = 0;
// Creates an instance of the type
virtual void* CreateInstance() = 0;
// </interfuscator:shuffle>
#ifdef SOFTCODE_ENABLED
// How many active instances exist of this type?
virtual size_t InstanceCount() const = 0;
// Used to remove a tracked instance from the Registrar
virtual void RemoveInstance(InstanceTracker* pTracker) = 0;
// Exchanges the instance state with the given exchanger data set
virtual bool ExchangeInstances(IExchanger& exchanger) = 0;
// Destroys all tracked instances of this type
virtual bool DestroyInstances() = 0;
// Returns true if pInstance is of this type (linear search)
virtual bool HasInstance(void* pInstance) const = 0;
#endif
};
struct ITypeLibrary
{
// <interfuscator:shuffle>
virtual ~ITypeLibrary() {}
virtual const char* GetName() = 0;
virtual void* CreateInstanceVoid(const char* typeName) = 0;
// </interfuscator:shuffle>
#ifdef SOFTCODE_ENABLED
virtual void SetOverride(ITypeLibrary* pOverrideLib) = 0;
// Fills in the supplied type list if large enough, and sets count to number of types
virtual size_t GetTypes(ITypeRegistrar** ppRegistrar, size_t& count) const = 0;
#endif
};
struct ISoftCodeListener
{
// <interfuscator:shuffle>
virtual ~ISoftCodeListener() {}
// Called when an instance is replaced to allow managing systems to fixup pointers
virtual void InstanceReplaced(void* pOldInstance, void* pNewInstance) = 0;
// </interfuscator:shuffle>
};
/// Interface for ...
struct ISoftCodeMgr
{
// <interfuscator:shuffle>
virtual ~ISoftCodeMgr() {}
// Used to register built-in libraries on first use
virtual void RegisterLibrary(ITypeLibrary* pLib) = 0;
// Loads any new SoftCode modules
virtual void LoadNewModules() = 0;
virtual void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName) = 0;
virtual void RemoveListener(const char* libraryName, ISoftCodeListener* pListener) = 0;
// To be called regularly to poll for library updates
virtual void PollForNewModules() = 0;
// Stops thread execution until a new SoftCode instance is available
virtual void* WaitForUpdate(void* pInstance) = 0;
/// Frees this instance from memory
//virtual void Release() = 0;
// </interfuscator:shuffle>
};
#endif // CRYINCLUDE_CRYCOMMON_ISOFTCODEMGR_H

@ -34,7 +34,6 @@
#include <list>
#include "smartptr.h"
#include <IThreadTask.h> // <> required for Interfuscator
#include "CryThread.h"
#include "IStreamEngineDefs.h"

@ -49,19 +49,15 @@
#include <ILog.h> // <> required for Interfuscator
#include "CryVersion.h"
#include "smartptr.h"
#include <ISystemScheduler.h> // <> required for Interfuscator
#include <memory> // shared_ptr
#include <CrySystemBus.h>
struct ISystem;
struct ILog;
struct IProfileLogSystem;
namespace AZ::IO
{
struct IArchive;
}
struct IKeyboard;
struct IMouse;
struct IConsole;
struct IRemoteConsole;
struct IRenderer;
@ -79,29 +75,21 @@ struct SFileVersion;
struct INameTable;
struct ILevelSystem;
struct IViewSystem;
struct IMaterialEffects;
class IOpticsManager;
class ICrySizer;
class IXMLBinarySerializer;
struct IReadWriteXMLSink;
struct IThreadTaskManager;
struct IResourceManager;
struct ITextModeConsole;
struct IAVI_Reader;
class CPNoise3;
struct IVisualLog;
struct ILocalizationManager;
struct ISoftCodeMgr;
struct IZLibCompressor;
struct IZLibDecompressor;
struct ILZ4Decompressor;
class IZStdDecompressor;
struct IOutputPrintSink;
struct IThreadManager;
struct IWindowMessageHandler;
struct IImageHandler;
class IResourceCompilerHelper;
class ILmbrAWS;
namespace AZ
{
@ -111,12 +99,6 @@ namespace AZ
}
}
class IResourceCompilerHelper;
namespace Serialization {
struct IArchiveHost;
}
typedef void* WIN_HWND;
class CCamera;
@ -124,39 +106,13 @@ struct CLoadingTimeProfiler;
class ICmdLine;
struct INotificationNetwork;
class ILyShine;
namespace JobManager {
struct IJobManager;
}
#define PROC_MENU 1
#define PROC_3DENGINE 2
// Summary:
// IDs for script userdata typing.
// Remarks:
// Maybe they should be moved into the game.dll .
//##@{
#define USER_DATA_SOUND 1
#define USER_DATA_TEXTURE 2
#define USER_DATA_OBJECT 3
#define USER_DATA_LIGHT 4
#define USER_DATA_BONEHANDLER 5
#define USER_DATA_POINTER 6
//##@}
enum ESystemUpdateFlags
{
ESYSUPDATE_IGNORE_PHYSICS = 0x0002,
// Summary:
// Special update mode for editor.
ESYSUPDATE_EDITOR = 0x0004,
ESYSUPDATE_MULTIPLAYER = 0x0008,
ESYSUPDATE_EDITOR_AI_PHYSICS = 0x0010,
ESYSUPDATE_EDITOR_ONLY = 0x0020,
ESYSUPDATE_UPDATE_VIEW_ONLY = 0x0040
ESYSUPDATE_EDITOR = 0x0004
};
// Description:
@ -189,29 +145,6 @@ enum ESystemConfigPlatform
END_CONFIG_PLATFORM_ENUM, // MUST BE LAST VALUE. USED FOR ERROR CHECKING.
};
enum ESubsystem
{
ESubsys_3DEngine = 0,
ESubsys_AI = 1,
ESubsys_Physics = 2,
ESubsys_Renderer = 3,
ESubsys_Script = 4
};
// Summary:
// Collates cycles taken per update.
struct sUpdateTimes
{
uint32 PhysYields;
uint64 SysUpdateTime;
uint64 PhysStepTime;
uint64 RenderTime;
//extended yimes info
uint64 physWaitTime;
uint64 streamingWaitTime;
uint64 animationWaitTime;
};
enum ESystemGlobalState
{
ESYSTEM_GLOBAL_STATE_UNKNOWN,
@ -568,33 +501,6 @@ struct IErrorObserver
// </interfuscator:shuffle>
};
enum ESystemProtectedFunctions
{
eProtectedFunc_Save = 0,
eProtectedFunc_Load = 1,
eProtectedFuncsLast = 10,
};
struct SCvarsDefault
{
SCvarsDefault()
{
sz_r_DriverDef = NULL;
}
const char* sz_r_DriverDef;
};
#if defined(CVARS_WHITELIST)
struct ICVarsWhitelist
{
// <interfuscator:shuffle>
virtual ~ICVarsWhitelist() {};
virtual bool IsWhiteListed(const string& command, bool silent) = 0;
// </interfuscator:shuffle>
};
#endif // defined(CVARS_WHITELIST)
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION ISYSTEM_H_SECTION_3
#include AZ_RESTRICTED_FILE(ISystem_h)
@ -616,9 +522,6 @@ struct SSystemInitParams
{
void* hInstance; //
void* hWnd; //
void* hWndForInputSystem; // the HWND for the input devices, distinct from the hWnd, which the rendering system overrides anyways
bool remoteResourceCompiler;
ILog* pLog; // You can specify your own ILog to be used by System.
ILogCallback* pLogCallback; // You can specify your own ILogCallback to be added on log creation (used by Editor).
@ -633,33 +536,14 @@ struct SSystemInitParams
bool bPreview; // When running in Preview mode (Minimal initialization).
bool bTestMode; // When running in Automated testing mode.
bool bDedicatedServer; // When running a dedicated server.
bool bExecuteCommandLine; // can be switched of to suppress the feature or do it later during the initialization.
bool bSkipFont; // Don't load CryFont.dll
bool bSkipConsole; // Don't create console
bool bSkipNetwork; // Don't create Network
bool bSkipWebsocketServer; // Don't create the WebSocket server
bool bMinimal; // Don't load banks
bool bTesting; // CryUnit
bool bNoRandom; //use fixed generator init/seed
bool bUnattendedMode; // When running as part of a build on build-machines: Prevent popping up of any dialog
bool bSkipMovie; // Don't load movie
bool bSkipAnimation; // Don't load animation
bool bToolMode; // System is running inside a tool. Will not create USER directory or anything else that the game needs to do
bool bSkipPhysics; // Don't initialize CryPhysics.
ISystem* pSystem; // Pointer to existing ISystem interface, it will be reused if not NULL.
typedef void* (*ProtectedFunction)(void* param1, void* param2);
ProtectedFunction pProtectedFunctions[eProtectedFuncsLast]; // Protected functions.
SCvarsDefault* pCvarsDefault; // to override the default value of some cvar
#if defined(CVARS_WHITELIST)
ICVarsWhitelist* pCVarsWhitelist; // CVars whitelist callback
#endif // defined(CVARS_WHITELIST)
SharedEnvironmentInstance* pSharedEnvironment;
// Summary:
@ -668,16 +552,10 @@ struct SSystemInitParams
{
hInstance = NULL;
hWnd = NULL;
hWndForInputSystem = NULL;
remoteResourceCompiler = false;
pLog = NULL;
pLogCallback = NULL;
pUserCallback = NULL;
#if defined(CVARS_WHITELIST)
pCVarsWhitelist = NULL;
#endif // defined(CVARS_WHITELIST)
sLogFileName = NULL;
autoBackupLogs = true;
pValidator = NULL;
@ -688,32 +566,13 @@ struct SSystemInitParams
bPreview = false;
bTestMode = false;
bDedicatedServer = false;
bExecuteCommandLine = true;
bExecuteCommandLine = true;
bSkipFont = false;
bSkipConsole = false;
bSkipNetwork = false;
#if defined(WIN32) || defined(WIN64)
// create websocket server by default. bear in mind that USE_HTTP_WEBSOCKETS is not defined in release.
bSkipWebsocketServer = false;
#else
// CTCPStreamSocket only seems to fully support Win32 and 64
bSkipWebsocketServer = true;
#endif
bMinimal = false;
bTesting = false;
bNoRandom = false;
bUnattendedMode = false;
bSkipMovie = false;
bSkipAnimation = false;
bToolMode = false;
bSkipPhysics = false;
pSystem = NULL;
memset(pProtectedFunctions, 0, sizeof(pProtectedFunctions));
pCvarsDefault = NULL;
pSharedEnvironment = nullptr;
}
};
@ -782,8 +641,6 @@ struct SSystemGlobalEnvironment
{
AZ::IO::IArchive* pCryPak;
AZ::IO::FileIOBase* pFileIO;
IProfileLogSystem* pProfileLogSystem;
IOpticsManager* pOpticsManager;
ITimer* pTimer;
ICryFont* pCryFont;
::IConsole* pConsole;
@ -791,81 +648,27 @@ struct SSystemGlobalEnvironment
ILog* pLog;
IMovieSystem* pMovieSystem;
INameTable* pNameTable;
IVisualLog* pVisualLog;
IRenderer* pRenderer;
IMaterialEffects* pMaterialEffects;
ISoftCodeMgr* pSoftCodeMgr;
ILyShine* pLyShine;
IResourceCompilerHelper* pResourceCompilerHelper;
SharedEnvironmentInstance* pSharedEnvironment;
IThreadManager* pThreadManager;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION ISYSTEM_H_SECTION_4
#include AZ_RESTRICTED_FILE(ISystem_h)
#endif
ISystemScheduler* pSystemScheduler;
threadID mMainThreadId; //The main thread ID is used in multiple systems so should be stored globally
//////////////////////////////////////////////////////////////////////////
uint32 nMainFrameID;
//////////////////////////////////////////////////////////////////////////
const char* szCmdLine; // Startup command line.
//////////////////////////////////////////////////////////////////////////
// Generic debug string which can be easily updated by any system and output by the debug handler
enum
{
MAX_DEBUG_STRING_LENGTH = 128
};
char szDebugStatus[MAX_DEBUG_STRING_LENGTH];
//////////////////////////////////////////////////////////////////////////
// Used to tell if this is a server/multiplayer instance
bool bServer;
bool bMultiplayer;
bool bHostMigrating;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Indicate Editor status.
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Used by CRY_ASSERT
bool bIgnoreAllAsserts;
bool bNoAssertDialog;
bool bTesting;
//////////////////////////////////////////////////////////////////////////
bool bNoRandomSeed;
SPlatformInfo pi;
// Protected functions.
SSystemInitParams::ProtectedFunction pProtectedFunctions[eProtectedFuncsLast]; // Protected functions.
//////////////////////////////////////////////////////////////////////////
// Flag to able to print out of memory conditon
bool bIsOutOfMemory;
bool bIsOutOfVideoMemory;
bool bToolMode;
int retCode = 0;
ILINE const bool IsClient() const
{
#if defined(CONSOLE)
return true;
#else
return bClient;
#endif
}
ILINE const bool IsDedicated() const
{
#if defined(CONSOLE)
@ -895,11 +698,6 @@ struct SSystemGlobalEnvironment
{
bDedicated = isDedicated;
}
ILINE void SetIsClient(bool isClient)
{
bClient = isClient;
}
#endif
//this way the compiler can strip out code for consoles
@ -939,26 +737,6 @@ struct SSystemGlobalEnvironment
#endif
}
ILINE const bool IsFMVPlaying() const
{
return m_isFMVPlaying;
}
ILINE void SetFMVIsPlaying(const bool isPlaying)
{
m_isFMVPlaying = isPlaying;
}
ILINE const bool IsCutscenePlaying() const
{
return m_isCutscenePlaying;
}
ILINE void SetCutsceneIsPlaying(const bool isPlaying)
{
m_isCutscenePlaying = isPlaying;
}
ILINE bool IsInToolMode() const
{
return bToolMode;
@ -969,35 +747,17 @@ struct SSystemGlobalEnvironment
bToolMode = bNewToolMode;
}
ILINE void SetDynamicMergedMeshGenerationEnabled(bool mmgenEnable)
{
m_bDynamicMergedMeshGenerationEnabled = mmgenEnable;
}
ILINE const bool IsDynamicMergedMeshGenerationEnabled() const
{
return m_bDynamicMergedMeshGenerationEnabled;
}
#if !defined(CONSOLE)
private:
bool bClient;
bool bEditor; // Engine is running under editor.
bool bEditorGameMode; // Engine is in editor game mode.
bool bEditorSimulationMode; // Engine is in editor simulation mode.
bool bDedicated; // Engine is in dedicated
#endif
bool m_isFMVPlaying;
bool m_isCutscenePlaying;
bool m_bDynamicMergedMeshGenerationEnabled;
public:
SSystemGlobalEnvironment()
: pSystemScheduler(nullptr)
, szCmdLine("")
, bToolMode(false)
, m_bDynamicMergedMeshGenerationEnabled(false)
: bToolMode(false)
{
};
};
@ -1035,37 +795,11 @@ struct IProfilingSystem
// Initialize and dispatch all engine's subsystems.
struct ISystem
{
struct ILoadingProgressListener
{
// <interfuscator:shuffle>
virtual ~ILoadingProgressListener() {}
virtual void OnLoadingProgress(int steps) = 0;
// </interfuscator:shuffle>
};
#ifndef _RELEASE
enum LevelLoadOrigin
{
eLLO_Unknown,
eLLO_NewLevel,
eLLO_Level2Level,
eLLO_Resumed,
eLLO_MapCmd,
};
struct ICheckpointData
{
int m_totalLoads;
LevelLoadOrigin m_loadOrigin;
};
#endif
// <interfuscator:shuffle>
virtual ~ISystem() {}
// Summary:
// Releases ISystem.
virtual void Release() = 0;
virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const = 0; // will return NULL if no whitelisting
// Summary:
// Returns pointer to the global environment structure.
@ -1094,9 +828,6 @@ struct ISystem
virtual void DoWorkDuringOcclusionChecks() = 0;
virtual bool NeedDoWorkDuringOcclusionChecks() = 0;
//! Update screen and call some important tick functions during loading.
virtual void SynchronousLoadingTick(const char* pFunc, int line) = 0;
// Summary:
// Returns the current used memory.
virtual uint32 GetUsedMemory() = 0;
@ -1170,7 +901,6 @@ struct ISystem
virtual IZLibDecompressor* GetIZLibDecompressor() = 0;
virtual ILZ4Decompressor* GetLZ4Decompressor() = 0;
virtual IZStdDecompressor* GetZStdDecompressor() = 0;
virtual INotificationNetwork* GetINotificationNetwork() = 0;
virtual IViewSystem* GetIViewSystem() = 0;
virtual ILevelSystem* GetILevelSystem() = 0;
virtual INameTable* GetINameTable() = 0;
@ -1187,24 +917,10 @@ struct ISystem
// Returns:
// Can be NULL, because it only exists when running through the editor, not in pure game mode.
virtual IResourceManager* GetIResourceManager() = 0;
virtual IThreadTaskManager* GetIThreadTaskManager() = 0;
virtual IProfilingSystem* GetIProfilingSystem() = 0;
virtual ISystemEventDispatcher* GetISystemEventDispatcher() = 0;
virtual IVisualLog* GetIVisualLog() = 0;
virtual ITimer* GetITimer() = 0;
virtual IThreadManager* GetIThreadManager() = 0;
virtual void SetLoadingProgressListener(ILoadingProgressListener* pListener) = 0;
virtual ISystem::ILoadingProgressListener* GetLoadingProgressListener() const = 0;
// Summary:
// Game is created after System init, so has to be set explicitly.
virtual void SetIMaterialEffects(IMaterialEffects* pMaterialEffects) = 0;
virtual void SetIOpticsManager(IOpticsManager* pOpticsManager) = 0;
virtual void SetIVisualLog(IVisualLog* pVisualLog) = 0;
//virtual const char *GetGamePath()=0;
virtual void DebugStats(bool checkpoint, bool leaks) = 0;
virtual void DumpWinHeaps() = 0;
@ -1219,7 +935,6 @@ struct ISystem
virtual bool WasInDevMode() const = 0;
virtual bool IsDevMode() const = 0;
virtual bool IsMODValid(const char* szMODName) const = 0;
virtual bool IsMinimalMode() const = 0;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
@ -1334,12 +1049,6 @@ struct ISystem
// Detects and set optimal spec.
virtual void AutoDetectSpec(bool detectResolution) = 0;
// Summary:
// Thread management for subsystems
// Return Value:
// Non-0 if the state was indeed changed, 0 if already in that state.
virtual int SetThreadState(ESubsystem subsys, bool bActive) = 0;
// Summary:
// Query if system is now paused.
// Pause flag is set when calling system update with pause mode.
@ -1406,14 +1115,6 @@ struct ISystem
// Get log index of the currently running Open 3D Engine application. (0 = first instance, 1 = second instance, etc)
virtual int GetApplicationLogInstance(const char* logFilePath) = 0;
// Summary:
// Retrieves the current stats for systems to update the respective time taken
virtual sUpdateTimes& GetCurrentUpdateTimeStats() = 0;
// Summary:
// Retrieves the array of update times and the number of entries
virtual const sUpdateTimes* GetUpdateTimeStats(uint32&, uint32&) = 0;
// Summary:
// Clear all currently logged and drawn on screen error messages
virtual void ClearErrorMessages() = 0;
@ -1458,17 +1159,6 @@ struct ISystem
virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync) = 0;
// </interfuscator:shuffle>
#if defined(CVARS_WHITELIST)
virtual ICVarsWhitelist* GetCVarsWhiteList() const = 0;
#endif // defined(CVARS_WHITELIST)
#ifndef _RELEASE
virtual void GetCheckpointData(ICheckpointData& data) = 0;
virtual void IncreaseCheckpointLoadCount() = 0;
virtual void SetLoadOrigin(LevelLoadOrigin origin) = 0;
#endif
#if !defined(_RELEASE)
virtual bool IsSavingResourceList() const = 0;
#endif
@ -1513,11 +1203,6 @@ struct ISystem
using CrySystemNotificationBus = AZ::EBus<CrySystemNotifications>;
};
//JAT - this is a very important function for the dedicated server - it lets us run >1000 players per piece of server hardware
//JAT - this saves us lots of money on the dedicated server hardware
#define SYNCHRONOUS_LOADING_TICK() do { if (gEnv && gEnv->pSystem) {gEnv->pSystem->SynchronousLoadingTick(__FUNC__, __LINE__); } \
} while (0)
#if defined(USE_DISK_PROFILER)
struct DiskOperationInfo
@ -1594,7 +1279,7 @@ typedef ISystem* (*PFNCREATESYSTEMINTERFACE)(SSystemInitParams& initParams);
//////////////////////////////////////////////////////////////////////////
// Global environment variable.
//////////////////////////////////////////////////////////////////////////
extern SC_API SSystemGlobalEnvironment* gEnv;
extern SSystemGlobalEnvironment* gEnv;
// Summary:
@ -1613,11 +1298,6 @@ inline ISystem* GetISystem()
}
return systemInterface;
};
inline ISystemScheduler* GetISystemScheduler(void)
{
return gEnv->pSystemScheduler;
};
//////////////////////////////////////////////////////////////////////////
// Description:
@ -1640,7 +1320,6 @@ void* GetDetachEnvironmentSymbol();
extern bool g_bProfilerEnabled;
extern int g_iTraceAllocations;
// Summary:
// Interface of the DLL.

@ -1,63 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H
#define CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H
#pragma once
#if defined(__cplusplus)
#define SLICE_AND_SLEEP() do { if (GetISystemScheduler()) { GetISystemScheduler()->SliceAndSleep(__FUNC__, __LINE__); } \
} while (0)
#define SLICE_SCOPE_DEFINE() CSliceLoadingMonitor sliceScope
#else
extern void SliceAndSleep(const char* pFunc, int line);
#define SLICE_AND_SLEEP() SliceAndSleep(__FILE__, __LINE__)
#endif
struct ISystemScheduler
{
virtual ~ISystemScheduler(){}
// <interfuscator:shuffle>
// Map load slicing functionality support
virtual void SliceAndSleep(const char* sliceName, int line) = 0;
virtual void SliceLoadingBegin() = 0;
virtual void SliceLoadingEnd() = 0;
virtual void SchedulingSleepIfNeeded(void) = 0;
// </interfuscator:shuffle>
};
ISystemScheduler* GetISystemScheduler(void);
class CSliceLoadingMonitor
{
public:
CSliceLoadingMonitor()
{
if (GetISystemScheduler())
{
GetISystemScheduler()->SliceLoadingBegin();
}
}
~CSliceLoadingMonitor()
{
if (GetISystemScheduler())
{
GetISystemScheduler()->SliceLoadingEnd();
}
}
};
#endif // CRYINCLUDE_CRYCOMMON_ISYSTEMSCHEDULER_H

@ -1,111 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
class IThreadConfigManager;
enum EJoinMode
{
eJM_TryJoin,
eJM_Join,
};
class IThread
{
public:
// <interfuscator:shuffle>
virtual ~IThread()
{
}
//! Entry functions for code executed on thread.
virtual void ThreadEntry() = 0;
// </interfuscator:shuffle>
};
enum EFPE_Severity
{
eFPE_None, //!< No Floating Point Exceptions.
eFPE_Basic, //!< Invalid operation, Div by 0.
eFPE_All, //!< Invalid operation, Div by 0, Denormalized operand, Overflow, Underflow, Inexact.
eFPE_LastEntry
};
//temp disable CRY DX12
//#define SCOPED_ENABLE_FLOAT_EXCEPTIONS(eFPESeverity) CScopedFloatingPointException scopedSetFloatExceptionMask(eFPESeverity)
//#define SCOPED_DISABLE_FLOAT_EXCEPTIONS() CScopedFloatingPointException scopedSetFloatExceptionMask(eFPE_None)
struct IThreadManager
{
public:
// <interfuscator:shuffle>
virtual ~IThreadManager()
{
}
//! Get thread config manager.
virtual IThreadConfigManager* GetThreadConfigManager() = 0;
//! Spawn a new thread and apply thread config settings at thread beginning.
virtual bool SpawnThread(IThread* pThread, const char* sThreadName, ...) = 0;
//! Wait on another thread to exit (Blocking).
//! Use eJM_TryJoin if you cannot be sure that the target thread is awake.
//! \retval true if target thread has not been started yet or has already exited.
//! \retval false if target thread is still running and therefore not in a state to exit.
virtual bool JoinThread(IThread* pThreadTask, EJoinMode joinStatus) = 0;
//! Register 3rd party thread with the thread manager.
//! Applies thread config for thread if found.
//! \param pThreadHandle If NULL, the current thread handle will be used.
virtual bool RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) = 0;
//! Unregister 3rd party thread with the thread manager.
virtual bool UnRegisterThirdPartyThread(const char* sThreadName, ...) = 0;
//! Get Thread Name.
//! Returns "" if thread not found.
virtual const char* GetThreadName(threadID nThreadId) = 0;
//! Get ThreadID.
virtual threadID GetThreadId(const char* sThreadName, ...) = 0;
//! Execute function for each other thread but this one.
typedef void (* ThreadModifFunction)(threadID nThreadId, void* pData);
virtual void ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData = 0) = 0;
virtual void EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId = 0) = 0;
virtual void EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) = 0;
virtual uint GetFloatingPointExceptionMask() = 0;
virtual void SetFloatingPointExceptionMask(uint nMask) = 0;
// </interfuscator:shuffle>
};
/*TEMP DISABLE CRY DX12
class CScopedFloatingPointException
{
public:
CScopedFloatingPointException(EFPE_Severity eFPESeverity)
{
oldMask = gEnv->pThreadManager->GetFloatingPointExceptionMask();
gEnv->pThreadManager->EnableFloatExceptions(eFPESeverity);
}
~CScopedFloatingPointException()
{
gEnv->pThreadManager->SetFloatingPointExceptionMask(oldMask);
}
private:
uint oldMask;
};
*/

@ -1,166 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "BitFiddling.h"
#ifndef CRYINCLUDE_CRYCOMMON_ITHREADTASK_H
#define CRYINCLUDE_CRYCOMMON_ITHREADTASK_H
#pragma once
#include <smartptr.h>
// forward declarations
struct SThreadTaskInfo;
enum EThreadTaskFlags
{
THREAD_TASK_BLOCKING = BIT(0), // Blocking tasks will be allocated on their own thread.
THREAD_TASK_ASSIGN_TO_POOL = BIT(1), // Task can be assigned to any thread in the group of threads
};
class IThreadTask_Thread
{
public:
// <interfuscator:shuffle>
virtual ~IThreadTask_Thread() {};
virtual void AddTask(SThreadTaskInfo* pTaskInfo) = 0;
virtual void RemoveTask(SThreadTaskInfo* pTaskInfo) = 0;
virtual void RemoveAllTasks() = 0;
virtual void SingleUpdate() = 0;
// </interfuscator:shuffle>
};
typedef int ThreadPoolHandle;
struct SThreadTaskParams
{
uint32 nFlags; // Task flags. @see ETaskFlags
union
{
int nPreferedThread; // Preferred Thread index (0,1,2,3...)
ThreadPoolHandle nThreadsGroupId; // Id of group of threads(useful only if THREAD_TASK_ASSIGN_TO_POOL is set)
};
int16 nPriorityOff; // If THREAD_TASK_BLOCKING, this will adjust the priority of the thread
int16 nStackSizeKB; // If THREAD_TASK_BLOCKING, this will adjust the stack size of the thread
const char* name; // Name for this task (thread for the blocking task will be named using this string)
SThreadTaskParams()
: nFlags(0)
, nPreferedThread(-1)
, nPriorityOff(0)
, name("")
, nStackSizeKB(SIMPLE_THREAD_STACK_SIZE_KB) {}
};
//////////////////////////////////////////////////////////////////////////
// Tasks must implement this interface.
//////////////////////////////////////////////////////////////////////////
struct IThreadTask
{
// <interfuscator:shuffle>
// The function to be called on every update for non bocking tasks.
// Or will be called only once for the blocking threads.
virtual void OnUpdate() = 0;
// Called to indicate that this task must quit.
// Warning! can be called from different thread then OnUpdate call.
virtual void Stop() = 0;
// Returns task info
virtual struct SThreadTaskInfo* GetTaskInfo() = 0;
virtual ~IThreadTask() {}
// </interfuscator:shuffle>
};
struct SThreadTaskInfo
: public CMultiThreadRefCount
{
IThreadTask_Thread* m_pThread;
IThreadTask* m_pTask;
SThreadTaskParams m_params;
SThreadTaskInfo()
: m_pThread(NULL)
, m_pTask(NULL) { m_params.nFlags = 0; m_params.nPreferedThread = -1; }
};
// Might be changed to uint64 etc in the future
typedef uint32 ThreadPoolAffinityMask;
#define INVALID_AFFINITY 0
//////////////////////////////////////////////////////////////////////////
// Description of thread pool to create
//////////////////////////////////////////////////////////////////////////
struct ThreadPoolDesc
{
ThreadPoolAffinityMask AffinityMask; // number of bits means number of threads. affinity overlapping is prohibited
string sPoolName;
int32 nThreadPriority;
int32 nThreadStackSizeKB;
ThreadPoolDesc()
: AffinityMask(INVALID_AFFINITY)
, sPoolName("UnnamedPool")
, nThreadPriority(-1)
, nThreadStackSizeKB(-1) { }
ILINE bool CreateThread(ThreadPoolAffinityMask affinityMask)
{
if (this->AffinityMask & affinityMask)
{
return false;
}
this->AffinityMask |= affinityMask;
return true;
}
ILINE uint32 GetThreadCount() const
{
return CountBits(AffinityMask);
}
};
//////////////////////////////////////////////////////////////////////////
// Task manager.
//////////////////////////////////////////////////////////////////////////
struct IThreadTaskManager
{
// <interfuscator:shuffle>
virtual ~IThreadTaskManager(){}
// Register new task to the manager.
virtual void RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options) = 0;
virtual void UnregisterTask(IThreadTask* pTask) = 0;
// Limit number of threads to this amount.
virtual void SetMaxThreadCount(int nMaxThreads) = 0;
// Create a pool of threads
virtual ThreadPoolHandle CreateThreadsPool(const ThreadPoolDesc& desc) = 0;
virtual const bool DestroyThreadsPool(const ThreadPoolHandle& handle) = 0;
virtual const bool GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const = 0;
virtual const bool SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask) = 0;
virtual void SetThreadName(threadID dwThreadId, const char* sThreadName) = 0;
virtual const char* GetThreadName(threadID dwThreadId) = 0;
// Return thread handle by thread name
virtual threadID GetThreadByName(const char* sThreadName) = 0;
// if bMark=true the calling thread will dump its stack during crashes
virtual void MarkThisThreadForDebugging(const char* name, bool bDump) = 0;
// </interfuscator:shuffle>
};
#endif // CRYINCLUDE_CRYCOMMON_ITHREADTASK_H

@ -585,8 +585,6 @@ public:
SDepthTexture * (int, int, bool));
MOCK_METHOD1(DestroyDepthSurface,
void(SDepthTexture * pDepthSurf));
MOCK_CONST_METHOD1(CreateOptics,
IOpticsElementBase * (EFlareType type));
MOCK_METHOD1(PauseTimer,
void(bool bPause));
MOCK_METHOD0(CreateShaderPublicParams,

@ -23,8 +23,6 @@ class SystemMock
public:
MOCK_METHOD0(Release,
void());
MOCK_CONST_METHOD0(GetCVarsWhiteListConfigSink,
ILoadConfigurationEntrySink * ());
MOCK_METHOD0(GetGlobalEnvironment,
SSystemGlobalEnvironment * ());
MOCK_METHOD2(UpdatePreTickBus,
@ -37,8 +35,6 @@ public:
void());
MOCK_METHOD0(NeedDoWorkDuringOcclusionChecks,
bool());
MOCK_METHOD2(SynchronousLoadingTick,
void(const char* pFunc, int line));
MOCK_METHOD0(RenderStatistics,
void());
MOCK_METHOD0(GetUsedMemory,
@ -84,8 +80,6 @@ public:
ILZ4Decompressor * ());
MOCK_METHOD0(GetZStdDecompressor,
IZStdDecompressor * ());
MOCK_METHOD0(GetINotificationNetwork,
INotificationNetwork * ());
MOCK_METHOD0(GetIViewSystem,
IViewSystem * ());
MOCK_METHOD0(GetILevelSystem,
@ -116,28 +110,12 @@ public:
IRemoteConsole * ());
MOCK_METHOD0(GetIResourceManager,
IResourceManager * ());
MOCK_METHOD0(GetIThreadTaskManager,
IThreadTaskManager * ());
MOCK_METHOD0(GetIProfilingSystem,
IProfilingSystem * ());
MOCK_METHOD0(GetISystemEventDispatcher,
ISystemEventDispatcher * ());
MOCK_METHOD0(GetIVisualLog,
IVisualLog * ());
MOCK_METHOD0(GetITimer,
ITimer * ());
MOCK_METHOD0(GetIThreadManager,
IThreadManager * ());
MOCK_METHOD1(SetLoadingProgressListener,
void(ILoadingProgressListener * pListener));
MOCK_CONST_METHOD0(GetLoadingProgressListener,
ISystem::ILoadingProgressListener * ());
MOCK_METHOD1(SetIMaterialEffects,
void(IMaterialEffects * pMaterialEffects));
MOCK_METHOD1(SetIOpticsManager,
void(IOpticsManager * pOpticsManager));
MOCK_METHOD1(SetIVisualLog,
void(IVisualLog * pVisualLog));
MOCK_METHOD2(DebugStats,
void(bool checkpoint, bool leaks));
MOCK_METHOD0(DumpWinHeaps,
@ -154,8 +132,6 @@ public:
bool());
MOCK_CONST_METHOD1(IsMODValid,
bool(const char* szMODName));
MOCK_CONST_METHOD0(IsMinimalMode,
bool());
MOCK_METHOD3(CreateXmlNode,
XmlNodeRef(const char*, bool, bool));
MOCK_METHOD4(LoadXmlFromBuffer,
@ -209,8 +185,6 @@ public:
void(ESystemConfigPlatform platform));
MOCK_METHOD1(AutoDetectSpec,
void(bool detectResolution));
MOCK_METHOD2(SetThreadState,
int(ESubsystem subsys, bool bActive));
MOCK_CONST_METHOD0(IsPaused,
bool());
MOCK_METHOD0(GetLocalizationManager,
@ -239,10 +213,6 @@ public:
int());
MOCK_METHOD1(GetApplicationLogInstance,
int(const char* logFilePath));
MOCK_METHOD0(GetCurrentUpdateTimeStats,
sUpdateTimes & ());
MOCK_METHOD2(GetUpdateTimeStats,
const sUpdateTimes * (uint32 &, uint32 &));
MOCK_METHOD0(ClearErrorMessages,
void());
MOCK_METHOD2(debug_GetCallStack,
@ -260,20 +230,6 @@ public:
MOCK_METHOD5(AsyncMemcpy,
void(void* dst, const void* src, size_t size, int nFlags, volatile int* sync));
#if defined(CVARS_WHITELIST)
MOCK_CONST_METHOD0(GetCVarsWhiteList,
ICVarsWhitelist * ());
#endif
#ifndef _RELEASE
MOCK_METHOD1(GetCheckpointData,
void(ICheckpointData & data));
MOCK_METHOD0(IncreaseCheckpointLoadCount,
void());
MOCK_METHOD1(SetLoadOrigin,
void(LevelLoadOrigin origin));
#endif
#if !defined(_RELEASE)
MOCK_CONST_METHOD0(IsSavingResourceList,
bool());

@ -1,15 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../../EngineSettingsBackendApple.cpp
../../EngineSettingsBackendApple.h
)

@ -1,15 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../../EngineSettingsBackendWin32.cpp
../../EngineSettingsBackendWin32.h
)

@ -1,70 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_PROFILELOG_H
#define CRYINCLUDE_CRYCOMMON_PROFILELOG_H
#pragma once
#include <ISystem.h> // <> required for Interfuscator
#include <ITimer.h> // <> required for Interfuscator
struct ILogElement
{
virtual ~ILogElement(){}
virtual ILogElement* Log (const char* name, const char* message) = 0;
virtual ILogElement* SetTime (float time) = 0;
virtual void Flush (stack_string& indent) = 0;
};
struct IProfileLogSystem
{
virtual ~IProfileLogSystem(){}
virtual ILogElement* Log (const char* name, const char* msg) = 0;
virtual void SetTime (ILogElement* pElement, float time) = 0;
virtual void Release () = 0;
};
struct SHierProfileLogItem
{
SHierProfileLogItem(const char* name, const char* msg, int inbDoLog)
: m_pLogElement(NULL)
, m_bDoLog(inbDoLog)
{
if (m_bDoLog)
{
m_pLogElement = gEnv->pProfileLogSystem->Log(name, msg);
m_startTime = gEnv->pTimer->GetAsyncTime();
}
}
~SHierProfileLogItem()
{
if (m_bDoLog)
{
CTimeValue endTime = gEnv->pTimer->GetAsyncTime();
gEnv->pProfileLogSystem->SetTime(m_pLogElement, (endTime - m_startTime).GetMilliSeconds());
}
}
private:
int m_bDoLog;
CTimeValue m_startTime;
ILogElement* m_pLogElement;
};
#define HPROFILE_BEGIN(msg1, msg2, doLog) { SHierProfileLogItem __hier_profile_uniq_var_in_this_scope__(msg1, msg2, doLog);
#define HPROFILE_END() }
#define HPROFILE(msg1, msg2, doLog) SHierProfileLogItem __hier_profile_uniq_var_in_this_scope__(msg1, msg2, doLog);
#endif // CRYINCLUDE_CRYCOMMON_PROFILELOG_H

@ -78,9 +78,6 @@ typedef uint32 vtx_idx;
#if defined(WIN32) || defined(WIN64) || LOG_CONST_CVAR_ACCESS
#define RELEASE_LOGGING
//#if defined(_RELEASE)
//#define CVARS_WHITELIST
//#endif // defined(_RELEASE)
#endif
#if defined(_RELEASE) && !defined(RELEASE_LOGGING)
@ -181,32 +178,6 @@ typedef uint32 vtx_idx;
#define SHADER_REFLECT_TEXTURE_SLOTS 0
#endif
#if (defined(WIN32) || defined(WIN64) || defined(AZ_PLATFORM_MAC)) && (!defined(AZ_MONOLITHIC_BUILD) || defined(RESOURCE_COMPILER))
#define CRY_ENABLE_RC_HELPER 1
#endif
#if !defined(_RELEASE) && PROJECTDEFINES_H_TRAIT_ENABLE_SOFTCODE_SYSTEM
#define SOFTCODE_SYSTEM_ENABLED
#endif
// Is SoftCoding enabled for this module? Usually set by the SoftCode AddIn in conjunction with a SoftCode.props file.
#ifdef SOFTCODE_ENABLED
// Is this current compilation unit part of a SOFTCODE build?
#ifdef SOFTCODE
// Import any SC functions from the host module
#define SC_API __declspec(dllimport)
#else
// Export any SC functions from the host module
#define SC_API __declspec(dllexport)
#endif
#else // SoftCode disabled
#define SC_API
#endif
// these enable and disable certain net features to give compatibility between PCs and consoles / profile and performance builds
#define PC_CONSOLE_NET_COMPATIBLE 0
#define PROFILE_PERFORMANCE_NET_COMPATIBLE 0
@ -292,10 +263,6 @@ typedef uint32 vtx_idx;
# define ENABLE_LOADING_PROFILER // requires AZ_PROFILE_TELEMETRY to also be defined
#endif
#if defined(SOFTCODE_ENABLED)
#error "SoftCode currently relies on CryMemoryManager being enabled. Either build without SoftCode support, or enable CryMemoryManager."
#endif
#if PROJECTDEFINES_H_TRAIT_USE_GPU_PARTICLES && !defined(NULL_RENDERER)
#define GPU_PARTICLES 1
#else

@ -1,639 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "ProjectDefines.h"
#if defined(CRY_ENABLE_RC_HELPER)
#include "ResourceCompilerHelper.h"
#include "EngineSettingsManager.h"
// When complining CryTiffPlugin the mayaAssert.h is included that defined
// Assert as _Assert. This wreaks havoc with AZ_Assert since under the covers
// it calls AzCore::Debug::Trace::Assert, which gets transformed bo
// Trace::_Assert, which does not exist. Gotta love macros. Undefine Assert
// before we include semaphore so that it can compile correctly
#if defined(Assert)
#undef Assert
#endif
#include <AzCore/std/parallel/semaphore.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/string/string_view.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Utils/Utils.h>
#if defined(AZ_PLATFORM_WINDOWS)
#include <windows.h>
#include <shellapi.h> // ShellExecuteW()
#endif
#if AZ_TRAIT_OS_PLATFORM_APPLE
#include "AppleSpecific.h"
#include <CoreFoundation/CoreFoundation.h>
#else
#undef RC_EXECUTABLE
#define RC_EXECUTABLE "rc.exe"
#endif
#include <assert.h>
#include <string> // lawsonn - we use std::string internally
#include <sstream>
namespace
{
class LineStreamBuffer
{
public:
template <typename T>
LineStreamBuffer(T* object, void (T::* method)(const char* line))
: m_charCount(0)
, m_bTruncated(false)
{
m_target = new Target<T>(object, method);
}
~LineStreamBuffer()
{
Flush();
delete m_target;
}
void HandleText(const char* text, int length)
{
const char* pos = text;
while (pos - text < length)
{
const char* start = pos;
while (pos - text < length && *pos != '\n' && *pos != '\r')
{
++pos;
}
size_t n = pos - start;
if (m_charCount + n > kMaxCharCount)
{
n = kMaxCharCount - m_charCount;
m_bTruncated = true;
}
memcpy(&m_buffer[m_charCount], start, n);
m_charCount += n;
if (pos - text < length)
{
Flush();
while (pos - text < length && (*pos == '\n' || *pos == '\r'))
{
++pos;
}
}
}
}
void Flush()
{
if (m_charCount > 0)
{
m_buffer[m_charCount] = 0;
m_target->Call(m_buffer);
m_charCount = 0;
}
}
bool IsTruncated() const
{
return m_bTruncated;
}
private:
struct ITarget
{
virtual ~ITarget() {}
virtual void Call(const char* line) = 0;
};
template <typename T>
struct Target
: public ITarget
{
public:
Target(T* object, void (T::* method)(const char* line))
: object(object)
, method(method) {}
virtual void Call(const char* line)
{
(object->*method)(line);
}
private:
T* object;
void (T::* method)(const char* line);
};
ITarget* m_target;
size_t m_charCount;
static const size_t kMaxCharCount = 2047;
char m_buffer[kMaxCharCount + 1];
bool m_bTruncated;
};
#if !defined(AZ_PLATFORM_WINDOWS)
void MessageBoxW(int, const wchar_t* header, const wchar_t* message, unsigned long)
{
#if AZ_TRAIT_OS_PLATFORM_APPLE
CFStringEncoding encoding = (CFByteOrderLittleEndian == CFByteOrderGetCurrent()) ?
kCFStringEncodingUTF32LE : kCFStringEncodingUTF32BE;
CFStringRef header_ref = CFStringCreateWithBytes(nullptr, reinterpret_cast<const UInt8*>(header), wcslen(header) * sizeof(wchar_t), encoding, false);
CFStringRef message_ref = CFStringCreateWithBytes(nullptr, reinterpret_cast<const UInt8*>(message), wcslen(message) * sizeof(wchar_t), encoding, false);
CFOptionFlags result; //result code from the message box
CFUserNotificationDisplayAlert(0, kCFUserNotificationStopAlertLevel, 0, 0, 0, header_ref, message_ref, 0, 0, 0, &result);
CFRelease(header_ref);
CFRelease(message_ref);
#endif
}
#endif
}
namespace
{
class RcLock
{
public:
RcLock()
: m_cs(0u, 1u)
{
m_cs.release();
}
~RcLock()
{
}
void Lock()
{
m_cs.acquire();
}
void Unlock()
{
m_cs.release();
}
private:
AZStd::semaphore m_cs;
};
template<class LockClass>
class RcAutoLock
{
public:
RcAutoLock(LockClass& lock)
: m_lock(lock)
{
m_lock.Lock();
}
~RcAutoLock()
{
m_lock.Unlock();
}
private:
RcAutoLock();
RcAutoLock(const RcAutoLock<LockClass>&);
RcAutoLock<LockClass>& operator =(const RcAutoLock<LockClass>&);
private:
LockClass& m_lock;
};
HANDLE s_rcProcessHandle = 0;
RcLock s_rcProcessHandleLock;
}
//////////////////////////////////////////////////////////////////////////
static void ShowMessageBoxRcNotFound([[maybe_unused]] const wchar_t* const szCmdLine, [[maybe_unused]] const wchar_t* const szDir)
{
SettingsManagerHelpers::CFixedString<wchar_t, MAX_PATH* 4 + 150> tmp;
tmp.append(L"The resource compiler (RC.EXE) was not found.");
MessageBoxW(0, tmp.c_str(), L"Error", MB_ICONERROR | MB_OK);
}
//////////////////////////////////////////////////////////////////////////
namespace
{
class ResourceCompilerLineHandler
{
public:
ResourceCompilerLineHandler(IResourceCompilerListener* listener)
: m_listener(listener)
{
}
void HandleLine(const char* line)
{
if (!m_listener || !line)
{
return;
}
// check the first three characters to see if it's a warning or error.
bool bHasPrefix;
IResourceCompilerListener::MessageSeverity severity;
if ((line[0] == 'E') && (line[1] == ':') && (line[2] == ' '))
{
bHasPrefix = true;
severity = IResourceCompilerListener::MessageSeverity_Error;
line += 3; // skip the prefix
}
else if ((line[0] == 'W') && (line[1] == ':') && (line[2] == ' '))
{
bHasPrefix = true;
severity = IResourceCompilerListener::MessageSeverity_Warning;
line += 3; // skip the prefix
}
else if ((line[0] == ' ') && (line[1] == ' ') && (line[2] == ' '))
{
bHasPrefix = true;
severity = IResourceCompilerListener::MessageSeverity_Info;
line += 3; // skip the prefix
}
else
{
bHasPrefix = false;
severity = IResourceCompilerListener::MessageSeverity_Info;
}
if (bHasPrefix)
{
// skip thread info "%d>", if present
{
const char* p = line;
while (*p == ' ')
{
++p;
}
if (isdigit(*p))
{
while (isdigit(*p))
{
++p;
}
if (*p == '>')
{
line = p + 1;
}
}
}
// skip time info "%d:%d", if present
{
const char* p = line;
while (*p == ' ')
{
++p;
}
if (isdigit(*p))
{
while (isdigit(*p))
{
++p;
}
if (*p == ':')
{
++p;
if (isdigit(*p))
{
while (isdigit(*p))
{
++p;
}
while (*p == ' ')
{
++p;
}
line = p;
}
}
}
}
}
m_listener->OnRCMessage(severity, line);
}
private:
IResourceCompilerListener* m_listener;
};
// we now support macros like #ENGINEROOT# in the string:
void replaceAllInStringInPlace(std::string& inOut, const char* findValue, const char* replaceValue)
{
if (!findValue)
{
return;
}
if (!replaceValue)
{
return;
}
std::string::size_type pos = std::string::npos;
std::string::size_type replaceLen = strlen(findValue);
while ((pos = inOut.find(findValue)) != std::string::npos)
{
inOut.replace(pos, replaceLen, replaceValue);
}
}
// given a string that contains macros (like #ENGINEROOT#), eliminate the macros and replace them with the real data.
// note that in the 'remote' implementation, these macros are sent to the remote RC. It can then expand them for its own environment
// but in a local RC, these macros are expanded by the local environment.
void expandMacros(const char* inputString, char* outputString, std::size_t bufferSize)
{
if (!inputString)
{
return;
}
if (!outputString)
{
return;
}
AZStd::string_view rootFolder;
AZ::ComponentApplicationBus::BroadcastResult(rootFolder, &AZ::ComponentApplicationRequests::GetAppRoot);
std::string finalString(inputString);
const AZStd::string rootFolderStr = rootFolder.data();
replaceAllInStringInPlace(finalString, "#ENGINEROOT#", rootFolderStr.c_str());
// put additional replacements here.
azstrcpy(outputString, bufferSize, finalString.c_str());
}
}
//////////////////////////////////////////////////////////////////////////
IResourceCompilerHelper::ERcCallResult CResourceCompilerHelper::CallResourceCompiler(
const char* szFileName,
const char* szAdditionalSettings,
IResourceCompilerListener* listener,
bool bMayShowWindow,
bool bSilent,
bool bNoUserDialog,
const wchar_t* szWorkingDirectory,
[[maybe_unused]] const wchar_t* szRootPath)
{
#if defined(AZ_PLATFORM_WINDOWS)
HANDLE hChildStdOutRd = INVALID_HANDLE_VALUE, hChildStdOutWr = INVALID_HANDLE_VALUE;
HANDLE hChildStdInRd = INVALID_HANDLE_VALUE, hChildStdInWr = INVALID_HANDLE_VALUE;
PROCESS_INFORMATION pi;
#else
FILE* hChildStdOutRd;
#endif
{
RcAutoLock<RcLock> lock(s_rcProcessHandleLock);
// make command for execution
SettingsManagerHelpers::CFixedString<wchar_t, MAX_PATH* 3> wRemoteCmdLine;
if (!szAdditionalSettings)
{
szAdditionalSettings = "";
}
// expand the additioanl settings.
char szActualFileName[512] = {0};
char szActualAdditionalSettings[512] = {0};
expandMacros(szFileName, szActualFileName, 512);
expandMacros(szAdditionalSettings, szActualAdditionalSettings, 512);
CSettingsManagerTools smTools = CSettingsManagerTools(); // moved this line to after macro expansion to avoid multiple of these existing at once.
AZStd::string_view exeFolderName;
AZ::ComponentApplicationBus::BroadcastResult(exeFolderName, &AZ::ComponentApplicationRequests::GetExecutableFolder);
wchar_t szRegSettingsBuffer[1024];
smTools.GetEngineSettingsManager()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(szRegSettingsBuffer, sizeof(szRegSettingsBuffer)));
bool enableSourceControl = true;
smTools.GetEngineSettingsManager()->GetValueByRef("RC_EnableSourceControl", enableSourceControl);
wRemoteCmdLine.appendAscii("\"");
wRemoteCmdLine.appendAscii(exeFolderName.data(), exeFolderName.size());
wRemoteCmdLine.appendAscii("/");
wRemoteCmdLine.appendAscii(RC_EXECUTABLE);
wRemoteCmdLine.appendAscii("\"");
if (!enableSourceControl)
{
wRemoteCmdLine.appendAscii(" -nosourcecontrol ");
}
if (!szFileName)
{
wRemoteCmdLine.appendAscii(" -userdialog=0 ");
wRemoteCmdLine.appendAscii(szActualAdditionalSettings);
wRemoteCmdLine.appendAscii(" ");
wRemoteCmdLine.append(szRegSettingsBuffer);
}
else
{
wRemoteCmdLine.appendAscii(" \"");
wRemoteCmdLine.appendAscii(szActualFileName);
wRemoteCmdLine.appendAscii("\"");
wRemoteCmdLine.appendAscii(bNoUserDialog ? " -userdialog=0 " : " -userdialog=1 ");
wRemoteCmdLine.appendAscii(szActualAdditionalSettings);
wRemoteCmdLine.appendAscii(" ");
wRemoteCmdLine.append(szRegSettingsBuffer);
}
// Create a pipe to read the stdout of the RC.
SECURITY_ATTRIBUTES saAttr;
if (listener)
{
#if defined(AZ_PLATFORM_WINDOWS)
ZeroMemory(&saAttr, sizeof(saAttr));
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = 0;
CreatePipe(&hChildStdOutRd, &hChildStdOutWr, &saAttr, 0);
SetHandleInformation(hChildStdOutRd, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN
CreatePipe(&hChildStdInRd, &hChildStdInWr, &saAttr, 0);
SetHandleInformation(hChildStdInWr, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN
#endif
}
#if defined(AZ_PLATFORM_WINDOWS)
STARTUPINFOW si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwX = 100;
si.dwY = 100;
if (listener)
{
si.hStdError = hChildStdOutWr;
si.hStdOutput = hChildStdOutWr;
si.hStdInput = hChildStdInRd;
si.dwFlags = STARTF_USEPOSITION | STARTF_USESTDHANDLES;
}
else
{
si.dwFlags = STARTF_USEPOSITION;
}
ZeroMemory(&pi, sizeof(pi));
#endif
bool bShowWindow;
if (bMayShowWindow)
{
wchar_t buffer[20];
smTools.GetEngineSettingsManager()->GetValueByRef("ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)));
bShowWindow = (wcscmp(buffer, L"true") == 0);
}
else
{
bShowWindow = false;
}
#if defined(AZ_PLATFORM_WINDOWS)
const wchar_t* szStartingDirectory = szWorkingDirectory;
if (!szStartingDirectory)
{
char currentDirectory[MAX_PATH];
AZ::Utils::GetExecutableDirectory(currentDirectory, MAX_PATH);
SettingsManagerHelpers::CFixedString<wchar_t, MAX_PATH> wCurrentDirectory;
wCurrentDirectory.appendAscii(currentDirectory);
szStartingDirectory = wCurrentDirectory.c_str();
}
if (!CreateProcessW(
NULL, // No module name (use command line).
const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
TRUE, // Set handle inheritance to TRUE.
bShowWindow ? 0 : CREATE_NO_WINDOW, // creation flags.
NULL, // Use parent's environment block.
szStartingDirectory, // Set starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi)) // Pointer to PROCESS_INFORMATION structure.
{
// The following code block is commented out instead of being deleted
// because it's good to have at hand for a debugging session.
#if 0
const size_t charsInMessageBuffer = 32768; // msdn about FormatMessage(): "The output buffer cannot be larger than 64K bytes."
wchar_t szMessageBuffer[charsInMessageBuffer] = L"";
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, szMessageBuffer, charsInMessageBuffer, NULL);
GetCurrentDirectoryW(charsInMessageBuffer, szMessageBuffer);
#endif
if (!bSilent)
{
ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szStartingDirectory);
}
return eRcCallResult_notFound;
}
s_rcProcessHandle = pi.hProcess;
#else
int fd = open(".", O_RDONLY);
char remoteCmdLineUtf8[MAX_PATH * 8];
char workingDirectory[MAX_PATH * 8];
ConvertUtf16ToUtf8(wRemoteCmdLine.c_str(), SettingsManagerHelpers::CCharBuffer(remoteCmdLineUtf8, MAX_PATH * 8));
if (szWorkingDirectory)
{
ConvertUtf16ToUtf8(szWorkingDirectory, SettingsManagerHelpers::CCharBuffer(workingDirectory, MAX_PATH * 8));
chdir(workingDirectory);
}
hChildStdOutRd = popen(remoteCmdLineUtf8, "r");
fchdir(fd);
if (hChildStdOutRd == nullptr)
{
if (!bSilent)
{
ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szWorkingDirectory);
}
return eRcCallResult_notFound;
}
#endif
}
bool bFailedToReadOutput = false;
if (listener)
{
#if defined(AZ_PLATFORM_WINDOWS)
// Close the pipe that writes to the child process, since we don't actually have any input for it.
CloseHandle(hChildStdInWr);
// Read all the output from the child process.
CloseHandle(hChildStdOutWr);
#endif
ResourceCompilerLineHandler lineHandler(listener);
LineStreamBuffer lineBuffer(&lineHandler, &ResourceCompilerLineHandler::HandleLine);
for (;; )
{
char buffer[2048];
DWORD bytesRead;
#if defined(AZ_PLATFORM_WINDOWS)
if (!ReadFile(hChildStdOutRd, buffer, sizeof(buffer), &bytesRead, NULL) || (bytesRead == 0))
#else
if (fgets(buffer, sizeof(buffer), hChildStdOutRd) == nullptr || (bytesRead = strlen(buffer) == 0))
#endif
{
break;
}
lineBuffer.HandleText(buffer, bytesRead);
}
bFailedToReadOutput = lineBuffer.IsTruncated();
}
#if defined(AZ_PLATFORM_WINDOWS)
// Wait until child process exits.
WaitForSingleObject(pi.hProcess, INFINITE);
#else
DWORD exitCode = pclose(hChildStdOutRd);
#endif
#if defined(AZ_PLATFORM_WINDOWS)
RcAutoLock<RcLock> lock(s_rcProcessHandleLock);
s_rcProcessHandle = 0;
DWORD exitCode = eRcExitCode_Error;
if (bFailedToReadOutput || GetExitCodeProcess(pi.hProcess, &exitCode) == 0)
{
exitCode = eRcExitCode_Error;
}
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
#endif
return ConvertResourceCompilerExitCodeToResultCode(exitCode);
}
#endif //(CRY_ENABLE_RC_HELPER)

@ -1,46 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H
#define CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H
#pragma once
#if defined(CRY_ENABLE_RC_HELPER)
#include "IResourceCompilerHelper.h"
//////////////////////////////////////////////////////////////////////////
// Provides settings and functions to make calls to RC.
// calls RC locally. only works on windows, does not exist on other platforms
// note: You shouldn't be calling this directly
// instead, you should be calling it via the IResourceCompilerHelper interface.
// since it may be replaced with a custom RC for your platform or a remote invocation
class CResourceCompilerHelper
: public IResourceCompilerHelper
{
public:
virtual ERcCallResult CallResourceCompiler(
const char* szFileName = 0,
const char* szAdditionalSettings = 0,
IResourceCompilerListener* listener = 0,
bool bMayShowWindow = true,
bool bSilent = false,
bool bNoUserDialog = false,
const wchar_t* szWorkingDirectory = 0,
const wchar_t* szRootPath = 0) override;
};
#endif // CRY_ENABLE_RC_HELPER
#endif // CRYINCLUDE_CRYCOMMON_RESOURCECOMPILERHELPER_H

@ -1,325 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "ProjectDefines.h"
#if defined(CRY_ENABLE_RC_HELPER)
#include "SettingsManagerHelpers.h"
#include "EngineSettingsManager.h"
#include <codecvt>
#include <locale>
#include <string>
#include <AzCore/std/string/string_view.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#if defined(AZ_PLATFORM_WINDOWS)
#include <windows.h>
#include <shellapi.h> //ShellExecuteW()
#pragma comment(lib, "Shell32.lib")
#endif
#if AZ_TRAIT_OS_PLATFORM_APPLE
#include "AppleSpecific.h"
#endif
bool SettingsManagerHelpers::Utf16ContainsAsciiOnly(const wchar_t* wstr)
{
while (*wstr)
{
if (*wstr > 127 || *wstr < 0)
{
return false;
}
++wstr;
}
return true;
}
void SettingsManagerHelpers::ConvertUtf16ToUtf8(const wchar_t* src, CCharBuffer dst)
{
if (dst.getSizeInElements() <= 0)
{
return;
}
if (src[0] == 0)
{
dst[0] = 0;
}
else
{
const std::codecvt<wchar_t, char, std::mbstate_t>& utf8Utf16Facet = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(std::locale());
std::mbstate_t mb{};
const wchar_t* from_next;
char* to_next;
std::codecvt_base::result result = utf8Utf16Facet.out(mb, src, src + wcslen(src), from_next, dst.getPtr(), dst.getPtr() + dst.getSizeInElements(), to_next);
if (result != std::codecvt_base::ok)
{
dst[0] = 0;
}
else
{
to_next = 0;
}
}
}
void SettingsManagerHelpers::ConvertUtf8ToUtf16(const char* src, CWCharBuffer dst)
{
if (dst.getSizeInElements() <= 0)
{
return;
}
if (src[0] == 0)
{
dst[0] = 0;
}
else
{
const std::codecvt<wchar_t, char, std::mbstate_t>& utf8Utf16Facet = std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t>>(std::locale());
std::mbstate_t mb{};
const char* from_next;
wchar_t* to_next;
std::codecvt_base::result result = utf8Utf16Facet.in(mb, src, src + strlen(src), from_next, dst.getPtr(), dst.getPtr() + dst.getSizeInElements(), to_next);
if (result != std::codecvt_base::ok)
{
dst[0] = 0;
}
else
{
to_next = 0;
}
}
}
void SettingsManagerHelpers::GetAsciiFilename(const wchar_t* wfilename, CCharBuffer buffer)
{
if (buffer.getSizeInElements() <= 0)
{
return;
}
if (wfilename[0] == 0)
{
buffer[0] = 0;
return;
}
if (Utf16ContainsAsciiOnly(wfilename))
{
ConvertUtf16ToUtf8(wfilename, buffer);
return;
}
#if defined(AZ_PLATFORM_WINDOWS)
// The path is non-ASCII unicode, so let's resort to short filenames (they are always ASCII-only, I hope)
wchar_t shortW[MAX_PATH];
const int bufferCharCount = sizeof(shortW) / sizeof(shortW[0]);
const int charCount = GetShortPathNameW(wfilename, shortW, bufferCharCount);
if (charCount <= 0 || charCount >= bufferCharCount)
{
buffer[0] = 0;
return;
}
shortW[charCount] = 0;
if (!Utf16ContainsAsciiOnly(shortW))
{
buffer[0] = 0;
return;
}
ConvertUtf16ToUtf8(shortW, buffer);
#else
buffer[0] = 0;
#endif
}
//////////////////////////////////////////////////////////////////////////
CSettingsManagerTools::CSettingsManagerTools(const wchar_t* szModuleName)
{
m_pSettingsManager = new CEngineSettingsManager(szModuleName);
}
//////////////////////////////////////////////////////////////////////////
CSettingsManagerTools::~CSettingsManagerTools()
{
delete m_pSettingsManager;
}
//////////////////////////////////////////////////////////////////////////
bool CSettingsManagerTools::GetInstalledBuildPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path)
{
return m_pSettingsManager->GetInstalledBuildRootPathUtf16(index, name, path);
}
bool CSettingsManagerTools::GetInstalledBuildPathAscii(const int index, SettingsManagerHelpers::CCharBuffer name, SettingsManagerHelpers::CCharBuffer path)
{
wchar_t wName[MAX_PATH];
wchar_t wPath[MAX_PATH];
if (GetInstalledBuildPathUtf16(index, SettingsManagerHelpers::CWCharBuffer(wName, sizeof(wName)), SettingsManagerHelpers::CWCharBuffer(wPath, sizeof(wPath))))
{
SettingsManagerHelpers::GetAsciiFilename(wName, name);
SettingsManagerHelpers::GetAsciiFilename(wPath, path);
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
static bool FileExists(const wchar_t* filename)
{
#if defined(AZ_PLATFORM_WINDOWS)
const DWORD dwAttrib = GetFileAttributesW(filename);
return dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
#else
char utf8Filename[MAX_PATH];
SettingsManagerHelpers::ConvertUtf16ToUtf8(filename, SettingsManagerHelpers::CCharBuffer(utf8Filename, sizeof(utf8Filename)));
struct stat buffer;
return (stat(utf8Filename, &buffer) == 0);
#endif
}
//////////////////////////////////////////////////////////////////////////
void CSettingsManagerTools::GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer wbuffer)
{
if (wbuffer.getSizeInElements() <= 0)
{
return;
}
AZStd::string_view exePath;
AZ::ComponentApplicationBus::BroadcastResult(exePath, &AZ::ComponentApplicationRequests::GetExecutableFolder);
SettingsManagerHelpers::CFixedString<wchar_t, 1024> editorExe;
editorExe = wbuffer.getPtr();
editorExe.appendAscii(exePath.data(), exePath.size());
if (editorExe.length() <= 0)
{
wbuffer[0] = 0;
return;
}
bool bFound = false;
if (Is64bitWindows())
{
const size_t len = editorExe.length();
editorExe.appendAscii("/Editor.exe");
bFound = FileExists(editorExe.c_str());
if (!bFound)
{
editorExe.setLength(len);
}
}
const size_t sizeToCopy = (editorExe.length() + 1) * sizeof(wbuffer[0]);
if (!bFound || sizeToCopy > wbuffer.getSizeInBytes())
{
wbuffer[0] = 0;
}
else
{
memcpy(wbuffer.getPtr(), editorExe.c_str(), sizeToCopy);
}
}
//////////////////////////////////////////////////////////////////////////
bool CSettingsManagerTools::CallEditor(void** pEditorWindow, [[maybe_unused]] void* hParent, const char* pWindowName, const char* pFlag)
{
#if !defined(AZ_PLATFORM_WINDOWS)
AZ_Assert(false, "CSettingsManagerTools::CallEditor is not supported on this platform!");
return false;
#else
HWND window = ::FindWindowA(NULL, pWindowName);
if (window)
{
*pEditorWindow = window;
return true;
}
else
{
*pEditorWindow = 0;
wchar_t buffer[512] = { L'\0' };
GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)));
SettingsManagerHelpers::CFixedString<wchar_t, 256> wFlags;
SettingsManagerHelpers::ConvertUtf8ToUtf16(pFlag, wFlags.getBuffer());
wFlags.setLength(wcslen(wFlags.c_str()));
if (buffer[0] != '\0')
{
INT_PTR hIns = (INT_PTR)ShellExecuteW(NULL, L"open", buffer, wFlags.c_str(), NULL, SW_SHOWNORMAL);
if (hIns > 32)
{
return true;
}
else
{
MessageBoxA(0, "Editor.exe was not found.\n\nPlease verify CryENGINE root path.", "Error", MB_ICONERROR | MB_OK);
}
}
}
return false;
#endif
}
//////////////////////////////////////////////////////////////////////////
// Modified version of
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139(v=vs.85).aspx
bool CSettingsManagerTools::Is64bitWindows()
{
#if defined(_WIN64)
// 64-bit programs run only on 64-bit Windows
return true;
#elif !defined(AZ_PLATFORM_WINDOWS)
return false;
#else
// 32-bit programs run on both 32-bit and 64-bit Windows
static bool bWin64 = false;
static bool bOnce = true;
if (bOnce)
{
typedef BOOL (WINAPI * LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process");
if (fnIsWow64Process != NULL)
{
BOOL itIsWow64Process = FALSE;
if (fnIsWow64Process(GetCurrentProcess(), &itIsWow64Process))
{
bWin64 = (itIsWow64Process == TRUE);
}
}
bOnce = false;
}
return bWin64;
#endif
}
#endif // #if defined(CRY_ENABLE_RC_HELPER)
// eof

@ -1,491 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H
#define CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H
#pragma once
#include "ProjectDefines.h"
#include <string.h> // memcpy
#include <algorithm> // std::min
namespace SettingsManagerHelpers
{
namespace Utils
{
inline size_t strlen(const char* p)
{
return p ? ::strlen(p) : 0;
}
inline size_t strcmp(const char* p0, const char* p1)
{
return ::strcmp(p0, p1);
}
inline size_t strlen(const wchar_t* p)
{
return p ? ::wcslen(p) : 0;
}
inline size_t strcmp(const wchar_t* p0, const wchar_t* p1)
{
return ::wcscmp(p0, p1);
}
}
// The function copies characters from src to dst one by one until any of
// the following conditions is met:
// 1) the end of the destination buffer (minus one character) is reached
// 2) the end of the source buffer is reached
// 3) zero character is found in the source buffer
//
// When any of 1), 2), 3) happens, the function writes the terminating zero
// character to the destination buffer and return.
//
// The function guarantees writing the terminating zero character to the
// destination buffer (if the buffer can fit at least one character).
//
// The function returns false when a null pointer is passed or when
// clamping happened (i.e. when the end of the destination buffer is
// reached but the source has some characters left).
inline bool strcpy_with_clamp(char* const dst, size_t const dst_size_in_bytes, const char* const src, size_t const src_size_in_bytes = (size_t)-1)
{
if (!dst || dst_size_in_bytes < sizeof(char))
{
return false;
}
if (!src || src_size_in_bytes < sizeof(char))
{
dst[0] = 0;
return src != 0; // we return true for non-null src without characters
}
const size_t src_n = src_size_in_bytes;
const size_t n = (std::min)(dst_size_in_bytes - 1, src_n);
for (size_t i = 0; i < n; ++i)
{
dst[i] = src[i];
if (!src[i])
{
return true;
}
}
dst[n] = 0;
return n >= src_n || src[n] == 0;
}
template<class T>
class CBuffer
{
public:
typedef T element_type;
private:
element_type* m_ptr;
size_t m_sizeInBytes;
public:
CBuffer(element_type* ptr, size_t sizeInBytes)
: m_ptr(ptr)
, m_sizeInBytes(ptr ? sizeInBytes : 0)
{
}
const element_type* getPtr() const
{
return m_ptr;
}
element_type* getPtr()
{
return m_ptr;
}
size_t getSizeInElements() const
{
return m_sizeInBytes / sizeof(element_type);
}
size_t getSizeInBytes() const
{
return m_sizeInBytes;
}
const element_type& operator[](size_t pos) const
{
return m_ptr[pos];
}
element_type& operator[](size_t pos)
{
return m_ptr[pos];
}
};
typedef CBuffer<char> CCharBuffer;
typedef CBuffer<wchar_t> CWCharBuffer;
template<class T, size_t CAPACITY>
class CFixedString
{
public:
typedef T char_type;
static const size_t npos = ~size_t(0);
private:
size_t m_count; // # chars (not counting trailing zero)
char_type m_buffer[CAPACITY + 1]; // '+ 1' is for trailing zero
public:
CFixedString()
{
clear();
}
CFixedString(const char_type* p)
{
set(p);
}
CFixedString& operator=(const char_type* p)
{
set(p);
return *this;
}
CFixedString& operator=(const CFixedString& s)
{
if (&s != this)
{
set(s.m_buffer, s.m_count);
}
return *this;
}
CBuffer<char_type> getBuffer()
{
return CBuffer<char_type>(m_buffer, (CAPACITY + 1) * sizeof(char_type));
}
char_type operator[](const size_t i) const
{
return m_buffer[i];
}
const char_type* c_str() const
{
return &m_buffer[0];
}
const size_t length() const
{
return m_count;
}
void clear()
{
m_count = 0;
m_buffer[m_count] = 0;
}
void setLength(size_t n)
{
m_count = (n <= CAPACITY) ? n : CAPACITY;
m_buffer[m_count] = 0;
}
char_type* ptr()
{
return &m_buffer[0];
}
CFixedString substr(size_t pos = 0, size_t n = npos) const
{
CFixedString s;
if (pos < m_count && n > 0)
{
if (n > m_count || pos + n > m_count)
{
n = m_count - pos;
}
s.set(&m_buffer[pos], n);
}
return s;
}
void set(const char_type* p, size_t n)
{
if (p == 0 || n <= 0)
{
m_count = 0;
}
else
{
m_count = (n > CAPACITY) ? CAPACITY : n;
// memmove() is used because p may point to m_buffer
memmove(m_buffer, p, m_count * sizeof(*p));
}
m_buffer[m_count] = 0;
}
void set(const char_type* p)
{
if (p && p[0])
{
set(p, Utils::strlen(p));
}
else
{
clear();
}
}
void append(const char_type* p, size_t n)
{
if (p && n > 0)
{
if (n > CAPACITY || m_count + n > CAPACITY)
{
// assert(0);
n = CAPACITY - m_count;
}
if (n > 0)
{
memcpy(&m_buffer[m_count], p, n * sizeof(*p));
m_count += n;
m_buffer[m_count] = 0;
}
}
}
void append(const char_type* p)
{
if (p && p[0])
{
append(p, Utils::strlen(p));
}
}
void appendAscii(const char* p, size_t n)
{
if (p && n > 0)
{
if (n > CAPACITY || m_count + n > CAPACITY)
{
// assert(0);
n = CAPACITY - m_count;
}
if (n > 0)
{
for (size_t i = 0; i < n; ++i)
{
m_buffer[m_count + i] = p[i];
}
m_count += n;
m_buffer[m_count] = 0;
}
}
}
void appendAscii(const char* p)
{
if (p && p[0])
{
appendAscii(p, Utils::strlen(p));
}
}
bool equals(const char_type* p) const
{
return (p == 0 || p[0] == 0)
? (m_count == 0)
: (Utils::strcmp(m_buffer, p) == 0);
}
void trim()
{
size_t begin = 0;
while (begin < m_count && (m_buffer[begin] == ' ' || m_buffer[begin] == '\r' || m_buffer[begin] == '\t' || m_buffer[begin] == '\n'))
{
++begin;
}
if (begin >= m_count)
{
clear();
return;
}
size_t end = m_count - 1;
while (end > begin && (m_buffer[begin] == ' ' || m_buffer[begin] == '\r' || m_buffer[begin] == '\t' || m_buffer[begin] == '\n'))
{
--end;
}
m_count = end + 1;
m_buffer[m_count] = 0;
if (begin > 0)
{
set(&m_buffer[begin], m_count - begin);
}
}
};
struct SKeyValue
{
CFixedString<char, 256> key;
CFixedString<wchar_t, 256> value;
};
template<size_t CAPACITY>
class CKeyValueArray
{
private:
size_t count;
SKeyValue data[CAPACITY];
public:
CKeyValueArray()
: count(0)
{
}
size_t size() const
{
return count;
}
const SKeyValue& operator[](size_t i) const
{
return data[i];
}
void clear()
{
count = 0;
}
const SKeyValue* find(const char* key) const
{
for (size_t i = 0; i < count; ++i)
{
if (data[i].key.equals(key))
{
return &data[i];
}
}
return 0;
}
SKeyValue* find(const char* key)
{
for (size_t i = 0; i < count; ++i)
{
if (data[i].key.equals(key))
{
return &data[i];
}
}
return 0;
}
SKeyValue* set(const char* key, const wchar_t* value)
{
SKeyValue* p = find(key);
if (!p)
{
if (count >= CAPACITY)
{
return 0;
}
p = &data[count++];
p->key = key;
}
p->value = value;
return p;
}
};
#if defined(CRY_ENABLE_RC_HELPER)
bool Utf16ContainsAsciiOnly(const wchar_t* wstr);
void ConvertUtf16ToUtf8(const wchar_t* src, CCharBuffer dst);
void ConvertUtf8ToUtf16(const char* src, CWCharBuffer dst);
template <size_t CAPACITY>
void AddPathSeparator(CFixedString<wchar_t, CAPACITY>& wstr)
{
if (wstr.length() <= 0)
{
return;
}
if (wstr[wstr.length() - 1] == L'/' || wstr[wstr.length() - 1] == L'\\')
{
return;
}
wstr.appendAscii("/");
}
void GetAsciiFilename(const wchar_t* wfilename, CCharBuffer buffer);
#endif // #if defined(CRY_ENABLE_RC_HELPER)
} // namespace SettingsManagerHelpers
#if defined(CRY_ENABLE_RC_HELPER)
//////////////////////////////////////////////////////////////////////////
// Provides settings and functions to make calls to RC.
class CEngineSettingsManager;
class CSettingsManagerTools
{
public:
CSettingsManagerTools(const wchar_t* szModuleName = 0);
~CSettingsManagerTools();
private:
CEngineSettingsManager* m_pSettingsManager;
public:
CEngineSettingsManager* GetEngineSettingsManager()
{
return m_pSettingsManager;
}
bool GetInstalledBuildPathUtf16(const int index, SettingsManagerHelpers::CWCharBuffer name, SettingsManagerHelpers::CWCharBuffer path);
bool GetInstalledBuildPathAscii(const int index, SettingsManagerHelpers::CCharBuffer name, SettingsManagerHelpers::CCharBuffer path);
void GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer wbuffer);
bool CallEditor(void** pEditorWindow, void* hParent, const char* pWndName, const char* pFlag);
static bool Is64bitWindows();
};
#endif // #if defined(CRY_ENABLE_RC_HELPER)
#endif // CRYINCLUDE_CRYCOMMON_SETTINGSMANAGERHELPERS_H

@ -1,27 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
ProjectDefines.h
SettingsManagerHelpers.cpp
SettingsManagerHelpers.h
EngineSettingsManager.cpp
EngineSettingsManager.h
EngineSettingsBackend.cpp
EngineSettingsBackend.h
ResourceCompilerHelper.cpp
ResourceCompilerHelper.h
)
# Remove files that cause #define collisions on Mac due to multiple inclusions of 'AppleSpecific.h' and include orders
set(SKIP_UNITY_BUILD_INCLUSION_FILES
SettingsManagerHelpers.cpp
)

@ -22,7 +22,6 @@ set(FILES
IConsole.h
IEntityRenderState.h
IEntityRenderState_info.cpp
IFlares.h
IFont.h
IFunctorBase.h
IFuncVariable.h
@ -40,12 +39,10 @@ set(FILES
ILog.h
ILZ4Decompressor.h
IMaterial.h
IMaterialEffects.h
IMemory.h
IMeshBaking.h
IMiniLog.h
IMovieSystem.h
INotificationNetwork.h
IPhysics.h
IPhysicsDebugRenderer.h
IPostEffectGroup.h
@ -55,12 +52,10 @@ set(FILES
IRenderer.h
IRenderMesh.h
IResourceCollector.h
IResourceCompilerHelper.h
IResourceManager.h
ISerialize.h
IShader.h
IShader_info.h
ISoftCodeMgr.h
ISplines.h
IStatObj.h
StatObjBus.h
@ -69,11 +64,8 @@ set(FILES
IStreamEngineDefs.h
ISurfaceType.h
ISystem.h
ISystemScheduler.h
ITextModeConsole.h
ITexture.h
IThreadManager.h
IThreadTask.h
ITimer.h
IValidator.h
IVideoRenderer.h
@ -108,7 +100,6 @@ set(FILES
MaterialUtils.h
MTPseudoRandom.cpp
CryTypeInfo.cpp
IResourceCompilerHelper.cpp
BaseTypes.h
CompileTimeAssert.h
CryThreadSafeWorkerContainer.h
@ -170,7 +161,6 @@ set(FILES
PoolAllocator.h
primitives.h
primitives_info.h
ProfileLog.h
ProjectDefines.h
Range.h
RenderContextConfig.h

@ -3244,7 +3244,6 @@ struct PhysicsVars
int nBodiesLargeGroup;
int bBreakOnValidation;
int bLogActiveObjects;
int bMultiplayer;
int bProfileEntities;
int bProfileFunx;
int bProfileGroups;

@ -33,7 +33,7 @@
#define PLATFORM_IMPL_H_SECTION_VIRTUAL_ALLOCATORS 7
#endif
SC_API struct SSystemGlobalEnvironment* gEnv = nullptr;
struct SSystemGlobalEnvironment* gEnv = nullptr;
// Traits
#if defined(AZ_RESTRICTED_PLATFORM)
@ -147,7 +147,6 @@ void* GetDetachEnvironmentSymbol()
#endif // !defined(SOFTCODE)
bool g_bProfilerEnabled = false;
int g_iTraceAllocations = 0;
//////////////////////////////////////////////////////////////////////////
// global random number generator used by cry_random functions

@ -1044,11 +1044,9 @@ void CSystem::AutoDetectSpec(const bool detectResolution)
unsigned int numSysCores(1), numProcCores(1);
Win32SysInspect::GetNumCPUCores(numSysCores, numProcCores);
CryLogAlways("--- Number of available cores: %d (out of %d)", numProcCores, numSysCores);
const int numLogicalProcs = gEnv->pi.numLogicalProcessors;
CryLogAlways("--- Number of logical processors: %d", numLogicalProcs);
// get CPU rating
const int cpuRating = numLogicalProcs >= 8 ? 3 : (numLogicalProcs >= 6 ? 2 : 1);
const int cpuRating = numProcCores >= 4 ? 3 : (numProcCores >= 3 ? 2 : 1);
// get GPU info
unsigned int gpuVendorId(0), gpuDeviceId(0), totVidMem(0);

@ -89,7 +89,6 @@ ly_add_target(
Legacy::CrySystem.Static
AZ::AzCore
Legacy::CryCommon
Legacy::CryCommon.EngineSettings.Static
)
################################################################################
@ -109,7 +108,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
PRIVATE
AZ::AzTest
Legacy::CryCommon
Legacy::CryCommon.EngineSettings.Static
Legacy::CrySystem.Static
AZ::AzFramework
)

@ -87,14 +87,6 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename)
filename = PathUtil::ReplaceExtension(filename, "cfg");
}
#if defined(CVARS_WHITELIST)
bool ignoreWhitelist = true;
if (_stricmp(sFilename, "autoexec.cfg") == 0)
{
ignoreWhitelist = false;
}
#endif // defined(CVARS_WHITELIST)
//////////////////////////////////////////////////////////////////////////
CCryFile file;
@ -179,18 +171,9 @@ bool CConsoleBatchFile::ExecuteConfigFile(const char* sFilename)
continue;
}
#if defined(CVARS_WHITELIST)
if (ignoreWhitelist || (gEnv->pSystem->GetCVarsWhiteList() && gEnv->pSystem->GetCVarsWhiteList()->IsWhiteListed(strLine, false)))
#endif // defined(CVARS_WHITELIST)
{
m_pConsole->ExecuteString(strLine);
}
#if defined(CVARS_WHITELIST)
else if (gEnv->IsDedicated())
{
gEnv->pSystem->GetILog()->LogError("Failed to execute command: '%s' as it is not whitelisted\n", strLine.c_str());
}
#endif // defined(CVARS_WHITELIST)
}
// See above
// ((CXConsole*)m_pConsole)->SetStatus(bConsoleStatus);

@ -117,7 +117,6 @@ struct IRenderer;
struct ISystem;
struct ITimer;
struct IFFont;
struct IKeyboard;
struct ICVar;
struct IConsole;
struct IProcess;

@ -1,259 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
//////////////////////////////////////////////////////////////////////////
// NOTE: INTERNAL HEADER NOT FOR PUBLIC USE
// This header should only be include by SystemThreading.cpp only
// It provides an interface for PThread intrinsics
// It's only client should be CThreadManager which should manage all thread interaction
#if !defined(INCLUDED_FROM_SYSTEM_THREADING_CPP)
# error "CRYTEK INTERNAL HEADER. ONLY INCLUDE FROM SYSTEMTHRADING.CPP."
#endif
//////////////////////////////////////////////////////////////////////////
#define DEFAULT_THREAD_STACK_SIZE_KB 0
#define CRY_PTHREAD_THREAD_NAME_MAX 16
//////////////////////////////////////////////////////////////////////////
// THREAD CREATION AND MANAGMENT
//////////////////////////////////////////////////////////////////////////
namespace CryThreadUtil
{
// Define type for platform specific thread handle
typedef pthread_t TThreadHandle;
struct SThreadCreationDesc
{
// Define platform specific thread entry function functor type
typedef void* (* EntryFunc)(void*);
const char* szThreadName;
EntryFunc fpEntryFunc;
void* pArgList;
uint32 nStackSizeInBytes;
};
//////////////////////////////////////////////////////////////////////////
TThreadHandle CryGetCurrentThreadHandle()
{
return (TThreadHandle)pthread_self();
}
//////////////////////////////////////////////////////////////////////////
// Note: Handle must be closed lated via CryCloseThreadHandle()
TThreadHandle CryDuplicateThreadHandle(const TThreadHandle& hThreadHandle)
{
// Do not do anything
// If you add a new platform which duplicates handles make sure to mirror the change in CryCloseThreadHandle(..)
return hThreadHandle;
}
//////////////////////////////////////////////////////////////////////////
void CryCloseThreadHandle(TThreadHandle& hThreadHandle)
{
pthread_detach(hThreadHandle);
}
//////////////////////////////////////////////////////////////////////////
threadID CryGetCurrentThreadId()
{
return threadID(pthread_self());
}
//////////////////////////////////////////////////////////////////////////
threadID CryGetThreadId(TThreadHandle hThreadHandle)
{
return threadID(hThreadHandle);
}
//////////////////////////////////////////////////////////////////////////
// Note: On OSX the thread name can only be set by the thread itself.
void CrySetThreadName(TThreadHandle pThreadHandle, const char* sThreadName)
{
char threadName[CRY_PTHREAD_THREAD_NAME_MAX];
if (!cry_strcpy(threadName, sThreadName))
{
CryLog("<ThreadInfo> CrySetThreadName: input thread name '%s' truncated to '%s'", sThreadName, threadName);
}
#if AZ_TRAIT_OS_PLATFORM_APPLE
// On OSX the thread name can only be set by the thread itself.
assert(pthread_equal(pthread_self(), (pthread_t )pThreadHandle));
if (pthread_setname_np(threadName) != 0)
#else
if (pthread_setname_np(pThreadHandle, threadName) != 0)
#endif
{
switch (errno)
{
case ERANGE:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> CrySetThreadName: Unable to rename thread \"%s\". Error Msg: \"Name to long. Exceeds %d bytes.\"", sThreadName, CRY_PTHREAD_THREAD_NAME_MAX);
break;
default:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> CrySetThreadName: Unsupported error code: %i", errno);
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
void CrySetThreadAffinityMask(TThreadHandle pThreadHandle, DWORD dwAffinityMask)
{
#if defined(AZ_PLATFORM_ANDROID)
// Not supported on ANDROID
// Alternative solution
// Watch out that android will clear the mask after a core has been switched off hence loosing the affinity mask setting!
// http://stackoverflow.com/questions/16319725/android-set-thread-affinity
#elif AZ_TRAIT_OS_PLATFORM_APPLE
# pragma message "Warning: <ThreadInfo> CrySetThreadAffinityMask not implemented for platform"
// Implementation details can be found here
// https://developer.apple.com/library/mac/releasenotes/Performance/RN-AffinityAPI/
#else
cpu_set_t cpu_mask;
CPU_ZERO(&cpu_mask);
for (int cpu = 0; cpu < sizeof(cpu_mask) * 8; ++cpu)
{
if (dwAffinityMask & (1 << cpu))
{
CPU_SET(cpu, &cpu_mask);
}
}
if (sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask) != 0)
{
switch (errno)
{
case EFAULT:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> CrySetThreadAffinityMask: Supplied memory address was invalid.");
break;
case EINVAL:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> CrySetThreadAffinityMask: The affinity bit mask [%u] contains no processors that are currently physically on the system and permitted to the process .", dwAffinityMask);
break;
case EPERM:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> CrySetThreadAffinityMask: The calling process does not have appropriate privileges. Mask [%u].", dwAffinityMask);
break;
case ESRCH:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> CrySetThreadAffinityMask: The process whose ID is pid could not be found.");
break;
default:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> CrySetThreadAffinityMask: Unsupported error code: %i", errno);
break;
}
}
#endif
}
//////////////////////////////////////////////////////////////////////////
void CrySetThreadPriority(TThreadHandle pThreadHandle, DWORD dwPriority)
{
int policy;
struct sched_param param;
pthread_getschedparam(pThreadHandle, &policy, &param);
param.sched_priority = sched_get_priority_max(dwPriority);
pthread_setschedparam(pThreadHandle, policy, &param);
}
//////////////////////////////////////////////////////////////////////////
void CrySetThreadPriorityBoost(TThreadHandle pThreadHandle, bool bEnabled)
{
// Not supported
}
//////////////////////////////////////////////////////////////////////////
bool CryCreateThread(TThreadHandle* pThreadHandle, const SThreadCreationDesc& threadDesc)
{
uint32 nStackSize = threadDesc.nStackSizeInBytes != 0 ? threadDesc.nStackSizeInBytes : DEFAULT_THREAD_STACK_SIZE_KB * 1024;
assert(pThreadHandle != reinterpret_cast<TThreadHandle*>(THREADID_NULL));
pthread_attr_t threadAttr;
sched_param schedParam;
pthread_attr_init(&threadAttr);
pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setstacksize(&threadAttr, nStackSize);
const int err = pthread_create(
pThreadHandle,
&threadAttr,
threadDesc.fpEntryFunc,
threadDesc.pArgList);
// Handle error on thread creation
switch (err)
{
case 0:
// No error
break;
case EAGAIN:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> Unable to create thread \"%s\". Error Msg: \"Insufficient resources to create another thread, or a system-imposed limit on the number of threads was encountered.\"", threadDesc.szThreadName);
return false;
case EINVAL:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> Unable to create thread \"%s\". Error Msg: \"Invalid attribute setting for thread creation.\"", threadDesc.szThreadName);
return false;
case EPERM:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> Unable to create thread \"%s\". Error Msg: \"No permission to set the scheduling policy and parameters specified in attribute setting\"", threadDesc.szThreadName);
return false;
default:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> Unable to create thread \"%s\". Unknown error message. Error code %i", threadDesc.szThreadName, err);
break;
}
// Print info to log
CryComment("<ThreadInfo>: New thread \"%s\" | StackSize: %u(KB)", threadDesc.szThreadName, threadDesc.nStackSizeInBytes / 1024);
return true;
}
//////////////////////////////////////////////////////////////////////////
void CryThreadExitCall()
{
// Notes on: pthread_exit
// A thread that was create with pthread_create implicitly calls pthread_exit when the thread returns from its start routine (the function that was first called after a thread was created).
// pthread_exit(NULL);
}
}
//////////////////////////////////////////////////////////////////////////
// FLOATING POINT EXCEPTIONS
//////////////////////////////////////////////////////////////////////////
namespace CryThreadUtil
{
///////////////////////////////////////////////////////////////////////////
void EnableFloatExceptions(EFPE_Severity eFPESeverity)
{
// TODO:
// Not implemented
// for potential implementation see http://linux.die.net/man/3/feenableexcept
}
//////////////////////////////////////////////////////////////////////////
void EnableFloatExceptions(threadID nThreadId, EFPE_Severity eFPESeverity)
{
// TODO:
// Not implemented
// for potential implementation see http://linux.die.net/man/3/feenableexcept
}
//////////////////////////////////////////////////////////////////////////
uint GetFloatingPointExceptionMask()
{
// Not implemented
return ~0;
}
//////////////////////////////////////////////////////////////////////////
void SetFloatingPointExceptionMask(uint nMask)
{
// Not implemented
}
}

@ -1,432 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
//////////////////////////////////////////////////////////////////////////
// NOTE: INTERNAL HEADER NOT FOR PUBLIC USE
// This header should only be include by SystemThreading.cpp only
// It provides an interface for WinApi intrinsics
// It's only client should be CThreadManager which should manage all thread interaction
#pragma once
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
#define CRYTHREADUTIL_WIN32_THREAD_H_SECTION_1 1
#define CRYTHREADUTIL_WIN32_THREAD_H_SECTION_2 2
#endif
#if !defined(INCLUDED_FROM_SYSTEM_THREADING_CPP)
# error "CRYTEK INTERNAL HEADER. ONLY INCLUDE FROM SYSTEMTHRADING.CPP."
#endif
//////////////////////////////////////////////////////////////////////////
#define DEFAULT_THREAD_STACK_SIZE_KB 0
// Returns the last Win32 error, in string format. Returns an empty string if there is no error.
static string GetLastErrorAsString()
{
// Get the error message, if any.
DWORD errorMessageID = GetLastError();
if (errorMessageID == 0)
{
return "";
}
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION CRYTHREADUTIL_WIN32_THREAD_H_SECTION_1
#include AZ_RESTRICTED_FILE(CryThreadUtil_win32_thread_h)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), messageBuffer, 0, NULL);
string message(messageBuffer, size);
// Free the buffer.
LocalFree(messageBuffer);
return message;
#endif
}
//////////////////////////////////////////////////////////////////////////
// THREAD CREATION AND MANAGMENT
//////////////////////////////////////////////////////////////////////////
namespace CryThreadUtil
{
// Define type for platform specific thread handle
typedef THREAD_HANDLE TThreadHandle;
struct SThreadCreationDesc
{
// Define platform specific thread entry function functor type
typedef unsigned int(_stdcall * EntryFunc)(void*);
const char* szThreadName;
EntryFunc fpEntryFunc;
void* pArgList;
uint32 nStackSizeInBytes;
};
//////////////////////////////////////////////////////////////////////////
TThreadHandle CryGetCurrentThreadHandle()
{
return GetCurrentThread(); // most likely returns pseudo handle (0xfffffffe)
}
//////////////////////////////////////////////////////////////////////////
// Note: Handle must be closed lated via CryCloseThreadHandle()
TThreadHandle CryDuplicateThreadHandle(const TThreadHandle& hThreadHandle)
{
// NOTES:
// GetCurrentThread() may return a psydo handle to the current thread
// to avoid going into the slower kernel mode.
// Hence the handle is useless when being used from an other thread.
// - GetCurrentThread() -> 0xfffffffe
// - GetCurrentProcess() -> 0xffffffff
HANDLE hRealHandle = 0;
DuplicateHandle(GetCurrentProcess(), // Source Process Handle.
hThreadHandle, // Source Handle to dup.
GetCurrentProcess(), // Target Process Handle.
&hRealHandle, // Target Handle pointer.
0, // Options flag.
TRUE, // Inheritable flag
DUPLICATE_SAME_ACCESS); // Options
return (TThreadHandle)hRealHandle;
}
//////////////////////////////////////////////////////////////////////////
void CryCloseThreadHandle(TThreadHandle& hThreadHandle)
{
if (hThreadHandle)
{
CloseHandle(hThreadHandle);
}
}
//////////////////////////////////////////////////////////////////////////
threadID CryGetCurrentThreadId()
{
return GetCurrentThreadId();
}
//////////////////////////////////////////////////////////////////////////
threadID CryGetThreadId(TThreadHandle hThreadHandle)
{
return GetThreadId(hThreadHandle);
}
//////////////////////////////////////////////////////////////////////////
void CrySetThreadName(TThreadHandle pThreadHandle, const char* sThreadName)
{
const DWORD MS_VC_EXCEPTION = 0x406D1388;
struct SThreadNameDesc
{
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
};
SThreadNameDesc info;
info.dwType = 0x1000;
info.szName = sThreadName;
info.dwThreadID = GetThreadId(pThreadHandle);
info.dwFlags = 0;
AZ_PUSH_DISABLE_WARNING(6312 6322, "-Wunknown-warning-option")
// warning C6312: Possible infinite loop: use of the constant EXCEPTION_CONTINUE_EXECUTION in the exception-filter expression of a try-except
// warning C6322: empty _except block
__try
{
// Raise exception to set thread name for attached debugger
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(DWORD), (ULONG_PTR*)&info);
}
__except (GetExceptionCode() == MS_VC_EXCEPTION ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER)
{
}
AZ_POP_DISABLE_WARNING
}
//////////////////////////////////////////////////////////////////////////
void CrySetThreadAffinityMask(TThreadHandle pThreadHandle, DWORD dwAffinityMask)
{
SetThreadAffinityMask(pThreadHandle, dwAffinityMask);
}
//////////////////////////////////////////////////////////////////////////
void CrySetThreadPriority(TThreadHandle pThreadHandle, DWORD dwPriority)
{
if (!SetThreadPriority(pThreadHandle, dwPriority))
{
string errMsg = GetLastErrorAsString();
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> Unable to set thread priority. System Error Msg: \"%s\"", errMsg.c_str());
return;
}
}
//////////////////////////////////////////////////////////////////////////
void CrySetThreadPriorityBoost(TThreadHandle pThreadHandle, bool bEnabled)
{
SetThreadPriorityBoost(pThreadHandle, !bEnabled);
}
//////////////////////////////////////////////////////////////////////////
bool CryCreateThread(TThreadHandle* pThreadHandle, const SThreadCreationDesc& threadDesc)
{
const uint32 nStackSize = threadDesc.nStackSizeInBytes != 0 ? threadDesc.nStackSizeInBytes : DEFAULT_THREAD_STACK_SIZE_KB * 1024;
// Create thread
unsigned int threadId = 0;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION CRYTHREADUTIL_WIN32_THREAD_H_SECTION_2
#include AZ_RESTRICTED_FILE(CryThreadUtil_win32_thread_h)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
*pThreadHandle = (void*)_beginthreadex(NULL, nStackSize, threadDesc.fpEntryFunc, threadDesc.pArgList, CREATE_SUSPENDED, &threadId);
#endif
if (!(*pThreadHandle))
{
string errMsg = GetLastErrorAsString();
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> Unable to create thread \"%s\". System Error Msg: \"%s\"", threadDesc.szThreadName, errMsg.c_str());
return false;
}
// Start thread
ResumeThread(*pThreadHandle);
// Print info to log
CryComment("<ThreadInfo>: New thread \"%s\" | StackSize: %u(KB)", threadDesc.szThreadName, threadDesc.nStackSizeInBytes / 1024);
return true;
}
//////////////////////////////////////////////////////////////////////////
void CryThreadExitCall()
{
// Note on: ExitThread() (from MSDN)
// ExitThread is the preferred method of exiting a thread in C code.
// However, in C++ code, the thread is exited before any destructor can be called or any other automatic cleanup can be performed.
// Therefore, in C++ code, you should return from your thread function.
}
}
//////////////////////////////////////////////////////////////////////////
// FLOATING POINT EXCEPTIONS
//////////////////////////////////////////////////////////////////////////
namespace CryThreadUtil
{
///////////////////////////////////////////////////////////////////////////
void EnableFloatExceptions([[maybe_unused]] EFPE_Severity eFPESeverity)
{
AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
// Optimization
// Enable DAZ/FZ
// Denormals Are Zeros
// Flush-to-Zero
_controlfp(_DN_FLUSH, _MCW_DN);
_mm_setcsr(_mm_getcsr() | _MM_FLUSH_ZERO_ON);
#ifndef _RELEASE
if (eFPESeverity == eFPE_None)
{
// mask all floating exceptions off.
_controlfp(_MCW_EM, _MCW_EM);
_mm_setcsr(_mm_getcsr() | _MM_MASK_MASK);
}
else
{
// Clear pending exceptions
_fpreset();
if (eFPESeverity == eFPE_Basic)
{
// Enable:
// - _EM_ZERODIVIDE
// - _EM_INVALID
//
// Disable:
// - _EM_DENORMAL
// - _EM_OVERFLOW
// - _EM_UNDERFLOW
// - _EM_INEXACT
_controlfp(_EM_INEXACT | _EM_DENORMAL | _EM_UNDERFLOW | _EM_OVERFLOW, _MCW_EM);
_mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (_MM_MASK_DENORM | _MM_MASK_INEXACT | _MM_MASK_UNDERFLOW | _MM_MASK_OVERFLOW));
//_mm_setcsr(_mm_getcsr() & ~0x280);
}
if (eFPESeverity == eFPE_All)
{
// Enable:
// - _EM_ZERODIVIDE
// - _EM_INVALID
// - _EM_UNDERFLOW
// - _EM_OVERFLOW
//
// Disable:
// - _EM_INEXACT
// - _EM_DENORMAL
_controlfp(_EM_INEXACT | _EM_DENORMAL, _MCW_EM);
_mm_setcsr((_mm_getcsr() & ~_MM_MASK_MASK) | (_MM_MASK_INEXACT | _MM_MASK_DENORM));
}
}
#endif // _RELEASE
AZ_POP_DISABLE_WARNING
}
//////////////////////////////////////////////////////////////////////////
void EnableFloatExceptions(threadID nThreadId, EFPE_Severity eFPESeverity)
{
if (eFPESeverity >= eFPE_LastEntry)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Floating Point Exception (FPE) severity is out of range. (%i)", eFPESeverity);
}
// Check if the thread ID matches the current thread
if (nThreadId == 0 || nThreadId == CryGetCurrentThreadId())
{
EnableFloatExceptions(eFPESeverity);
return;
}
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, true, nThreadId);
if (hThread == 0)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Unable to open thread. %p", hThread);
return;
}
SuspendThread(hThread);
CONTEXT ctx;
memset(&ctx, 0, sizeof(ctx));
ctx.ContextFlags = CONTEXT_ALL;
if (GetThreadContext(hThread, &ctx) == 0)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Unable to get thread context");
ResumeThread(hThread);
CloseHandle(hThread);
return;
}
#ifdef PLATFORM_64BIT
//////////////////////////////////////////////////////////////////////////
// Note:
// DO NOT USE ctx.FltSave.MxCsr ... SetThreadContext() will copy the value of ctx.MxCsr into it
//////////////////////////////////////////////////////////////////////////
DWORD& floatMxCsr = ctx.MxCsr; // Hold FPE Mask and Status for MMX (SSE) floating point registers
WORD& floatControlWord = ctx.FltSave.ControlWord; // Hold FPE Mask for floating point registers
#ifndef _RELEASE
WORD& floatStatuslWord = ctx.FltSave.StatusWord; // Holds FPE Status for floating point registers
#endif
#else
DWORD& floatMxCsr = *(DWORD*)(&ctx.ExtendedRegisters[24]); // Hold FPE Mask and Status for MMX (SSE) floating point registers
DWORD& floatControlWord = ctx.FloatSave.ControlWord; // Hold FPE Mask for floating point registers
DWORD& floatStatuslWord = ctx.FloatSave.StatusWord; // Holds FPE Status for floating point registers
#endif
// Flush-To-Zero Mode
// Two conditions must be met for FTZ processing to occur:
// - The FTZ bit (bit 15) in the MXCSR register must be masked (value = 1).
// - The underflow exception (bit 11) needs to be masked (value = 1).
// Set flush mode to zero mode
floatControlWord = (floatControlWord & ~_MCW_DN) | _DN_FLUSH;
floatMxCsr = (floatMxCsr & ~_MM_FLUSH_ZERO_MASK) | (_MM_FLUSH_ZERO_ON);
#ifndef _RELEASE
// Reset FPE bits
floatControlWord = floatControlWord | _MCW_EM;
floatMxCsr = floatMxCsr | _MM_MASK_MASK;
// Clear pending exceptions
floatStatuslWord = floatStatuslWord & ~(_SW_INEXACT | _SW_UNDERFLOW | _SW_OVERFLOW | _SW_ZERODIVIDE | _SW_INVALID | _SW_DENORMAL);
floatMxCsr = floatMxCsr & ~(_MM_EXCEPT_INEXACT | _MM_EXCEPT_UNDERFLOW | _MM_EXCEPT_OVERFLOW | _MM_EXCEPT_DIV_ZERO | _MM_EXCEPT_INVALID | _MM_EXCEPT_DENORM);
if (eFPESeverity == eFPE_Basic)
{
// Enable:
// - _EM_ZERODIVIDE
// - _EM_INVALID
//
// Disable:
// - _EM_DENORMAL
// - _EM_OVERFLOW
// - _EM_UNDERFLOW
// - _EM_INEXACT
floatControlWord = (floatControlWord & ~_MCW_EM) | (_EM_DENORMAL | _EM_INEXACT | EM_UNDERFLOW | _EM_OVERFLOW);
floatMxCsr = (floatMxCsr & ~_MM_MASK_MASK) | (_MM_MASK_DENORM | _MM_MASK_INEXACT | _MM_MASK_UNDERFLOW | _MM_MASK_OVERFLOW);
}
if (eFPESeverity == eFPE_All)
{
// Enable:
// - _EM_ZERODIVIDE
// - _EM_INVALID
// - _EM_UNDERFLOW
// - _EM_OVERFLOW
//
// Disable:
// - _EM_INEXACT
// - _EM_DENORMAL
floatControlWord = (floatControlWord & ~_MCW_EM) | (_EM_INEXACT | _EM_DENORMAL);
floatMxCsr = (floatMxCsr & ~_MM_MASK_MASK) | (_MM_MASK_INEXACT | _MM_MASK_DENORM);
}
#endif
ctx.ContextFlags = CONTEXT_ALL;
if (SetThreadContext(hThread, &ctx) == 0)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Error setting ThreadContext for ThreadID: %u", nThreadId);
ResumeThread(hThread);
CloseHandle(hThread);
return;
}
ResumeThread(hThread);
CloseHandle(hThread);
}
//////////////////////////////////////////////////////////////////////////
uint GetFloatingPointExceptionMask()
{
uint nMask = 0;
_clearfp();
_controlfp_s(&nMask, 0, 0);
return nMask;
}
//////////////////////////////////////////////////////////////////////////
void SetFloatingPointExceptionMask(uint nMask)
{
uint temp = 0;
_clearfp();
const unsigned int kAllowedBits = _MCW_DN | _MCW_EM | _MCW_RC;
_controlfp_s(&temp, nMask, kAllowedBits);
}
}

@ -1,926 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "DebugCallStack.h"
#if defined(WIN32) || defined(WIN64)
#include <IConsole.h>
#include <CryPath.h>
#include <Pak/CryPakUtils.h>
#include "System.h"
#include <AzCore/Debug/StackTracer.h>
#include <AzCore/Debug/EventTraceDrillerBus.h>
#include "resource.h"
__pragma(comment(lib, "version.lib"))
//! Needs one external of DLL handle.
extern HMODULE gDLLHandle;
#include <DbgHelp.h>
#define MAX_PATH_LENGTH 1024
#define MAX_SYMBOL_LENGTH 512
static HWND hwndException = 0;
static bool g_bUserDialog = true; // true=on crash show dialog box, false=supress user interaction
static int PrintException(EXCEPTION_POINTERS* pex);
static bool IsFloatingPointException(EXCEPTION_POINTERS* pex);
extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers);
extern LONG WINAPI CryEngineExceptionFilterMiniDump(struct _EXCEPTION_POINTERS* pExceptionPointers, const char* szDumpPath, MINIDUMP_TYPE mdumpValue);
//=============================================================================
CONTEXT CaptureCurrentContext()
{
CONTEXT context;
memset(&context, 0, sizeof(context));
context.ContextFlags = CONTEXT_FULL;
RtlCaptureContext(&context);
return context;
}
LONG __stdcall CryUnhandledExceptionHandler(EXCEPTION_POINTERS* pex)
{
return DebugCallStack::instance()->handleException(pex);
}
BOOL CALLBACK EnumModules(
PCSTR ModuleName,
DWORD64 BaseOfDll,
PVOID UserContext)
{
DebugCallStack::TModules& modules = *static_cast<DebugCallStack::TModules*>(UserContext);
modules[(void*)BaseOfDll] = ModuleName;
return TRUE;
}
//=============================================================================
// Class Statics
//=============================================================================
// Return single instance of class.
IDebugCallStack* IDebugCallStack::instance()
{
static DebugCallStack sInstance;
return &sInstance;
}
//------------------------------------------------------------------------------------------------------------------------
// Sets up the symbols for functions in the debug file.
//------------------------------------------------------------------------------------------------------------------------
DebugCallStack::DebugCallStack()
: prevExceptionHandler(0)
, m_pSystem(0)
, m_nSkipNumFunctions(0)
, m_bCrash(false)
, m_szBugMessage(NULL)
{
}
DebugCallStack::~DebugCallStack()
{
}
void DebugCallStack::RemoveOldFiles()
{
RemoveFile("error.log");
RemoveFile("error.bmp");
RemoveFile("error.dmp");
}
void DebugCallStack::RemoveFile(const char* szFileName)
{
FILE* pFile = nullptr;
azfopen(&pFile, szFileName, "r");
const bool bFileExists = (pFile != NULL);
if (bFileExists)
{
fclose(pFile);
WriteLineToLog("Removing file \"%s\"...", szFileName);
if (remove(szFileName) == 0)
{
WriteLineToLog("File successfully removed.");
}
else
{
WriteLineToLog("Couldn't remove file!");
}
}
}
void DebugCallStack::installErrorHandler(ISystem* pSystem)
{
m_pSystem = pSystem;
prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler);
}
//////////////////////////////////////////////////////////////////////////
void DebugCallStack::SetUserDialogEnable(const bool bUserDialogEnable)
{
g_bUserDialog = bUserDialogEnable;
}
DWORD g_idDebugThreads[10];
const char* g_nameDebugThreads[10];
int g_nDebugThreads = 0;
volatile int g_lockThreadDumpList = 0;
void MarkThisThreadForDebugging(const char* name)
{
EBUS_EVENT(AZ::Debug::EventTraceDrillerSetupBus, SetThreadName, AZStd::this_thread::get_id(), name);
WriteLock lock(g_lockThreadDumpList);
DWORD id = GetCurrentThreadId();
if (g_nDebugThreads == sizeof(g_idDebugThreads) / sizeof(g_idDebugThreads[0]))
{
return;
}
for (int i = 0; i < g_nDebugThreads; i++)
{
if (g_idDebugThreads[i] == id)
{
return;
}
}
g_nameDebugThreads[g_nDebugThreads] = name;
g_idDebugThreads[g_nDebugThreads++] = id;
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions);
}
void UnmarkThisThreadFromDebugging()
{
WriteLock lock(g_lockThreadDumpList);
DWORD id = GetCurrentThreadId();
for (int i = g_nDebugThreads - 1; i >= 0; i--)
{
if (g_idDebugThreads[i] == id)
{
memmove(g_idDebugThreads + i, g_idDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_idDebugThreads[0]));
memmove(g_nameDebugThreads + i, g_nameDebugThreads + i + 1, (g_nDebugThreads - 1 - i) * sizeof(g_nameDebugThreads[0]));
--g_nDebugThreads;
}
}
}
extern int prev_sys_float_exceptions;
void UpdateFPExceptionsMaskForThreads()
{
int mask = -iszero(g_cvars.sys_float_exceptions);
CONTEXT ctx;
for (int i = 0; i < g_nDebugThreads; i++)
{
if (g_idDebugThreads[i] != GetCurrentThreadId())
{
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]);
ctx.ContextFlags = CONTEXT_ALL;
SuspendThread(hThread);
GetThreadContext(hThread, &ctx);
#ifndef WIN64
(ctx.FloatSave.ControlWord |= 7) &= ~5 | mask;
(*(WORD*)(ctx.ExtendedRegisters + 24) |= 0x280) &= ~0x280 | mask;
#else
(ctx.FltSave.ControlWord |= 7) &= ~5 | mask;
(ctx.FltSave.MxCsr |= 0x280) &= ~0x280 | mask;
#endif
SetThreadContext(hThread, &ctx);
ResumeThread(hThread);
}
}
}
//////////////////////////////////////////////////////////////////////////
int DebugCallStack::handleException(EXCEPTION_POINTERS* exception_pointer)
{
if (gEnv == NULL)
{
return EXCEPTION_EXECUTE_HANDLER;
}
ResetFPU(exception_pointer);
prev_sys_float_exceptions = 0;
const int cached_sys_float_exceptions = g_cvars.sys_float_exceptions;
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(0);
if (g_cvars.sys_WER)
{
gEnv->pLog->FlushAndClose();
return CryEngineExceptionFilterWER(exception_pointer);
}
if (g_cvars.sys_no_crash_dialog)
{
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
}
m_bCrash = true;
if (g_cvars.sys_no_crash_dialog)
{
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
}
static bool firstTime = true;
if (g_cvars.sys_dump_aux_threads)
{
for (int i = 0; i < g_nDebugThreads; i++)
{
if (g_idDebugThreads[i] != GetCurrentThreadId())
{
SuspendThread(OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]));
}
}
}
// uninstall our exception handler.
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)prevExceptionHandler);
if (!firstTime)
{
WriteLineToLog("Critical Exception! Called Multiple Times!");
gEnv->pLog->FlushAndClose();
// Exception called more then once.
return EXCEPTION_EXECUTE_HANDLER;
}
// Print exception info:
{
char excCode[80];
char excAddr[80];
WriteLineToLog("<CRITICAL EXCEPTION>");
sprintf_s(excAddr, "0x%04X:0x%p", exception_pointer->ContextRecord->SegCs, exception_pointer->ExceptionRecord->ExceptionAddress);
sprintf_s(excCode, "0x%08X", exception_pointer->ExceptionRecord->ExceptionCode);
WriteLineToLog("Exception: %s, at Address: %s", excCode, excAddr);
{
IMemoryManager::SProcessMemInfo memInfo;
if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo))
{
uint32 nMemUsage = (uint32)(memInfo.PagefileUsage / (1024 * 1024));
WriteLineToLog("Virtual memory usage: %dMb", nMemUsage);
}
gEnv->szDebugStatus[SSystemGlobalEnvironment::MAX_DEBUG_STRING_LENGTH - 1] = '\0';
WriteLineToLog("Debug Status: %s", gEnv->szDebugStatus);
}
}
firstTime = false;
const int ret = SubmitBug(exception_pointer);
if (ret != IDB_IGNORE)
{
CryEngineExceptionFilterWER(exception_pointer);
}
gEnv->pLog->FlushAndClose();
if (exception_pointer->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
{
// This is non continuable exception. abort application now.
exit(exception_pointer->ExceptionRecord->ExceptionCode);
}
//typedef long (__stdcall *ExceptionFunc)(EXCEPTION_POINTERS*);
//ExceptionFunc prevFunc = (ExceptionFunc)prevExceptionHandler;
//return prevFunc( (EXCEPTION_POINTERS*)exception_pointer );
if (ret == IDB_EXIT)
{
// Immediate exit.
// on windows, exit() and _exit() do all sorts of things, unfortuantely
// TerminateProcess is the only way to die.
TerminateProcess(GetCurrentProcess(), exception_pointer->ExceptionRecord->ExceptionCode); // we crashed, so don't return a zero exit code!
// on linux based systems, _exit will not call ATEXIT and other things, which makes it more suitable for termination in an emergency such
// as an unhandled exception.
// however, this function is a windows exception handler.
}
else if (ret == IDB_IGNORE)
{
#ifndef WIN64
exception_pointer->ContextRecord->FloatSave.StatusWord &= ~31;
exception_pointer->ContextRecord->FloatSave.ControlWord |= 7;
(*(WORD*)(exception_pointer->ContextRecord->ExtendedRegisters + 24) &= 31) |= 0x1F80;
#else
exception_pointer->ContextRecord->FltSave.StatusWord &= ~31;
exception_pointer->ContextRecord->FltSave.ControlWord |= 7;
(exception_pointer->ContextRecord->FltSave.MxCsr &= 31) |= 0x1F80;
#endif
firstTime = true;
prevExceptionHandler = (void*)SetUnhandledExceptionFilter(CryUnhandledExceptionHandler);
g_cvars.sys_float_exceptions = cached_sys_float_exceptions;
((CSystem*)gEnv->pSystem)->EnableFloatExceptions(g_cvars.sys_float_exceptions);
return EXCEPTION_CONTINUE_EXECUTION;
}
// Continue;
return EXCEPTION_EXECUTE_HANDLER;
}
void DebugCallStack::ReportBug(const char* szErrorMessage)
{
WriteLineToLog("Reporting bug: %s", szErrorMessage);
m_szBugMessage = szErrorMessage;
m_context = CaptureCurrentContext();
SubmitBug(NULL);
m_szBugMessage = NULL;
}
void DebugCallStack::dumpCallStack(std::vector<string>& funcs)
{
WriteLineToLog("=============================================================================");
int len = (int)funcs.size();
for (int i = 0; i < len; i++)
{
const char* str = funcs[i].c_str();
WriteLineToLog("%2d) %s", len - i, str);
}
WriteLineToLog("=============================================================================");
}
//////////////////////////////////////////////////////////////////////////
void DebugCallStack::LogExceptionInfo(EXCEPTION_POINTERS* pex)
{
string path("");
if ((gEnv) && (gEnv->pFileIO))
{
const char* logAlias = gEnv->pFileIO->GetAlias("@log@");
if (!logAlias)
{
logAlias = gEnv->pFileIO->GetAlias("@root@");
}
if (logAlias)
{
path = logAlias;
path += "/";
}
}
string fileName = path;
fileName += "error.log";
struct stat fileInfo;
string timeStamp;
string backupPath;
if (gEnv->IsDedicated())
{
backupPath = PathUtil::ToUnixPath(PathUtil::AddSlash(path + "DumpBackups"));
gEnv->pFileIO->CreatePath(backupPath.c_str());
if (stat(fileName.c_str(), &fileInfo) == 0)
{
// Backup log
tm creationTime;
localtime_s(&creationTime, &fileInfo.st_mtime);
char tempBuffer[32];
strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime);
timeStamp = tempBuffer;
string backupFileName = backupPath + timeStamp + " error.log";
CopyFile(fileName.c_str(), backupFileName.c_str(), true);
}
}
FILE* f = nullptr;
azfopen(&f, fileName.c_str(), "wt");
CDebugAllowFileAccess ignoreInvalidFileAccess;
static char errorString[s_iCallStackSize];
errorString[0] = 0;
// Time and Version.
char versionbuf[1024];
azstrcpy(versionbuf, AZ_ARRAY_SIZE(versionbuf), "");
PutVersion(versionbuf, AZ_ARRAY_SIZE(versionbuf));
cry_strcat(errorString, versionbuf);
cry_strcat(errorString, "\n");
char excCode[MAX_WARNING_LENGTH];
char excAddr[80];
char desc[1024];
char excDesc[MAX_WARNING_LENGTH];
// make sure the mouse cursor is visible
ShowCursor(TRUE);
const char* excName;
if (m_bIsFatalError || !pex)
{
const char* const szMessage = m_bIsFatalError ? s_szFatalErrorCode : m_szBugMessage;
excName = szMessage;
cry_strcpy(excCode, szMessage);
cry_strcpy(excAddr, "");
cry_strcpy(desc, "");
cry_strcpy(m_excModule, "");
cry_strcpy(excDesc, szMessage);
}
else
{
sprintf_s(excAddr, "0x%04X:0x%p", pex->ContextRecord->SegCs, pex->ExceptionRecord->ExceptionAddress);
sprintf_s(excCode, "0x%08X", pex->ExceptionRecord->ExceptionCode);
excName = TranslateExceptionCode(pex->ExceptionRecord->ExceptionCode);
cry_strcpy(desc, "");
sprintf_s(excDesc, "%s\r\n%s", excName, desc);
if (pex->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
{
if (pex->ExceptionRecord->NumberParameters > 1)
{
ULONG_PTR iswrite = pex->ExceptionRecord->ExceptionInformation[0];
DWORD64 accessAddr = pex->ExceptionRecord->ExceptionInformation[1];
if (iswrite)
{
sprintf_s(desc, "Attempt to write data to address 0x%08llu\r\nThe memory could not be \"written\"", accessAddr);
}
else
{
sprintf_s(desc, "Attempt to read from address 0x%08llu\r\nThe memory could not be \"read\"", accessAddr);
}
}
}
}
WriteLineToLog("Exception Code: %s", excCode);
WriteLineToLog("Exception Addr: %s", excAddr);
WriteLineToLog("Exception Module: %s", m_excModule);
WriteLineToLog("Exception Name : %s", excName);
WriteLineToLog("Exception Description: %s", desc);
cry_strcpy(m_excDesc, excDesc);
cry_strcpy(m_excAddr, excAddr);
cry_strcpy(m_excCode, excCode);
char errs[32768];
sprintf_s(errs, "Exception Code: %s\nException Addr: %s\nException Module: %s\nException Description: %s, %s\n",
excCode, excAddr, m_excModule, excName, desc);
IMemoryManager::SProcessMemInfo memInfo;
if (gEnv->pSystem->GetIMemoryManager()->GetProcessMemInfo(memInfo))
{
char memoryString[256];
double MB = 1024 * 1024;
sprintf_s(memoryString, "Memory in use: %3.1fMB\n", (double)(memInfo.PagefileUsage) / MB);
cry_strcat(errs, memoryString);
}
{
const int tempStringSize = 256;
char tempString[tempStringSize];
gEnv->szDebugStatus[SSystemGlobalEnvironment::MAX_DEBUG_STRING_LENGTH - 1] = '\0';
sprintf_s(tempString, tempStringSize, "Debug Status: %s\n", gEnv->szDebugStatus);
cry_strcat(errs, tempString);
sprintf_s(tempString, tempStringSize, "Out of Memory: %d\n", gEnv->bIsOutOfMemory);
cry_strcat(errs, tempString);
}
cry_strcat(errs, "\nCall Stack Trace:\n");
std::vector<string> funcs;
if (gEnv->bIsOutOfMemory)
{
cry_strcat(errs, "1) OUT_OF_MEMORY()\n");
}
else
{
AZ::Debug::StackFrame frames[25];
AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 3);
if (numFrames)
{
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
for (unsigned int i = 0; i < numFrames; i++)
{
funcs.push_back(lines[i]);
}
}
dumpCallStack(funcs);
// Fill call stack.
char str[s_iCallStackSize];
cry_strcpy(str, "");
for (unsigned int i = 0; i < funcs.size(); i++)
{
char temp[s_iCallStackSize];
sprintf_s(temp, "%2zd) %s", funcs.size() - i, (const char*)funcs[i].c_str());
cry_strcat(str, temp);
cry_strcat(str, "\r\n");
cry_strcat(errs, temp);
cry_strcat(errs, "\n");
}
cry_strcpy(m_excCallstack, str);
}
cry_strcat(errorString, errs);
if (f)
{
fwrite(errorString, strlen(errorString), 1, f);
if (!gEnv->bIsOutOfMemory)
{
if (g_cvars.sys_dump_aux_threads)
{
for (int i = 0; i < g_nDebugThreads; i++)
{
if (g_idDebugThreads[i] != GetCurrentThreadId())
{
fprintf(f, "\n\nSuspended thread (%s):\n", g_nameDebugThreads[i]);
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, TRUE, g_idDebugThreads[i]);
// mirrors the AZ::Debug::Trace::PrintCallstack() functionality, but prints to a file
{
AZ::Debug::StackFrame frames[10];
// Without StackFrame explicit alignment frames array is aligned to 4 bytes
// which causes the stack tracing to fail.
AZ::Debug::SymbolStorage::StackLine lines[AZ_ARRAY_SIZE(frames)];
unsigned int numFrames = AZ::Debug::StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames), 0, hThread);
if (numFrames)
{
AZ::Debug::SymbolStorage::DecodeFrames(frames, numFrames, lines);
for (unsigned int i2 = 0; i2 < numFrames; ++i2)
{
fprintf(f, "%2d) %s\n", numFrames - i2, lines[i2]);
}
}
}
ResumeThread(hThread);
}
}
}
}
fflush(f);
fclose(f);
}
if (pex)
{
MINIDUMP_TYPE mdumpValue;
bool bDump = true;
switch (g_cvars.sys_dump_type)
{
case 0:
bDump = false;
break;
case 1:
mdumpValue = MiniDumpNormal;
break;
case 2:
mdumpValue = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpWithDataSegs);
break;
case 3:
mdumpValue = MiniDumpWithFullMemory;
break;
default:
mdumpValue = (MINIDUMP_TYPE)g_cvars.sys_dump_type;
break;
}
if (bDump)
{
fileName = path + "error.dmp";
if (gEnv->IsDedicated() && stat(fileName.c_str(), &fileInfo) == 0)
{
// Backup dump (use timestamp from error.log if available)
if (timeStamp.empty())
{
tm creationTime;
localtime_s(&creationTime, &fileInfo.st_mtime);
char tempBuffer[32];
strftime(tempBuffer, sizeof(tempBuffer), "%d %b %Y (%H %M %S)", &creationTime);
timeStamp = tempBuffer;
}
string backupFileName = backupPath + timeStamp + " error.dmp";
CopyFile(fileName.c_str(), backupFileName.c_str(), true);
}
CryEngineExceptionFilterMiniDump(pex, fileName.c_str(), mdumpValue);
}
}
//if no crash dialog don't even submit the bug
if (m_postBackupProcess && g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog)
{
m_postBackupProcess();
}
else
{
// lawsonn: Disabling the JIRA-based crash reporter for now
// we'll need to deal with it our own way, pending QA.
// if you're customizing the engine this is also your opportunity to deal with it.
if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog)
{
// ------------ place custom crash handler here ---------------------
// it should launch an executable!
/// by this time, error.bmp will be in the engine root folder
// error.log and error.dmp will also be present in the engine root folder
// if your error dumper wants those, it should zip them up and send them or offer to do so.
// ------------------------------------------------------------------
}
}
const bool bQuitting = !gEnv || !gEnv->pSystem || gEnv->pSystem->IsQuitting();
//[AlexMcC|16.04.10] When the engine is shutting down, MessageBox doesn't display a box
// and immediately returns IDYES. Avoid this by just not trying to save if we're quitting.
// Don't ask to save if this isn't a real crash (a real crash has exception pointers)
if (g_cvars.sys_no_crash_dialog == 0 && g_bUserDialog && gEnv->IsEditor() && !bQuitting && pex)
{
BackupCurrentLevel();
const INT_PTR res = DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CONFIRM_SAVE_LEVEL), NULL, DebugCallStack::ConfirmSaveDialogProc, NULL);
if (res == IDB_CONFIRM_SAVE)
{
if (SaveCurrentLevel())
{
MessageBox(NULL, "Level has been successfully saved!\r\nPress Ok to terminate Editor.", "Save", MB_OK);
}
else
{
MessageBox(NULL, "Error saving level.\r\nPress Ok to terminate Editor.", "Save", MB_OK | MB_ICONWARNING);
}
}
}
if (g_cvars.sys_no_crash_dialog != 0 || !g_bUserDialog)
{
// terminate immediately - since we're in a crash, there is no point unwinding stack, we've already done access violation or worse.
// calling exit will only cause further death down the line...
TerminateProcess(GetCurrentProcess(), pex->ExceptionRecord->ExceptionCode);
}
}
INT_PTR CALLBACK DebugCallStack::ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
static EXCEPTION_POINTERS* pex;
static char errorString[32768] = "";
switch (message)
{
case WM_INITDIALOG:
{
pex = (EXCEPTION_POINTERS*)lParam;
HWND h;
if (pex->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
{
// Disable continue button for non continuable exceptions.
//h = GetDlgItem( hwndDlg,IDB_CONTINUE );
//if (h) EnableWindow( h,FALSE );
}
DebugCallStack* pDCS = static_cast<DebugCallStack*>(DebugCallStack::instance());
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_DESC);
if (h)
{
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excDesc);
}
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_CODE);
if (h)
{
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excCode);
}
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_MODULE);
if (h)
{
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excModule);
}
h = GetDlgItem(hwndDlg, IDC_EXCEPTION_ADDRESS);
if (h)
{
SendMessage(h, EM_REPLACESEL, FALSE, (LONG_PTR)pDCS->m_excAddr);
}
// Fill call stack.
HWND callStack = GetDlgItem(hwndDlg, IDC_CALLSTACK);
if (callStack)
{
SendMessage(callStack, WM_SETTEXT, FALSE, (LPARAM)pDCS->m_excCallstack);
}
if (hwndException)
{
DestroyWindow(hwndException);
hwndException = 0;
}
if (IsFloatingPointException(pex))
{
EnableWindow(GetDlgItem(hwndDlg, IDB_IGNORE), TRUE);
}
}
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDB_EXIT:
case IDB_IGNORE:
// Fall through.
EndDialog(hwndDlg, wParam);
return TRUE;
}
}
return FALSE;
}
INT_PTR CALLBACK DebugCallStack::ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, [[maybe_unused]] LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
// The user might be holding down the spacebar while the engine crashes.
// If we don't remove keyboard focus from this dialog, the keypress will
// press the default button before the dialog actually appears, even if
// the user has already released the key, which is bad.
SetFocus(NULL);
} break;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDB_CONFIRM_SAVE: // Fall through
case IDB_DONT_SAVE:
{
EndDialog(hwndDlg, wParam);
return TRUE;
}
}
} break;
}
return FALSE;
}
bool DebugCallStack::BackupCurrentLevel()
{
CSystem* pSystem = static_cast<CSystem*>(m_pSystem);
if (pSystem && pSystem->GetUserCallback())
{
return pSystem->GetUserCallback()->OnBackupDocument();
}
return false;
}
bool DebugCallStack::SaveCurrentLevel()
{
CSystem* pSystem = static_cast<CSystem*>(m_pSystem);
if (pSystem && pSystem->GetUserCallback())
{
return pSystem->GetUserCallback()->OnSaveDocument();
}
return false;
}
int DebugCallStack::SubmitBug(EXCEPTION_POINTERS* exception_pointer)
{
int ret = IDB_EXIT;
assert(!hwndException);
RemoveOldFiles();
AZ::Debug::Trace::PrintCallstack("", 2);
LogExceptionInfo(exception_pointer);
if (IsFloatingPointException(exception_pointer))
{
//! Print exception dialog.
ret = PrintException(exception_pointer);
}
return ret;
}
void DebugCallStack::ResetFPU(EXCEPTION_POINTERS* pex)
{
if (IsFloatingPointException(pex))
{
// How to reset FPU: http://www.experts-exchange.com/Programming/System/Windows__Programming/Q_10310953.html
_clearfp();
#ifndef WIN64
pex->ContextRecord->FloatSave.ControlWord |= 0x2F;
pex->ContextRecord->FloatSave.StatusWord &= ~0x8080;
#endif
}
}
string DebugCallStack::GetModuleNameForAddr(void* addr)
{
if (m_modules.empty())
{
return "[unknown]";
}
if (addr < m_modules.begin()->first)
{
return "[unknown]";
}
TModules::const_iterator it = m_modules.begin();
TModules::const_iterator end = m_modules.end();
for (; ++it != end; )
{
if (addr < it->first)
{
return (--it)->second;
}
}
//if address is higher than the last module, we simply assume it is in the last module.
return m_modules.rbegin()->second;
}
void DebugCallStack::GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
{
AZ::Debug::SymbolStorage::StackLine func, file, module;
AZ::Debug::SymbolStorage::FindFunctionFromIP(addr, &func, &file, &module, line, baseAddr);
procName = func;
filename = file;
}
string DebugCallStack::GetCurrentFilename()
{
char fullpath[MAX_PATH_LENGTH + 1];
GetModuleFileName(NULL, fullpath, MAX_PATH_LENGTH);
return fullpath;
}
static bool IsFloatingPointException(EXCEPTION_POINTERS* pex)
{
if (!pex)
{
return false;
}
DWORD exceptionCode = pex->ExceptionRecord->ExceptionCode;
switch (exceptionCode)
{
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_FLT_UNDERFLOW:
case STATUS_FLOAT_MULTIPLE_FAULTS:
case STATUS_FLOAT_MULTIPLE_TRAPS:
return true;
default:
return false;
}
}
int DebugCallStack::PrintException(EXCEPTION_POINTERS* exception_pointer)
{
return (int)DialogBoxParam(gDLLHandle, MAKEINTRESOURCE(IDD_CRITICAL_ERROR), NULL, DebugCallStack::ExceptionDialogProc, (LPARAM)exception_pointer);
}
#else
void MarkThisThreadForDebugging(const char*) {}
void UnmarkThisThreadFromDebugging() {}
void UpdateFPExceptionsMaskForThreads() {}
#endif //WIN32

@ -1,95 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
#define CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H
#pragma once
#include "IDebugCallStack.h"
#if defined (WIN32) || defined (WIN64)
//! Limits the maximal number of functions in call stack.
const int MAX_DEBUG_STACK_ENTRIES_FILE_DUMP = 12;
struct ISystem;
//!============================================================================
//!
//! DebugCallStack class, capture call stack information from symbol files.
//!
//!============================================================================
class DebugCallStack
: public IDebugCallStack
{
public:
DebugCallStack();
virtual ~DebugCallStack();
ISystem* GetSystem() { return m_pSystem; };
virtual string GetModuleNameForAddr(void* addr);
virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line);
virtual string GetCurrentFilename();
void installErrorHandler(ISystem* pSystem);
virtual int handleException(EXCEPTION_POINTERS* exception_pointer);
virtual void ReportBug(const char*);
void dumpCallStack(std::vector<string>& functions);
void SetUserDialogEnable(const bool bUserDialogEnable);
typedef std::map<void*, string> TModules;
protected:
static void RemoveOldFiles();
static void RemoveFile(const char* szFileName);
static int PrintException(EXCEPTION_POINTERS* exception_pointer);
static INT_PTR CALLBACK ExceptionDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
static INT_PTR CALLBACK ConfirmSaveDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam);
void LogExceptionInfo(EXCEPTION_POINTERS* exception_pointer);
bool BackupCurrentLevel();
bool SaveCurrentLevel();
int SubmitBug(EXCEPTION_POINTERS* exception_pointer);
void ResetFPU(EXCEPTION_POINTERS* pex);
static const int s_iCallStackSize = 32768;
char m_excLine[256];
char m_excModule[128];
char m_excDesc[MAX_WARNING_LENGTH];
char m_excCode[MAX_WARNING_LENGTH];
char m_excAddr[80];
char m_excCallstack[s_iCallStackSize];
void* prevExceptionHandler;
bool m_bCrash;
const char* m_szBugMessage;
ISystem* m_pSystem;
int m_nSkipNumFunctions;
CONTEXT m_context;
TModules m_modules;
};
#endif //WIN32
#endif // CRYINCLUDE_CRYSYSTEM_DEBUGCALLSTACK_H

@ -14,7 +14,6 @@
#include "CrySystem_precompiled.h"
#include "System.h"
#include <AZCrySystemInitLogSink.h>
#include "DebugCallStack.h"
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
@ -72,10 +71,6 @@ public:
{
switch (event)
{
case ESYSTEM_EVENT_LEVEL_UNLOAD:
gEnv->pSystem->SetThreadState(ESubsys_Physics, false);
break;
case ESYSTEM_EVENT_LEVEL_LOAD_START:
case ESYSTEM_EVENT_LEVEL_LOAD_END:
{
@ -87,7 +82,6 @@ public:
{
CryCleanup();
STLALLOCATOR_CLEANUP;
gEnv->pSystem->SetThreadState(ESubsys_Physics, true);
break;
}
}
@ -135,21 +129,6 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar
startupParams.pUserCallback->OnSystemConnect(pSystem);
}
// Environment Variable to signal we don't want to override our exception handler - our crash report system will set this
auto envVar = AZ::Environment::FindVariable<bool>("ExceptionHandlerIsSet");
bool handlerIsSet = (envVar && *envVar);
if (!startupParams.bMinimal && !handlerIsSet) // in minimal mode, we want to crash when we crash!
{
#if defined(WIN32)
// Install exception handler in Release modes.
((DebugCallStack*)IDebugCallStack::instance())->installErrorHandler(pSystem);
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_3
#include AZ_RESTRICTED_FILE(DllMain_cpp)
#endif
}
bool retVal = false;
{
AZ::Debug::StartupLogSinkReporter<AZ::Debug::CrySystemInitLogSink> initLogSink;
@ -171,20 +150,5 @@ CRYSYSTEM_API ISystem* CreateSystemInterface(const SSystemInitParams& startupPar
return pSystem;
}
CRYSYSTEM_API void WINAPI CryInstallUnhandledExceptionHandler()
{
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION DLLMAIN_CPP_SECTION_4
#include AZ_RESTRICTED_FILE(DllMain_cpp)
#endif
}
#if defined(ENABLE_PROFILING_CODE) && !defined(LINUX) && !defined(APPLE)
CRYSYSTEM_API void CryInstallPostExceptionHandler(void (* PostExceptionHandlerCallback)())
{
return IDebugCallStack::instance()->FileCreationCallback(PostExceptionHandlerCallback);
}
#endif
};

@ -1,278 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : A multiplatform base class for handling errors and collecting call stacks
#include "CrySystem_precompiled.h"
#include "IDebugCallStack.h"
#include <Pak/CryPakUtils.h>
#include "System.h"
#include <AzFramework/IO/FileOperations.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Utils/Utils.h>
//#if !defined(LINUX)
#include <ISystem.h>
const char* const IDebugCallStack::s_szFatalErrorCode = "FATAL_ERROR";
IDebugCallStack::IDebugCallStack()
: m_bIsFatalError(false)
, m_postBackupProcess(0)
, m_memAllocFileHandle(AZ::IO::InvalidHandle)
{
}
IDebugCallStack::~IDebugCallStack()
{
StopMemLog();
}
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_SINGLETON
IDebugCallStack* IDebugCallStack::instance()
{
static IDebugCallStack sInstance;
return &sInstance;
}
#endif
void IDebugCallStack::FileCreationCallback(void (* postBackupProcess)())
{
m_postBackupProcess = postBackupProcess;
}
//////////////////////////////////////////////////////////////////////////
void IDebugCallStack::LogCallstack()
{
AZ::Debug::Trace::PrintCallstack("", 2);
}
const char* IDebugCallStack::TranslateExceptionCode(DWORD dwExcept)
{
switch (dwExcept)
{
#if AZ_LEGACY_CRYSYSTEM_TRAIT_DEBUGCALLSTACK_TRANSLATE
case EXCEPTION_ACCESS_VIOLATION:
return "EXCEPTION_ACCESS_VIOLATION";
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
return "EXCEPTION_DATATYPE_MISALIGNMENT";
break;
case EXCEPTION_BREAKPOINT:
return "EXCEPTION_BREAKPOINT";
break;
case EXCEPTION_SINGLE_STEP:
return "EXCEPTION_SINGLE_STEP";
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
return "EXCEPTION_FLT_DENORMAL_OPERAND";
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
break;
case EXCEPTION_FLT_INEXACT_RESULT:
return "EXCEPTION_FLT_INEXACT_RESULT";
break;
case EXCEPTION_FLT_INVALID_OPERATION:
return "EXCEPTION_FLT_INVALID_OPERATION";
break;
case EXCEPTION_FLT_OVERFLOW:
return "EXCEPTION_FLT_OVERFLOW";
break;
case EXCEPTION_FLT_STACK_CHECK:
return "EXCEPTION_FLT_STACK_CHECK";
break;
case EXCEPTION_FLT_UNDERFLOW:
return "EXCEPTION_FLT_UNDERFLOW";
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
return "EXCEPTION_INT_DIVIDE_BY_ZERO";
break;
case EXCEPTION_INT_OVERFLOW:
return "EXCEPTION_INT_OVERFLOW";
break;
case EXCEPTION_PRIV_INSTRUCTION:
return "EXCEPTION_PRIV_INSTRUCTION";
break;
case EXCEPTION_IN_PAGE_ERROR:
return "EXCEPTION_IN_PAGE_ERROR";
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
return "EXCEPTION_ILLEGAL_INSTRUCTION";
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
break;
case EXCEPTION_STACK_OVERFLOW:
return "EXCEPTION_STACK_OVERFLOW";
break;
case EXCEPTION_INVALID_DISPOSITION:
return "EXCEPTION_INVALID_DISPOSITION";
break;
case EXCEPTION_GUARD_PAGE:
return "EXCEPTION_GUARD_PAGE";
break;
case EXCEPTION_INVALID_HANDLE:
return "EXCEPTION_INVALID_HANDLE";
break;
//case EXCEPTION_POSSIBLE_DEADLOCK: return "EXCEPTION_POSSIBLE_DEADLOCK"; break ;
case STATUS_FLOAT_MULTIPLE_FAULTS:
return "STATUS_FLOAT_MULTIPLE_FAULTS";
break;
case STATUS_FLOAT_MULTIPLE_TRAPS:
return "STATUS_FLOAT_MULTIPLE_TRAPS";
break;
#endif
default:
return "Unknown";
break;
}
}
void IDebugCallStack::PutVersion(char* str, size_t length)
{
AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
if (!gEnv || !gEnv->pSystem)
{
return;
}
char sFileVersion[128];
gEnv->pSystem->GetFileVersion().ToString(sFileVersion, sizeof(sFileVersion));
char sProductVersion[128];
gEnv->pSystem->GetProductVersion().ToString(sProductVersion, sizeof(sFileVersion));
//! Get time.
time_t ltime;
time(&ltime);
tm* today = localtime(&ltime);
char s[1024];
//! Use strftime to build a customized time string.
strftime(s, 128, "Logged at %#c\n", today);
azstrcat(str, length, s);
sprintf_s(s, "FileVersion: %s\n", sFileVersion);
azstrcat(str, length, s);
sprintf_s(s, "ProductVersion: %s\n", sProductVersion);
azstrcat(str, length, s);
if (gEnv->pLog)
{
const char* logfile = gEnv->pLog->GetFileName();
if (logfile)
{
sprintf (s, "LogFile: %s\n", logfile);
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 (AZ::StringFunc::Path::GetFullFileName(s, exeName))
{
azstrcat(str, length, "Executable: ");
azstrcat(str, length, exeName.c_str());
# ifdef AZ_DEBUG_BUILD
azstrcat(str, length, " (debug: yes");
# else
azstrcat(str, length, " (debug: no");
# endif
}
#endif
AZ_POP_DISABLE_WARNING
}
//Crash the application, in this way the debug callstack routine will be called and it will create all the necessary files (error.log, dump, and eventually screenshot)
void IDebugCallStack::FatalError(const char* description)
{
m_bIsFatalError = true;
WriteLineToLog(description);
#ifndef _RELEASE
bool bShowDebugScreen = g_cvars.sys_no_crash_dialog == 0;
// showing the debug screen is not safe when not called from mainthread
// it normally leads to a infinity recursion followed by a stack overflow, preventing
// useful call stacks, thus they are disabled
bShowDebugScreen = bShowDebugScreen && gEnv->mMainThreadId == CryGetCurrentThreadId();
if (bShowDebugScreen)
{
EBUS_EVENT(AZ::NativeUI::NativeUIRequestBus, DisplayOkDialog, "Open 3D Engine Fatal Error", description, false);
}
#endif
#if defined(WIN32) || !defined(_RELEASE)
int* p = 0x0;
PREFAST_SUPPRESS_WARNING(6011) * p = 1; // we're intentionally crashing here
#endif
}
void IDebugCallStack::WriteLineToLog(const char* format, ...)
{
CDebugAllowFileAccess allowFileAccess;
va_list ArgList;
char szBuffer[MAX_WARNING_LENGTH];
va_start(ArgList, format);
vsnprintf_s(szBuffer, sizeof(szBuffer), sizeof(szBuffer) - 1, format, ArgList);
cry_strcat(szBuffer, "\n");
szBuffer[sizeof(szBuffer) - 1] = '\0';
va_end(ArgList);
AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle;
AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\error.log", AZ::IO::GetOpenModeFromStringMode("a+t"), fileHandle);
if (fileHandle != AZ::IO::InvalidHandle)
{
AZ::IO::FileIOBase::GetDirectInstance()->Write(fileHandle, szBuffer, strlen(szBuffer));
AZ::IO::FileIOBase::GetDirectInstance()->Flush(fileHandle);
AZ::IO::FileIOBase::GetDirectInstance()->Close(fileHandle);
}
}
//////////////////////////////////////////////////////////////////////////
void IDebugCallStack::StartMemLog()
{
AZ::IO::FileIOBase::GetDirectInstance()->Open("@Log@\\memallocfile.log", AZ::IO::OpenMode::ModeWrite, m_memAllocFileHandle);
assert(m_memAllocFileHandle != AZ::IO::InvalidHandle);
}
//////////////////////////////////////////////////////////////////////////
void IDebugCallStack::StopMemLog()
{
if (m_memAllocFileHandle != AZ::IO::InvalidHandle)
{
AZ::IO::FileIOBase::GetDirectInstance()->Close(m_memAllocFileHandle);
m_memAllocFileHandle = AZ::IO::InvalidHandle;
}
}
//#endif //!defined(LINUX)

@ -1,90 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : A multiplatform base class for handling errors and collecting call stacks
#ifndef CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
#define CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H
#pragma once
#include "System.h"
#if AZ_LEGACY_CRYSYSTEM_TRAIT_FORWARD_EXCEPTION_POINTERS
struct EXCEPTION_POINTERS;
#endif
//! Limits the maximal number of functions in call stack.
enum
{
MAX_DEBUG_STACK_ENTRIES = 80
};
class IDebugCallStack
{
public:
// Returns single instance of DebugStack
static IDebugCallStack* instance();
virtual int handleException([[maybe_unused]] EXCEPTION_POINTERS* exception_pointer){return 0; }
// returns the module name of a given address
virtual string GetModuleNameForAddr([[maybe_unused]] void* addr) { return "[unknown]"; }
// returns the function name of a given address together with source file and line number (if available) of a given address
virtual void GetProcNameForAddr(void* addr, string& procName, void*& baseAddr, string& filename, int& line)
{
filename = "[unknown]";
line = 0;
baseAddr = addr;
#if defined(PLATFORM_64BIT)
procName.Format("[%016llX]", addr);
#else
procName.Format("[%08X]", addr);
#endif
}
// returns current filename
virtual string GetCurrentFilename() { return "[unknown]"; }
//! Dumps Current Call Stack to log.
virtual void LogCallstack();
//triggers a fatal error, so the DebugCallstack can create the error.log and terminate the application
void FatalError(const char*);
//Reports a bug and continues execution
virtual void ReportBug(const char*) {}
virtual void FileCreationCallback(void (* postBackupProcess)());
static void WriteLineToLog(const char* format, ...);
virtual void StartMemLog();
virtual void StopMemLog();
protected:
IDebugCallStack();
virtual ~IDebugCallStack();
static const char* TranslateExceptionCode(DWORD dwExcept);
static void PutVersion(char* str, size_t length);
bool m_bIsFatalError;
static const char* const s_szFatalErrorCode;
void (* m_postBackupProcess)();
AZ::IO::HandleType m_memAllocFileHandle;
};
#endif // CRYINCLUDE_CRYSYSTEM_IDEBUGCALLSTACK_H

@ -1,59 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
struct SThreadConfig
{
enum eThreadParamFlag
{
eThreadParamFlag_ThreadName = BIT(0),
eThreadParamFlag_StackSize = BIT(1),
eThreadParamFlag_Affinity = BIT(2),
eThreadParamFlag_Priority = BIT(3),
eThreadParamFlag_PriorityBoost = BIT(4),
};
typedef uint32 TThreadParamFlag;
const char* szThreadName;
uint32 stackSizeBytes;
uint32 affinityFlag;
int32 priority;
bool bDisablePriorityBoost;
TThreadParamFlag paramActivityFlag;
};
class IThreadConfigManager
{
public:
virtual ~IThreadConfigManager()
{
}
//! Called once during System startup.
//! Loads the thread configuration for the executing platform from file.
virtual bool LoadConfig(const char* pcPath) = 0;
//! Returns true if a config has been loaded.
virtual bool ConfigLoaded() const = 0;
//! Gets the thread configuration for the specified thread on the active platform.
//! If no matching config is found a default configuration is returned (which does not have the same name as the search string).
virtual const SThreadConfig* GetThreadConfig(const char* sThreadName, ...) = 0;
virtual const SThreadConfig* GetDefaultThreadConfig() const = 0;
//! Dump a detailed description of the thread startup configurations for this platform to the log file.
virtual void DumpThreadConfigurationsToLog() = 0;
};

@ -17,7 +17,6 @@
#include "LevelSystem.h"
#include <IAudioSystem.h>
#include "IMovieSystem.h"
#include "IMaterialEffects.h"
#include <IResourceManager.h>
#include <ILocalizationManager.h>
#include "CryPath.h"
@ -648,20 +647,6 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName)
AZStd::string levelPath(pLevelInfo->GetPath());
/*
ICVar *pFileCache = gEnv->pConsole->GetCVar("sys_FileCache"); CRY_ASSERT(pFileCache);
if(pFileCache->GetIVal())
{
if(pPak->OpenPack("",pLevelInfo->GetPath()+string("/FileCache.dat")))
gEnv->pLog->Log("FileCache.dat loaded");
else
gEnv->pLog->Log("FileCache.dat not loaded");
}
*/
m_pSystem->SetThreadState(ESubsys_Physics, false);
ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay");
float spamDelay = 0.0f;
if (pSpamDelay)
@ -768,8 +753,6 @@ ILevel* CLevelSystem::LoadLevelInternal(const char* _levelName)
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0);
m_pSystem->SetThreadState(ESubsys_Physics, true);
return m_pCurrentLevel;
}

@ -247,8 +247,6 @@ namespace LegacyLevelSystem
auto pPak = gEnv->pCryPak;
m_pSystem->SetThreadState(ESubsys_Physics, false);
ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay");
float spamDelay = 0.0f;
if (pSpamDelay)
@ -343,8 +341,6 @@ namespace LegacyLevelSystem
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0);
m_pSystem->SetThreadState(ESubsys_Physics, true);
return true;
}

@ -920,13 +920,7 @@ bool CLog::LogToMainThread(const char* szString, ELogType logType, bool bAdd, SL
msg.bAdd = bAdd;
msg.destination = destination;
msg.logType = logType;
// don't try to store the log message for later in case of out of memory, since then its very likely that this allocation
// also fails and results in a stack overflow. This way we should at least get a out of memory on-screen message instead of
// a not obvious crash
if ((gEnv) && (gEnv->bIsOutOfMemory == false))
{
m_threadSafeMsgQueue.push(msg);
}
m_threadSafeMsgQueue.push(msg);
return true;
}
return false;
@ -1448,8 +1442,6 @@ void CLog::UpdateLoadingScreen(const char* szFormat, ...)
if (CryGetCurrentThreadId() == m_nMainThreadId)
{
((CSystem*)m_pSystem)->UpdateLoadingScreen();
#ifndef LINUX
// Take this opportunity to update streaming engine.
if (IStreamEngine* pStreamEngine = GetISystem()->GetStreamEngine())

File diff suppressed because it is too large Load Diff

@ -1,293 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H
#define CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H
#pragma once
#include <IConsole.h>
#include <INotificationNetwork.h>
#include <CryThread.h>
#include <AzCore/Socket/AzSocket_fwd.h>
class CNotificationNetwork;
namespace NotificationNetwork {
// Constants
static const uint32 NN_PACKET_HEADER_LENGTH = 2 * sizeof(uint32) + NN_CHANNEL_NAME_LENGTH_MAX;
static const uint32 NN_PACKET_HEADER_OFFSET_MESSAGE = 0;
static const uint32 NN_PACKET_HEADER_OFFSET_DATA_LENGTH = sizeof(uint32);
static const uint32 NN_PACKET_HEADER_OFFSET_CHANNEL = sizeof(uint32) + sizeof(uint32);
static const char* NN_THREAD_NAME = "NotificationNetwork";
enum EMessage
{
eMessage_DataTransfer = 0xbada2217,
eMessage_ChannelRegister = 0xab4eda30,
eMessage_ChannelUnregister = 0xfa4e3423,
};
// Classes
struct CChannel
{
public:
static bool IsNameValid(const char* name);
public:
CChannel();
CChannel(const char* name);
~CChannel();
public:
void WriteToPacketHeader(void* pPacket) const;
void ReadFromPacketHeader(void* pPacket);
public:
bool operator ==(const CChannel& channel) const;
bool operator !=(const CChannel& channel) const;
private:
char m_name[NN_CHANNEL_NAME_LENGTH_MAX];
};
// TEMP
struct SBuffer
{
uint8* pData;
uint32 length;
CChannel channel;
};
class CListeners
{
public:
CListeners();
~CListeners();
public:
size_t Count() { return m_listeners.size(); }
size_t Count(const CChannel& channel);
CChannel& Channel(size_t index) { return m_listeners[index].second; }
CChannel* Channel(INotificationNetworkListener* pListener);
bool Bind(const CChannel& channel, INotificationNetworkListener* pListener);
bool Remove(INotificationNetworkListener* pListener);
void NotificationPush(const SBuffer& buffer);
void NotificationsProcess();
private:
std::vector< std::pair<INotificationNetworkListener*, CChannel> > m_listeners;
std::queue<SBuffer> m_notifications[2];
std::queue<SBuffer>* m_pNotificationWrite;
std::queue<SBuffer>* m_pNotificationRead;
CryCriticalSection m_notificationCriticalSection;
};
class CConnectionBase
{
public:
CConnectionBase(CNotificationNetwork* pNotificationNetwork);
virtual ~CConnectionBase();
public:
AZSOCKET CreateSocket();
bool Connect(const char* address, uint16 port);
AZSOCKET GetSocket() { return m_socket; }
bool Validate();
bool SendNotification(const CChannel& channel, const void* pBuffer, size_t length);
bool Receive(CListeners& listeners);
bool GetIsConnectedFlag();
bool GetIsFailedToConnectFlag() const;
protected:
CNotificationNetwork* GetNotificationNetwork() { return m_pNotificationNetwork; }
void SetAddress(const char* address, uint16 port);
void SetSocket(AZSOCKET sock) { m_socket = sock; }
bool Send(const void* pBuffer, size_t length);
bool SendMessage(EMessage eMessage, const CChannel& channel, uint32 data);
bool Select_Internal();
void CloseSocket_Internal();
virtual bool OnConnect([[maybe_unused]] bool bConnectionResult) { return true; }
virtual bool OnDisconnect() {return true; }
virtual bool OnMessage([[maybe_unused]] EMessage eMessage, [[maybe_unused]] const CChannel& channel) { return false; }
private:
bool ReceiveMessage(CListeners& listeners);
bool ReceiveNotification(CListeners& listeners);
protected:
CNotificationNetwork* m_pNotificationNetwork;
char m_address[16];
uint16 m_port;
AZSOCKET m_socket;
uint8 m_bufferHeader[NN_PACKET_HEADER_LENGTH];
SBuffer m_buffer;
uint32 m_dataLeft;
volatile bool m_boIsConnected;
volatile bool m_boIsFailedToConnect;
};
class CClient
: public CConnectionBase
, public INotificationNetworkClient
{
public:
typedef std::vector<INotificationNetworkConnectionCallback*> TDNotificationNetworkConnectionCallbacks;
static CClient* Create(CNotificationNetwork* pNotificationNetwork, const char* address, uint16 port);
static CClient* Create(CNotificationNetwork* pNotificationNetwork);
private:
CClient(CNotificationNetwork* pNotificationNetwork);
~CClient();
public:
bool Receive() { return CConnectionBase::Receive(m_listeners); }
void Update();
// CConnectionBase
public:
virtual bool OnConnect(bool bConnectionResult);
virtual bool OnDisconnect();
virtual bool OnMessage(EMessage eMessage, const CChannel& channel);
// INotificationNetworkClient
public:
bool Connect(const char* address, uint16 port);
void Release() { delete this; }
virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener);
virtual bool ListenerRemove(INotificationNetworkListener* pListener);
virtual bool Send(const char* channelName, const void* pBuffer, size_t length);
virtual bool IsConnected() {return CConnectionBase::GetIsConnectedFlag(); }
virtual bool IsFailedToConnect() const{return CConnectionBase::GetIsFailedToConnectFlag(); }
virtual bool RegisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback);
virtual bool UnregisterCallbackListener(INotificationNetworkConnectionCallback* pConnectionCallback);
private:
CListeners m_listeners;
TDNotificationNetworkConnectionCallbacks m_cNotificationNetworkConnectionCallbacks;
CryCriticalSection m_stConnectionCallbacksLock;
};
} // namespace NotificationNetwork
class CNotificationNetwork
: public INotificationNetwork
{
private:
class CConnection
: public NotificationNetwork::CConnectionBase
{
public:
CConnection(CNotificationNetwork* pNotificationNetwork, AZSOCKET sock);
virtual ~CConnection();
public:
bool IsListening(const NotificationNetwork::CChannel& channel);
// CConnectionBase
protected:
virtual bool OnMessage(NotificationNetwork::EMessage eMessage, const NotificationNetwork::CChannel& channel);
private:
std::vector<NotificationNetwork::CChannel> m_listeningChannels;
};
class CThread
: public CryThread<CThread>
{
public:
CThread();
~CThread();
public:
bool Begin(CNotificationNetwork* pNotificationNetwork);
void End();
// CryRunnable
public:
virtual void Run();
private:
CNotificationNetwork* m_pNotificationNetwork;
bool m_bRun;
} m_thread;
public:
static CNotificationNetwork* Create();
public:
CNotificationNetwork();
~CNotificationNetwork();
public:
void ReleaseClients(NotificationNetwork::CClient* pClient);
private:
void ProcessSockets();
// INotificationNetwork
public:
virtual void Release() { delete this; }
virtual INotificationNetworkClient* CreateClient();
virtual INotificationNetworkClient* Connect(const char* address, uint16 port);
virtual size_t GetConnectionCount(const char* channelName);
virtual void Update();
virtual bool ListenerBind(const char* channelName, INotificationNetworkListener* pListener);
virtual bool ListenerRemove(INotificationNetworkListener* pListener);
virtual uint32 Send(const char* channelName, const void* pBuffer, size_t length);
private:
AZSOCKET m_socket;
std::vector<CConnection*> m_connections;
std::vector<NotificationNetwork::CClient*> m_clients;
NotificationNetwork::CListeners m_listeners;
CryCriticalSection m_clientsCriticalSection;
};
#endif // CRYINCLUDE_CRYSYSTEM_NOTIFICATIONNETWORK_H

@ -1,134 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "ProfileLogSystem.h"
//////////////////////////////////////////////////////////////////////////
// class CLogElement
//////////////////////////////////////////////////////////////////////////
CLogElement::CLogElement()
: m_pParent (NULL)
, m_time (0)
{
}
CLogElement::CLogElement(CLogElement* pParent)
: m_pParent (pParent)
, m_time (0)
{
}
CLogElement::CLogElement(CLogElement* pParent, const char* name, const char* message)
: m_pParent (pParent)
, m_strName (name)
, m_strMessage(message)
, m_time (0)
{
}
void CLogElement::Flush(stack_string& indent)
{
if (m_logElements.empty())
{
CryLog("%s%s [%.3f ms] %s", indent.c_str(), m_strName.c_str(), m_time, m_strMessage.c_str());
return;
}
CryLog("%s+%s [%.3f ms] %s", indent.c_str(), m_strName.c_str(), m_time, m_strMessage.c_str());
indent += " ";
for (std::list<CLogElement>::iterator it = m_logElements.begin(); it != m_logElements.end(); ++it)
{
(*it).Flush(indent);
}
indent.erase(0, 2);
CryLog("%s-%s", indent.c_str(), m_strName.c_str());
}
ILogElement* CLogElement::Log(const char* name, const char* message)
{
m_logElements.push_back(CLogElement(this));
m_logElements.back().m_strName = name;
m_logElements.back().m_strMessage = message;
return &m_logElements.back();
}
ILogElement* CLogElement::SetTime(float time)
{
m_time = time;
return m_pParent;
}
void CLogElement::Clear()
{
m_logElements.resize(0);
}
//////////////////////////////////////////////////////////////////////////
// class CProfileLogSystem
//////////////////////////////////////////////////////////////////////////
CProfileLogSystem::CProfileLogSystem()
: m_rootElelent(NULL)
, m_pLastElelent(NULL)
{
}
CProfileLogSystem::~CProfileLogSystem()
{
}
ILogElement* CProfileLogSystem::Log(const char* name, const char* message)
{
if (m_pLastElelent)
{
m_pLastElelent = m_pLastElelent->Log(name, message);
}
else
{
m_rootElelent.Clear();
m_rootElelent.SetName(name);
m_rootElelent.SetMessage(message);
m_pLastElelent = &m_rootElelent;
}
return m_pLastElelent;
}
void CProfileLogSystem::SetTime(ILogElement* pElement, float time)
{
if (pElement == NULL)
{
return;
}
m_pLastElelent = pElement->SetTime(time);
if (m_pLastElelent)
{
return;
}
stack_string indent;
m_rootElelent.Flush(indent);
m_rootElelent.Clear();
}
void CProfileLogSystem::Release()
{
delete this;
}

@ -1,74 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Implementation of the IProfileLogSystem interface, which is used to
// save hierarchical log with SHierProfileLogItem
#ifndef CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H
#define CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H
#pragma once
#include "ProfileLog.h"
class CLogElement
: public ILogElement
{
public:
CLogElement();
CLogElement(CLogElement* pParent);
CLogElement(CLogElement* pParent, const char* name, const char* message);
virtual ILogElement* Log (const char* name, const char* message);
virtual ILogElement* SetTime (float time);
virtual void Flush (stack_string& indent);
void Clear ();
inline void SetName(const char* name)
{
m_strName = name;
}
inline void SetMessage(const char* message)
{
m_strMessage = message;
}
private:
string m_strName;
string m_strMessage;
float m_time; // milliSeconds
CLogElement* m_pParent;
std::list<CLogElement> m_logElements;
};
class CProfileLogSystem
: public IProfileLogSystem
{
public:
CProfileLogSystem();
~CProfileLogSystem();
virtual ILogElement* Log (const char* name, const char* message);
virtual void SetTime (ILogElement* pElement, float time);
virtual void Release ();
private:
CLogElement m_rootElelent;
ILogElement* m_pLastElelent;
};
#endif // CRYINCLUDE_CRYSYSTEM_PROFILELOGSYSTEM_H

@ -699,7 +699,7 @@ void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_P
if (g_cvars.archiveVars.nLoadCache)
{
//Load the frontend common mode switch pak, this can considerably reduce the time spent switching especially from disc
if (!gEnv->bMultiplayer && LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false)
if (LoadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP) == false)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Could not load %s during init. This file can significantly reduce frontend loading times.\n", FRONTEND_COMMON_PAK_FILENAME_SP);
}
@ -710,14 +710,7 @@ void CResourceManager::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_P
case ESYSTEM_EVENT_LEVEL_LOAD_PREPARE:
{
if (!gEnv->bMultiplayer)
{
UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp");
}
else
{
UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_MP, FRONTEND_COMMON_LIST_FILENAME "_mp");
}
UnloadMenuCommonPak(FRONTEND_COMMON_PAK_FILENAME_SP, FRONTEND_COMMON_LIST_FILENAME "_sp");
m_bLevelTransitioning = !m_sLevelName.empty();

@ -1,787 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#ifdef SOFTCODE_SYSTEM_ENABLED
#ifndef SOFTCODE_ENABLED
// Even if this module isn't built with SC enabled, if the SC system is enabled we define
// it for this compilation unit to ensure we use the correct versions of the IType* interfaces.
#define SOFTCODE_ENABLED
#endif
#include "SoftCodeMgr.h"
#include <IConsole.h>
#include <CryLibrary.h>
#include <CryPath.h>
#include <AzCore/std/functional.h> // for function<> in find files
// This should resolve to "GetTypeLibrary" but we export by ordinal to avoid overheads on 360
// and keep everything consistent.
static const char* DLL_GETTYPELIBRARY = (LPCSTR)1;
struct CInstanceData
{
CInstanceData(void* pInstance, size_t memberCount)
: m_pOldInstance(pInstance)
, m_pNewInstance()
{
m_members.resize(memberCount);
}
~CInstanceData()
{
// Delete all members
for (TMemberVec::iterator iter(m_members.begin());
iter != m_members.end();
++iter)
{
// TODO: Safe cross module? Same allocator? Use a Destroy() method?
delete *iter;
}
}
void* Instance() { return m_pOldInstance; }
void AddMember(size_t index, IExchangeValue& value)
{
// TODO: Add support for members with same name at different hierarchy levels
assert(m_members[index] == NULL);
assert(index != ~0);
// Support expansion of m_members during while resolving members
if (index >= m_members.size())
{
m_members.resize(index + 1);
}
m_members[index] = value.Clone();
}
IExchangeValue* GetMember(size_t index) const
{
assert(index < m_members.size());
return m_members[index];
}
void SetNewInstance(void* pNewInstance) { m_pNewInstance = pNewInstance; }
void* m_pOldInstance;
void* m_pNewInstance;
typedef std::vector<IExchangeValue*> TMemberVec;
TMemberVec m_members;
};
class CExchanger
: public IExchanger
{
public:
CExchanger()
: m_pInstanceData()
, m_instanceIndex(~0)
, m_state(eState_ResolvingMembers)
{}
virtual ~CExchanger()
{
DestroyInstanceData();
}
virtual bool IsLoading() const { return m_state >= eState_WritingNewMembers; }
virtual size_t InstanceCount() const { return m_instances.size(); }
virtual bool BeginInstance(void* pInstance)
{
if (IsLoading())
{
if (++m_instanceIndex < m_instances.size())
{
m_pInstanceData = m_instances[m_instanceIndex];
m_pInstanceData->SetNewInstance(pInstance);
}
else
{
m_pInstanceData = NULL;
}
}
else // Reading/resolving members
{
m_instanceIndex = m_instances.size();
m_pInstanceData = new CInstanceData(pInstance, m_memberMap.size());
m_instances.push_back(m_pInstanceData);
}
return m_pInstanceData != NULL;
}
virtual bool SetValue(const char* name, IExchangeValue& value)
{
assert(!IsLoading());
const size_t index = FindMemberIndex(name);
const bool consumingValue = index != ~0;
if (consumingValue)
{
m_pInstanceData->AddMember(index, value);
}
return consumingValue;
}
virtual IExchangeValue* GetValue(const char* name, void* pTarget, size_t targetSize)
{
assert(IsLoading());
const size_t index = FindMemberIndex(name);
// If member resolved (may not be if restoring to old instances)
if (index != ~0)
{
// If member data available (may not be if member is new)
if (IExchangeValue* pValue = m_pInstanceData->GetMember(index))
{
if (pValue->GetSizeOf() == targetSize)
{
return pValue;
}
else // Member size mismatch
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING,
"SoftCode: Member %s of instance %p has changed size (old: %d new: %d), setting to default value.",
name, m_pInstanceData->Instance(), (int)pValue->GetSizeOf(), (int)targetSize);
}
}
else // Member unknown
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING,
"SoftCode: Member %s (of instance %p) appears to be new.",
name, m_pInstanceData->Instance());
// TODO: Could attempt to validate against a known wipe pattern ie. 0xfefefefe
// This could catch most uninitialized variables...
if (targetSize <= sizeof(void*))
{
switch (targetSize)
{
case 1:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %d", *reinterpret_cast<char*>(pTarget));
break;
case 2:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %04x", *reinterpret_cast<short*>(pTarget));
break;
case 4:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %08x", *reinterpret_cast<int*>(pTarget));
break;
case 8:
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "\tLeaving as: %llx", *reinterpret_cast<long long*>(pTarget));
break;
}
}
}
}
// Indicate value should be default constructed
return NULL;
}
// Used once required members have been established, members not already
// encountered will be ignored.
void LockMemberSet()
{
assert(m_state == eState_ResolvingMembers);
DestroyInstanceData();
m_state = eState_ReadingOldMembers;
}
// Rewinds instance data and prepare for loading
void RewindForLoading()
{
assert(m_state == eState_ReadingOldMembers);
m_pInstanceData = NULL;
m_instanceIndex = ~0;
m_state = eState_WritingNewMembers;
}
// Rewinds instance data to prepare to restore old members (UNDO)
void RewindForRestore()
{
assert(m_state == eState_WritingNewMembers);
m_pInstanceData = NULL;
m_instanceIndex = ~0;
m_state = eState_RestoringOldMembers;
}
void NotifyListenerOfReplacements(ISoftCodeListener* pListener)
{
for (TInstanceVec::const_iterator iter(m_instances.begin()); iter != m_instances.end(); ++iter)
{
CInstanceData* pInstanceData = *iter;
pListener->InstanceReplaced(pInstanceData->m_pOldInstance, pInstanceData->m_pNewInstance);
}
}
private:
void DestroyInstanceData()
{
m_pInstanceData = NULL;
m_instanceIndex = ~0;
for (TInstanceVec::iterator iter(m_instances.begin()); iter != m_instances.end(); ++iter)
{
delete *iter;
}
m_instances.resize(0);
}
inline size_t FindMemberIndex(const string& memberName)
{
size_t index = ~0;
// If needed members have been resolved
if (m_state != eState_ResolvingMembers)
{
TMemberMap::const_iterator iter(m_memberMap.find(memberName));
if (iter != m_memberMap.end())
{
index = iter->second;
}
}
else // Add this member to the map with a new index
{
// Ensure there's no member name duplicates
assert(m_memberMap.find(memberName) == m_memberMap.end());
// A new entry
index = m_memberMap.size();
size_t& newIndex = m_memberMap[memberName];
newIndex = index;
}
return index;
}
private:
CInstanceData* m_pInstanceData;
size_t m_instanceIndex;
typedef std::vector<CInstanceData*> TInstanceVec;
TInstanceVec m_instances;
// Maps instance members to offsets in instance member vectors
typedef std::map<string, size_t> TMemberMap;
TMemberMap m_memberMap;
enum EState
{
eState_ResolvingMembers = 0, // Record new member names as found
eState_ReadingOldMembers, // Scrape requested member data from old instances
eState_WritingNewMembers, // Write old member data to new instances
eState_RestoringOldMembers, // Restore scraped values to old instances (UNDO)
};
EState m_state;
};
// ----
DynamicTypeLibrary::DynamicTypeLibrary(const char* name)
: m_name(name)
, m_listeners(1)
{}
const char* DynamicTypeLibrary::GetName()
{
return m_name;
}
void* DynamicTypeLibrary::CreateInstanceVoid(const char* typeName)
{
TTypeMap::const_iterator typeIter(m_types.find(typeName));
if (typeIter != m_types.end())
{
ITypeRegistrar* pRegistrar = typeIter->second;
return pRegistrar->CreateInstance();
}
return NULL;
}
void DynamicTypeLibrary::SetOverride(ITypeLibrary* /*pOverrideLib*/)
{
CryFatalError("Unsupported: Attempting to SetOverride on a DynamicTypeLibrary!");
}
size_t DynamicTypeLibrary::GetTypes([[maybe_unused]] ITypeRegistrar** ppRegistrar, [[maybe_unused]] size_t& count) const
{
CryFatalError("Unsupported: Attempting to GetTypes on a DynamicTypeLibrary!");
return 0;
}
void DynamicTypeLibrary::AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName)
{
// This DynamicTypeLibrary could have been created by this listener request
// So ensure we have a name...!
if (!m_name)
{
m_name = libraryName;
}
m_listeners.Add(pListener, listenerName);
}
void DynamicTypeLibrary::RemoveListener(ISoftCodeListener* pListener)
{
m_listeners.Remove(pListener);
}
void DynamicTypeLibrary::IntegrateLibrary(ITypeLibrary* pLib, bool isDefault)
{
typedef std::vector<ITypeRegistrar*> TTypeVec;
// Resolve our name if we haven't already
if (!m_name)
{
m_name = pLib->GetName();
}
// Override the new lib immediately
pLib->SetOverride(this);
// Query the new library for its types
size_t typeCount = 0;
pLib->GetTypes(NULL, typeCount);
if (typeCount > 0)
{
TTypeVec typeVec;
typeVec.resize(typeCount);
pLib->GetTypes(&(typeVec.front()), typeCount);
if (!isDefault)
{
CryLogAlways("SoftCode: Integrating %d new types defined in %s...", (int)typeCount, m_name);
}
// Attempt to integrate each type found
for (TTypeVec::iterator typeIter(typeVec.begin()); typeIter != typeVec.end(); ++typeIter)
{
IntegrateType(*typeIter, isDefault);
}
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: New %s library has no registered types. Nothing to integrate.", pLib->GetName());
}
}
ITypeRegistrar* DynamicTypeLibrary::FindTypeForInstance(void* pInstance) const
{
for (TTypeMap::const_iterator iter(m_types.begin()); iter != m_types.end(); ++iter)
{
ITypeRegistrar* pType = iter->second;
if (pType->HasInstance(pInstance))
{
return pType;
}
}
return NULL;
}
void DynamicTypeLibrary::IntegrateType(ITypeRegistrar* pType, bool isDefault)
{
const char* typeName = pType->GetName();
// If there's an existing registrar
ITypeRegistrar* pExistingType = m_types[typeName];
assert(pExistingType != pType); // Sanity check
// If the new type is the default (built-in) type but it's already been overridden
if (isDefault && pExistingType)
{
return; // Nothing to do
}
// TODO: Inform listeners that there's a new library available
// and ask if we should use it immediately or defer
CExchanger exchanger;
// If the type can be safely created, visited and destroyed
if (EvaluateType(pType, exchanger))
{
// Override the type
m_types[typeName] = pType;
if (!isDefault)
{
CryLogAlways("SoftCode: Overridden %s in library %s", typeName, m_name);
}
const size_t instanceCount = (pExistingType) ? pExistingType->InstanceCount() : 0;
// If there are any existing instances
if (instanceCount > 0)
{
CryLogAlways("SoftCode: Attempting to exchange %d %s instances to the new version...", (int)instanceCount, typeName);
// Read instance members for type (removes data for resolved members)
if (pExistingType->ExchangeInstances(exchanger))
{
exchanger.RewindForLoading();
// Write instance members for type
if (pType->ExchangeInstances(exchanger))
{
// Success! Tell the listeners to fix up their pointers
for (TListeners::Notifier notifier(m_listeners); notifier.IsValid(); notifier.Next())
{
exchanger.NotifyListenerOfReplacements(*notifier);
}
CryLogAlways("SoftCode: %d %s instances successfully overridden to latest!", (int)instanceCount, typeName);
// Clean up old instances
if (!pExistingType->DestroyInstances())
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: Failed to destroy old instances of type %s - leak probable.", typeName);
}
}
else // Failed to create & write into new instances
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to create and write into new instances of %s. Attempting restore of old instances...", typeName);
if (!pType->DestroyInstances())
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "SoftCode: Failed to destroy new instances of type %s - leak probable.", typeName);
}
// Restore the original type library as the active one
m_types[typeName] = pExistingType;
// Attempt to restore the old instances with their original data
exchanger.RewindForRestore();
if (pExistingType->ExchangeInstances(exchanger))
{
CryLogAlways("SoftCode: Type %s in library %s successfully restored to previous revision!", typeName, m_name);
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Restore of old %s instances failed. State now undefined!", typeName);
}
}
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to read members on %s", typeName);
}
}
}
}
bool DynamicTypeLibrary::EvaluateType(ITypeRegistrar* pType, CExchanger& exchanger)
{
// Try a full object life-time with a single instance of the
// new type before attempting a member exchange. This also allow the
// exchanger to determine the required members to be removed from the
// old instances.
bool testPassed = false;
// Create a single test instance of the type
if (pType->CreateInstance())
{
// Read the instance members (also prepares the exchanger member set)
if (pType->ExchangeInstances(exchanger))
{
// Destroy the old instance
if (pType->DestroyInstances())
{
// Indicate required members are now resolved
exchanger.LockMemberSet();
testPassed = true;
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to destroy test instance of type: %s. New type will be skipped.", pType->GetName());
}
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to read members in test instance of type: %s. New type will be skipped.", pType->GetName());
}
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to create test instance of type: %s. New type will be skipped.", pType->GetName());
}
return testPassed;
}
// ----
// The export we expect to find in the SoftCode modules
typedef ITypeLibrary* (__stdcall * TGetTypeLibraryFcn)();
static void SoftCode_UpdateCmd([[maybe_unused]] IConsoleCmdArgs* pArgs)
{
gEnv->pSoftCodeMgr->LoadNewModules();
}
static int g_autoUpdatePeriod = 0;
SoftCodeMgr::SoftCodeMgr()
{
REGISTER_CVAR2("sc_autoupdate", &g_autoUpdatePeriod, 5, VF_CHEAT, "Set the auto-update poll period for new SoftCode modules. Set to zero to disable");
REGISTER_COMMAND("sc_update", reinterpret_cast<ConsoleCommandFunc>(&SoftCode_UpdateCmd), VF_CHEAT, "Loads any new SoftCode modules");
// Clear out any old modules
{
typedef std::vector<string> TStringVec;
TStringVec filePaths;
if (FindSoftCodeFiles("*", filePaths) > 0)
{
for (TStringVec::const_iterator iter(filePaths.begin()); iter != filePaths.end(); ++iter)
{
if (!DeleteFile(iter->c_str()))
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "SoftCode: Failed to clean %s", iter->c_str());
}
}
}
}
}
SoftCodeMgr::~SoftCodeMgr()
{
if (gEnv->pConsole)
{
gEnv->pConsole->RemoveCommand("sc_update");
gEnv->pConsole->UnregisterVariable("sc_autoupdate");
}
}
// Used to register built-in libraries on first use
void SoftCodeMgr::RegisterLibrary(ITypeLibrary* pDefaultLib)
{
DynamicTypeLibrary& typeLib = m_libraryMap[pDefaultLib->GetName()];
typeLib.IntegrateLibrary(pDefaultLib, true);
}
// Look for new SoftCode modules and load them, adding their types to the registry
void SoftCodeMgr::LoadNewModules()
{
typedef std::vector<string> TStringVec;
typedef TStringVec::const_iterator TModuleIter;
TStringVec modulePaths;
// Find modules
FindSoftCodeFiles("*.dll", modulePaths);
for (TModuleIter libIter(modulePaths.begin()); libIter != modulePaths.end(); ++libIter)
{
const char* moduleName = libIter->c_str();
LoadModule(moduleName);
}
}
void SoftCodeMgr::AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName)
{
// Find an existing lib or create a new one to add the listener to
DynamicTypeLibrary& lib = m_libraryMap[libraryName];
lib.AddListener(libraryName, pListener, listenerName);
}
void SoftCodeMgr::RemoveListener(const char* libraryName, ISoftCodeListener* pListener)
{
TLibMap::iterator iter(m_libraryMap.find(libraryName));
if (iter != m_libraryMap.end())
{
iter->second.RemoveListener(pListener);
}
}
// To be called regularly to poll for library updates
void SoftCodeMgr::PollForNewModules()
{
if (g_autoUpdatePeriod > 0)
{
const CTimeValue frameStartTime(gEnv->pTimer->GetFrameStartTime(ITimer::ETIMER_UI));
if (m_nextAutoCheckTime <= frameStartTime)
{
m_nextAutoCheckTime.SetSeconds((int64)g_autoUpdatePeriod);
m_nextAutoCheckTime += frameStartTime;
// Attempt to find and load any new modules
LoadNewModules();
}
}
}
namespace
{
// Util
class InstanceFixup
: public ISoftCodeListener
{
public:
InstanceFixup(void* pOldInstance)
: m_pOldInstance(pOldInstance)
, m_pNewInstance() {}
virtual void InstanceReplaced(void* pOldInstance, void* pNewInstance)
{
if (m_pOldInstance == pOldInstance)
{
m_pNewInstance = pNewInstance;
}
}
void* NewInstance() const { return m_pNewInstance; }
private:
void* m_pOldInstance;
void* m_pNewInstance;
};
}
// Stops thread execution until a new SoftCode module is available
void* SoftCodeMgr::WaitForUpdate(void* pInstance)
{
DynamicTypeLibrary* pOwningLib = NULL;
ITypeRegistrar* pOldType = NULL;
// Find existing instance
for (TLibMap::iterator libIter(m_libraryMap.begin()); libIter != m_libraryMap.end(); ++libIter)
{
DynamicTypeLibrary& lib = libIter->second;
if (ITypeRegistrar* pType = lib.FindTypeForInstance(pInstance))
{
pOwningLib = &lib;
pOldType = pType;
break;
}
}
if (!pOwningLib)
{
CryFatalError("SoftCode: Attempting to wait for update on an unknown instance!");
return NULL;
}
InstanceFixup instanceFixup(pInstance);
pOwningLib->AddListener(pOwningLib->GetName(), &instanceFixup, "InstanceFixup");
while (true)
{
// Find and load new modules
LoadNewModules();
// Got a new instance?
if (instanceFixup.NewInstance())
{
break;
}
// Wait for a new module
CryLogAlways("SoftCode: Pausing execution until class %s in %s library is updated...", pOldType->GetName(), pOwningLib->GetName());
__debugbreak(); // Stopped here? Check your log!
}
pOwningLib->RemoveListener(&instanceFixup);
return instanceFixup.NewInstance();
}
bool SoftCodeMgr::LoadModule(const char* moduleName)
{
bool success = false;
// If module not yet loaded
if (m_loadedSet.find(moduleName) == m_loadedSet.end())
{
m_loadedSet.insert(moduleName);
CryLogAlways("SoftCode: Found new module %s, attempting to load...", moduleName);
HMODULE hModule = CryLoadLibrary(moduleName);
if (hModule)
{
TGetTypeLibraryFcn pGetTypeLibraryFcn = reinterpret_cast<TGetTypeLibraryFcn>(GetProcAddress(hModule, DLL_GETTYPELIBRARY));
if (pGetTypeLibraryFcn)
{
// Add to list of loaded libs & override any earlier TypeLibraries already registered
ITypeLibrary* pTypeLibrary = pGetTypeLibraryFcn();
if (pTypeLibrary)
{
const char* libraryName = pTypeLibrary->GetName();
m_libraryMap[libraryName].IntegrateLibrary(pTypeLibrary, false);
CryLogAlways("SoftCode: Loaded new type library \"%s\" from module %s.", libraryName, moduleName);
success = true;
}
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to resolve GetTypeLibrary() export in: %s (error: %x)", moduleName, GetLastError());
}
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "Failed to load: %s (error: %x)", moduleName, GetLastError());
}
}
return success;
}
size_t SoftCodeMgr::FindSoftCodeFiles(const string& searchName, std::vector<string>& foundPaths) const
{
foundPaths.clear();
stack_string scSoftCodeDir;
TCHAR modulePath[MAX_PATH];
GetModuleFileName(NULL, modulePath, sizeof(modulePath));
scSoftCodeDir = PathUtil::GetParentDirectory(modulePath);
scSoftCodeDir += "\\SoftCode\\";
gEnv->pFileIO->FindFiles(scSoftCodeDir.c_str(), searchName, [&](const char* filePath) -> bool
{
if (!gEnv->pFileIO->IsDirectory(filePath) && !gEnv->pFileIO->IsReadOnly(filePath))
{
foundPaths.push_back(filePath);
}
// Keep asking for more files, no early out
return true;
});
// Sort the paths into name order
std::sort(foundPaths.begin(), foundPaths.end());
return foundPaths.size();
}
#endif // SOFTCODE_ENABLED

@ -1,111 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H
#define CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H
#pragma once
#include <CryListenerSet.h>
#include "ISoftCodeMgr.h"
struct ITypeLibrary;
struct ITypeRegistrar;
class CExchanger;
// Internal: Performs the dynamic type management needed for SoftCoding
class DynamicTypeLibrary
: public ITypeLibrary
{
public:
DynamicTypeLibrary(const char* name = NULL);
// ITypeLibrary impl.
virtual const char* GetName();
virtual void* CreateInstanceVoid(const char* typeName);
virtual void SetOverride(ITypeLibrary* pOverrideLib);
virtual size_t GetTypes(ITypeRegistrar** ppRegistrar, size_t& count) const;
void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName);
void RemoveListener(ISoftCodeListener* pListener);
// Attempts to add the library types the active set
void IntegrateLibrary(ITypeLibrary* pLib, bool isDefault);
ITypeRegistrar* FindTypeForInstance(void* pInstance) const;
private:
// Attempts to add the type the active set
void IntegrateType(ITypeRegistrar* pType, bool isDefault);
// Ensure the type can be safely created, visited, destroyed and prep exchanger
bool EvaluateType(ITypeRegistrar* pType, CExchanger& exchanger);
private:
typedef std::vector<ITypeLibrary*> TLibVec;
typedef std::map<string, ITypeRegistrar*> TTypeMap;
typedef CListenerSet<ISoftCodeListener*> TListeners;
// The current set of active types
std::map<string, ITypeRegistrar*> m_types;
// Current set of loaded libraries
TLibVec m_history;
// Set of listeners to SC changes
TListeners m_listeners;
const char* m_name; // Supplied by the first real library that registers
};
// Implements the global singleton responsible for SoftCode management
class SoftCodeMgr
: public ISoftCodeMgr
{
public:
SoftCodeMgr();
virtual ~SoftCodeMgr();
// Used to register built-in libraries on first use
virtual void RegisterLibrary(ITypeLibrary* pLib);
// Look for new SoftCode modules and load them, adding their types to the registry
virtual void LoadNewModules();
virtual void AddListener(const char* libraryName, ISoftCodeListener* pListener, const char* listenerName);
virtual void RemoveListener(const char* libraryName, ISoftCodeListener* pListener);
// To be called regularly to poll for library updates
virtual void PollForNewModules();
// Stops thread execution until a new SoftCode module is available
virtual void* WaitForUpdate(void* pInstance);
private:
bool LoadModule(const char* moduleName);
size_t FindSoftCodeFiles(const string& searchName, std::vector<string>& foundPaths) const;
private:
typedef std::map<string, DynamicTypeLibrary> TLibMap;
typedef std::set<string> TLoadedLibSet;
// Records the history for each TypeLibrary keyed by library name
TLibMap m_libraryMap;
// Records the library files already loaded
TLoadedLibSet m_loadedSet;
// Used to determine when the next auto-update will occur
CTimeValue m_nextAutoCheckTime;
};
#endif // CRYINCLUDE_CRYSYSTEM_SOFTCODE_SOFTCODEMGR_H

@ -124,8 +124,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include <ILog.h>
#include <IAudioSystem.h>
#include <IProcess.h>
#include <INotificationNetwork.h>
#include <ISoftCodeMgr.h>
#include <LyShine/ILyShine.h>
#include <LoadScreenBus.h>
@ -133,8 +131,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include <AzFramework/Archive/Archive.h>
#include "XConsole.h"
#include "Log.h"
#include "NotificationNetwork.h"
#include "ProfileLog.h"
#include "XML/xml.h"
#include "XML/ReadWriteXMLSink.h"
@ -148,7 +144,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#include "ServerThrottle.h"
#include "ResourceManager.h"
#include "HMDBus.h"
#include <IThreadManager.h>
#include "IZLibCompressor.h"
#include "IZlibDecompressor.h"
@ -267,22 +262,6 @@ namespace
}
#endif
#if defined(CVARS_WHITELIST)
struct SCVarsWhitelistConfigSink
: public ILoadConfigurationEntrySink
{
virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup)
{
ICVarsWhitelist* pCVarsWhitelist = gEnv->pSystem->GetCVarsWhiteList();
bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(szKey, false) : true;
if (whitelisted)
{
gEnv->pConsole->LoadConfigVar(szKey, szValue);
}
}
} g_CVarsWhitelistConfigSink;
#endif // defined(CVARS_WHITELIST)
/////////////////////////////////////////////////////////////////////////////////
// System Implementation.
//////////////////////////////////////////////////////////////////////////
@ -322,27 +301,13 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_env.pSystem = this;
m_env.pTimer = &m_Time;
m_env.pNameTable = &m_nameTable;
m_env.bServer = false;
m_env.bMultiplayer = false;
m_env.bHostMigrating = false;
m_env.bIgnoreAllAsserts = false;
m_env.bNoAssertDialog = false;
m_env.bTesting = false;
m_env.pSharedEnvironment = pSharedEnvironment;
m_env.SetFMVIsPlaying(false);
m_env.SetCutsceneIsPlaying(false);
m_env.szDebugStatus[0] = '\0';
#if !defined(CONSOLE)
m_env.SetIsClient(false);
#endif
//////////////////////////////////////////////////////////////////////////
m_pStreamEngine = NULL;
m_PhysThread = 0;
m_pIFont = NULL;
m_pIFontUi = NULL;
@ -370,7 +335,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_pILZ4Decompressor = NULL;
m_pIZStdDecompressor = nullptr;
m_pLocalizationManager = NULL;
m_sys_physics_CPU = 0;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_2
#include AZ_RESTRICTED_FILE(System_cpp)
@ -378,15 +342,9 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_sys_min_step = 0;
m_sys_max_step = 0;
m_pNotificationNetwork = NULL;
m_cvAIUpdate = NULL;
m_pUserCallback = NULL;
#if defined(CVARS_WHITELIST)
m_pCVarsWhitelist = NULL;
m_pCVarsWhitelistConfigSink = &g_CVarsWhitelistConfigSink;
#endif // defined(CVARS_WHITELIST)
m_sys_memory_debug = NULL;
m_sysWarnings = NULL;
m_sysKeyboard = NULL;
@ -409,13 +367,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_bNoCrashDialog = false;
m_bNoErrorReportWindow = false;
#ifndef _RELEASE
m_checkpointLoadCount = 0;
m_loadOrigin = eLLO_Unknown;
m_hasJustResumed = false;
m_expectingMapCommand = false;
#endif
m_pCVarQuit = NULL;
m_bForceNonDevMode = false;
@ -429,13 +380,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_nServerConfigSpec = CONFIG_VERYHIGH_SPEC;
m_nMaxConfigSpec = CONFIG_VERYHIGH_SPEC;
//m_hPhysicsThread = INVALID_HANDLE_VALUE;
//m_hPhysicsActive = INVALID_HANDLE_VALUE;
//m_bStopPhysics = 0;
//m_bPhysicsActive = 0;
m_pProgressListener = 0;
m_bPaused = false;
m_bNoUpdate = false;
m_nUpdateCounter = 0;
@ -444,12 +388,9 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
m_pXMLUtils = new CXmlUtils(this);
m_pMemoryManager = CryGetIMemoryManager();
m_pThreadTaskManager = new CThreadTaskManager;
m_pResourceManager = new CResourceManager;
m_pTextModeConsole = NULL;
InitThreadSystem();
g_pPakHeap = new CMTSafeHeap;
if (!AZ::AllocatorInstance<AZ::OSAllocator>::IsReady())
@ -464,7 +405,6 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
AZ::Debug::Trace::Instance().Init();
}
m_UpdateTimesIdx = 0U;
m_bNeedDoWorkDuringOcclusionChecks = false;
m_eRuntimeState = ESYSTEM_EVENT_LEVEL_UNLOAD;
@ -478,15 +418,12 @@ CSystem::CSystem(SharedEnvironmentInstance* pSharedEnvironment)
#endif
m_ConfigPlatform = CONFIG_INVALID_PLATFORM;
AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect();
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
CSystem::~CSystem()
{
AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect();
ShutDown();
#if AZ_LEGACY_CRYSYSTEM_TRAIT_USE_MESSAGE_HANDLER
@ -496,16 +433,8 @@ CSystem::~CSystem()
CRY_ASSERT(m_windowMessageHandlers.empty() && "There exists a dangling window message handler somewhere");
SAFE_DELETE(m_pXMLUtils);
SAFE_DELETE(m_pThreadTaskManager);
SAFE_DELETE(m_pResourceManager);
SAFE_DELETE(m_pSystemEventDispatcher);
// SAFE_DELETE(m_pMemoryManager);
if (gEnv && gEnv->pThreadManager)
{
gEnv->pThreadManager->UnRegisterThirdPartyThread("Main");
}
ShutDownThreadSystem();
SAFE_DELETE(g_pPakHeap);
@ -617,8 +546,6 @@ void CSystem::ShutDown()
SAFE_DELETE(m_pTextModeConsole);
KillPhysicsThread();
if (m_sys_firstlaunch)
{
m_sys_firstlaunch->Set("0");
@ -664,8 +591,6 @@ void CSystem::ShutDown()
gEnv->pLyShine = nullptr;
}
SAFE_DELETE(m_env.pResourceCompilerHelper);
SAFE_RELEASE(m_env.pMovieSystem);
SAFE_RELEASE(m_env.pLyShine);
SAFE_RELEASE(m_env.pCryFont);
@ -706,7 +631,6 @@ void CSystem::ShutDown()
SAFE_RELEASE(m_sys_GraphicsQuality);
SAFE_RELEASE(m_sys_firstlaunch);
SAFE_RELEASE(m_sys_enable_budgetmonitoring);
SAFE_RELEASE(m_sys_physics_CPU);
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_3
@ -716,9 +640,6 @@ void CSystem::ShutDown()
SAFE_RELEASE(m_sys_min_step);
SAFE_RELEASE(m_sys_max_step);
SAFE_RELEASE(m_pNotificationNetwork);
SAFE_DELETE(m_env.pSoftCodeMgr);
SAFE_DELETE(m_pDefaultValidator);
m_pValidator = nullptr;
@ -743,7 +664,6 @@ void CSystem::ShutDown()
SAFE_RELEASE(m_env.pConsole);
// Log must be last thing released.
SAFE_RELEASE(m_env.pProfileLogSystem);
if (m_env.pLog)
{
m_env.pLog->FlushAndClose();
@ -752,10 +672,6 @@ void CSystem::ShutDown()
ShutdownFileSystem();
#if defined(MAP_LOADING_SLICING)
delete gEnv->pSystemScheduler;
#endif // defined(MAP_LOADING_SLICING)
ShutdownModuleLibraries();
EBUS_EVENT(CrySystemEventBus, OnCrySystemPostShutdown);
@ -841,273 +757,6 @@ ISystem* CSystem::GetCrySystem()
return this;
}
//////////////////////////////////////////////////////////////////////////
// Physics thread task
//////////////////////////////////////////////////////////////////////////
class CPhysicsThreadTask
: public IThreadTask
{
public:
CPhysicsThreadTask()
{
m_bStopRequested = 0;
m_bIsActive = 0;
m_stepRequested = 0;
m_bProcessing = 0;
m_doZeroStep = 0;
m_lastStepTimeTaken = 0U;
m_lastWaitTimeTaken = 0U;
}
//////////////////////////////////////////////////////////////////////////
// IThreadTask implementation.
//////////////////////////////////////////////////////////////////////////
virtual void OnUpdate()
{
Run();
// At the end.. delete the task
delete this;
}
virtual void Stop()
{
Cancel();
}
virtual SThreadTaskInfo* GetTaskInfo() { return &m_TaskInfo; }
//////////////////////////////////////////////////////////////////////////
virtual void Run()
{
m_bStopRequested = 0;
m_bIsActive = 1;
float step, timeTaken, kSlowdown = 1.0f;
int nSlowFrames = 0;
int64 timeStart;
#ifdef ENABLE_LW_PROFILERS
LARGE_INTEGER stepStart, stepEnd;
#endif
LARGE_INTEGER waitStart, waitEnd;
MarkThisThreadForDebugging("Physics");
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_5
#include AZ_RESTRICTED_FILE(System_cpp)
#endif
while (true)
{
QueryPerformanceCounter(&waitStart);
m_FrameEvent.Wait(); // Wait untill new frame
QueryPerformanceCounter(&waitEnd);
m_lastWaitTimeTaken = waitEnd.QuadPart - waitStart.QuadPart;
if (m_bStopRequested)
{
UnmarkThisThreadFromDebugging();
return;
}
bool stepped = false;
#ifdef ENABLE_LW_PROFILERS
QueryPerformanceCounter(&stepStart);
#endif
while ((step = m_stepRequested) > 0 || m_doZeroStep)
{
stepped = true;
m_stepRequested = 0;
m_bProcessing = 1;
m_doZeroStep = 0;
if (kSlowdown != 1.0f)
{
step = max(1, FtoI(step * kSlowdown * 50 - 0.5f)) * 0.02f;
}
timeStart = CryGetTicks();
timeTaken = gEnv->pTimer->TicksToSeconds(CryGetTicks() - timeStart);
if (timeTaken > step * 0.9f)
{
if (++nSlowFrames > 5)
{
kSlowdown = step * 0.9f / timeTaken;
}
}
else
{
kSlowdown = 1.0f, nSlowFrames = 0;
}
m_bProcessing = 0;
//int timeSleep = (int)((m_timeTarget-gEnv->pTimer->GetAsyncTime()).GetMilliSeconds()*0.9f);
//Sleep(max(0,timeSleep));
}
if (!stepped)
{
Sleep(0);
}
m_FrameDone.Set();
#ifdef ENABLE_LW_PROFILERS
QueryPerformanceCounter(&stepEnd);
m_lastStepTimeTaken = stepEnd.QuadPart - stepStart.QuadPart;
#endif
}
}
virtual void Cancel()
{
Pause();
m_bStopRequested = 1;
m_FrameEvent.Set();
m_bIsActive = 0;
}
int Pause()
{
if (m_bIsActive)
{
AZ_PROFILE_FUNCTION_STALL(AZ::Debug::ProfileCategory::System);
m_bIsActive = 0;
while (m_bProcessing)
{
;
}
return 1;
}
return 0;
}
int Resume()
{
if (!m_bIsActive)
{
m_bIsActive = 1;
return 1;
}
return 0;
}
int IsActive() { return m_bIsActive; }
int RequestStep(float dt)
{
if (m_bIsActive && dt > FLT_EPSILON)
{
m_stepRequested += dt;
if (dt <= 0.0f)
{
m_doZeroStep = 1;
}
m_FrameEvent.Set();
}
return m_bProcessing;
}
float GetRequestedStep() { return m_stepRequested; }
uint64 LastStepTaken() const
{
return m_lastStepTimeTaken;
}
uint64 LastWaitTime() const
{
return m_lastWaitTimeTaken;
}
void EnsureStepDone()
{
FRAME_PROFILER("SysUpdate:PhysicsEnsureDone", gEnv->pSystem, PROFILE_SYSTEM);
if (m_bIsActive)
{
while (m_stepRequested > 0.0f || m_bProcessing)
{
m_FrameDone.Wait();
}
}
}
protected:
volatile int m_bStopRequested;
volatile int m_bIsActive;
volatile float m_stepRequested;
volatile int m_bProcessing;
volatile int m_doZeroStep;
volatile uint64 m_lastStepTimeTaken;
volatile uint64 m_lastWaitTimeTaken;
CryEvent m_FrameEvent;
CryEvent m_FrameDone;
SThreadTaskInfo m_TaskInfo;
};
void CSystem::CreatePhysicsThread()
{
if (!m_PhysThread)
{
//////////////////////////////////////////////////////////////////////////
SThreadTaskParams threadParams;
threadParams.name = "Physics";
threadParams.nFlags = THREAD_TASK_BLOCKING;
threadParams.nStackSizeKB = PHYSICS_STACK_SIZE >> 10;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_CPP_SECTION_6
#include AZ_RESTRICTED_FILE(System_cpp)
#endif
{
m_PhysThread = new CPhysicsThreadTask;
GetIThreadTaskManager()->RegisterTask(m_PhysThread, threadParams);
}
}
}
void CSystem::KillPhysicsThread()
{
if (m_PhysThread)
{
GetIThreadTaskManager()->UnregisterTask(m_PhysThread);
m_PhysThread = 0;
}
}
///////////////////////////////////////////////////////////////////////////
// AzFramework::Terrain::TerrainDataNotificationBus START
void CSystem::OnTerrainDataCreateBegin()
{
KillPhysicsThread();
}
void CSystem::OnTerrainDataDestroyBegin()
{
OnTerrainDataCreateBegin();
}
// AzFramework::Terrain::TerrainDataNotificationBus END
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
int CSystem::SetThreadState(ESubsystem subsys, bool bActive)
{
switch (subsys)
{
case ESubsys_Physics:
{
if (m_PhysThread)
{
return bActive ? ((CPhysicsThreadTask*)m_PhysThread)->Resume() : ((CPhysicsThreadTask*)m_PhysThread)->Pause();
}
}
break;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
void CSystem::SleepIfInactive()
{
// ProcessSleep()
if (m_bDedicatedServer || m_bEditor || gEnv->bMultiplayer)
{
return;
}
}
//////////////////////////////////////////////////////////////////////////
void CSystem::SleepIfNeeded()
{
@ -1180,11 +829,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
// do the dedicated sleep earlier than the frame profiler to avoid having it counted
if (gEnv->IsDedicated())
{
#if defined(MAP_LOADING_SLICING)
gEnv->pSystemScheduler->SchedulingSleepIfNeeded();
#else
SleepIfNeeded();
#endif // defined(MAP_LOADING_SLICING)
}
#endif //EXCLUDE_UPDATE_ON_CONSOLE
@ -1199,9 +844,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
m_nUpdateCounter++;
#ifndef EXCLUDE_UPDATE_ON_CONSOLE
// Check if game needs to be sleeping when not active.
SleepIfInactive();
if (m_pUserCallback)
{
m_pUserCallback->OnUpdate();
@ -1216,7 +858,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
prev_sys_float_exceptions = g_cvars.sys_float_exceptions;
EnableFloatExceptions(g_cvars.sys_float_exceptions);
UpdateFPExceptionsMaskForThreads();
}
#endif //EXCLUDE_UPDATE_ON_CONSOLE
//////////////////////////////////////////////////////////////////////////
@ -1263,13 +904,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
}
#endif //PROFILE_WITH_VTUNE
#ifdef SOFTCODE_SYSTEM_ENABLED
if (m_env.pSoftCodeMgr)
{
m_env.pSoftCodeMgr->PollForNewModules();
}
#endif
if (m_pStreamEngine)
{
FRAME_PROFILER("StreamEngine::Update()", this, PROFILE_SYSTEM);
@ -1290,7 +924,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
if (m_sysNoUpdate && m_sysNoUpdate->GetIVal())
{
bNoUpdate = true;
updateFlags = ESYSUPDATE_IGNORE_PHYSICS;
}
m_bNoUpdate = bNoUpdate;
@ -1373,16 +1006,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
return false;
}
#ifndef EXCLUDE_UPDATE_ON_CONSOLE
//////////////////////////////////////////////////////////////////////
//update notification network system
if (m_pNotificationNetwork)
{
FRAME_PROFILER("SysUpdate:NotificationNetwork", this, PROFILE_SYSTEM);
m_pNotificationNetwork->Update();
}
#endif //EXCLUDE_UPDATE_ON_CONSOLE
//////////////////////////////////////////////////////////////////////
//update sound system Part 1 if in Editor / in Game Mode Viewsystem updates the Listeners
if (!m_env.IsEditorGameMode())
@ -1401,15 +1024,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
}
}
//////////////////////////////////////////////////////////////////////////
// Update Threads Task Manager.
//////////////////////////////////////////////////////////////////////////
if (m_pThreadTaskManager)
{
FRAME_PROFILER("SysUpdate:ThreadTaskManager", this, PROFILE_SYSTEM);
m_pThreadTaskManager->OnUpdate();
}
//////////////////////////////////////////////////////////////////////////
// Update Resource Manager.
//////////////////////////////////////////////////////////////////////////
@ -1418,77 +1032,6 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
m_pResourceManager->Update();
}
//////////////////////////////////////////////////////////////////////
// update physic system
//static float time_zero = 0;
if (m_sys_physics_CPU->GetIVal() > 0 && !gEnv->IsDedicated())
{
CreatePhysicsThread();
}
else
{
KillPhysicsThread();
}
static int g_iPausedPhys = 0;
CPhysicsThreadTask* pPhysicsThreadTask = ((CPhysicsThreadTask*)m_PhysThread);
if (!pPhysicsThreadTask)
{
FRAME_PROFILER_LEGACYONLY("SysUpdate:AllAIAndPhysics", this, PROFILE_SYSTEM);
AZ_TRACE_METHOD_NAME("SysUpdate::AllAIAndPhysics");
//////////////////////////////////////////////////////////////////////
// update entity system (a little bit) before physics
if (nPauseMode != 1)
{
if (!bNoUpdate)
{
EBUS_EVENT(CrySystemEventBus, OnCrySystemPrePhysicsUpdate);
}
}
// intermingle physics/AI updates so that if we get a big timestep (frame rate glitch etc) the
// AI gets to steer entities before they travel over cliffs etc.
const float maxTimeStep = 0.25f;
int maxSteps = 1;
//float fCurTime = m_Time.GetCurrTime();
float timeToDo = m_Time.GetFrameTime();//fCurTime - fPrevTime;
if (m_env.bMultiplayer)
{
timeToDo = m_Time.GetRealFrameTime();
}
while (timeToDo > 0.0001f && maxSteps-- > 0)
{
float thisStep = min(maxTimeStep, timeToDo);
timeToDo -= thisStep;
EBUS_EVENT(CrySystemEventBus, OnCrySystemPostPhysicsUpdate);
}
}
else
{
// In multithreaded physics mode, post physics fires after physics events are dispatched on the main thread.
EBUS_EVENT(CrySystemEventBus, OnCrySystemPostPhysicsUpdate);
//////////////////////////////////////////////////////////////////////
// update entity system (a little bit) before physics
if (nPauseMode != 1)
{
if (!bNoUpdate)
{
EBUS_EVENT(CrySystemEventBus, OnCrySystemPrePhysicsUpdate);
}
}
}
// Use UI timer for CryMovie, because it should not be affected by pausing game time
const float fMovieFrameTime = m_Time.GetFrameTime(ITimer::ETIMER_UI);
@ -1550,8 +1093,6 @@ bool CSystem::UpdatePostTickBus(int updateFlags, int /*nPauseMode*/)
m_updateTimes.push_back(std::make_pair(cur_time, updateTime));
}
UpdateUpdateTimes();
{
FRAME_PROFILER("SysUpdate - SystemEventDispatcher::Update", this, PROFILE_SYSTEM);
m_pSystemEventDispatcher->Update();
@ -1890,12 +1431,6 @@ ILocalizationManager* CSystem::GetLocalizationManager()
return m_pLocalizationManager;
}
//////////////////////////////////////////////////////////////////////////
IThreadTaskManager* CSystem::GetIThreadTaskManager()
{
return m_pThreadTaskManager;
}
//////////////////////////////////////////////////////////////////////////
IResourceManager* CSystem::GetIResourceManager()
{
@ -1960,10 +1495,6 @@ void CSystem::ExecuteCommandLine(bool deferred)
if (pCmd->GetType() == eCLAT_Post)
{
string sLine = pCmd->GetName();
#if defined(CVARS_WHITELIST)
if (!GetCVarsWhiteList() || GetCVarsWhiteList()->IsWhiteListed(sLine, false))
#endif
{
if (pCmd->GetValue())
{
@ -1973,12 +1504,6 @@ void CSystem::ExecuteCommandLine(bool deferred)
GetILog()->Log("Executing command from command line: \n%s\n", sLine.c_str()); // - the actual command might be executed much later (e.g. level load pause)
GetIConsole()->ExecuteString(sLine.c_str(), false, deferred);
}
#if defined(CVARS_WHITELIST)
else if (gEnv->IsDedicated())
{
GetILog()->LogError("Failed to execute command: '%s' as it is not whitelisted\n", sLine.c_str());
}
#endif
}
}
@ -2078,93 +1603,6 @@ void CProfilingSystem::VTunePause()
#endif
}
//////////////////////////////////////////////////////////////////////////
sUpdateTimes& CSystem::GetCurrentUpdateTimeStats()
{
return m_UpdateTimes[m_UpdateTimesIdx];
}
//////////////////////////////////////////////////////////////////////////
const sUpdateTimes* CSystem::GetUpdateTimeStats(uint32& index, uint32& num)
{
index = m_UpdateTimesIdx;
num = NUM_UPDATE_TIMES;
return m_UpdateTimes;
}
void CSystem::UpdateUpdateTimes()
{
sUpdateTimes& sample = m_UpdateTimes[m_UpdateTimesIdx];
if (m_PhysThread)
{
static uint64 lastPhysTime = 0U;
static uint64 lastMainTime = 0U;
static uint64 lastYields = 0U;
static uint64 lastPhysWait = 0U;
uint64 physTime = 0, mainTime = 0;
uint32 yields = 0;
physTime = ((CPhysicsThreadTask*)m_PhysThread)->LastStepTaken();
mainTime = CryGetTicks() - lastMainTime;
lastMainTime = mainTime;
lastPhysWait = ((CPhysicsThreadTask*)m_PhysThread)->LastWaitTime();
sample.PhysStepTime = physTime;
sample.SysUpdateTime = mainTime;
sample.PhysYields = yields;
sample.physWaitTime = lastPhysWait;
}
++m_UpdateTimesIdx;
if (m_UpdateTimesIdx >= NUM_UPDATE_TIMES)
{
m_UpdateTimesIdx = 0;
}
}
#ifndef _RELEASE
void CSystem::GetCheckpointData(ICheckpointData& data)
{
data.m_totalLoads = m_checkpointLoadCount;
data.m_loadOrigin = m_loadOrigin;
}
void CSystem::IncreaseCheckpointLoadCount()
{
if (!m_hasJustResumed)
{
++m_checkpointLoadCount;
}
m_hasJustResumed = false;
}
void CSystem::SetLoadOrigin(LevelLoadOrigin origin)
{
switch (origin)
{
case eLLO_NewLevel: // Intentional fall through
case eLLO_Level2Level:
m_expectingMapCommand = true;
break;
case eLLO_Resumed:
m_hasJustResumed = true;
break;
case eLLO_MapCmd:
if (m_expectingMapCommand)
{
// We knew a map command was coming, so don't process this.
m_expectingMapCommand = false;
return;
}
break;
}
m_loadOrigin = origin;
m_checkpointLoadCount = 0;
}
#endif
bool CSystem::SteamInit()
{
#if USE_STEAM

@ -26,14 +26,12 @@
#include "MTSafeAllocator.h"
#include "CPUDetect.h"
#include <AzFramework/Archive/ArchiveVars.h>
#include "ThreadTask.h"
#include "RenderBus.h"
#include <LoadScreenBus.h>
#include <ThermalInfo.h>
#include <AzCore/Module/DynamicModuleHandle.h>
#include <AzFramework/Terrain/TerrainDataRequestBus.h>
namespace AzFramework
{
@ -44,7 +42,6 @@ struct IConsoleCmdArgs;
class CServerThrottle;
struct IZLibCompressor;
class CWatchdogThread;
class CThreadManager;
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
@ -183,8 +180,6 @@ class CThreadManager;
#include "CryLibrary.h"
#endif
#define NUM_UPDATE_TIMES (128U)
#ifdef WIN32
typedef void* WIN_HMODULE;
#else
@ -241,7 +236,6 @@ struct SSystemCVars
int sys_WER;
int sys_dump_type;
int sys_ai;
int sys_physics;
int sys_entitysystem;
int sys_trackview;
int sys_vtune;
@ -342,7 +336,6 @@ class CSystem
, public IWindowMessageHandler
, public AZ::RenderNotificationsBus::Handler
, public CrySystemRequestBus::Handler
, private AzFramework::Terrain::TerrainDataNotificationBus::Handler
{
public:
@ -397,20 +390,8 @@ public:
ISystem* GetCrySystem() override;
////////////////////////////////////////////////////////////////////////
//! Update screen during loading.
void UpdateLoadingScreen();
//! Update screen and call some important tick functions during loading.
void SynchronousLoadingTick(const char* pFunc, int line);
uint32 GetUsedMemory();
#ifndef _RELEASE
virtual void GetCheckpointData(ICheckpointData& data);
virtual void IncreaseCheckpointLoadCount();
virtual void SetLoadOrigin(LevelLoadOrigin origin);
#endif
virtual bool SteamInit();
void Relaunch(bool bRelaunch);
@ -425,8 +406,6 @@ public:
virtual const char* GetUserName();
virtual int GetApplicationInstance();
int GetApplicationLogInstance(const char* logFilePath) override;
virtual sUpdateTimes& GetCurrentUpdateTimeStats();
virtual const sUpdateTimes* GetUpdateTimeStats(uint32&, uint32&);
ITimer* GetITimer(){ return m_env.pTimer; }
AZ::IO::IArchive* GetIPak() { return m_env.pCryPak; };
@ -434,7 +413,6 @@ public:
IRemoteConsole* GetIRemoteConsole();
IMovieSystem* GetIMovieSystem() { return m_env.pMovieSystem; };
IMemoryManager* GetIMemoryManager(){ return m_pMemoryManager; }
IThreadManager* GetIThreadManager() override {return m_env.pThreadManager; }
ICryFont* GetICryFont(){ return m_env.pCryFont; }
ILog* GetILog(){ return m_env.pLog; }
ICmdLine* GetICmdLine(){ return m_pCmdLine; }
@ -444,11 +422,8 @@ public:
IViewSystem* GetIViewSystem();
ILevelSystem* GetILevelSystem();
ISystemEventDispatcher* GetISystemEventDispatcher() { return m_pSystemEventDispatcher; }
IThreadTaskManager* GetIThreadTaskManager();
IResourceManager* GetIResourceManager();
ITextModeConsole* GetITextModeConsole();
IVisualLog* GetIVisualLog() { return m_env.pVisualLog; }
INotificationNetwork* GetINotificationNetwork() { return m_pNotificationNetwork; }
IProfilingSystem* GetIProfilingSystem() { return &m_ProfilingSystem; }
IZLibCompressor* GetIZLibCompressor() { return m_pIZLibCompressor; }
IZLibDecompressor* GetIZLibDecompressor() { return m_pIZLibDecompressor; }
@ -459,19 +434,6 @@ public:
CPNoise3* GetNoiseGen();
virtual uint64 GetUpdateCounter() { return m_nUpdateCounter; };
virtual void SetLoadingProgressListener(ILoadingProgressListener* pLoadingProgressListener)
{
m_pProgressListener = pLoadingProgressListener;
};
virtual ILoadingProgressListener* GetLoadingProgressListener() const
{
return m_pProgressListener;
};
void SetIMaterialEffects(IMaterialEffects* pMaterialEffects) { m_env.pMaterialEffects = pMaterialEffects; }
void SetIOpticsManager(IOpticsManager* pOpticsManager) { m_env.pOpticsManager = pOpticsManager; }
void SetIVisualLog(IVisualLog* pVisualLog) { m_env.pVisualLog = pVisualLog; }
void DetectGameFolderAccessRights();
virtual void ExecuteCommandLine(bool deferred=true);
@ -554,12 +516,6 @@ public:
//! Return pointer to user defined callback.
ISystemUserCallback* GetUserCallback() const { return m_pUserCallback; };
#if defined(CVARS_WHITELIST)
virtual ICVarsWhitelist* GetCVarsWhiteList() const { return m_pCVarsWhitelist; };
virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const { return m_pCVarsWhitelistConfigSink; }
#else
virtual ILoadConfigurationEntrySink* GetCVarsWhiteListConfigSink() const { return nullptr; }
#endif // defined(CVARS_WHITELIST)
//////////////////////////////////////////////////////////////////////////
virtual void SaveConfiguration();
@ -571,7 +527,6 @@ public:
virtual void SetConfigPlatform(ESystemConfigPlatform platform);
//////////////////////////////////////////////////////////////////////////
virtual int SetThreadState(ESubsystem subsys, bool bActive);
virtual bool IsPaused() const { return m_bPaused; };
virtual ILocalizationManager* GetLocalizationManager();
@ -608,8 +563,6 @@ private:
// Release all resources.
void ShutDown();
void SleepIfInactive();
bool LoadEngineDLLs();
//! @name Initialization routines
@ -623,12 +576,6 @@ private:
//@}
//////////////////////////////////////////////////////////////////////////
// Threading functions.
//////////////////////////////////////////////////////////////////////////
void InitThreadSystem();
void ShutDownThreadSystem();
//////////////////////////////////////////////////////////////////////////
// Helper functions.
//////////////////////////////////////////////////////////////////////////
@ -645,9 +592,6 @@ private:
void LogBuildInfo();
void SetDevMode(bool bEnable);
void CreatePhysicsThread();
void KillPhysicsThread();
#ifndef _RELEASE
static void SystemVersionChanged(ICVar* pCVar);
#endif // #ifndef _RELEASE
@ -676,7 +620,6 @@ public:
virtual bool GetForceNonDevMode() const;
virtual bool WasInDevMode() const { return m_bWasInDevMode; };
virtual bool IsDevMode() const { return m_bInDevMode && !GetForceNonDevMode(); }
virtual bool IsMinimalMode() const { return m_bMinimal; }
virtual bool IsMODValid(const char* szMODName) const
{
if (!szMODName || strstr(szMODName, ".") || strstr(szMODName, "\\"))
@ -727,7 +670,6 @@ private: // ------------------------------------------------------
bool m_bRelaunch; //!< relaunching the app or not (true beforerelaunch)
int m_iLoadingMode; //!< Game is loading w/o changing context (0 not, 1 quickloading, 2 full loading)
bool m_bTestMode; //!< If running in testing mode.
bool m_bMinimal; //!< If running in 'minimal mode'.
bool m_bEditor; //!< If running in Editor.
bool m_bNoCrashDialog;
bool m_bNoErrorReportWindow;
@ -742,16 +684,6 @@ private: // ------------------------------------------------------
SDefaultValidator* m_pDefaultValidator; //!<
CCpuFeatures* m_pCpu; //!< CPU features
int m_ttMemStatSS; //!< Time to memstat screenshot
string m_szCmdLine;
int m_iTraceAllocations;
#ifndef _RELEASE
int m_checkpointLoadCount;// Total times game has loaded from a checkpoint
LevelLoadOrigin m_loadOrigin; // Where the load was initiated from
bool m_hasJustResumed; // Has resume game just been called
bool m_expectingMapCommand;
#endif
bool m_bDrawConsole; //!< Set to true if OK to draw the console.
bool m_bDrawUI; //!< Set to true if OK to draw UI.
@ -867,8 +799,6 @@ private: // ------------------------------------------------------
ICVar* m_sys_asset_processor;
ICVar* m_sys_load_files_to_memory;
ICVar* m_sys_physics_CPU;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_H_SECTION_4
#include AZ_RESTRICTED_FILE(System_h)
@ -891,15 +821,6 @@ private: // ------------------------------------------------------
//! User define callback for system events.
ISystemUserCallback* m_pUserCallback;
#if defined(CVARS_WHITELIST)
//////////////////////////////////////////////////////////////////////////
//! User define callback for whitelisting cvars
ICVarsWhitelist* m_pCVarsWhitelist;
ILoadConfigurationEntrySink* m_pCVarsWhitelistConfigSink;
#endif // defined(CVARS_WHITELIST)
//int m_nCurrentLogVerbosity;
SFileVersion m_fileVersion;
SFileVersion m_productVersion;
SFileVersion m_buildVersion;
@ -910,8 +831,6 @@ private: // ------------------------------------------------------
// Name table.
CNameTable m_nameTable;
IThreadTask* m_PhysThread;
ESystemConfigSpec m_nServerConfigSpec;
ESystemConfigSpec m_nMaxConfigSpec;
ESystemConfigPlatform m_ConfigPlatform;
@ -919,8 +838,6 @@ private: // ------------------------------------------------------
std::unique_ptr<CServerThrottle> m_pServerThrottle;
CProfilingSystem m_ProfilingSystem;
sUpdateTimes m_UpdateTimes[NUM_UPDATE_TIMES];
uint32 m_UpdateTimesIdx;
// Pause mode.
bool m_bPaused;
@ -991,26 +908,14 @@ private:
ESystemGlobalState m_systemGlobalState;
static const char* GetSystemGlobalStateName(const ESystemGlobalState systemGlobalState);
///////////////////////////////////////////////////////////////////////////
// AzFramework::Terrain::TerrainDataNotificationBus START
void OnTerrainDataCreateBegin() override;
void OnTerrainDataDestroyBegin() override;
// AzFramework::Terrain::TerrainDataNotificationBus END
///////////////////////////////////////////////////////////////////////////
public:
void InitLocalization();
void UpdateUpdateTimes();
protected: // -------------------------------------------------------------
ILoadingProgressListener* m_pProgressListener;
CCmdLine* m_pCmdLine;
CThreadManager* m_pThreadManager;
CThreadTaskManager* m_pThreadTaskManager;
class CResourceManager* m_pResourceManager;
ITextModeConsole* m_pTextModeConsole;
INotificationNetwork* m_pNotificationNetwork;
string m_currentLanguageAudio;
string m_systemConfigName; // computed from system_(hardwareplatform)_(assetsPlatform) - eg, system_android_es3.cfg or system_android_opengl.cfg or system_windows_pc.cfg

@ -35,13 +35,9 @@
#define SYSTEMINIT_CPP_SECTION_17 17
#endif
#if defined(MAP_LOADING_SLICING)
#include "SystemScheduler.h"
#endif // defined(MAP_LOADING_SLICING)
#include "CryLibrary.h"
#include "CryPath.h"
#include <StringUtils.h>
#include <IThreadManager.h>
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
#include <AzFramework/IO/LocalFileIO.h>
@ -103,16 +99,12 @@
#include "PhysRenderer.h"
#include "LocalizedStringManager.h"
#include "SystemEventDispatcher.h"
#include "ThreadConfigManager.h"
#include "Validator.h"
#include "ServerThrottle.h"
#include "SystemCFG.h"
#include "AutoDetectSpec.h"
#include "ResourceManager.h"
#include "MTSafeAllocator.h"
#include "NotificationNetwork.h"
#include "ProfileLogSystem.h"
#include "SoftCode/SoftCodeMgr.h"
#include "ZLibCompressor.h"
#include "ZLibDecompressor.h"
#include "ZStdDecompressor.h"
@ -146,8 +138,6 @@
#include "MobileDetectSpec.h"
#endif
#include "IDebugCallStack.h"
#include "WindowsConsole.h"
#if defined(EXTERNAL_CRASH_REPORTING)
@ -163,11 +153,6 @@
# include <AzFramework/Network/AssetProcessorConnection.h>
#endif
// if we enable the built-in local version instead of remote:
#if defined(CRY_ENABLE_RC_HELPER)
#include "ResourceCompilerHelper.h"
#endif
#ifdef WIN32
extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers);
#endif
@ -400,26 +385,20 @@ struct SysSpecOverrideSink
}
else
{
// This could bypass the restricted/whitelisted cvar checks that exist elsewhere depending on
// This could bypass the restricted cvar checks that exist elsewhere depending on
// the calling code so we also need check here before setting.
bool isConst = pCvar->IsConstCVar();
bool isCheat = ((pCvar->GetFlags() & (VF_CHEAT | VF_CHEAT_NOCHECK | VF_CHEAT_ALWAYS_CHECK)) != 0);
bool isReadOnly = ((pCvar->GetFlags() & VF_READONLY) != 0);
bool isDeprecated = ((pCvar->GetFlags() & VF_DEPRECATED) != 0);
bool allowApplyCvar = true;
bool whitelisted = true;
#if defined CVARS_WHITELIST
ICVarsWhitelist* cvarWhitelist = gEnv->pSystem->GetCVarsWhiteList();
whitelisted = cvarWhitelist ? cvarWhitelist->IsWhiteListed(szKey, true) : true;
#endif
if ((isConst || isCheat || isReadOnly) || isDeprecated)
{
allowApplyCvar = !isDeprecated && (gEnv->pSystem->IsDevMode()) || (gEnv->IsEditor());
}
if ((allowApplyCvar && whitelisted) || ALLOW_CONST_CVAR_MODIFICATIONS)
if ((allowApplyCvar) || ALLOW_CONST_CVAR_MODIFICATIONS)
{
applyCvar = true;
}
@ -1028,7 +1007,6 @@ bool CSystem::InitFileSystem()
// get the DirectInstance FileIOBase which should be the AZ::LocalFileIO
m_env.pFileIO = AZ::IO::FileIOBase::GetDirectInstance();
m_env.pResourceCompilerHelper = nullptr;
m_env.pCryPak = AZ::Interface<AZ::IO::IArchive>::Get();
m_env.pFileIO = AZ::IO::FileIOBase::GetInstance();
@ -1107,8 +1085,7 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&)
{
LOADING_TIME_PROFILE_SECTION;
{
ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink();
LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink);
LoadConfiguration(m_systemConfigName.c_str());
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Loading system configuration from %s...", m_systemConfigName.c_str());
}
@ -1118,13 +1095,6 @@ bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&)
GetISystem()->SetConfigPlatform(GetDevicePlatform());
#if defined(CRY_ENABLE_RC_HELPER)
if (!m_env.pResourceCompilerHelper)
{
m_env.pResourceCompilerHelper = new CResourceCompilerHelper();
}
#endif
auto projectPath = AZ::Utils::GetProjectPath();
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Path: %s\n", projectPath.empty() ? "None specified" : projectPath.c_str());
@ -1179,7 +1149,6 @@ bool CSystem::InitAudioSystem(const SSystemInitParams& initParams)
bool useRealAudioSystem = false;
if (!initParams.bPreview
&& !initParams.bMinimal
&& !m_bDedicatedServer
&& m_sys_audio_disable->GetIVal() == 0)
{
@ -1672,12 +1641,8 @@ bool CSystem::Init(const SSystemInitParams& startupParams)
gEnv->mMainThreadId = GetCurrentThreadId(); //Set this ASAP on startup
InlineInitializationProcessing("CSystem::Init start");
m_szCmdLine = startupParams.szSystemCmdLine;
m_env.szCmdLine = m_szCmdLine.c_str();
m_env.bTesting = startupParams.bTesting;
m_env.bNoAssertDialog = startupParams.bTesting;
m_env.bNoRandomSeed = startupParams.bNoRandom;
m_env.bNoAssertDialog = false;
m_bNoCrashDialog = gEnv->IsDedicated();
@ -1754,16 +1719,10 @@ AZ_POP_DISABLE_WARNING
m_bPreviewMode = startupParams.bPreview;
m_bTestMode = startupParams.bTestMode;
m_pUserCallback = startupParams.pUserCallback;
m_bMinimal = startupParams.bMinimal;
#if defined(CVARS_WHITELIST)
m_pCVarsWhitelist = startupParams.pCVarsWhitelist;
#endif // defined(CVARS_WHITELIST)
m_bDedicatedServer = startupParams.bDedicatedServer;
m_currentLanguageAudio = "";
memcpy(gEnv->pProtectedFunctions, startupParams.pProtectedFunctions, sizeof(startupParams.pProtectedFunctions));
#if !defined(CONSOLE)
m_env.SetIsEditor(m_bEditor);
m_env.SetIsEditorGameMode(false);
@ -1771,7 +1730,6 @@ AZ_POP_DISABLE_WARNING
#endif
m_env.SetToolMode(startupParams.bToolMode);
m_env.bIsOutOfMemory = false;
if (m_bEditor)
{
@ -1935,23 +1893,6 @@ AZ_POP_DISABLE_WARNING
// so we log this immediately after setting the log filename
LogVersion();
//here we should be good to ask Crypak to do something
// Initialise after pLog and CPU feature initialization
// AND after console creation (Editor only)
// May need access to engine folder .pak files
gEnv->pThreadManager->GetThreadConfigManager()->LoadConfig("config/engine_core.thread_config");
if (m_bEditor)
{
gEnv->pThreadManager->GetThreadConfigManager()->LoadConfig("config/engine_sandbox.thread_config");
}
// Setup main thread
void* pThreadHandle = 0; // Let system figure out thread handle
gEnv->pThreadManager->RegisterThirdPartyThread(pThreadHandle, "Main");
m_env.pProfileLogSystem = new CProfileLogSystem();
bool devModeEnable = true;
#if defined(_RELEASE)
@ -1967,22 +1908,6 @@ AZ_POP_DISABLE_WARNING
SetDevMode(devModeEnable);
//////////////////////////////////////////////////////////////////////////
// CREATE NOTIFICATION NETWORK
//////////////////////////////////////////////////////////////////////////
m_pNotificationNetwork = nullptr;
#ifndef _RELEASE
#ifndef LINUX
if (!startupParams.bMinimal)
{
m_pNotificationNetwork = CNotificationNetwork::Create();
}
#endif//LINUX
#endif // _RELEASE
InlineInitializationProcessing("CSystem::Init NotificationNetwork");
//////////////////////////////////////////////////////////////////////////
// CREATE CONSOLE
//////////////////////////////////////////////////////////////////////////
@ -2051,8 +1976,6 @@ AZ_POP_DISABLE_WARNING
// CPU features detection.
m_pCpu = new CCpuFeatures;
m_pCpu->Detect();
m_env.pi.numCoresAvailableToProcess = m_pCpu->GetCPUCount();
m_env.pi.numLogicalProcessors = m_pCpu->GetLogicalCPUCount();
// Check hard minimum CPU requirements
if (!CheckCPURequirements(m_pCpu, this))
@ -2102,17 +2025,15 @@ AZ_POP_DISABLE_WARNING
}
{
ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetCVarsWhiteListConfigSink();
// We have to load this file again since first time we did it without devmode
LoadConfiguration(m_systemConfigName.c_str(), pCVarsWhiteListConfigSink);
LoadConfiguration(m_systemConfigName.c_str());
// Optional user defined overrides
LoadConfiguration("user.cfg", pCVarsWhiteListConfigSink);
LoadConfiguration("user.cfg");
#if defined(ENABLE_STATS_AGENT)
if (m_pCmdLine->FindArg(eCLAT_Pre, "useamblecfg"))
{
LoadConfiguration("amble.cfg", pCVarsWhiteListConfigSink);
LoadConfiguration("amble.cfg");
}
#endif
}
@ -2159,7 +2080,7 @@ AZ_POP_DISABLE_WARNING
InlineInitializationProcessing("CSystem::Init LoadConfigurations");
#ifdef WIN32
if ((g_cvars.sys_WER) && (!startupParams.bMinimal))
if ((g_cvars.sys_WER))
{
SetUnhandledExceptionFilter(CryEngineExceptionFilterWER);
}
@ -2169,7 +2090,6 @@ AZ_POP_DISABLE_WARNING
//////////////////////////////////////////////////////////////////////////
// Localization
//////////////////////////////////////////////////////////////////////////
if (!startupParams.bMinimal)
{
InitLocalization();
}
@ -2187,7 +2107,6 @@ AZ_POP_DISABLE_WARNING
//////////////////////////////////////////////////////////////////////////
// AUDIO
//////////////////////////////////////////////////////////////////////////
if (!startupParams.bMinimal)
{
if (InitAudioSystem(startupParams))
{
@ -2210,12 +2129,6 @@ AZ_POP_DISABLE_WARNING
m_pUserCallback->OnInitProgress("First time asset processing - may take a minute...");
}
#ifdef SOFTCODE_SYSTEM_ENABLED
m_env.pSoftCodeMgr = new SoftCodeMgr();
#else
m_env.pSoftCodeMgr = nullptr;
#endif
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// System cursor
@ -2225,8 +2138,7 @@ AZ_POP_DISABLE_WARNING
// - System cursor has to be enabled manually by the Game if needed; the custom UiCursor will typically be used instead
if (!gEnv->IsDedicated() &&
!gEnv->IsEditor() &&
!startupParams.bTesting)
!gEnv->IsEditor())
{
AzFramework::InputSystemCursorRequestBus::Event(AzFramework::InputDeviceMouse::Id,
&AzFramework::InputSystemCursorRequests::SetSystemCursorState,
@ -2322,27 +2234,6 @@ AZ_POP_DISABLE_WARNING
InlineInitializationProcessing("CSystem::Init ZStdDecompressor");
//////////////////////////////////////////////////////////////////////////
// Initialize task threads.
//////////////////////////////////////////////////////////////////////////
{
m_pThreadTaskManager->InitThreads();
SetAffinity();
AZ_Assert(CryMemory::IsHeapValid(), "CryMemory heap must be valid before initializing VTune.");
if (strstr(startupParams.szSystemCmdLine, "-VTUNE") != 0 || g_cvars.sys_vtune != 0)
{
if (!InitVTuneProfiler())
{
return false;
}
}
}
InlineInitializationProcessing("CSystem::Init InitTaskThreads");
if (m_env.pLyShine)
{
m_env.pLyShine->PostInit();
@ -2366,8 +2257,6 @@ AZ_POP_DISABLE_WARNING
}
}
EnableFloatExceptions(g_cvars.sys_float_exceptions);
MarkThisThreadForDebugging("Main");
}
InlineInitializationProcessing("CSystem::Init End");
@ -2422,8 +2311,7 @@ static void LoadConfigurationCmd(IConsoleCmdArgs* pParams)
return;
}
ILoadConfigurationEntrySink* pCVarsWhiteListConfigSink = GetISystem()->GetCVarsWhiteListConfigSink();
GetISystem()->LoadConfiguration(string("Config/") + pParams->GetArg(1), pCVarsWhiteListConfigSink);
GetISystem()->LoadConfiguration(string("Config/") + pParams->GetArg(1));
}
@ -2648,20 +2536,6 @@ void CmdDrillToFile(IConsoleCmdArgs* pArgs)
}
}
void ChangeLogAllocations(ICVar* pVal)
{
g_iTraceAllocations = pVal->GetIVal();
if (g_iTraceAllocations == 2)
{
IDebugCallStack::instance()->StartMemLog();
}
else
{
IDebugCallStack::instance()->StopMemLog();
}
}
//////////////////////////////////////////////////////////////////////////
void CSystem::CreateSystemVars()
{
@ -2719,9 +2593,6 @@ void CSystem::CreateSystemVars()
m_cvAIUpdate = REGISTER_INT("ai_NoUpdate", 0, VF_CHEAT, "Disables AI system update when 1");
m_iTraceAllocations = g_iTraceAllocations;
REGISTER_CVAR2_CB("sys_logallocations", &m_iTraceAllocations, m_iTraceAllocations, VF_DUMPTODISK, "Save allocation call stack", ChangeLogAllocations);
m_cvMemStats = REGISTER_INT("MemStats", 0, 0,
"0/x=refresh rate in milliseconds\n"
"Use 1000 to switch on and 0 to switch off\n"
@ -2860,16 +2731,6 @@ void CSystem::CreateSystemVars()
m_sys_TaskThread_CPU[5] = REGISTER_INT("sys_TaskThread5_CPU", 1, 0,
"Specifies the physical CPU index taskthread5 will run on");
//if physics thread is excluded all locks inside are mapped to NO_LOCK
//var must be not visible to accidentally get enabled
#if defined(EXCLUDE_PHYSICS_THREAD)
m_sys_physics_CPU = REGISTER_INT("sys_physics_CPU_disabled", 0, 0,
"Specifies the physical CPU index physics will run on");
#else
m_sys_physics_CPU = REGISTER_INT("sys_physics_CPU", 1, 0,
"Specifies the physical CPU index physics will run on");
#endif
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_12
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
@ -3033,7 +2894,6 @@ void CSystem::CreateSystemVars()
"0=off / 1=enabled");
*/
REGISTER_CVAR2("sys_AI", &g_cvars.sys_ai, 1, 0, "Enables AI Update");
REGISTER_CVAR2("sys_physics", &g_cvars.sys_physics, 1, 0, "Enables Physics Update");
REGISTER_CVAR2("sys_entities", &g_cvars.sys_entitysystem, 1, 0, "Enables Entities Update");
REGISTER_CVAR2("sys_trackview", &g_cvars.sys_trackview, 1, 0, "Enables TrackView Update");
@ -3068,10 +2928,6 @@ void CSystem::CreateSystemVars()
REGISTER_STRING("dlc_directory", "", 0, "Holds the path to the directory where DLC should be installed to and read from");
#if defined(MAP_LOADING_SLICING)
CreateSystemScheduler(this);
#endif // defined(MAP_LOADING_SLICING)
#if defined(WIN32) || defined(WIN64)
REGISTER_INT("sys_screensaver_allowed", 0, VF_NULL, "Specifies if screen saver is allowed to start up while the game is running.");
#endif

@ -39,8 +39,6 @@
#include <ILevelSystem.h>
#include <LyShine/ILyShine.h>
#include "ThreadInfo.h"
#include <LoadScreenBus.h>
#if defined(AZ_RESTRICTED_PLATFORM)
@ -90,52 +88,6 @@ void CSystem::OnScene3DEnd()
}
}
//! Update screen and call some important tick functions during loading.
void CSystem::SynchronousLoadingTick([[maybe_unused]] const char* pFunc, [[maybe_unused]] int line)
{
LOADING_TIME_PROFILE_SECTION;
if (gEnv && gEnv->bMultiplayer && !gEnv->IsEditor())
{
//UpdateLoadingScreen currently contains a couple of tick functions that need to be called regularly during the synchronous level loading,
//when the usual engine and game ticks are suspended.
UpdateLoadingScreen();
#if defined(MAP_LOADING_SLICING)
GetISystemScheduler()->SliceAndSleep(pFunc, line);
#endif
}
}
//////////////////////////////////////////////////////////////////////////
void CSystem::UpdateLoadingScreen()
{
// Do not update the network thread from here - it will cause context corruption - use the NetworkStallTicker thread system
if (GetCurrentThreadId() != gEnv->mMainThreadId)
{
return;
}
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMRENDERER_CPP_SECTION_2
#include AZ_RESTRICTED_FILE(SystemRender_cpp)
#endif
#if AZ_LOADSCREENCOMPONENT_ENABLED
EBUS_EVENT(LoadScreenBus, UpdateAndRender);
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
if (!m_bEditor && !IsQuitting())
{
if (m_pProgressListener)
{
m_pProgressListener->OnLoadingProgress(0);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CSystem::DisplayErrorMessage(const char* acMessage,

@ -1,211 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Implementation of the CSystemScheduler class
#include "CrySystem_precompiled.h"
#include "ProjectDefines.h"
#if defined(MAP_LOADING_SLICING)
#include "SystemScheduler.h"
#include "MiniQueue.h"
#include "ClientHandler.h"
#include "ServerHandler.h"
void CreateSystemScheduler(CSystem* pSystem)
{
gEnv->pSystemScheduler = new CSystemScheduler(pSystem);
}
CSystemScheduler::CSystemScheduler(CSystem* pSystem)
: m_pSystem(pSystem)
, m_lastSliceCheckTime(0.0f)
, m_sliceLoadingRef(0)
{
int defaultSchedulingMode = 0;
if (gEnv->IsDedicated())
{
defaultSchedulingMode = 2;
}
m_svSchedulingMode = REGISTER_INT("sv_scheduling", defaultSchedulingMode, 0, "Scheduling mode\n"
" 0: Normal mode\n"
" 1: Client\n"
" 2: Server\n");
m_svSchedulingBucket = REGISTER_INT("sv_schedulingBucket", 0, 0, "Scheduling bucket\n");
m_svSchedulingAffinity = REGISTER_INT("sv_SchedulingAffinity", 0, 0, "Scheduling affinity\n");
m_svSchedulingClientTimeout = REGISTER_INT("sv_schedulingClientTimeout", 1000, 0, "Client wait server\n");
m_svSchedulingServerTimeout = REGISTER_INT("sv_schedulingServerTimeout", 100, 0, "Server wait server\n");
#if defined(MAP_LOADING_SLICING)
m_svSliceLoadEnable = REGISTER_INT("sv_sliceLoadEnable", 1, 0, "Enable/disable slice loading logic\n");
;
m_svSliceLoadBudget = REGISTER_INT("sv_sliceLoadBudget", 10, 0, "Slice budget\n");
;
m_svSliceLoadLogging = REGISTER_INT("sv_sliceLoadLogging", 0, 0, "Enable/disable slice loading logging\n");
#endif
m_pLastSliceName = "INACTIVE";
m_lastSliceLine = 0;
}
CSystemScheduler::~CSystemScheduler(void)
{
}
void CSystemScheduler::SliceLoadingBegin()
{
m_lastSliceCheckTime = gEnv->pTimer->GetAsyncTime();
m_sliceLoadingRef++;
m_pLastSliceName = "START";
m_lastSliceLine = 0;
}
void CSystemScheduler::SliceLoadingEnd()
{
m_sliceLoadingRef--;
m_pLastSliceName = "INACTIVE";
m_lastSliceLine = 0;
}
void CSystemScheduler::SliceAndSleep(const char* sliceName, int line)
{
#if defined(MAP_LOADING_SLICING)
if (!gEnv->IsDedicated())
{
return;
}
if (!m_sliceLoadingRef)
{
return;
}
if (!m_svSliceLoadEnable->GetIVal())
{
return;
}
SchedulingModeUpdate();
CTimeValue currTime = gEnv->pTimer->GetAsyncTime();
float sliceBudget = CLAMP(m_svSliceLoadBudget->GetFVal(), 0, 1000.0f / m_pSystem->GetDedicatedMaxRate()->GetFVal());
bool doSleep = true;
if ((currTime - m_pSystem->GetLastTickTime()).GetMilliSeconds() < sliceBudget)
{
m_lastSliceCheckTime = currTime;
doSleep = false;
}
if (doSleep)
{
if (m_svSliceLoadLogging->GetIVal())
{
float diff = (currTime - m_lastSliceCheckTime).GetMilliSeconds();
if (diff > sliceBudget)
{
CryLogAlways("[SliceAndSleep]: Interval between slice [%s:%i] and [%s:%i] was [%f] out of budget [%f]", m_pLastSliceName, m_lastSliceLine, sliceName, line, diff, sliceBudget);
}
}
m_pSystem->SleepIfNeeded();
}
m_pLastSliceName = sliceName;
m_lastSliceLine = line;
#endif
}
void CSystemScheduler::SchedulingSleepIfNeeded()
{
if (!gEnv->IsDedicated())
{
return;
}
SchedulingModeUpdate();
m_pSystem->SleepIfNeeded();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Scheduling mode routines
//
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Scheduling mode update logic
//
///////////////////////////////////////////////////////////////////////////////////////////////////
void CSystemScheduler::SchedulingModeUpdate()
{
static std::unique_ptr<ClientHandler> m_client;
static std::unique_ptr<ServerHandler> m_server;
if (int scheduling = m_svSchedulingMode->GetIVal())
{
if (scheduling == 1) //client
{
if (!m_client.get())
{
m_server.reset();
m_client.reset(new ClientHandler(m_svSchedulingBucket->GetString(), m_svSchedulingAffinity->GetIVal(), m_svSchedulingClientTimeout->GetIVal()));
}
if (m_client->Sync())
{
return;
}
}
else if (scheduling == 2) //server
{
if (!m_server.get())
{
m_client.reset();
m_server.reset(new ServerHandler(m_svSchedulingBucket->GetString(), m_svSchedulingAffinity->GetIVal(), m_svSchedulingServerTimeout->GetIVal()));
}
if (m_server->Sync())
{
return;
}
}
}
else
{
m_client.reset();
m_server.reset();
}
}
#endif // defined(MAP_LOADING_SLICING)
extern "C" void SliceAndSleep(const char* pFunc, int line)
{
if (GetISystemScheduler())
{
GetISystemScheduler()->SliceAndSleep(pFunc, line);
}
}

@ -1,63 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H
#define CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H
#pragma once
#include "System.h"
#include <ISystemScheduler.h>
class CSystemScheduler
: public ISystemScheduler
{
public:
CSystemScheduler(CSystem* pSystem);
virtual ~CSystemScheduler(void);
// ISystemScheduler
virtual void SliceAndSleep(const char* sliceName, int line);
virtual void SliceLoadingBegin();
virtual void SliceLoadingEnd();
virtual void SchedulingSleepIfNeeded(void);
// ~ISystemScheduler
protected:
void SchedulingModeUpdate(void);
private:
CSystem* m_pSystem;
ICVar* m_svSchedulingAffinity;
ICVar* m_svSchedulingClientTimeout;
ICVar* m_svSchedulingServerTimeout;
ICVar* m_svSchedulingBucket;
ICVar* m_svSchedulingMode;
ICVar* m_svSliceLoadEnable;
ICVar* m_svSliceLoadBudget;
ICVar* m_svSliceLoadLogging;
CTimeValue m_lastSliceCheckTime;
int m_sliceLoadingRef;
const char* m_pLastSliceName;
int m_lastSliceLine;
};
// Summary:
// Creates the system scheduler interface.
void CreateSystemScheduler(CSystem* pSystem);
#endif // CRYINCLUDE_CRYSYSTEM_SYSTEMSCHEDULER_H

@ -1,697 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "System.h"
#include "ThreadConfigManager.h"
#include "IThreadManager.h"
#include <CryCustomTypes.h>
#include "CryUtils.h"
#define INCLUDED_FROM_SYSTEM_THREADING_CPP
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
#define SYSTEMTHREADING_CPP_SECTION_1 1
#define SYSTEMTHREADING_CPP_SECTION_2 2
#define SYSTEMTHREADING_CPP_SECTION_3 3
#endif
#if defined(WIN32) || defined(WIN64)
#include "CryThreadUtil_win32_thread.h"
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_1
#include AZ_RESTRICTED_FILE(SystemThreading_cpp)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
#include "CryThreadUtil_pthread.h"
#endif
#undef INCLUDED_FROM_SYSTEM_THREADING_CPP
//////////////////////////////////////////////////////////////////////////
static void ApplyThreadConfig(CryThreadUtil::TThreadHandle pThreadHandle, const SThreadConfig& rThreadDesc)
{
// Apply config
if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName)
{
CryThreadUtil::CrySetThreadName(pThreadHandle, rThreadDesc.szThreadName);
}
if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity)
{
CryThreadUtil::CrySetThreadAffinityMask(pThreadHandle, rThreadDesc.affinityFlag);
}
if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority)
{
CryThreadUtil::CrySetThreadPriority(pThreadHandle, rThreadDesc.priority);
}
if (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost)
{
CryThreadUtil::CrySetThreadPriorityBoost(pThreadHandle, !rThreadDesc.bDisablePriorityBoost);
}
CryComment("<ThreadInfo> Configured thread \"%s\" %s | AffinityMask: %u %s | Priority: %i %s | PriorityBoost: %s %s",
rThreadDesc.szThreadName, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) ? "" : "(ignored)",
rThreadDesc.affinityFlag, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) ? "" : "(ignored)",
rThreadDesc.priority, (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) ? "" : "(ignored)",
!rThreadDesc.bDisablePriorityBoost ? "enabled" : "disabled", (rThreadDesc.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) ? "" : "(ignored)");
}
//////////////////////////////////////////////////////////////////////////
struct SThreadMetaData
: public CMultiThreadRefCount
{
SThreadMetaData()
: m_pThreadTask(0)
, m_threadHandle(0)
, m_threadId(0)
, m_threadName("Cry_UnnamedThread")
, m_isRunning(false)
{
}
IThread* m_pThreadTask; // Pointer to thread task to be executed
CThreadManager* m_pThreadMngr; // Pointer to thread manager
CryThreadUtil::TThreadHandle m_threadHandle; // Thread handle
threadID m_threadId; // The active threadId, 0 = Invalid Id
CryMutex m_threadExitMutex; // Mutex used to safeguard thread exit condition signaling
CryConditionVariable m_threadExitCondition; // Signaled when the thread is about to exit
CryFixedStringT<THREAD_NAME_LENGTH_MAX> m_threadName; // Thread name
volatile bool m_isRunning; // Indicates the thread is not ready to exit yet
};
//////////////////////////////////////////////////////////////////////////
class CThreadManager
: public IThreadManager
{
public:
// <interfuscator:shuffle>
virtual ~CThreadManager()
{
}
virtual bool SpawnThread(IThread* pThread, const char* sThreadName, ...) override;
virtual bool JoinThread(IThread* pThreadTask, EJoinMode eJoinMode) override;
virtual bool RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...) override;
virtual bool UnRegisterThirdPartyThread(const char* sThreadName, ...) override;
virtual const char* GetThreadName(threadID nThreadId) override;
virtual threadID GetThreadId(const char* sThreadName, ...) override;
virtual void ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData = 0) override;
virtual void EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId = 0) override;
virtual void EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity) override;
virtual uint GetFloatingPointExceptionMask() override;
virtual void SetFloatingPointExceptionMask(uint nMask) override;
IThreadConfigManager* GetThreadConfigManager() override
{
return &m_threadConfigManager;
}
// </interfuscator:shuffle>
private:
#if defined(WIN32) || defined(WIN64)
static unsigned __stdcall RunThread(void* thisPtr);
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_2
#include AZ_RESTRICTED_FILE(SystemThreading_cpp)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
static void* RunThread(void* thisPtr);
#endif
private:
bool UnregisterThread(IThread* pThreadTask);
bool SpawnThreadImpl(IThread* pThread, const char* sThreadName);
bool RegisterThirdPartyThreadImpl(CryThreadUtil::TThreadHandle pThreadHandle, const char* sThreadName);
bool UnRegisterThirdPartyThreadImpl(const char* sThreadName);
threadID GetThreadIdImpl(const char* sThreadName);
private:
// Note: Guard SThreadMetaData with a _smart_ptr and lock to ensure that a thread waiting to be signaled by another still
// has access to valid SThreadMetaData even though the other thread terminated and as a result unregistered itself from the CThreadManager.
// An example would be the join method. Where one thread waits on a signal from an other thread to terminate and release its SThreadMetaData,
// sharing the same SThreadMetaData condition variable.
typedef std::map<IThread*, _smart_ptr<SThreadMetaData> > SpawnedThreadMap;
typedef std::map<IThread*, _smart_ptr<SThreadMetaData> >::iterator SpawnedThreadMapIter;
typedef std::map<IThread*, _smart_ptr<SThreadMetaData> >::const_iterator SpawnedThreadMapConstIter;
typedef std::pair<IThread*, _smart_ptr<SThreadMetaData> > ThreadMapPair;
typedef std::map<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, _smart_ptr<SThreadMetaData> > SpawnedThirdPartyThreadMap;
typedef std::map<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, _smart_ptr<SThreadMetaData> >::iterator SpawnedThirdPartyThreadMapIter;
typedef std::map<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, _smart_ptr<SThreadMetaData> >::const_iterator SpawnedThirdPartyThreadMapConstIter;
typedef std::pair<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, _smart_ptr<SThreadMetaData> > ThirdPartyThreadMapPair;
CryCriticalSection m_spawnedThreadsLock; // Use lock for the rare occasion a thread is created/destroyed
SpawnedThreadMap m_spawnedThreads; // Holds information of all spawned threads (through this system)
CryCriticalSection m_spawnedThirdPartyThreadsLock; // Use lock for the rare occasion a thread is created/destroyed
SpawnedThirdPartyThreadMap m_spawnedThirdPartyThread; // Holds information of all registered 3rd party threads (through this system)
CThreadConfigManager m_threadConfigManager;
};
//////////////////////////////////////////////////////////////////////////
#if defined(WIN32) || defined(WIN64)
unsigned __stdcall CThreadManager::RunThread(void* thisPtr)
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMTHREADING_CPP_SECTION_3
#include AZ_RESTRICTED_FILE(SystemThreading_cpp)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
void* CThreadManager::RunThread(void* thisPtr)
#endif
{
// Check that we are not spawning a thread before gEnv->pSystem has been set
// Otherwise we cannot enable floating point exceptions
if (!gEnv || !gEnv->pSystem)
{
CryFatalError("[Error]: CThreadManager::RunThread requires gEnv->pSystem to be initialized.");
}
IThreadConfigManager* pThreadConfigMngr = gEnv->pThreadManager->GetThreadConfigManager();
SThreadMetaData* pThreadData = reinterpret_cast<SThreadMetaData*>(thisPtr);
pThreadData->m_threadId = CryThreadUtil::CryGetCurrentThreadId();
// Apply config
const SThreadConfig* pThreadConfig = pThreadConfigMngr->GetThreadConfig(pThreadData->m_threadName.c_str());
ApplyThreadConfig(pThreadData->m_threadHandle, *pThreadConfig);
// Config not found, append thread name with no config tag
if (pThreadConfig == pThreadConfigMngr->GetDefaultThreadConfig())
{
CryFixedStringT<THREAD_NAME_LENGTH_MAX> tmpString(pThreadData->m_threadName);
const char* cNoConfigAppendix = "(NoCfgFound)";
int nNumCharsToReplace = strlen(cNoConfigAppendix);
// Replace thread name ending
if (pThreadData->m_threadName.size() > THREAD_NAME_LENGTH_MAX - nNumCharsToReplace)
{
tmpString.replace(THREAD_NAME_LENGTH_MAX - nNumCharsToReplace, nNumCharsToReplace, cNoConfigAppendix, nNumCharsToReplace);
}
else
{
tmpString.append(cNoConfigAppendix);
}
// Print to log
if (pThreadConfigMngr->ConfigLoaded())
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> No Thread config found for thread %s using ... default config.", pThreadData->m_threadName.c_str());
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo> Thread config not loaded yet. Hence no thread config was found for thread %s ... using default config.", pThreadData->m_threadName.c_str());
}
// Rename Thread
CryThreadUtil::CrySetThreadName(pThreadData->m_threadHandle, tmpString.c_str());
}
// Enable FPEs
gEnv->pThreadManager->EnableFloatExceptions((EFPE_Severity)g_cvars.sys_float_exceptions);
// Execute thread code
pThreadData->m_pThreadTask->ThreadEntry();
// Disable FPEs
gEnv->pThreadManager->EnableFloatExceptions(eFPE_None);
// Signal imminent thread end
pThreadData->m_threadExitMutex.Lock();
pThreadData->m_isRunning = false;
pThreadData->m_threadExitCondition.Notify();
pThreadData->m_threadExitMutex.Unlock();
// Unregister thread
// Note: Unregister after m_threadExitCondition.Notify() to ensure pThreadData is still valid
pThreadData->m_pThreadMngr->UnregisterThread(pThreadData->m_pThreadTask);
CryThreadUtil::CryThreadExitCall();
return NULL;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::JoinThread(IThread* pThreadTask, EJoinMode eJoinMode)
{
// Get thread object
_smart_ptr<SThreadMetaData> pThreadImpl = 0;
{
AUTO_LOCK(m_spawnedThreadsLock);
SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask);
if (res == m_spawnedThreads.end())
{
// Thread has already finished and unregistered itself.
// As it is complete we cannot wait for it.
// Hence return true.
return true;
}
pThreadImpl = res->second; // Keep object alive
}
// On try join, exit if the thread is not in a state to exit
if (eJoinMode == eJM_TryJoin && pThreadImpl->m_isRunning)
{
return false;
}
// Wait for completion of the target thread exit condition
pThreadImpl->m_threadExitMutex.Lock();
while (pThreadImpl->m_isRunning)
{
pThreadImpl->m_threadExitCondition.Wait(pThreadImpl->m_threadExitMutex);
}
pThreadImpl->m_threadExitMutex.Unlock();
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::UnregisterThread(IThread* pThreadTask)
{
AUTO_LOCK(m_spawnedThreadsLock);
SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask);
if (res == m_spawnedThreads.end())
{
// Duplicate thread deletion
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: UnregisterThread: Unable to unregister thread. Thread name could not be found. Double deletion? IThread pointer: %p", pThreadTask);
return false;
}
m_spawnedThreads.erase(res);
return true;
}
//////////////////////////////////////////////////////////////////////////
const char* CThreadManager::GetThreadName(threadID nThreadId)
{
// Loop over internally spawned threads
{
AUTO_LOCK(m_spawnedThreadsLock);
SpawnedThreadMapConstIter iter = m_spawnedThreads.begin();
SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end();
for (; iter != iterEnd; ++iter)
{
if (iter->second->m_threadId == nThreadId)
{
return iter->second->m_threadName.c_str();
}
}
}
// Loop over third party threads
{
AUTO_LOCK(m_spawnedThirdPartyThreadsLock);
SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin();
SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end();
for (; iter != iterEnd; ++iter)
{
if (iter->second->m_threadId == nThreadId)
{
return iter->second->m_threadName.c_str();
}
}
}
return "";
}
//////////////////////////////////////////////////////////////////////////
void CThreadManager::ForEachOtherThread(IThreadManager::ThreadModifFunction fpThreadModiFunction, void* pFuncData)
{
threadID nCurThreadId = CryThreadUtil::CryGetCurrentThreadId();
// Loop over internally spawned threads
{
AUTO_LOCK(m_spawnedThreadsLock);
SpawnedThreadMapConstIter iter = m_spawnedThreads.begin();
SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end();
for (; iter != iterEnd; ++iter)
{
if (iter->second->m_threadId != nCurThreadId)
{
fpThreadModiFunction(iter->second->m_threadId, pFuncData);
}
}
}
// Loop over third party threads
{
AUTO_LOCK(m_spawnedThirdPartyThreadsLock);
SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin();
SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end();
for (; iter != iterEnd; ++iter)
{
if (iter->second->m_threadId != nCurThreadId)
{
fpThreadModiFunction(iter->second->m_threadId, pFuncData);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::SpawnThread(IThread* pThreadTask, const char* sThreadName, ...)
{
va_list args;
va_start(args, sThreadName);
// Format thread name
char strThreadName[THREAD_NAME_LENGTH_MAX];
const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args);
if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1 || cNumCharsNeeded < 0)
{
strThreadName[THREAD_NAME_LENGTH_MAX - 1] = '\0'; // The WinApi only null terminates if strLen < bufSize
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1);
}
// Spawn thread
bool ret = SpawnThreadImpl(pThreadTask, strThreadName);
if (!ret)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: CSystem::SpawnThread error spawning thread: \"%s\" ", strThreadName);
}
va_end(args);
return ret;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::SpawnThreadImpl(IThread* pThreadTask, const char* sThreadName)
{
if (pThreadTask == NULL)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_ERROR, "<ThreadInfo>: SpawnThread '%s' ThreadTask is NULL : ignoring", sThreadName);
return false;
}
// Init thread meta data
SThreadMetaData* pThreadMetaData = new SThreadMetaData();
pThreadMetaData->m_pThreadTask = pThreadTask;
pThreadMetaData->m_pThreadMngr = this;
pThreadMetaData->m_threadName = sThreadName;
// Add thread to map
{
AUTO_LOCK(m_spawnedThreadsLock);
SpawnedThreadMapIter res = m_spawnedThreads.find(pThreadTask);
if (res != m_spawnedThreads.end())
{
// Thread with same name already spawned
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: SpawnThread: Thread \"%s\" already exists.", sThreadName);
delete pThreadMetaData;
return false;
}
// Insert thread data
m_spawnedThreads.insert(ThreadMapPair(pThreadTask, pThreadMetaData));
}
// Load config if we can and if no config has been defined to be loaded
const SThreadConfig* pThreadConfig = gEnv->pThreadManager->GetThreadConfigManager()->GetThreadConfig(sThreadName);
// Create thread description
CryThreadUtil::SThreadCreationDesc desc = {sThreadName, RunThread, pThreadMetaData, pThreadConfig->paramActivityFlag & SThreadConfig::eThreadParamFlag_StackSize ? pThreadConfig->stackSizeBytes : 0};
// Spawn new thread
pThreadMetaData->m_isRunning = CryThreadUtil::CryCreateThread(&(pThreadMetaData->m_threadHandle), desc);
// Validate thread creation
if (!pThreadMetaData->m_isRunning)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: SpawnThread: Could not spawn thread \"%s\" .", sThreadName);
// Remove thread from map (also releases SThreadMetaData _smart_ptr)
m_spawnedThreads.erase(m_spawnedThreads.find(pThreadTask));
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::RegisterThirdPartyThread(void* pThreadHandle, const char* sThreadName, ...)
{
if (!pThreadHandle)
{
pThreadHandle = reinterpret_cast<void*>(CryThreadUtil::CryGetCurrentThreadHandle());
}
va_list args;
va_start(args, sThreadName);
// Format thread name
char strThreadName[THREAD_NAME_LENGTH_MAX];
const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args);
if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1);
}
// Register 3rd party thread
bool ret = RegisterThirdPartyThreadImpl(reinterpret_cast<CryThreadUtil::TThreadHandle>(pThreadHandle), strThreadName);
va_end(args);
return ret;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::RegisterThirdPartyThreadImpl(CryThreadUtil::TThreadHandle threadHandle, const char* sThreadName)
{
if (strcmp(sThreadName, "") == 0)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: CThreadManager::RegisterThirdPartyThread error registering third party thread. No name provided.");
return false;
}
// Init thread meta data
SThreadMetaData* pThreadMetaData = new SThreadMetaData();
pThreadMetaData->m_pThreadTask = 0;
pThreadMetaData->m_pThreadMngr = this;
pThreadMetaData->m_threadName = sThreadName;
pThreadMetaData->m_threadHandle = CryThreadUtil::CryDuplicateThreadHandle(threadHandle); // Ensure that we are not storing a pseudo handle
pThreadMetaData->m_threadId = CryThreadUtil::CryGetThreadId(pThreadMetaData->m_threadHandle);
{
AUTO_LOCK(m_spawnedThirdPartyThreadsLock);
// Check for duplicate
SpawnedThirdPartyThreadMapConstIter res = m_spawnedThirdPartyThread.find(sThreadName);
if (res != m_spawnedThirdPartyThread.end())
{
CryFatalError("CThreadManager::RegisterThirdPartyThread - Unable to register thread \"%s\""
"because another third party thread with the same name \"%s\" has already been registered with ThreadHandle: %p",
sThreadName, res->second->m_threadName.c_str(), reinterpret_cast<void*>(threadHandle));
delete pThreadMetaData;
return false;
}
// Insert thread data
m_spawnedThirdPartyThread.insert(ThirdPartyThreadMapPair(pThreadMetaData->m_threadName.c_str(), pThreadMetaData));
}
// Get thread config
const SThreadConfig* pThreadConfig = gEnv->pThreadManager->GetThreadConfigManager()->GetThreadConfig(sThreadName);
// Apply config (if not default config)
if (strcmp(pThreadConfig->szThreadName, sThreadName) == 0)
{
ApplyThreadConfig(threadHandle, *pThreadConfig);
}
// Update FP exception mask for 3rd party thread
if (pThreadMetaData->m_threadId)
{
CryThreadUtil::EnableFloatExceptions(pThreadMetaData->m_threadId, (EFPE_Severity)g_cvars.sys_float_exceptions);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::UnRegisterThirdPartyThread(const char* sThreadName, ...)
{
va_list args;
va_start(args, sThreadName);
// Format thread name
char strThreadName[THREAD_NAME_LENGTH_MAX];
const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args);
if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1);
}
// Unregister 3rd party thread
bool ret = UnRegisterThirdPartyThreadImpl(strThreadName);
va_end(args);
return ret;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadManager::UnRegisterThirdPartyThreadImpl(const char* sThreadName)
{
AUTO_LOCK(m_spawnedThirdPartyThreadsLock);
SpawnedThirdPartyThreadMapIter res = m_spawnedThirdPartyThread.find(sThreadName);
if (res == m_spawnedThirdPartyThread.end())
{
// Duplicate thread deletion
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: UnRegisterThirdPartyThread: Unable to unregister thread. Thread name \"%s\" could not be found. Double deletion? ", sThreadName);
return false;
}
// Close thread handle
CryThreadUtil::CryCloseThreadHandle(res->second->m_threadHandle);
// Delete reference from container
m_spawnedThirdPartyThread.erase(res);
return true;
}
//////////////////////////////////////////////////////////////////////////
threadID CThreadManager::GetThreadId(const char* sThreadName, ...)
{
va_list args;
va_start(args, sThreadName);
// Format thread name
char strThreadName[THREAD_NAME_LENGTH_MAX];
const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), sThreadName, args);
if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1);
}
// Get thread name
threadID ret = GetThreadIdImpl(strThreadName);
va_end(args);
return ret;
}
//////////////////////////////////////////////////////////////////////////
threadID CThreadManager::GetThreadIdImpl(const char* sThreadName)
{
// Loop over internally spawned threads
{
AUTO_LOCK(m_spawnedThreadsLock);
SpawnedThreadMapConstIter iter = m_spawnedThreads.begin();
SpawnedThreadMapConstIter iterEnd = m_spawnedThreads.end();
for (; iter != iterEnd; ++iter)
{
if (iter->second->m_threadName.compare(sThreadName) == 0)
{
return iter->second->m_threadId;
}
}
}
// Loop over third party threads
{
AUTO_LOCK(m_spawnedThirdPartyThreadsLock);
SpawnedThirdPartyThreadMapConstIter iter = m_spawnedThirdPartyThread.begin();
SpawnedThirdPartyThreadMapConstIter iterEnd = m_spawnedThirdPartyThread.end();
for (; iter != iterEnd; ++iter)
{
if (iter->second->m_threadName.compare(sThreadName) == 0)
{
return iter->second->m_threadId;
}
}
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
static void EnableFPExceptionsForThread(threadID nThreadId, void* pData)
{
EFPE_Severity eFPESeverity = *(EFPE_Severity*)pData;
CryThreadUtil::EnableFloatExceptions(nThreadId, eFPESeverity);
}
//////////////////////////////////////////////////////////////////////////
void CThreadManager::EnableFloatExceptions(EFPE_Severity eFPESeverity, threadID nThreadId /*=0*/)
{
CryThreadUtil::EnableFloatExceptions(nThreadId, eFPESeverity);
}
//////////////////////////////////////////////////////////////////////////
void CThreadManager::EnableFloatExceptionsForEachOtherThread(EFPE_Severity eFPESeverity)
{
ForEachOtherThread(EnableFPExceptionsForThread, &eFPESeverity);
}
//////////////////////////////////////////////////////////////////////////
uint CThreadManager::GetFloatingPointExceptionMask()
{
return CryThreadUtil::GetFloatingPointExceptionMask();
}
//////////////////////////////////////////////////////////////////////////
void CThreadManager::SetFloatingPointExceptionMask(uint nMask)
{
CryThreadUtil::SetFloatingPointExceptionMask(nMask);
}
//////////////////////////////////////////////////////////////////////////
void CSystem::InitThreadSystem()
{
m_pThreadManager = new CThreadManager();
m_env.pThreadManager = m_pThreadManager;
}
//////////////////////////////////////////////////////////////////////////
void CSystem::ShutDownThreadSystem()
{
SAFE_DELETE(m_pThreadManager);
}

@ -46,8 +46,6 @@
#include <shlobj.h>
#endif
#include "IDebugCallStack.h"
#if defined(APPLE) || defined(LINUX)
#include <pwd.h>
#endif
@ -752,13 +750,6 @@ void CSystem::FatalError(const char* format, ...)
}
// Dump callstack.
#endif
#if defined (WIN32)
//Triggers a fatal error, so the DebugCallstack can create the error.log and terminate the application
IDebugCallStack::instance()->FatalError(szBuffer);
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMWIN32_CPP_SECTION_1
#include AZ_RESTRICTED_FILE(SystemWin32_cpp)
#endif
CryDebugBreak();
@ -800,8 +791,6 @@ void CSystem::ReportBug([[maybe_unused]] const char* format, ...)
va_start(ArgList, format);
azvsnprintf(szBuffer + strlen(sPrefix), MAX_WARNING_LENGTH - strlen(sPrefix), format, ArgList);
va_end(ArgList);
IDebugCallStack::instance()->ReportBug(szBuffer);
#endif
}
@ -910,10 +899,6 @@ void CSystem::LogSystemInfo()
OSVERSIONINFO OSVerInfo;
OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
// log Windows type
Win32SysInspect::GetOS(m_env.pi.winVer, m_env.pi.win64Bit, szBuffer, sizeof(szBuffer));
CryLogAlways(szBuffer);
// log system language
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGLANGUAGE, szLanguageBuffer, sizeof(szLanguageBuffer));
azsprintf(szBuffer, "System language: %s", szLanguageBuffer);

@ -1,577 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "ThreadConfigManager.h"
#include "IConsole.h"
#include "System.h"
#include <StringUtils.h>
#include <CryCustomTypes.h>
#include "CryUtils.h"
namespace
{
const char* sCurThreadConfigFilename = "";
const uint32 sPlausibleStackSizeLimitKB = (1024 * 100); // 100mb
}
//////////////////////////////////////////////////////////////////////////
CThreadConfigManager::CThreadConfigManager()
{
m_defaultConfig.szThreadName = "CryThread_Unnamed";
m_defaultConfig.stackSizeBytes = 0;
m_defaultConfig.affinityFlag = -1;
m_defaultConfig.priority = THREAD_PRIORITY_NORMAL;
m_defaultConfig.bDisablePriorityBoost = false;
m_defaultConfig.paramActivityFlag = (SThreadConfig::TThreadParamFlag)~0;
}
//////////////////////////////////////////////////////////////////////////
const SThreadConfig* CThreadConfigManager::GetThreadConfig(const char* szThreadName, ...)
{
va_list args;
va_start(args, szThreadName);
// Format thread name
char strThreadName[THREAD_NAME_LENGTH_MAX];
const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), szThreadName, args);
if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1);
}
// Get Thread Config
const SThreadConfig* retThreasdConfig = GetThreadConfigImpl(strThreadName);
va_end(args);
return retThreasdConfig;
}
//////////////////////////////////////////////////////////////////////////
const SThreadConfig* CThreadConfigManager::GetThreadConfigImpl(const char* szThreadName)
{
// Get thread config for platform
ThreadConfigMapConstIter threatRet = m_threadConfig.find(CryFixedStringT<THREAD_NAME_LENGTH_MAX>(szThreadName));
if (threatRet == m_threadConfig.end())
{
// Search in wildcard setups
ThreadConfigMapConstIter wildCardIter = m_wildcardThreadConfig.begin();
ThreadConfigMapConstIter wildCardIterEnd = m_wildcardThreadConfig.end();
for (; wildCardIter != wildCardIterEnd; ++wildCardIter)
{
if (CryStringUtils::MatchWildcard(szThreadName, wildCardIter->second.szThreadName))
{
// Store new thread config
SThreadConfig threadConfig = wildCardIter->second;
std::pair<ThreadConfigMapIter, bool> res;
res = m_threadConfig.insert(ThreadConfigMapPair(CryFixedStringT<THREAD_NAME_LENGTH_MAX>(szThreadName), threadConfig));
// Store name (ref to key)
SThreadConfig& rMapThreadConfig = res.first->second;
rMapThreadConfig.szThreadName = res.first->first.c_str();
// Return new thread config
return &res.first->second;
}
}
// Failure case, no match found
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: Unable to find config for thread:%s", szThreadName);
return &m_defaultConfig;
}
// Return thread config
return &threatRet->second;
}
//////////////////////////////////////////////////////////////////////////
const SThreadConfig* CThreadConfigManager::GetDefaultThreadConfig() const
{
return &m_defaultConfig;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadConfigManager::LoadConfig(const char* pcPath)
{
// Adjust filename for OnDisk or in .pak file loading
char szFullPathBuf[AZ::IO::IArchive::MaxPath];
gEnv->pCryPak->AdjustFileName(pcPath, szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), 0);
// Open file
XmlNodeRef xmlRoot = GetISystem()->LoadXmlFromFile(szFullPathBuf);
if (!xmlRoot)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: File \"%s\" not found!", pcPath);
return false;
}
// Load config for active platform
sCurThreadConfigFilename = pcPath;
const char* strPlatformId = IdentifyPlatform();
CryFixedStringT<32> tmpPlatformStr;
bool retValue = false;
// Try load common platform settings
tmpPlatformStr.Format("%s_Common", strPlatformId);
LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str());
#if defined(CRY_PLATFORM_DESKTOP)
// Handle PC specifically as we do not know the core setup of the executing machine.
// Try and find the next power of 2 core setup. Otherwise fallback to a lower power of 2 core setup spec
// Try and load next pow of 2 setup for active pc core configuration
const unsigned int numCPUs = ((CSystem*)GetISystem())->GetCPUFeatures()->GetLogicalCPUCount();
uint32 i = numCPUs;
for (; i > 0; --i)
{
tmpPlatformStr.Format("%s_%i", strPlatformId, i);
retValue = LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str());
if (retValue)
{
break;
}
}
if (retValue && i != numCPUs)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: (%s: %u core) Unable to find platform config \"%s\". Next valid config found was %s_%u.",
strPlatformId, numCPUs, tmpPlatformStr.c_str(), strPlatformId, i);
}
#else
tmpPlatformStr.Format("%s", strPlatformId);
retValue = LoadPlatformConfig(xmlRoot, strPlatformId);
#endif
// Print out info
if (retValue)
{
CryLogAlways("<ThreadConfigInfo>: Thread profile loaded: \"%s\" (%s) ", tmpPlatformStr.c_str(), pcPath);
}
else
{
// Could not find any matching platform
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: Active platform identifier string \"%s\" not found in config \"%s\".", strPlatformId, sCurThreadConfigFilename);
}
sCurThreadConfigFilename = "";
return retValue;
}
//////////////////////////////////////////////////////////////////////////
bool CThreadConfigManager::ConfigLoaded() const
{
return !m_threadConfig.empty();
}
//////////////////////////////////////////////////////////////////////////
bool CThreadConfigManager::LoadPlatformConfig(const XmlNodeRef& rXmlRoot, const char* sPlatformId)
{
// Validate node
if (!rXmlRoot->isTag("ThreadConfig"))
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: Unable to find root xml node \"ThreadConfig\"");
return false;
}
// Find active platform
const uint32 numPlatforms = rXmlRoot->getChildCount();
for (uint32 i = 0; i < numPlatforms; ++i)
{
const XmlNodeRef xmlPlatformNode = rXmlRoot->getChild(i);
// Is platform node
if (!xmlPlatformNode->isTag("Platform"))
{
continue;
}
// Is has Name attribute
if (!xmlPlatformNode->haveAttr("Name"))
{
continue;
}
// Is platform of interest
const char* platformName = xmlPlatformNode->getAttr("Name");
if (_stricmp(sPlatformId, platformName) == 0)
{
// Load platform
LoadThreadDefaultConfig(xmlPlatformNode);
LoadPlatformThreadConfigs(xmlPlatformNode);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
void CThreadConfigManager::LoadPlatformThreadConfigs(const XmlNodeRef& rXmlPlatformRef)
{
// Get thread configurations for active platform
const uint32 numThreads = rXmlPlatformRef->getChildCount();
for (uint32 j = 0; j < numThreads; ++j)
{
const XmlNodeRef xmlThreadNode = rXmlPlatformRef->getChild(j);
if (!xmlThreadNode->isTag("Thread"))
{
continue;
}
// Ensure thread config has name
if (!xmlThreadNode->haveAttr("Name"))
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Thread node without \"name\" attribute encountered.");
continue;
}
// Load thread config
SThreadConfig loadedThreadConfig = SThreadConfig(m_defaultConfig);
LoadThreadConfig(xmlThreadNode, loadedThreadConfig);
// Get thread name and check if it contains wildcard characters
const char* szThreadName = xmlThreadNode->getAttr("Name");
bool bWildCard = strchr(szThreadName, '*') ? true : false;
ThreadConfigMap& threadConfig = bWildCard ? m_wildcardThreadConfig : m_threadConfig;
// Check for duplicate and override it with new config if found
if (threadConfig.find(szThreadName) != threadConfig.end())
{
CryLogAlways("<ThreadConfigInfo>: [XML Parsing] Thread with name \"%s\" already loaded. Overriding with new configuration", szThreadName);
threadConfig[szThreadName] = loadedThreadConfig;
continue;
}
// Store new thread config
std::pair<ThreadConfigMapIter, bool> res;
res = threadConfig.insert(ThreadConfigMapPair(CryFixedStringT<THREAD_NAME_LENGTH_MAX>(szThreadName), loadedThreadConfig));
// Store name (ref to key)
SThreadConfig& rMapThreadConfig = res.first->second;
rMapThreadConfig.szThreadName = res.first->first.c_str();
}
}
//////////////////////////////////////////////////////////////////////////
bool CThreadConfigManager::LoadThreadDefaultConfig(const XmlNodeRef& rXmlPlatformRef)
{
// Find default thread config node
const uint32 numNodes = rXmlPlatformRef->getChildCount();
for (uint32 j = 0; j < numNodes; ++j)
{
const XmlNodeRef xmlNode = rXmlPlatformRef->getChild(j);
// Load default config
if (xmlNode->isTag("ThreadDefault"))
{
LoadThreadConfig(xmlNode, m_defaultConfig);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
void CThreadConfigManager::LoadAffinity(const XmlNodeRef& rXmlThreadRef, uint32& rAffinity, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
{
const char* szValidCharacters = "-,0123456789";
uint32 affinity = 0;
// Validate node
if (!rXmlThreadRef->haveAttr("Affinity"))
{
return;
}
// Validate token
CryFixedStringT<32> affinityRawStr(rXmlThreadRef->getAttr("Affinity"));
if (affinityRawStr.empty())
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Empty attribute \"Affinity\" encountered");
return;
}
if (affinityRawStr.compareNoCase("ignore") == 0)
{
// Param is inactive, clear bit
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Affinity;
return;
}
CryFixedStringT<32>::size_type nPos = affinityRawStr.find_first_not_of(" -,0123456789");
if (nPos != CryFixedStringT<32>::npos)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING,
"<ThreadConfigInfo>: [XML Parsing] Invalid character \"%c\" encountered in \"Affinity\" attribute. Valid characters:\"%s\" Offending token:\"%s\"", affinityRawStr.at(nPos),
szValidCharacters, affinityRawStr.c_str());
return;
}
// Tokenize comma separated string
int pos = 0;
CryFixedStringT<32> affnityTokStr = affinityRawStr.Tokenize(",", pos);
while (!affnityTokStr.empty())
{
affnityTokStr.Trim();
long affinityId = strtol(affnityTokStr.c_str(), NULL, 10);
if (affinityId == LONG_MAX || affinityId == LONG_MIN)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unknown value \"%s\" encountered for attribute \"Affinity\"", affnityTokStr.c_str());
return;
}
// Allow scheduler to pick thread
if (affinityId == -1)
{
affinity = ~0;
break;
}
// Set affinity bit
affinity |= BIT(affinityId);
// Move to next token
affnityTokStr = affinityRawStr.Tokenize(",", pos);
}
// Set affinity reference
rAffinity = affinity;
}
//////////////////////////////////////////////////////////////////////////
void CThreadConfigManager::LoadPriority(const XmlNodeRef& rXmlThreadRef, int32& rPriority, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
{
const char* szValidCharacters = "-,0123456789";
// Validate node
if (!rXmlThreadRef->haveAttr("Priority"))
{
return;
}
// Validate token
CryFixedStringT<32> threadPrioStr(rXmlThreadRef->getAttr("Priority"));
threadPrioStr.Trim();
if (threadPrioStr.empty())
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Empty attribute \"Priority\" encountered");
return;
}
if (threadPrioStr.compareNoCase("ignore") == 0)
{
// Param is inactive, clear bit
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Priority;
return;
}
// Test for character string (no numbers allowed)
if (threadPrioStr.find_first_of(szValidCharacters) == CryFixedStringT<32>::npos)
{
threadPrioStr.MakeLower();
// Set priority
if (threadPrioStr.compare("below_normal") == 0)
{
rPriority = THREAD_PRIORITY_BELOW_NORMAL;
}
else if (threadPrioStr.compare("normal") == 0)
{
rPriority = THREAD_PRIORITY_NORMAL;
}
else if (threadPrioStr.compare("above_normal") == 0)
{
rPriority = THREAD_PRIORITY_ABOVE_NORMAL;
}
else if (threadPrioStr.compare("idle") == 0)
{
rPriority = THREAD_PRIORITY_IDLE;
}
else if (threadPrioStr.compare("lowest") == 0)
{
rPriority = THREAD_PRIORITY_LOWEST;
}
else if (threadPrioStr.compare("highest") == 0)
{
rPriority = THREAD_PRIORITY_HIGHEST;
}
else if (threadPrioStr.compare("time_critical") == 0)
{
rPriority = THREAD_PRIORITY_TIME_CRITICAL;
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Platform unsupported value \"%s\" encountered for attribute \"Priority\"", threadPrioStr.c_str());
return;
}
}
// Test for number string (no alphabetical characters allowed)
else if (threadPrioStr.find_first_not_of(szValidCharacters) == CryFixedStringT<32>::npos)
{
long numValue = strtol(threadPrioStr.c_str(), NULL, 10);
if (numValue == LONG_MAX || numValue == LONG_MIN)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unsupported number type \"%s\" for for attribute \"Priority\"", threadPrioStr.c_str());
return;
}
// Set priority
rPriority = numValue;
}
else
{
// String contains characters and numbers
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unsupported type \"%s\" encountered for attribute \"Priority\". Token containers numbers and characters", threadPrioStr.c_str());
return;
}
}
//////////////////////////////////////////////////////////////////////////
void CThreadConfigManager::LoadDisablePriorityBoost(const XmlNodeRef& rXmlThreadRef, bool& rPriorityBoost, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
{
// Validate node
if (!rXmlThreadRef->haveAttr("DisablePriorityBoost"))
{
return;
}
// Extract bool info
CryFixedStringT<16> sAttribToken(rXmlThreadRef->getAttr("DisablePriorityBoost"));
sAttribToken.Trim();
sAttribToken.MakeLower();
if (sAttribToken.compare("ignore") == 0)
{
// Param is inactive, clear bit
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_PriorityBoost;
return;
}
else if (sAttribToken.compare("true") == 0 || sAttribToken.compare("1") == 0)
{
rPriorityBoost = true;
}
else if (sAttribToken.compare("false") == 0 || sAttribToken.compare("0") == 0)
{
rPriorityBoost = false;
}
else
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unsupported bool type \"%s\" encountered for attribute \"DisablePriorityBoost\"",
rXmlThreadRef->getAttr("DisablePriorityBoost"));
return;
}
}
//////////////////////////////////////////////////////////////////////////
void CThreadConfigManager::LoadStackSize(const XmlNodeRef& rXmlThreadRef, uint32& rStackSize, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
{
const char* sValidCharacters = "0123456789";
if (rXmlThreadRef->haveAttr("StackSizeKB"))
{
// Read stack size
CryFixedStringT<32> stackSize(rXmlThreadRef->getAttr("StackSizeKB"));
// Validate stack size
if (stackSize.empty())
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Empty attribute \"StackSize\" encountered");
return;
}
else if (stackSize.compareNoCase("ignore") == 0)
{
// Param is inactive, clear bit
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_StackSize;
return;
}
else if (stackSize.find_first_not_of(sValidCharacters) == CryFixedStringT<32>::npos)
{
// Convert string to long
long stackSizeVal = strtol(stackSize.c_str(), NULL, 10);
if (stackSizeVal == LONG_MAX || stackSizeVal == LONG_MIN)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Invalid number for \"StackSize\" encountered. \"%s\"", stackSize.c_str());
return;
}
else if (stackSizeVal <= 0 || stackSizeVal > sPlausibleStackSizeLimitKB)
{
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] \"StackSize\" value not plausible \"%" PRId64 "KB\"", (int64)stackSizeVal);
return;
}
// Set stack size
rStackSize = stackSizeVal * 1024; // Convert to bytes
}
}
}
//////////////////////////////////////////////////////////////////////////
void CThreadConfigManager::LoadThreadConfig(const XmlNodeRef& rXmlThreadRef, SThreadConfig& rThreadConfig)
{
LoadAffinity(rXmlThreadRef, rThreadConfig.affinityFlag, rThreadConfig.paramActivityFlag);
LoadPriority(rXmlThreadRef, rThreadConfig.priority, rThreadConfig.paramActivityFlag);
LoadDisablePriorityBoost(rXmlThreadRef, rThreadConfig.bDisablePriorityBoost, rThreadConfig.paramActivityFlag);
LoadStackSize(rXmlThreadRef, rThreadConfig.stackSizeBytes, rThreadConfig.paramActivityFlag);
}
//////////////////////////////////////////////////////////////////////////
const char* CThreadConfigManager::IdentifyPlatform()
{
#if defined(AZ_RESTRICTED_PLATFORM)
#include AZ_RESTRICTED_FILE(ThreadConfigManager_cpp)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(ANDROID)
return "android";
#elif defined(LINUX)
return "linux";
#elif defined(APPLE)
return "mac";
#elif defined(WIN32) || defined(WIN64)
return "pc";
#else
#error "Undefined platform"
#endif
}
//////////////////////////////////////////////////////////////////////////
void CThreadConfigManager::DumpThreadConfigurationsToLog()
{
#if !defined(RELEASE)
// Print header
CryLogAlways("== Thread Startup Config List (\"%s\") ==", IdentifyPlatform());
// Print loaded default config
CryLogAlways(" (Default) 1. \"%s\" (StackSize:%uKB | Affinity:%u | Priority:%i | PriorityBoost:\"%s\")", m_defaultConfig.szThreadName, m_defaultConfig.stackSizeBytes / 1024,
m_defaultConfig.affinityFlag, m_defaultConfig.priority, m_defaultConfig.bDisablePriorityBoost ? "disabled" : "enabled");
// Print loaded thread configs
int listItemCounter = 1;
ThreadConfigMapConstIter iter = m_threadConfig.begin();
ThreadConfigMapConstIter iterEnd = m_threadConfig.end();
for (; iter != iterEnd; ++iter)
{
const SThreadConfig& threadConfig = iter->second;
CryLogAlways("%3d.\"%s\" %s (StackSize:%uKB %s | Affinity:%u %s | Priority:%i %s | PriorityBoost:\"%s\" %s)", ++listItemCounter,
threadConfig.szThreadName, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) ? "" : "(ignored)",
threadConfig.stackSizeBytes / 1024u, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_StackSize) ? "" : "(ignored)",
threadConfig.affinityFlag, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) ? "" : "(ignored)",
threadConfig.priority, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) ? "" : "(ignored)",
!threadConfig.bDisablePriorityBoost ? "enabled" : "disabled", (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) ? "" : "(ignored)");
}
#endif
}

@ -1,137 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#pragma once
#include <map>
#include "IThreadConfigManager.h"
/*
ThreadConfigManager:
Loads a thread configuration from an xml file and stores them.
== XML File Layout and Rules: ===
= Platform names =
(case insensitive)
"ANDROID"
"PC"
"MAC"
etc.
= Basic Layout =
<ThreadConfig>
<Platform name="XXX">
<ThreadDefault Affinity="XX" Priority="XX" StackSizeKB="XX">
<Thread name ="A" Affinity="XX" Priority="XX" StackSizeKB="XX">
<Thread name ="B" Affinity="XX" >
...
</Platform>
<Platform name="YYY">
...
</Platform>
</ThreadConfig>
= Parser Order for Platform =
1. PlatformName_Common (valid for all potential platform configurations. Can be overridden by concert platform configuration)
2. PlatformName or PlatformName_X (for platforms with unknown CPU count where X is the number of potential cores. The equal or next lower matching configuration for the identified core count at runtime will be taken)
Note: Overriding of thread configuration by later parsed configuration allowed.
= <ThreadDefault> and <Thread> XML attributes =
!!!
Note: Use "ignore" as value if you do not want the thread system to set the value specifically!
If a value is not defines the <ThreadDefault> value of the parameter will be used.
This is useful when dealing with 3rdParty threads where you are not in control of the parameter setup.
!!!
Name:
"x" (string) : Name of thread
"x*y" (string) : Name of thread with wildcard character
Affinity:
"-1" : Put SW thread affinity in the hands of the scheduler - (default) -
"x" : Run thread on specified core
"x, y, ..." : Run thread on specified cores
Priority:
"idle" : Hint to CryEngine to run thread with pre-set priority
"below_normal" : Hint to CryEngine to run thread with pre-set priority
"normal" : Hint to CryEngine to run thread with pre-set priority - (default) -
"above_normal" : Hint to CryEngine to run thread with pre-set priority
"highest" : Hint to CryEngine to run thread with pre-set priority
"time_critical" : Hint to CryEngine to run thread with pre-set priority
"x" (number) : User defined thread priority number
StackSizeKB:
"0" : Let platform decide on the stack size - (default) -
"x" : Create thread with "x" KB of stack size
DisablePriorityBoost:
"true" : Disable priority boosting - (default) -
"false" : Enable priority boosting
*/
class CThreadConfigManager
: public IThreadConfigManager
{
public:
typedef std::map<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, SThreadConfig> ThreadConfigMap;
typedef std::pair<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, SThreadConfig> ThreadConfigMapPair;
typedef std::map<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, SThreadConfig>::iterator ThreadConfigMapIter;
typedef std::map<CryFixedStringT<THREAD_NAME_LENGTH_MAX>, SThreadConfig>::const_iterator ThreadConfigMapConstIter;
public:
CThreadConfigManager();
~CThreadConfigManager()
{
}
// Called once during System startup.
// Loads the thread configuration for the executing platform from file.
virtual bool LoadConfig(const char* pcPath) override;
// Returns true if a config has been loaded
virtual bool ConfigLoaded() const override;
// Gets the thread configuration for the specified thread on the active platform.
// If no matching config is found a default configuration is returned
// (which does not have the same name as the search string).
virtual const SThreadConfig* GetThreadConfig(const char* sThreadName, ...) override;
virtual const SThreadConfig* GetDefaultThreadConfig() const override;
virtual void DumpThreadConfigurationsToLog() override;
private:
const char* IdentifyPlatform();
const SThreadConfig* GetThreadConfigImpl(const char* cThreadName);
bool LoadPlatformConfig(const XmlNodeRef& rXmlRoot, const char* sPlatformId);
void LoadPlatformThreadConfigs(const XmlNodeRef& rXmlPlatformRef);
bool LoadThreadDefaultConfig(const XmlNodeRef& rXmlPlatformRef);
void LoadThreadConfig(const XmlNodeRef& rXmlThreadRef, SThreadConfig& rThreadConfig);
void LoadAffinity(const XmlNodeRef& rXmlThreadRef, uint32& rAffinity, SThreadConfig::TThreadParamFlag& rParamActivityFlag);
void LoadPriority(const XmlNodeRef& rXmlThreadRef, int32& rPriority, SThreadConfig::TThreadParamFlag& rParamActivityFlag);
void LoadDisablePriorityBoost(const XmlNodeRef& rXmlThreadRef, bool& rPriorityBoost, SThreadConfig::TThreadParamFlag& rParamActivityFlag);
void LoadStackSize(const XmlNodeRef& rXmlThreadRef, uint32& rStackSize, SThreadConfig::TThreadParamFlag& rParamActivityFlag);
private:
ThreadConfigMap m_threadConfig; // Note: The map key is referenced by as const char* by the value's storage class. Other containers may not support this behaviour as they will re-allocate memory as they grow/shrink.
ThreadConfigMap m_wildcardThreadConfig;
SThreadConfig m_defaultConfig;
};

@ -1,123 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "CrySystem_precompiled.h"
#include "ThreadInfo.h"
#include "System.h"
////////////////////////////////////////////////////////////////////////////
#if defined(AZ_RESTRICTED_PLATFORM)
#undef AZ_RESTRICTED_SECTION
#define THREADINFO_CPP_SECTION_1 1
#define THREADINFO_CPP_SECTION_2 2
#endif
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION THREADINFO_CPP_SECTION_1
#include AZ_RESTRICTED_FILE(ThreadInfo_cpp)
#endif
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
#if AZ_LEGACY_CRYSYSTEM_TRAIT_THREADINFO_WINDOWS_STYLE
////////////////////////////////////////////////////////////////////////////
void SThreadInfo::GetCurrentThreads(TThreadInfo& threadsOut)
{
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
DWORD currProcessId = GetCurrentProcessId();
if (h != INVALID_HANDLE_VALUE)
{
THREADENTRY32 te;
te.dwSize = sizeof(te);
if (Thread32First(h, &te))
{
do
{
if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID))
{
if (te.th32OwnerProcessID == currProcessId)
{
threadsOut[te.th32ThreadID] = CryThreadGetName(te.th32ThreadID);
}
}
te.dwSize = sizeof(te);
} while (Thread32Next(h, &te));
}
CloseHandle(h);
}
}
////////////////////////////////////////////////////////////////////////////
void SThreadInfo::OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds /* = TThreadIds()*/, bool ignoreCurrThread /* = true*/)
{
TThreadIds threadids = threadIds;
if (threadids.empty())
{
TThreadInfo threads;
GetCurrentThreads(threads);
DWORD currThreadId = GetCurrentThreadId();
for (TThreadInfo::iterator it = threads.begin(), end = threads.end(); it != end; ++it)
{
if (!ignoreCurrThread || it->first != currThreadId)
{
threadids.push_back(it->first);
}
}
}
for (TThreadIds::iterator it = threadids.begin(), end = threadids.end(); it != end; ++it)
{
SThreadHandle thread;
thread.Id = *it;
thread.Handle = OpenThread(THREAD_ALL_ACCESS, FALSE, *it);
threadsOut.push_back(thread);
}
}
////////////////////////////////////////////////////////////////////////////
void SThreadInfo::CloseThreadHandles(const TThreads& threads)
{
for (TThreads::const_iterator it = threads.begin(), end = threads.end(); it != end; ++it)
{
CloseHandle(it->Handle);
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION THREADINFO_CPP_SECTION_2
#include AZ_RESTRICTED_FILE(ThreadInfo_cpp)
#elif defined(LINUX) || defined(APPLE)
void SThreadInfo::GetCurrentThreads(TThreadInfo& threadsOut)
{
assert(false); // not implemented!
}
////////////////////////////////////////////////////////////////////////////
void SThreadInfo::OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds /* = TThreadIds()*/, bool ignoreCurrThread /* = true*/)
{
assert(false); // not implemented!
}
////////////////////////////////////////////////////////////////////////////
void SThreadInfo::CloseThreadHandles(const TThreads& threads)
{
assert(false); // not implemented!
}
////////////////////////////////////////////////////////////////////////////
#endif

@ -1,43 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_THREADINFO_H
#define CRYINCLUDE_CRYSYSTEM_THREADINFO_H
#pragma once
struct SThreadInfo
{
public:
struct SThreadHandle
{
HANDLE Handle;
uint32 Id;
};
typedef std::vector<uint32> TThreadIds;
typedef std::vector<SThreadHandle> TThreads;
typedef std::map<uint32, string> TThreadInfo;
// returns thread info
static void GetCurrentThreads(TThreadInfo& threadsOut);
// fills threadsOut vector with thread handles of given thread ids; if threadIds vector is emtpy it fills all running threads
// if ignoreCurrThread is true it will not return the current thread
static void OpenThreadHandles(TThreads& threadsOut, const TThreadIds& threadIds = TThreadIds(), bool ignoreCurrThread = true);
// closes thread handles; should be called whenever GetCurrentThreads was called!
static void CloseThreadHandles(const TThreads& threads);
};
#endif // CRYINCLUDE_CRYSYSTEM_THREADINFO_H

File diff suppressed because it is too large Load Diff

@ -1,181 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYSYSTEM_THREADTASK_H
#define CRYINCLUDE_CRYSYSTEM_THREADTASK_H
#pragma once
#include <IThreadTask.h>
#include <CryThread.h>
#include <MultiThread_Containers.h>
#define MAIN_THREAD_INDEX 0
class CThreadTask_Thread;
void MarkThisThreadForDebugging(const char* name);
void UnmarkThisThreadFromDebugging();
void UpdateFPExceptionsMaskForThreads();
class CThreadTaskManager;
///
struct IThreadTaskRunnable
{
virtual ~IThreadTaskRunnable(){}
virtual void Run() = 0;
virtual void Cancel() = 0;
};
//////////////////////////////////////////////////////////////////////////
class CThreadTask_Thread
: public CryThread<IThreadTaskRunnable>
, public IThreadTask_Thread
{
protected:
void Init();
public:
CThreadTask_Thread(CThreadTaskManager* pTaskMgr, const char* sName, int nThreadIndex, int nProcessor, int nThreadPriority, ThreadPoolHandle poolHandle = -1);
~CThreadTask_Thread();
// see IThreadTaskRunnable, CryThread<>
void Run() override;
void Cancel() override;
// see CryThread<>
void Terminate() override;
// IThreadTask_Thread
void AddTask(SThreadTaskInfo* pTaskInfo) override;
void RemoveTask(SThreadTaskInfo* pTaskInfo) override;
void RemoveAllTasks() override;
void SingleUpdate() override;
void ChangeProcessor(int nProcessor);
public:
CThreadTaskManager* m_pTaskManager;
string m_sThreadName;
int m_nThreadIndex; // -1 means the thread is blocking
int m_nProcessor;
int m_nThreadPriority;
THREAD_HANDLE m_hThreadHandle;
// Tasks running on this thread.
typedef CryMT::CLocklessPointerQueue<SThreadTaskInfo, stl::STLGlobalAllocator<SThreadTaskInfo> > Tasks;
Tasks tasks;
// The task is being processing now
SThreadTaskInfo* m_pProcessingTask;
CryEvent m_waitForTasks;
// Set to true when thread must stop.
volatile bool bStopThread;
volatile bool bRunning;
// handle of threads pool which this thread belongs to(if any)
ThreadPoolHandle m_poolHandle;
};
//////////////////////////////////////////////////////////////////////////
class CThreadTaskManager
: public IThreadTaskManager
{
private:
typedef std::vector<CThreadTask_Thread*, stl::STLGlobalAllocator<CThreadTask_Thread*> > Threads;
// note: this struct is auxilary and NOT thread-safe
// it is only for internal use inside the task manager
struct CThreadsPool
{
ThreadPoolHandle m_hHandle;
Threads m_Threads;
ThreadPoolDesc m_pDescription;
const bool SetAffinity(const ThreadPoolAffinityMask AffinityMask);
const bool operator < (const CThreadsPool& p) const { return m_hHandle < p.m_hHandle; }
const bool operator == (const CThreadsPool& p) const { return m_hHandle == p.m_hHandle; }
};
typedef std::vector<CThreadsPool> ThreadsPools;
public:
CThreadTaskManager();
~CThreadTaskManager();
void InitThreads();
void CloseThreads();
void StopAllThreads();
//////////////////////////////////////////////////////////////////////////
// IThreadTaskManager
//////////////////////////////////////////////////////////////////////////
virtual void RegisterTask(IThreadTask* pTask, const SThreadTaskParams& options);
virtual void UnregisterTask(IThreadTask* pTask);
virtual void SetMaxThreadCount(int nMaxThreads);
virtual void SetThreadName(threadID dwThreadId, const char* sThreadName);
virtual const char* GetThreadName(threadID dwThreadId);
virtual threadID GetThreadByName(const char* sThreadName);
// Thread pool framework
virtual ThreadPoolHandle CreateThreadsPool(const ThreadPoolDesc& desc);
virtual const bool DestroyThreadsPool(const ThreadPoolHandle& handle);
virtual const bool GetThreadsPoolDesc(const ThreadPoolHandle handle, ThreadPoolDesc* pDesc) const;
virtual const bool SetThreadsPoolAffinity(const ThreadPoolHandle handle, const ThreadPoolAffinityMask AffinityMask);
virtual void MarkThisThreadForDebugging(const char* name, bool bDump);
//////////////////////////////////////////////////////////////////////////
// This is on update function of the main thread.
void OnUpdate();
void AddSystemThread(threadID nThreadId);
void RemoveSystemThread(threadID nThreadId);
// Balancing tasks in the pool between threads
void BalanceThreadsPool(const ThreadPoolHandle& handle);
void BalanceThreadInPool(CThreadTask_Thread* pFreeThread, Threads* pThreads = NULL);
private:
void ScheduleTask(SThreadTaskInfo* pTaskInfo);
void RescheduleTasks();
private:
// User created threads pools
mutable CryReadModifyLock m_threadsPoolsLock;
ThreadsPools m_threadsPools;
// Physical threads available to system.
Threads m_threads;
// Threads with single blocking task attached.
Threads m_blockingThreads;
typedef CryMT::CLocklessPointerQueue<SThreadTaskInfo> Tasks;
Tasks m_unassignedTasks;
mutable CryCriticalSection m_threadNameLock;
mutable CryCriticalSection m_threadRemove;
typedef std::map<threadID, string> ThreadNames;
ThreadNames m_threadNames;
mutable CryCriticalSection m_systemThreadsLock;
std::vector<threadID> m_systemThreads;
// Max threads that can be executed at same time.
int m_nMaxThreads;
};
#endif // CRYINCLUDE_CRYSYSTEM_THREADTASK_H

@ -1,46 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "CrySystem_precompiled.h"
#include <AzTest/AzTest.h>
#include <Cry_Math.h>
namespace UnitTest
{
class CryMathTestFixture
: public ::testing::Test
{};
#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS
TEST_F(CryMathTestFixture, DISABLED_InverserSqrt_HasAtLeast22BitsOfAccuracy)
#else
TEST_F(CryMathTestFixture, InverserSqrt_HasAtLeast22BitsOfAccuracy)
#endif
{
float testFloat(0.336950600);
const float result = isqrt_safe_tpl(testFloat * testFloat);
const float epsilon = 0.00001f;
EXPECT_NEAR(2.96779, result, epsilon);
}
#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS
TEST_F(CryMathTestFixture, DISABLED_SimdSqrt_HasAtLeast23BitsOfAccuracy)
#else
TEST_F(CryMathTestFixture, SimdSqrt_HasAtLeast23BitsOfAccuracy)
#endif
{
float testFloat(3434.34839439);
const float result = sqrt_tpl(testFloat);
const float epsilon = 0.00001f;
EXPECT_NEAR(58.60331, result, epsilon);
}
}

@ -1,141 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "CrySystem_precompiled.h"
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/UnitTest.h>
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/IO/SystemFile.h> // for max path decl
#include <AzCore/std/parallel/thread.h>
#include <AzCore/std/parallel/semaphore.h>
#include <AzCore/std/functional.h> // for function<> in the find files callback.
#include <AzFramework/IO/LocalFileIO.h>
#include <AzFramework/Archive/ArchiveFileIO.h>
#include <AzFramework/Archive/Archive.h>
#include <AzFramework/Archive/INestedArchive.h>
#include <ILevelSystem.h>
namespace CryPakUnitTests
{
#if defined(AZ_PLATFORM_WINDOWS)
// Note: none of the below is really a unit test, its all basic feature tests
// for critical functionality
class Integ_CryPakUnitTests
: public ::testing::Test
{
protected:
bool IsPackValid(const char* path)
{
AZ::IO::IArchive* pak = gEnv->pCryPak;
if (!pak)
{
return false;
}
if (!pak->OpenPack(path, AZ::IO::IArchive::FLAGS_PATH_REAL))
{
return false;
}
pak->ClosePack(path);
return true;
}
};
TEST_F(Integ_CryPakUnitTests, TestCryPakModTime)
{
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
ASSERT_NE(nullptr, fileIo);
AZ::IO::IArchive* pak = gEnv->pCryPak;
// repeat the following test multiple times, since timing (seconds) can affect it and it involves time!
for (int iteration = 0; iteration < 10; ++iteration)
{
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds{ 100 });
// helper paths and strings
AZStd::string gameFolder = fileIo->GetAlias("@usercache@");
AZStd::string testFile = "unittest.bin";
AZStd::string testFilePath = gameFolder + "\\" + testFile;
AZStd::string testPak = "unittest.pak";
AZStd::string testPakPath = gameFolder + "\\" + testPak;
AZStd::string zipCmd = "-zip=" + testPakPath;
// delete test files in case they already exist
fileIo->Remove(testFilePath.c_str());
pak->ClosePack(testPakPath);
fileIo->Remove(testPakPath.c_str());
// create a test file
char data[] = "unittest";
FILE* f = nullptr;
azfopen(&f, testFilePath.c_str(), "wb");
EXPECT_TRUE(f != nullptr); // file successfully opened for writing
EXPECT_TRUE(fwrite(data, sizeof(char), sizeof(data), f) == sizeof(data)); // file written to successfully
EXPECT_TRUE(fclose(f) == 0); // file closed successfully
AZ::IO::HandleType fDisk = pak->FOpen(testFilePath.c_str(), "rb");
EXPECT_TRUE(fDisk > 0); // opened file on disk successfully
uint64_t modTimeDisk = pak->GetModificationTime(fDisk); // high res mod time extracted from file on disk
EXPECT_TRUE(pak->FClose(fDisk) == 0); // file closed successfully
// create a low res copy of disk file's mod time
uint64_t absDiff, maxDiff = 20000000ul;
uint16_t dosDate, dosTime;
FILETIME ft;
LARGE_INTEGER lt;
ft.dwHighDateTime = modTimeDisk >> 32;
ft.dwLowDateTime = modTimeDisk & 0xFFFFFFFF;
EXPECT_TRUE(FileTimeToDosDateTime(&ft, &dosDate, &dosTime) != FALSE); // converted to DOSTIME successfully
ft.dwHighDateTime = 0;
ft.dwLowDateTime = 0;
EXPECT_TRUE(DosDateTimeToFileTime(dosDate, dosTime, &ft) != FALSE); // converted to FILETIME successfully
lt.HighPart = ft.dwHighDateTime;
lt.LowPart = ft.dwLowDateTime;
uint64_t modTimeDiskLowRes = lt.QuadPart;
absDiff = modTimeDiskLowRes >= modTimeDisk ? modTimeDiskLowRes - modTimeDisk : modTimeDisk - modTimeDiskLowRes;
EXPECT_LE(absDiff, maxDiff); // FILETIME (high res) and DOSTIME (low res) should be at most 2 seconds apart
gEnv->pResourceCompilerHelper->CallResourceCompiler(testFilePath.c_str(), zipCmd.c_str());
EXPECT_EQ(AZ::IO::ResultCode::Success, fileIo->Remove(testFilePath.c_str())); // test file on disk deleted successfully
EXPECT_TRUE(pak->OpenPack(testPakPath)); // opened pak successfully
AZ::IO::HandleType fPak = pak->FOpen(testFilePath.c_str(), "rb");
EXPECT_GT(fPak, 0); // file (in pak) opened correctly
uint64_t modTimePak = pak->GetModificationTime(fPak); // low res mod time extracted from file in pak
EXPECT_EQ(0, pak->FClose(fPak)); // file closed successfully
EXPECT_TRUE(pak->ClosePack(testPakPath)); // closed pak successfully
EXPECT_EQ(AZ::IO::ResultCode::Success, fileIo->Remove(testPakPath.c_str())); // test pak file deleted successfully
absDiff = modTimePak >= modTimeDisk ? modTimePak - modTimeDisk : modTimeDisk - modTimePak;
// compare mod times. They are allowed to be up to 2 seconds apart but no more
EXPECT_LE(absDiff, maxDiff); // FILETIME (disk) and DOSTIME (pak) should be at most 2 seconds apart
// note: Do not directly compare the disk time and pack time, the resolution drops the last digit off in some cases in pak
// it only has a 2 second resolution. you may compare to make sure that the pak time is WITHIN 2 seconds (as above) but not equal.
// we depend on the fact that crypak is rounding up, instead of down
EXPECT_GE(modTimePak, modTimeDisk);
}
}
#endif
}

@ -783,12 +783,6 @@ void CUNIXConsole::KeyEnter()
if (pushCommand)
{
CSystem* pSystem = static_cast<CSystem*>(gEnv->pSystem);
#if defined(CVARS_WHITELIST)
ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList();
bool execute = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(m_InputLine, false) : true;
if (execute)
#endif // defined(CVARS_WHITELIST)
{
m_CommandQueue.push_back(m_InputLine);
}

@ -140,147 +140,6 @@ void Command_SetWaitFrames(IConsoleCmdArgs* pCmd)
}
}
/*
CNotificationNetworkConsole
*/
#include <INotificationNetwork.h>
class CNotificationNetworkConsole
: public INotificationNetworkListener
{
private:
static const uint32 LENGTH_MAX = 256;
static CNotificationNetworkConsole* s_pInstance;
public:
static bool Initialize()
{
if (s_pInstance)
{
return true;
}
INotificationNetwork* pNotificationNetwork = gEnv->pSystem->GetINotificationNetwork();
if (!pNotificationNetwork)
{
return false;
}
s_pInstance = new CNotificationNetworkConsole();
pNotificationNetwork->ListenerBind("Command", s_pInstance);
return true;
}
static void Shutdown()
{
if (!s_pInstance)
{
return;
}
delete s_pInstance;
s_pInstance = NULL;
}
static void Update()
{
if (s_pInstance)
{
s_pInstance->ProcessCommand();
}
}
private:
CNotificationNetworkConsole()
{
m_pConsole = NULL;
m_commandBuffer[0][0] = '\0';
m_commandBuffer[1][0] = '\0';
m_commandBufferIndex = 0;
m_commandCriticalSection = ::CryCreateCriticalSection();
}
~CNotificationNetworkConsole()
{
if (m_commandCriticalSection)
{
::CryDeleteCriticalSection(m_commandCriticalSection);
}
}
private:
void ProcessCommand()
{
if (!ValidateConsole())
{
return;
}
char* command = NULL;
::CryEnterCriticalSection(m_commandCriticalSection);
if (*m_commandBuffer[m_commandBufferIndex])
{
command = m_commandBuffer[m_commandBufferIndex];
}
++m_commandBufferIndex &= 1;
::CryLeaveCriticalSection(m_commandCriticalSection);
if (command)
{
m_pConsole->ExecuteString(command);
*command = '\0';
}
}
bool ValidateConsole()
{
if (m_pConsole)
{
return true;
}
if (!gEnv->pConsole)
{
return false;
}
m_pConsole = gEnv->pConsole;
return true;
}
// INotificationNetworkListener
public:
void OnNotificationNetworkReceive(const void* pBuffer, size_t length)
{
if (!ValidateConsole())
{
return;
}
if (length > LENGTH_MAX)
{
length = LENGTH_MAX;
}
::CryEnterCriticalSection(m_commandCriticalSection);
::memcpy(m_commandBuffer[m_commandBufferIndex], pBuffer, length);
m_commandBuffer[m_commandBufferIndex][LENGTH_MAX - 1] = '\0';
::CryLeaveCriticalSection(m_commandCriticalSection);
}
private:
IConsole* m_pConsole;
char m_commandBuffer[2][LENGTH_MAX];
size_t m_commandBufferIndex;
void* m_commandCriticalSection;
};
CNotificationNetworkConsole* CNotificationNetworkConsole::s_pInstance = NULL;
void ConsoleShow(IConsoleCmdArgs*)
{
gEnv->pConsole->ShowConsole(true);
@ -359,8 +218,6 @@ CXConsole::CXConsole()
m_waitSeconds = 0.0f;
m_blockCounter = 0;
CNotificationNetworkConsole::Initialize();
AzFramework::ConsoleRequestBus::Handler::BusConnect();
AzFramework::CommandRegistrationBus::Handler::BusConnect();
@ -379,8 +236,6 @@ CXConsole::~CXConsole()
gEnv->pSystem->GetIRemoteConsole()->UnregisterListener(this);
}
CNotificationNetworkConsole::Shutdown();
if (!m_mapVariables.empty())
{
while (!m_mapVariables.empty())
@ -1205,8 +1060,6 @@ void CXConsole::Update()
}
}
}
CNotificationNetworkConsole::Update();
}
//enable this for now, we need it for profiling etc
@ -1749,11 +1602,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg)
int devOnlyMask = VF_DEV_ONLY;
int dediOnlyMask = VF_DEDI_ONLY;
int excludeMask = cheatMask | constMask | readOnlyMask | devOnlyMask | dediOnlyMask;
#if defined(CVARS_WHITELIST)
CSystem* pSystem = static_cast<CSystem*>(gEnv->pSystem);
ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList();
bool excludeWhitelist = true;
#endif // defined(CVARS_WHITELIST)
if (numArgs > 1)
{
@ -1786,13 +1634,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg)
excludeMask &= ~dediOnlyMask;
}
#if defined(CVARS_WHITELIST)
if (azstricmp(arg, "whitelist") == 0)
{
excludeWhitelist = false;
}
#endif // defined(CVARS_WHITELIST)
--numArgs;
}
}
@ -1810,11 +1651,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg)
int devOnlyFlags = (command.m_nFlags & devOnlyMask);
int dediOnlyFlags = (command.m_nFlags & dediOnlyMask);
bool shouldLog = ((cheatFlags | devOnlyFlags | dediOnlyFlags) == 0) || (((cheatFlags | devOnlyFlags | dediOnlyFlags) & ~excludeMask) != 0);
#if defined(CVARS_WHITELIST)
bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(command.m_sName, true) : true;
shouldLog &= (!whitelisted || (whitelisted & !excludeWhitelist));
#endif // defined(CVARS_WHITELIST)
if (shouldLog)
{
CryLogAlways("[CVARS]: [COMMAND] %s%s%s%s%s",
@ -1822,11 +1658,7 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg)
(cheatFlags != 0) ? " [VF_CHEAT]" : "",
(devOnlyFlags != 0) ? " [VF_DEV_ONLY]" : "",
(dediOnlyFlags != 0) ? " [VF_DEDI_ONLY]" : "",
#if defined(CVARS_WHITELIST)
(whitelisted == true) ? " [WHITELIST]" : ""
#else
""
#endif // defined(CVARS_WHITELIST)
);
++commandCount;
}
@ -1843,11 +1675,6 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg)
int devOnlyFlags = (flags & devOnlyMask);
int dediOnlyFlags = (flags & dediOnlyMask);
bool shouldLog = ((cheatFlags | constFlags | readOnlyFlags | devOnlyFlags | dediOnlyFlags) == 0) || (((cheatFlags | constFlags | readOnlyFlags | devOnlyFlags | dediOnlyFlags) & ~excludeMask) != 0);
#if defined(CVARS_WHITELIST)
bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(pVariable->GetName(), true) : true;
shouldLog &= (!whitelisted || (whitelisted & !excludeWhitelist));
#endif // defined(CVARS_WHITELIST)
if (shouldLog)
{
CryLogAlways("[CVARS]: [VARIABLE] %s%s%s%s%s%s%s",
@ -1857,11 +1684,7 @@ void CXConsole::AuditCVars(IConsoleCmdArgs* pArg)
(readOnlyFlags != 0) ? " [VF_READONLY]" : "",
(devOnlyFlags != 0) ? " [VF_DEV_ONLY]" : "",
(dediOnlyFlags != 0) ? " [VF_DEDI_ONLY]" : "",
#if defined(CVARS_WHITELIST)
(whitelisted == true) ? " [WHITELIST]" : ""
#else
""
#endif // defined(CVARS_WHITELIST)
);
++cvarCount;
}
@ -2520,11 +2343,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
}
}
//try to search in command list
#if defined(CVARS_WHITELIST)
CSystem* pSystem = static_cast<CSystem*>(gEnv->pSystem);
ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList();
#endif // defined(CVARS_WHITELIST)
bool bArgumentAutoComplete = false;
std::vector<string> matches;
@ -2565,10 +2383,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
string cmd = string(sVar) + " " + pArgumentAutoComplete->GetValue(i);
if (_strnicmp(m_sPrevTab.c_str(), cmd.c_str(), m_sPrevTab.length()) == 0)
{
#if defined(CVARS_WHITELIST)
bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(cmd, true) : true;
if (whitelisted)
#endif // defined(CVARS_WHITELIST)
{
bArgumentAutoComplete = true;
matches.push_back(cmd);
@ -2590,10 +2404,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
{
if (_strnicmp(m_sPrevTab.c_str(), itrCmds->first.c_str(), m_sPrevTab.length()) == 0)
{
#if defined(CVARS_WHITELIST)
bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(itrCmds->first, true) : true;
if (whitelisted)
#endif // defined(CVARS_WHITELIST)
{
matches.push_back((char* const)itrCmds->first.c_str());
}
@ -2613,10 +2423,6 @@ const char* CXConsole::ProcessCompletion(const char* szInputBuffer)
{//if(itrVars->first.compare(0,m_sPrevTab.length(),m_sPrevTab)==0)
if (_strnicmp(m_sPrevTab.c_str(), itrVars->first, m_sPrevTab.length()) == 0)
{
#if defined(CVARS_WHITELIST)
bool whitelisted = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(itrVars->first, true) : true;
if (whitelisted)
#endif // defined(CVARS_WHITELIST)
{
matches.push_back((char* const)itrVars->first);
}
@ -2990,12 +2796,6 @@ void CXConsole::ExecuteInputBuffer()
AddCommandToHistory(sTemp.c_str());
#if defined(CVARS_WHITELIST)
CSystem* pSystem = static_cast<CSystem*>(gEnv->pSystem);
ICVarsWhitelist* pCVarsWhitelist = pSystem->GetCVarsWhiteList();
bool execute = (pCVarsWhitelist) ? pCVarsWhitelist->IsWhiteListed(sTemp, false) : true;
if (execute)
#endif // defined(CVARS_WHITELIST)
{
ExecuteStringInternal(sTemp.c_str(), true); // from console
}

@ -1809,8 +1809,6 @@ XmlNodeRef XmlParserImp::ParseFile(const char* filename, XmlString& errorString,
ParseEnd();
}
SYNCHRONOUS_LOADING_TICK();
delete [] pFileContents;
return root;

@ -19,14 +19,11 @@ set(FILES
ConsoleBatchFile.cpp
ConsoleHelpGen.cpp
CryAsyncMemcpy.cpp
DebugCallStack.cpp
GeneralMemoryHeap.cpp
HandlerBase.cpp
IDebugCallStack.cpp
AsyncPakManager.cpp
Log.cpp
SystemRender.cpp
NotificationNetwork.cpp
PhysRenderer.cpp
ResourceManager.cpp
ServerHandler.cpp
@ -36,7 +33,6 @@ set(FILES
SystemCFG.cpp
SystemEventDispatcher.cpp
SystemInit.cpp
SystemScheduler.cpp
SystemWin32.cpp
Timer.cpp
UnixConsole.cpp
@ -52,7 +48,6 @@ set(FILES
ServerHandler.h
ServerThrottle.h
SyncLock.h
SystemScheduler.h
UnixConsole.h
SystemInit.h
XML/ReadWriteXMLSink.h
@ -63,12 +58,8 @@ set(FILES
ConsoleBatchFile.h
ConsoleHelpGen.h
CryWaterMark.h
DebugCallStack.h
GeneralMemoryHeap.h
IDebugCallStack.h
IThreadConfigManager.h
Log.h
NotificationNetwork.h
resource.h
SimpleStringPool.h
CrySystem_precompiled.h
@ -107,24 +98,12 @@ set(FILES
XML/WriteXMLSource.cpp
ZipFile.h
ZipFileFormat_info.h
ProfileLogSystem.cpp
Sampler.cpp
ProfileLogSystem.h
Sampler.h
LocalizedStringManager.cpp
LocalizedStringManager.h
CryThreadUtil_win32_thread.h
ThreadInfo.cpp
ThreadInfo.h
ThreadTask.h
ThreadTask.cpp
ThreadConfigManager.h
ThreadConfigManager.cpp
SystemThreading.cpp
ZLibCompressor.cpp
ZLibCompressor.h
SoftCode/SoftCodeMgr.cpp
SoftCode/SoftCodeMgr.h
Huffman.cpp
Huffman.h
RemoteConsole/RemoteConsole.cpp

@ -18,7 +18,5 @@ set(FILES
Tests/Test_Localization.cpp
Tests/test_Main.cpp
Tests/test_MaterialUtils.cpp
UnitTests/CryMathTests.cpp
UnitTests/CryPakUnitTests.cpp
DllMain.cpp
)

@ -1304,7 +1304,7 @@ namespace AZ
// Add all auto loadable non-asset gems to the list of gem modules to load
if (!moduleLoadData.m_autoLoad)
{
break;
continue;
}
for (AZ::OSString& dynamicLibraryPath : moduleLoadData.m_dynamicLibraryPaths)
{

@ -407,11 +407,6 @@ namespace AzFramework
{
if (input->m_state == InputChannel::State::Began)
{
if (input->m_state == InputChannel::State::Updated)
{
return;
}
m_translation |= translationFromKey(input->m_channelId);
if (m_translation != TranslationType::Nil)
{

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save