Merge remote-tracking branch 'upstream/main' into nvsickle/DebugInfoDisplay

This commit is contained in:
nvsickle
2021-05-14 10:27:33 -07:00
698 changed files with 4528 additions and 41223 deletions
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:45b58009dc2f9340e08cafd5e68f142d15d77e19e7cef142933f2dff3cfb9293
size 38352
@@ -68,7 +68,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
TEST_SUITE periodic
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/scripting/TestSuite_Active.py
TIMEOUT 3000
TIMEOUT 1500
RUNTIME_DEPENDENCIES
Legacy::Editor
AZ::AssetProcessor
@@ -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.
"""
@@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568856
Test Case Title: Multiple Entities can be targeted in the Debugger tool
"""
@@ -25,20 +21,20 @@ class Tests():
GENERAL_WAIT = 0.5 # seconds
def Debugging_TargetMultipleEntities():
def Debugger_HappyPath_TargetMultipleEntities():
"""
Summary:
Multiple Entities can be targeted in the Debugger tool
Expected Behavior:
Selected files can be checked for logging.
Multiple selected files can be checked for logging.
Upon checking, checkboxes of the parent folders change to either full or partial check.
Test Steps:
1) Create temp level
2) Create two entities with scriptcanvas components
3) Set values for scriptcanvas
4) Open Script Canvas window and get sc opbject
4) Open Script Canvas window and get sc object
5) Open Debugging(Logging) window
6) Click on Entities tab in logging window
7) Verify if the scriptcanvas exist under entities
@@ -53,7 +49,6 @@ def Debugging_TargetMultipleEntities():
:return: None
"""
from PySide2 import QtWidgets
from PySide2.QtCore import Qt
import azlmbr.legacy.general as general
@@ -140,4 +135,4 @@ if __name__ == "__main__":
imports.init()
from utils import Report
Report.start_test(Debugging_TargetMultipleEntities)
Report.start_test(Debugger_HappyPath_TargetMultipleEntities)
@@ -7,29 +7,25 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569137
Test Case Title: Multiple Graphs can be targeted in the Debugger tool
"""
# fmt: off
class Tests():
select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected")
select_multiple_targets = ("Multiple targets are selected", "Multiple targets are not selected")
# fmt: on
GENERAL_WAIT = 0.5 # seconds
def Debugging_TargetMultipleGraphs():
def Debugger_HappyPath_TargetMultipleGraphs():
"""
Summary:
Multiple Graphs can be targeted in the Debugger tool
Expected Behavior:
Selected files can be checked for logging.
Multiple elected files can be checked for logging.
Upon checking, checkboxes of the parent folders change to either full or partial check.
Test Steps:
@@ -49,7 +45,6 @@ def Debugging_TargetMultipleGraphs():
:return: None
"""
from PySide2 import QtWidgets
from PySide2.QtCore import Qt
import azlmbr.legacy.general as general
@@ -106,7 +101,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(Debugging_TargetMultipleGraphs)
Report.start_test(Debugger_HappyPath_TargetMultipleGraphs)
@@ -7,12 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569049
Test Case Title: Edit > Undo undoes the last action
Test case ID: T92569051
Test Case Title: Edit > Redo redoes the last undone action
"""
@@ -24,7 +18,7 @@ class Tests():
# fmt: on
def EditMenu_UndoRedo():
def EditMenu_Default_UndoRedo():
"""
Summary:
Edit > Undo undoes the last action
@@ -33,8 +27,8 @@ def EditMenu_UndoRedo():
redo it and verify if the variable is created again.
Expected Behavior:
The last action is undone.
The last undone action is redone.
The last action is undone upon selecting Undo.
The last undone action is redone upon selecting Redo.
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
@@ -44,7 +38,7 @@ def EditMenu_UndoRedo():
5) Create new variable
6) Verify if the variable is created initially
7) Trigger Undo action and verify if variable is removed in Variable Manager
8) Trigger Redo action and verify if variable is readded in Variable Manager
8) Trigger Redo action and verify if variable is re-added in Variable Manager
9) Close SC window
Note:
@@ -54,13 +48,12 @@ def EditMenu_UndoRedo():
:return: None
"""
from PySide2 import QtWidgets, QtCore
import azlmbr.legacy.general as general
import pyside_utils
import azlmbr.legacy.general as general
# 1) Open Script Canvas window
general.idle_enable(True)
general.open_pane("Script Canvas")
@@ -115,7 +108,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(EditMenu_UndoRedo)
Report.start_test(EditMenu_Default_UndoRedo)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562978
Test Case Title: Script Canvas Component can be added to an entity
"""
@@ -23,13 +20,13 @@ class Tests():
# fmt: on
def Entity_AddScriptCanvasComponent():
def Entity_HappyPath_AddScriptCanvasComponent():
"""
Summary:
verify if Script Canvas component can be added to Entity without any issue
Script Canvas Component can be added to an entity
Expected Behavior:
Script Canvas Component is added to the entity successfully without issue.
Script Canvas Component is added to the entity successfully without issue
Test Steps:
1) Create temp level
@@ -46,7 +43,6 @@ def Entity_AddScriptCanvasComponent():
:return: None
"""
from utils import TestHelper as helper
from utils import Tracer
from editor_entity_utils import EditorEntity
@@ -84,4 +80,4 @@ if __name__ == "__main__":
imports.init()
from utils import Report
Report.start_test(Entity_AddScriptCanvasComponent)
Report.start_test(Entity_HappyPath_AddScriptCanvasComponent)
@@ -7,22 +7,15 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569037
Test Case Title: File > New Script creates a new script
Test case ID: T92569039
Test Case Title: File > Open opens the Open... dialog
"""
import os
import sys
from PySide2 import QtWidgets
import azlmbr.legacy.general as general
import editor_python_test_tools.pyside_utils as pyside_utils
from editor_python_test_tools.utils import Report
import azlmbr.legacy.general as general
# fmt: off
class Tests():
new_action = "File->New action working as expected"
@@ -33,10 +26,11 @@ class Tests():
GENERAL_WAIT = 0.5 # seconds
class TestFileMenuNewOpen:
class TestFileMenuDefaultNewOpen:
"""
Summary:
When clicked on File->New, new script opens and File->Open should open the FileBrowser
When clicked on File->New, new script opens
File->Open should open the FileBrowser
Expected Behavior:
New and Open actions should work as expected.
@@ -92,5 +86,5 @@ class TestFileMenuNewOpen:
general.close_pane("Script Canvas")
test = TestFileMenuNewOpen()
test = TestFileMenuDefaultNewOpen()
test.run_test()
@@ -7,24 +7,17 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92563070
Test Case Title: Graphs can be closed by clicking X on the Graph name tab
Test case ID: T92563068
Test Case Title: Save Prompt: User is prompted to save a graph on close after
creating a new graph
"""
import os
import sys
from PySide2 import QtWidgets
import azlmbr.legacy.general as general
import editor_python_test_tools.pyside_utils as pyside_utils
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.utils import Report
import azlmbr.legacy.general as general
# fmt: off
class Tests():
new_graph = "New graph created"
@@ -36,14 +29,15 @@ class Tests():
GENERAL_WAIT = 0.5 # seconds
class TestGraphCloseSavePrompt:
class TestGraphClose_Default_SavePrompt:
"""
Summary:
The graph is closed when x button is clicked.
Save Prompt is opened before closing.
Expected Behavior:
New and Open actions should work as expected.
The Graph is closed.
Upon closing the graph, User is prompted whether or not to save changes.
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
@@ -104,5 +98,5 @@ class TestGraphCloseSavePrompt:
general.close_pane("Script Canvas")
test = TestGraphCloseSavePrompt()
test = TestGraphClose_Default_SavePrompt()
test.run_test()
@@ -7,12 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569079
Test Case Title: View > Zoom In zooms the graph in
Test case ID: T92569081
Test Case Title: View > Zoom In zooms the graph out
"""
@@ -26,7 +20,7 @@ class Tests():
GENERAL_WAIT = 0.5 # seconds
def Graph_ZoomInZoomOut():
def Graph_HappyPath_ZoomInZoomOut():
"""
Summary:
The graph can be zoomed in and zoomed out.
@@ -91,7 +85,7 @@ def Graph_ZoomInZoomOut():
zin = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomIn", "type": QtWidgets.QAction})
zin.trigger()
result = helper.wait_for_condition(
lambda: curr_m11 < graphics_view.transform().m11() and curr_m22 < graphics_view.transform().m22(), GENERAL_WAIT,
lambda: curr_m11 < graphics_view.transform().m11() and curr_m22 < graphics_view.transform().m22(), GENERAL_WAIT
)
Report.result(Tests.zoom_in, result)
@@ -100,7 +94,7 @@ def Graph_ZoomInZoomOut():
zout = pyside_utils.find_child_by_pattern(sc_main, {"objectName": "action_ZoomOut", "type": QtWidgets.QAction})
zout.trigger()
result = helper.wait_for_condition(
lambda: curr_m11 > graphics_view.transform().m11() and curr_m22 > graphics_view.transform().m22(), GENERAL_WAIT,
lambda: curr_m11 > graphics_view.transform().m11() and curr_m22 > graphics_view.transform().m22(), GENERAL_WAIT
)
Report.result(Tests.zoom_out, result)
@@ -112,7 +106,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(Graph_ZoomInZoomOut)
Report.start_test(Graph_HappyPath_ZoomInZoomOut)
@@ -13,5 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
def init():
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../EditorPythonTestTools/editor_python_test_tools')
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../automatedtesting_shared")
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + "/../EditorPythonTestTools/editor_python_test_tools")
@@ -7,11 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568942
Test Case Title: Clicking the "+" button and selecting "New Script Event" opens the
Asset Editor with a new Script Event asset
"""
from PySide2 import QtWidgets
@@ -35,11 +30,10 @@ GENERAL_WAIT = 0.5 # seconds
class TestAssetEditor_NewScriptEvent:
"""
Summary:
Clicking the "+" button in Node Palette and creating New Script Event opens Asset Editor
Verifying logic flow of the "+" button on the Script Canvas pane's Node Palette is as expected
Expected Behavior:
Clicking the "+" button and selecting "New Script Event" opens the Asset Editor with a
new Script Event asset
Clicking the "+" button and selecting "New Script Event" opens the Asset Editor with a new Script Event asset
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562988
Test Case Title: Left-click/double click expands and collapses node categories
"""
@@ -123,6 +120,8 @@ def NodeCategory_ExpandOnClick():
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(NodeCategory_ExpandOnClick)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568982
Test Case Title: Renaming variables in the Node Inspector
"""
@@ -24,7 +21,7 @@ class Tests():
GENERAL_WAIT = 0.5 # seconds
def NodeInspector_RenameVariable():
def NodeInspector_HappyPath_VariableRenames():
"""
Summary:
Renaming variables in the Node Inspector, renames the actual variable.
@@ -50,16 +47,16 @@ def NodeInspector_RenameVariable():
:return: None
"""
TEST_NAME = "test name"
from PySide2 import QtWidgets, QtCore, QtTest
from PySide2.QtCore import Qt
import azlmbr.legacy.general as general
import pyside_utils
from utils import TestHelper as helper
import azlmbr.legacy.general as general
TEST_NAME = "test name"
def open_tool(sc, dock_widget_name, pane_name):
if sc.findChild(QtWidgets.QDockWidget, dock_widget_name) is None:
action = pyside_utils.find_child_by_pattern(sc, {"text": pane_name, "type": QtWidgets.QAction})
@@ -120,12 +117,10 @@ def NodeInspector_RenameVariable():
general.close_pane("Script Canvas")
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(NodeInspector_RenameVariable)
Report.start_test(NodeInspector_HappyPath_VariableRenames)
@@ -7,30 +7,27 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92568940
Test Case Title: Categories and Nodes can be selected
"""
# fmt: off
class Tests():
category_selected = ("Category can be selected", "Category cannot be selected")
node_selected = ("Node can be selected", "Node cannot be selected")
category_selected = ("Category can be selected", "Category cannot be selected")
node_selected = ("Node can be selected", "Node cannot be selected")
# fmt: on
GENERAL_WAIT = 0.5 # seconds
def NodePalette_SelectNode():
def NodePalette_HappyPath_CanSelectNode():
"""
Summary:
Categories and Nodes can be selected
Expected Behavior:
When clicked on Node Palette, nodes and categories can be selected.
A category can be selected inside the Node Palette
A Node can be selected inside the Node Palette
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
@@ -53,11 +50,12 @@ def NodePalette_SelectNode():
NODE = "Find Path To Entity"
from PySide2 import QtWidgets
import azlmbr.legacy.general as general
import pyside_utils
from utils import TestHelper as helper
import azlmbr.legacy.general as general
# 1) Open Script Canvas window (Tools > Script Canvas)
general.idle_enable(True)
general.open_pane("Script Canvas")
@@ -97,7 +95,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(NodePalette_SelectNode)
Report.start_test(NodePalette_HappyPath_CanSelectNode)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562993
Test Case Title: Clicking the X button on the Search Box clears the currently entered string
"""
@@ -20,14 +17,14 @@ class Tests():
# fmt: on
def NodePalette_ClearSelection():
def NodePalette_HappyPath_ClearSelection():
"""
Summary:
We enter some string in the Node Palette Search box, and click on the X button to verify if the
search string got cleared.
Clicking the X button on the Search Box clears the currently entered string
Expected Behavior:
Clicking the X button on the Search Box clears the currently entered string
After entering a string value into the Node Palette's search box and click on
the X button, the search box should be cleared
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
@@ -44,15 +41,13 @@ def NodePalette_ClearSelection():
:return: None
"""
from PySide2 import QtWidgets
import pyside_utils
from utils import TestHelper as helper
import azlmbr.legacy.general as general
import pyside_utils
TEST_STRING = "Test String"
# 1) Open Script Canvas window (Tools > Script Canvas)
@@ -90,4 +85,4 @@ if __name__ == "__main__":
imports.init()
from utils import Report
Report.start_test(NodePalette_ClearSelection)
Report.start_test(NodePalette_HappyPath_ClearSelection)
@@ -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)
@@ -7,33 +7,30 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702821 // C1702832
Test Case Title: Retain visibility, size and location upon Script Canvas restart
"""
# fmt: off
class Tests():
relaunch_sc = ("Script Canvas window is relaunched", "Failed to relaunch Script Canvas window")
test_panes_visible = ("All the test panes are opened", "Failed to open one or more test panes")
close_pane_1 = ("Test pane 1 is closed", "Failed to close test pane 1")
visiblity_retained = ("Test pane retained its visiblity on SC restart", "Failed to retain visiblity of test pane on SC restart")
resize_pane_3 = ("Test pane 3 resized successfully", "Failed to resize Test pane 3")
size_retained = ("Test pane retained its size on SC restart", "Failed to retain size of test pane on SC restart")
location_changed = ("Location of test pane 2 changed successfully", "Failed to change locatio of test pane 2")
location_retained = ("Test pane retained its location on SC restart", "Failed to retain location of test pane on SC restart")
relaunch_sc = ("Script Canvas window is relaunched", "Failed to relaunch Script Canvas window")
test_panes_visible = ("All the test panes are opened", "Failed to open one or more test panes")
close_pane_1 = ("Test pane 1 is closed", "Failed to close test pane 1")
visibility_retained = ("Test pane retained its visibility on SC restart", "Failed to retain visibility of test pane on SC restart")
resize_pane_3 = ("Test pane 3 resized successfully", "Failed to resize Test pane 3")
size_retained = ("Test pane retained its size on SC restart", "Failed to retain size of test pane on SC restart")
location_changed = ("Location of test pane 2 changed successfully", "Failed to change location of test pane 2")
location_retained = ("Test pane retained its location on SC restart", "Failed to retain location of test pane on SC restart")
# fmt: on
def Pane_RetainOnSCRestart():
def Pane_Default_RetainOnSCRestart():
"""
Summary:
The Script Canvas window is opened to verify if Script canvas panes can retain its visibility, size and location
upon ScriptCanvas restart.
Expected Behavior:
The ScriptCanvas pane retain it's visiblity, size and location upon ScriptCanvas restart.
The ScriptCanvas pane retain it's visibility, size and location upon ScriptCanvas restart.
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
@@ -42,7 +39,7 @@ def Pane_RetainOnSCRestart():
4) Change dock location of test pane 2
5) Resize test pane 3
6) Relaunch Script Canvas
7) Verify if test pane 1 retain its visiblity
7) Verify if test pane 1 retain its visibility
8) Verify if location of test pane 2 is retained
9) Verify if size of test pane 3 is retained
10) Restore default layout and close SC window
@@ -55,6 +52,10 @@ def Pane_RetainOnSCRestart():
:return: None
"""
# Pyside imports
from PySide2 import QtCore, QtWidgets
from PySide2.QtCore import Qt
# Helper imports
from utils import Report
from utils import TestHelper as helper
@@ -63,11 +64,6 @@ def Pane_RetainOnSCRestart():
# Open 3D Engine Imports
import azlmbr.legacy.general as general
# Pyside imports
from PySide2 import QtCore, QtWidgets
from PySide2.QtCore import Qt
# Constants
TEST_PANE_1 = "NodePalette" # test visibility
TEST_PANE_2 = "VariableManager" # test location
TEST_PANE_3 = "NodeInspector" # test size
@@ -128,10 +124,10 @@ def Pane_RetainOnSCRestart():
sc_visible = helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0)
Report.result(Tests.relaunch_sc, sc_visible)
# 7) Verify if test pane 1 retain its visiblity
# 7) Verify if test pane 1 retain its visibility
editor_window = pyside_utils.get_editor_main_window()
sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
Report.result(Tests.visiblity_retained, not find_pane(sc, TEST_PANE_1).isVisible())
Report.result(Tests.visibility_retained, not find_pane(sc, TEST_PANE_1).isVisible())
# 8) Verify if location of test pane 2 is retained
sc_main = sc.findChild(QtWidgets.QMainWindow)
@@ -156,7 +152,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(Pane_RetainOnSCRestart)
Report.start_test(Pane_Default_RetainOnSCRestart)
@@ -7,24 +7,21 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702824
Test Case Title: Docking
"""
# fmt: off
class Tests():
pane_opened = ("Pane is opened successfully", "Failed to open pane")
dock_pane = ("Pane is docked successfully", "Failed to dock Pane into one or more allowed area")
pane_opened = ("Pane is opened successfully", "Failed to open pane")
dock_pane = ("Pane is docked successfully", "Failed to dock Pane into one or more allowed area")
# fmt: on
def Docking_Pane():
def Pane_HappyPath_DocksProperly():
"""
Summary:
The Script Canvas window is opened to verify if Script canvas panes can be docked into
every possible area of Script Canvas main window.
The Script Canvas window is opened to verify if Script canvas panes can be docked into every
possible area of Script Canvas main window. (top, bottom, right and left sides of the window)
Expected Behavior:
The pane docks successfully.
@@ -43,12 +40,6 @@ def Docking_Pane():
:return: None
"""
# Helper imports
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
import editor_python_test_tools.pyside_utils as pyside_utils
@@ -110,7 +101,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(Docking_Pane)
Report.start_test(Pane_HappyPath_DocksProperly)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702834 // C1702823
Test Case Title: Opening pane // Closing pane
"""
@@ -21,13 +18,13 @@ class Tests():
# fmt: on
def Opening_Closing_Pane():
def Pane_HappyPath_OpenCloseSuccessfully():
"""
Summary:
The Script Canvas window is opened to verify if Script canvas panes can be opened and closed.
The Script Canvas window is opened to verify if Script Canvas panes can be opened and closed.
Expected Behavior:
The pane opens and closes successfully.
The panes open and close successfully.
Test Steps:
1) Open Script Canvas window (Tools > Script Canvas)
@@ -113,7 +110,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(Opening_Closing_Pane)
Report.start_test(Pane_HappyPath_OpenCloseSuccessfully)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702829
Test Case Title: Resizing pane
"""
@@ -20,10 +17,10 @@ class Tests():
# fmt: on
def Resizing_Pane():
def Pane_HappyPath_ResizesProperly():
"""
Summary:
The Script Canvas window is opened to verify if Script canvas panes can be resized and scaled
The Script Canvas window is opened to verify if Script Canvas panes can be resized and scaled
Expected Behavior:
The pane is resized and scaled appropriately.
@@ -32,7 +29,7 @@ def Resizing_Pane():
1) Open Script Canvas window (Tools > Script Canvas)
2) Restore default layout
3) Make sure pane is opened
4) Resize pane
4) Resize pane and verify change
5) Restore default layout
6) Close Script Canvas window
@@ -44,6 +41,8 @@ def Resizing_Pane():
:return: None
"""
from PySide2 import QtWidgets
from editor_python_test_tools.utils import Report
from editor_python_test_tools.utils import TestHelper as helper
import editor_python_test_tools.pyside_utils as pyside_utils
@@ -51,9 +50,6 @@ def Resizing_Pane():
# Open 3D Engine imports
import azlmbr.legacy.general as general
# Pyside imports
from PySide2 import QtWidgets
PANE_WIDGET = "NodePalette"
SCALE_INT = 10
@@ -86,7 +82,7 @@ def Resizing_Pane():
Report.result(Tests.open_pane, pane.isVisible())
# 4) Resize pane
# 4) Resize pane and verify change
initial_size = pane.frameSize()
pane.resize(initial_size.width() + SCALE_INT, initial_size.height() + SCALE_INT)
new_size = pane.frameSize()
@@ -109,4 +105,4 @@ if __name__ == "__main__":
imports.init()
from editor_python_test_tools.utils import Report
Report.start_test(Resizing_Pane)
Report.start_test(Pane_HappyPath_ResizesProperly)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C1702825 // C1702831
Test Case Title: Undocking // Closing script canvas with the pane floating
"""
@@ -21,7 +18,7 @@ class Tests():
# fmt: on
def UnDockedPane_CloseSCWindow():
def Pane_Undocked_ClosesSuccessfully():
"""
Summary:
The Script Canvas window is opened with one of the pane undocked.
@@ -45,6 +42,8 @@ def UnDockedPane_CloseSCWindow():
:return: None
"""
from PySide2 import QtWidgets
# Helper imports
from utils import Report
from utils import TestHelper as helper
@@ -53,9 +52,6 @@ def UnDockedPane_CloseSCWindow():
# Open 3D Engine imports
import azlmbr.legacy.general as general
# Pyside imports
from PySide2 import QtWidgets
TEST_PANE = "NodePalette" # Chosen most commonly used pane
def click_menu_option(window, option_text):
@@ -120,7 +116,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(UnDockedPane_CloseSCWindow)
Report.start_test(Pane_Undocked_ClosesSuccessfully)
@@ -7,29 +7,26 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569253 // T92569254
Test Case Title: On Entity Activated // On Entity Deactivated
"""
# fmt: off
class Tests():
level_created = ("Successfully created temp level", "Failed to create temp level")
controller_exists = ("Successfully found controller entity", "Failed to find controller entity")
activated_exists = ("Successfully found activated entity", "Failed to find activated entity")
deactivated_exists = ("Successfully found deactivated entity","Failed to find deactivated entity")
start_states_correct = ("Start states set up successfully", "Start states set up incorrectly")
game_mode_entered = ("Successfully entered game mode" "Failed to enter game mode")
lines_found = ("Successfully found expected prints", "Failed to find expected prints")
game_mode_exited = ("Successfully exited game mode" "Failed to exit game mode")
level_created = ("Successfully created temp level", "Failed to create temp level")
controller_exists = ("Successfully found controller entity", "Failed to find controller entity")
activated_exists = ("Successfully found activated entity", "Failed to find activated entity")
deactivated_exists = ("Successfully found deactivated entity", "Failed to find deactivated entity")
start_states_correct = ("Start states set up successfully", "Start states set up incorrectly")
game_mode_entered = ("Successfully entered game mode" "Failed to enter game mode")
lines_found = ("Successfully found expected prints", "Failed to find expected prints")
game_mode_exited = ("Successfully exited game mode" "Failed to exit game mode")
# fmt: on
def OnEntityActivatedDeactivated_PrintMessage():
def ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage():
"""
Summary:
Verify that the On Entity Activation node is working as expected
Verify that the On Entity Activated/On Entity Deactivated nodes are working as expected
Expected Behavior:
Upon entering game mode, the Controller entity will wait 1 second and then activate the ActivationTest
@@ -54,9 +51,9 @@ def OnEntityActivatedDeactivated_PrintMessage():
"""
import os
from utils import TestHelper as helper
from editor_entity_utils import EditorEntity as Entity
from utils import Report
from utils import TestHelper as helper
from utils import Tracer
import azlmbr.legacy.general as general
@@ -68,33 +65,45 @@ def OnEntityActivatedDeactivated_PrintMessage():
controller_dict = {
"name": "Controller",
"status": "active",
"path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "controller.scriptcanvas")
"path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "controller.scriptcanvas"),
}
activated_dict = {
"name": "ActivationTest",
"status": "inactive",
"path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "activator.scriptcanvas")
"path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "activator.scriptcanvas"),
}
deactivated_dict = {
"name": "DeactivationTest",
"status": "active",
"path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "deactivator.scriptcanvas")
"path": os.path.join("ScriptCanvas", "OnEntityActivatedScripts", "deactivator.scriptcanvas"),
}
def get_asset(asset_path):
return azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False)
return azlmbr.asset.AssetCatalogRequestBus(
azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False
)
def setup_level():
def create_editor_entity(entity_dict:dict, entity_to_activate:EditorEntity=None, entity_to_deactivate:EditorEntity=None) -> EditorEntity:
def create_editor_entity(
entity_dict: dict, entity_to_activate: EditorEntity = None, entity_to_deactivate: EditorEntity = None
) -> EditorEntity:
entity = Entity.create_editor_entity(entity_dict["name"])
entity.set_start_status(entity_dict["status"])
sc_component = entity.add_component("Script Canvas")
sc_component.set_component_property_value("Script Canvas Asset|Script Canvas Asset", get_asset(entity_dict["path"]))
sc_component.set_component_property_value(
"Script Canvas Asset|Script Canvas Asset", get_asset(entity_dict["path"])
)
if entity_dict["name"] == "Controller":
sc_component.get_property_tree()
sc_component.set_component_property_value("Properties|Variable Fields|Variables|[0]|Name,Value|Datum|Datum|EntityToActivate", entity_to_activate.id)
sc_component.set_component_property_value("Properties|Variable Fields|Variables|[1]|Name,Value|Datum|Datum|EntityToDeactivate", entity_to_deactivate.id)
sc_component.set_component_property_value(
"Properties|Variable Fields|Variables|[0]|Name,Value|Datum|Datum|EntityToActivate",
entity_to_activate.id,
)
sc_component.set_component_property_value(
"Properties|Variable Fields|Variables|[1]|Name,Value|Datum|Datum|EntityToDeactivate",
entity_to_deactivate.id,
)
return entity
activated = create_editor_entity(activated_dict)
@@ -110,7 +119,7 @@ def OnEntityActivatedDeactivated_PrintMessage():
Report.critical_result(test_tuple, entity.id.IsValid())
return entity
def validate_start_state(entity:EditorEntity, expected_state:str):
def validate_start_state(entity: EditorEntity, expected_state: str):
"""
Validate that the starting state of the entity is correct, if it isn't then attempt to rectify and recheck.
:return: bool: Whether state is set as expected
@@ -176,8 +185,8 @@ def OnEntityActivatedDeactivated_PrintMessage():
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
imports.init()
from utils import Report
Report.start_test(OnEntityActivatedDeactivated_PrintMessage)
Report.start_test(ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage)
@@ -7,12 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: C92569165, C92569167, C92569168, C92569170
Test Case Title: Tools > Node Palette toggles the Node Palette
Tools > Node Inspector toggles the Node Inspector
Tools > Bookmarks toggles the Bookmarks
Tools > Variable Manager toggles the Variable Manager
"""
@@ -33,7 +27,7 @@ class Tests():
# fmt: on
def Toggle_ScriptCanvasTools():
def ScriptCanvasTools_Toggle_OpenCloseSuccess():
"""
Summary:
Toggle Node Palette, Node Inspector, Bookmarks and Variable Manager in Script Canvas.
@@ -58,6 +52,8 @@ def Toggle_ScriptCanvasTools():
:return: None
"""
from PySide2 import QtWidgets
from utils import Report
from utils import TestHelper as helper
import pyside_utils
@@ -65,9 +61,6 @@ def Toggle_ScriptCanvasTools():
# Open 3D Engine imports
import azlmbr.legacy.general as general
# Pyside imports
from PySide2 import QtWidgets
def click_menu_option(window, option_text):
action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction})
action.trigger()
@@ -126,7 +119,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(Toggle_ScriptCanvasTools)
Report.start_test(ScriptCanvasTools_Toggle_OpenCloseSuccess)
@@ -7,10 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92562986
Test Case Title: Changing the assigned Script Canvas Asset on an entity properly updates
level functionality
"""
@@ -24,7 +20,7 @@ class Tests():
# fmt: on
def ScriptCanvas_ChangingAssets():
def ScriptCanvas_ChangingAssets_ComponentStable():
"""
Summary:
Changing the assigned Script Canvas Asset on an entity properly updates level functionality
@@ -57,7 +53,6 @@ def ScriptCanvas_ChangingAssets():
import azlmbr.math as math
import azlmbr.asset as asset
import azlmbr.bus as bus
import azlmbr.paths as paths
LEVEL_NAME = "tmp_level"
ASSET_1 = os.path.join("scriptcanvas", "ScriptCanvas_TwoComponents0.scriptcanvas")
@@ -83,7 +78,6 @@ def ScriptCanvas_ChangingAssets():
Report.result(Tests.found_lines, find_expected_line(EXP_LINE))
helper.exit_game_mode(Tests.game_mode_exited)
# 1) Create temp level
general.idle_enable(True)
result = general.create_level_no_prompt(LEVEL_NAME, 128, 1, 512, True)
@@ -112,4 +106,4 @@ if __name__ == "__main__":
imports.init()
from utils import Report
Report.start_test(ScriptCanvas_ChangingAssets)
Report.start_test(ScriptCanvas_ChangingAssets_ComponentStable)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92563190
Test Case Title: A single Entity with two Script Canvas components works properly
"""
@@ -26,7 +23,7 @@ class LogLines:
expected_lines = ["Greetings from the first script", "Greetings from the second script"]
def ScriptCanvas_TwoComponents():
def ScriptCanvas_TwoComponents_InteractSuccessfully():
"""
Summary:
A test entity contains two Script Canvas components with different unique script canvas files.
@@ -57,6 +54,7 @@ def ScriptCanvas_TwoComponents():
import hydra_editor_utils as hydra
from utils import Report
from utils import Tracer
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.asset as asset
@@ -111,7 +109,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(ScriptCanvas_TwoComponents)
Report.start_test(ScriptCanvas_TwoComponents_InteractSuccessfully)
@@ -7,26 +7,23 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92563191
Test Case Title: Two Entities can use the same Graph asset successfully at RunTime
"""
# fmt: off
class Tests():
level_created = ("New level created", "New level not created")
level_created = ("New level created successfully", "New level failed to create")
game_mode_entered = ("Game Mode successfully entered", "Game mode failed to enter")
game_mode_exited = ("Game Mode successfully exited", "Game mode failed to exited")
found_lines = ("Expected log lines were found", "Expected log lines were not found")
# fmt: on
def ScriptCanvas_TwoEntities():
def ScriptCanvas_TwoEntities_UseSimultaneously():
"""
Summary:
Two Entities can use the same Graph asset successfully at RunTime. The script canvas asset
attached to the enties will print the respective entity names.
attached to the entities will print the respective entity names.
Expected Behavior:
When game mode is entered, respective strings of different entities should be printed.
@@ -48,9 +45,10 @@ def ScriptCanvas_TwoEntities():
import os
import hydra_editor_utils as hydra
from utils import TestHelper as helper
from utils import Tracer
import hydra_editor_utils as hydra
import azlmbr.legacy.general as general
import azlmbr.math as math
import azlmbr.asset as asset
@@ -103,4 +101,4 @@ if __name__ == "__main__":
imports.init()
from utils import Report
Report.start_test(ScriptCanvas_TwoEntities)
Report.start_test(ScriptCanvas_TwoEntities_UseSimultaneously)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92569013
Test Case Title: Script Event file can be created
"""
@@ -117,7 +114,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(CreateScriptEventFile)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92567320
Test Case Title: Script Events: Can send and receive a script event successfully
"""
@@ -23,7 +20,7 @@ class Tests():
# fmt: on
def ScriptEvents_SendReceiveSuccessfully():
def ScriptEvents_Default_SendReceiveSuccessfully():
"""
Summary:
An entity exists in the level that contains a Script Canvas component. In the graph is both a Send Event
@@ -103,7 +100,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(ScriptEvents_SendReceiveSuccessfully)
Report.start_test(ScriptEvents_Default_SendReceiveSuccessfully)
@@ -7,9 +7,6 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92567321
Test Case Title: Script Events: Can send and receive a script event across multiple entities successfully
"""
@@ -24,10 +21,11 @@ class Tests():
# fmt: on
def ScriptEvents_SendReceiveAcrossMultiple():
def ScriptEvents_HappyPath_SendReceiveAcrossMultiple():
"""
Summary:
EntityA and EntityB will be created in a level. Attached to both will be a Script Canvas component. The Script Event created for the test will be sent from EntityA to EntityB.
EntityA and EntityB will be created in a level. Attached to both will be a Script Canvas component.
The Script Event created for the test will be sent from EntityA to EntityB.
Expected Behavior:
The output of the Script Event should be printed to the console
@@ -49,7 +47,7 @@ def ScriptEvents_SendReceiveAcrossMultiple():
:return: None
"""
import os
from editor_entity_utils import EditorEntity as Entity
from utils import Report
from utils import TestHelper as helper
@@ -65,20 +63,19 @@ def ScriptEvents_SendReceiveAcrossMultiple():
"assetA": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}A.scriptcanvas"),
"assetB": os.path.join("ScriptCanvas", f"{ASSET_PREFIX}B.scriptcanvas"),
}
sc_for_entities = {
"EntityA": asset_paths["assetA"],
"EntityB": asset_paths["assetB"]
}
sc_for_entities = {"EntityA": asset_paths["assetA"], "EntityB": asset_paths["assetB"]}
EXPECTED_LINES = ["Incoming Message Received"]
def get_asset(asset_path):
return azlmbr.asset.AssetCatalogRequestBus(azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False)
return azlmbr.asset.AssetCatalogRequestBus(
azlmbr.bus.Broadcast, "GetAssetIdByPath", asset_path, azlmbr.math.Uuid(), False
)
def create_editor_entity(name, sc_asset):
entity = Entity.create_editor_entity(name)
sc_comp = entity.add_component("Script Canvas")
sc_comp.set_component_property_value("Script Canvas Asset|Script Canvas Asset", get_asset(sc_asset))
Report.critical_result(Tests.__dict__[name.lower()+"_created"], entity.id.isValid())
Report.critical_result(Tests.__dict__[name.lower() + "_created"], entity.id.isValid())
def locate_expected_lines(line_list: list):
found_lines = [printInfo.message.strip() for printInfo in section_tracer.prints]
@@ -112,8 +109,8 @@ def ScriptEvents_SendReceiveAcrossMultiple():
if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
imports.init()
from utils import Report
Report.start_test(ScriptEvents_SendReceiveAcrossMultiple)
Report.start_test(ScriptEvents_HappyPath_SendReceiveAcrossMultiple)
@@ -106,7 +106,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(ScriptEvents_ReturnSetType_Successfully)
@@ -29,79 +29,73 @@ TEST_DIRECTORY = os.path.dirname(__file__)
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
@pytest.mark.test_case_id("C1702834", "C1702823")
def test_Opening_Closing_Pane(self, request, workspace, editor, launcher_platform):
from . import Opening_Closing_Pane as test_module
def test_Pane_HappyPath_OpenCloseSuccessfully(self, request, workspace, editor, launcher_platform):
from . import Pane_HappyPath_OpenCloseSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("C1702824")
def test_Docking_Pane(self, request, workspace, editor, launcher_platform):
from . import Docking_Pane as test_module
def test_Pane_HappyPath_DocksProperly(self, request, workspace, editor, launcher_platform):
from . import Pane_HappyPath_DocksProperly as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("C1702829")
def test_Resizing_Pane(self, request, workspace, editor, launcher_platform):
from . import Resizing_Pane as test_module
def test_Pane_HappyPath_ResizesProperly(self, request, workspace, editor, launcher_platform):
from . import Pane_HappyPath_ResizesProperly as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92563190")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_ScriptCanvas_TwoComponents(self, request, workspace, editor, launcher_platform, level):
def test_ScriptCanvas_TwoComponents_InteractSuccessfully(self, request, workspace, editor, launcher_platform, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptCanvas_TwoComponents as test_module
from . import ScriptCanvas_TwoComponents_InteractSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92562986")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_ScriptCanvas_ChangingAssets(self, request, workspace, editor, launcher_platform, project, level):
def test_ScriptCanvas_ChangingAssets_ComponentStable(self, request, workspace, editor, launcher_platform, project, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptCanvas_ChangingAssets as test_module
from . import ScriptCanvas_ChangingAssets_ComponentStable as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92569079", "T92569081")
def test_Graph_ZoomInZoomOut(self, request, workspace, editor, launcher_platform):
from . import Graph_ZoomInZoomOut as test_module
def test_Graph_HappyPath_ZoomInZoomOut(self, request, workspace, editor, launcher_platform):
from . import Graph_HappyPath_ZoomInZoomOut as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92568940")
def test_NodePalette_SelectNode(self, request, workspace, editor, launcher_platform):
from . import NodePalette_SelectNode as test_module
def test_NodePalette_HappyPath_CanSelectNode(self, request, workspace, editor, launcher_platform):
from . import NodePalette_HappyPath_CanSelectNode as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92569253")
@pytest.mark.test_case_id("T92569254")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level):
def test_ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage(self, request, workspace, editor, launcher_platform, project, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import OnEntityActivatedDeactivated_PrintMessage as test_module
from . import ScriptCanvasComponent_OnEntityActivatedDeactivated_PrintMessage as test_module
self._run_test(request, workspace, editor, test_module)
<<<<<<< HEAD
def test_NodePalette_HappyPath_ClearSelection(self, request, workspace, editor, launcher_platform, project):
from . import NodePalette_HappyPath_ClearSelection as 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
>>>>>>> main
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92563191")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_ScriptCanvas_TwoEntities(self, request, workspace, editor, launcher_platform, project, level):
def test_ScriptCanvas_TwoEntities_UseSimultaneously(self, request, workspace, editor, launcher_platform, project, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptCanvas_TwoEntities as test_module
from . import ScriptCanvas_TwoEntities_UseSimultaneously as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92569013")
def test_AssetEditor_CreateScriptEventFile(self, request, workspace, editor, launcher_platform, project):
def test_ScriptEvent_HappyPath_CreatedWithoutError(self, request, workspace, editor, launcher_platform, project):
def teardown():
file_system.delete(
[os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True
@@ -110,77 +104,72 @@ class TestAutomation(TestAutomationBase):
file_system.delete(
[os.path.join(workspace.paths.project(), "ScriptCanvas", "test_file.scriptevent")], True, True
)
from . import AssetEditor_CreateScriptEventFile as test_module
from . import ScriptEvent_HappyPath_CreatedWithoutError as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92569165", "T92569167", "T92569168", "T92569170")
def test_Toggle_ScriptCanvasTools(self, request, workspace, editor, launcher_platform):
from . import Toggle_ScriptCanvasTools as test_module
def test_ScriptCanvasTools_Toggle_OpenCloseSuccess(self, request, workspace, editor, launcher_platform):
from . import ScriptCanvasTools_Toggle_OpenCloseSuccess as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92568982")
def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project):
from . import NodeInspector_RenameVariable as test_module
def test_NodeInspector_HappyPath_VariableRenames(self, request, workspace, editor, launcher_platform, project):
from . import NodeInspector_HappyPath_VariableRenames as test_module
self._run_test(request, workspace, editor, test_module)
def test_Debugger_HappyPath_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project):
from . import Debugger_HappyPath_TargetMultipleGraphs as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92569137")
def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project):
from . import Debugging_TargetMultipleGraphs as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92568856")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_Debugging_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level):
def test_Debugger_HappyPath_TargetMultipleEntities(self, request, workspace, editor, launcher_platform, project, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import Debugging_TargetMultipleEntities as test_module
from . import Debugger_HappyPath_TargetMultipleEntities as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92569049", "T92569051")
def test_EditMenu_UndoRedo(self, request, workspace, editor, launcher_platform, project):
from . import EditMenu_UndoRedo as test_module
def test_EditMenu_Default_UndoRedo(self, request, workspace, editor, launcher_platform, project):
from . import EditMenu_Default_UndoRedo as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("C1702825", "C1702831")
def test_UnDockedPane_CloseSCWindow(self, request, workspace, editor, launcher_platform):
from . import UnDockedPane_CloseSCWindow as test_module
def test_Pane_Undocked_ClosesSuccessfully(self, request, workspace, editor, launcher_platform):
from . import Pane_Undocked_ClosesSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92562978")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_Entity_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level):
def test_Entity_HappyPath_AddScriptCanvasComponent(self, request, workspace, editor, launcher_platform, project, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import Entity_AddScriptCanvasComponent as test_module
from . import Entity_HappyPath_AddScriptCanvasComponent as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("C1702821", "C1702832")
def test_Pane_RetainOnSCRestart(self, request, workspace, editor, launcher_platform):
from . import Pane_RetainOnSCRestart as test_module
def test_Pane_Default_RetainOnSCRestart(self, request, workspace, editor, launcher_platform):
from . import Pane_Default_RetainOnSCRestart as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92567321")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_ScriptEvents_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level):
def test_ScriptEvents_HappyPath_SendReceiveAcrossMultiple(self, request, workspace, editor, launcher_platform, project, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptEvents_SendReceiveAcrossMultiple as test_module
from . import ScriptEvents_HappyPath_SendReceiveAcrossMultiple as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.test_case_id("T92567320")
@pytest.mark.parametrize("level", ["tmp_level"])
def test_ScriptEvents_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level):
def test_ScriptEvents_Default_SendReceiveSuccessfully(self, request, workspace, editor, launcher_platform, project, level):
def teardown():
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
request.addfinalizer(teardown)
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
from . import ScriptEvents_SendReceiveSuccessfully as test_module
from . import ScriptEvents_Default_SendReceiveSuccessfully as test_module
self._run_test(request, workspace, editor, test_module)
@pytest.mark.parametrize("level", ["tmp_level"])
@@ -195,7 +184,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 +193,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
@@ -214,18 +207,16 @@ class TestScriptCanvasTests(object):
The following tests use hydra_test_utils.py to launch the editor and validate the results.
"""
@pytest.mark.test_case_id("T92569037", "T92569039")
def test_FileMenu_New_Open(self, request, editor, launcher_platform):
def test_FileMenu_Default_NewAndOpen(self, request, editor, launcher_platform):
expected_lines = [
"File->New action working as expected: True",
"File->Open action working as expected: True",
]
hydra.launch_and_validate_results(
request, TEST_DIRECTORY, editor, "FileMenu_New_Open.py", expected_lines, auto_test_mode=False, timeout=60,
request, TEST_DIRECTORY, editor, "FileMenu_Default_NewAndOpen.py", expected_lines, auto_test_mode=False, timeout=60,
)
@pytest.mark.test_case_id("T92568942")
def test_AssetEditor_NewScriptEvent(self, request, editor, launcher_platform):
def test_NewScriptEventButton_HappyPath_ContainsSCCategory(self, request, editor, launcher_platform):
expected_lines = [
"New Script event action found: True",
"Asset Editor opened: True",
@@ -236,14 +227,13 @@ class TestScriptCanvasTests(object):
request,
TEST_DIRECTORY,
editor,
"AssetEditor_NewScriptEvent.py",
"NewScriptEventButton_HappyPath_ContainsSCCategory.py",
expected_lines,
auto_test_mode=False,
timeout=60,
)
@pytest.mark.test_case_id("T92563068", "T92563070")
def test_GraphClose_SavePrompt(self, request, editor, launcher_platform):
def test_GraphClose_Default_SavePrompt(self, request, editor, launcher_platform):
expected_lines = [
"New graph created: True",
"Save prompt opened as expected: True",
@@ -253,14 +243,13 @@ class TestScriptCanvasTests(object):
request,
TEST_DIRECTORY,
editor,
"GraphClose_SavePrompt.py",
"GraphClose_Default_SavePrompt.py",
expected_lines,
auto_test_mode=False,
timeout=60,
)
@pytest.mark.test_case_id("T92564789", "T92568873")
def test_VariableManager_CreateDeleteVars(self, request, editor, launcher_platform):
def test_VariableManager_Default_CreateDeleteVars(self, request, editor, launcher_platform):
var_types = ["Boolean", "Color", "EntityID", "Number", "String", "Transform", "Vector2", "Vector3", "Vector4"]
expected_lines = [f"Success: {var_type} variable is created" for var_type in var_types]
expected_lines.extend([f"Success: {var_type} variable is deleted" for var_type in var_types])
@@ -268,7 +257,7 @@ class TestScriptCanvasTests(object):
request,
TEST_DIRECTORY,
editor,
"VariableManager_CreateDeleteVars.py",
"VariableManager_Default_CreateDeleteVars.py",
expected_lines,
auto_test_mode=False,
timeout=60,
@@ -7,18 +7,13 @@ distribution (the "License"). All use of this software is governed by the Licens
or, if provided, by the license below or the license accompanying this file. Do not
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Test case ID: T92564789
Test Case Title: Each Variable type can be created
Test case ID: T92568873
Test Case Title: Each Variable type can be deleted
"""
def VariableManager_CreateDeleteVars():
def VariableManager_Default_CreateDeleteVars():
"""
Summary:
Each variable type can be created and deleted in variable manager.
Creating and deleting each type of variable in the Variable Manager pane
Expected Behavior:
Each variable type can be created and deleted in variable manager.
@@ -41,15 +36,13 @@ def VariableManager_CreateDeleteVars():
"""
from PySide2 import QtWidgets, QtCore, QtTest
from PySide2.QtCore import Qt
from utils import TestHelper as helper
import pyside_utils
import azlmbr.legacy.general as general
import pyside_utils
def generate_test_tuple(var_type, action):
return (f"{var_type} variable is {action}d", f"{var_type} variable is not {action}d")
@@ -118,4 +111,4 @@ if __name__ == "__main__":
imports.init()
from utils import Report
Report.start_test(VariableManager_CreateDeleteVars)
Report.start_test(VariableManager_Default_CreateDeleteVars)
@@ -115,7 +115,6 @@ if __name__ == "__main__":
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(VariableManager_UnpinVariableType_Works)
@@ -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
}
}
}
-6
View File
@@ -1,6 +0,0 @@
#Ignore these directories
SDKs
#ColinB (8/26)- I know there are depot files that this will ignore... But these files should not be
#here, they should all be in 3rdParty... so we will ignore them until I can move them, it should
#be OK for now because they shouldn't change at all anyway.
-525
View File
@@ -1,525 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : shadow volume AABB functionality for overlap testings
#ifndef CRYINCLUDE_CRYCOMMON_AABBSV_H
#define CRYINCLUDE_CRYCOMMON_AABBSV_H
#pragma once
#include "Cry_Geo.h"
struct Shadowvolume
{
uint32 sideamount;
uint32 nplanes;
Plane oplanes[10];
};
namespace NAABB_SV
{
//***************************************************************************************
//***************************************************************************************
//*** Calculate a ShadowVolume using an AABB and a point-light ***
//***************************************************************************************
//*** The planes of the AABB facing away from the point-light are the far-planes ***
//*** of the ShadowVolume. There can be 3-6 far-planes. ***
//***************************************************************************************
void AABB_ReceiverShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv);
//***************************************************************************************
//***************************************************************************************
//*** Calculate a ShadowVolume using an AABB and a point-light ***
//***************************************************************************************
//*** The planes of the AABB facing the point-light are the near-planes of the ***
//*** the ShadowVolume. There can be 1-3 near-planes. ***
//*** The far-plane is defined by lightrange. ***
//***************************************************************************************
void AABB_ShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv, f32 lightrange);
//***************************************************************************************
//*** this is the "fast" version to check if an AABB is overlapping a shadowvolume ***
//***************************************************************************************
bool Is_AABB_In_ShadowVolume(const Shadowvolume& sv, const AABB& Receiver);
//***************************************************************************************
//*** this is the "hierarchical" check ***
//***************************************************************************************
char Is_AABB_In_ShadowVolume_hierarchical(const Shadowvolume& sv, const AABB& Receiver);
}
inline void NAABB_SV::AABB_ReceiverShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv)
{
sv.sideamount = 0;
sv.nplanes = 0;
//------------------------------------------------------------------------------
//-- check if PointLight is in front of any occluder plane or inside occluder --
//------------------------------------------------------------------------------
uint32 front = 0;
if (PointLight.x < Occluder.min.x)
{
front |= 0x01;
}
if (PointLight.x > Occluder.max.x)
{
front |= 0x02;
}
if (PointLight.y < Occluder.min.y)
{
front |= 0x04;
}
if (PointLight.y > Occluder.max.y)
{
front |= 0x08;
}
if (PointLight.z < Occluder.min.z)
{
front |= 0x10;
}
if (PointLight.z > Occluder.max.z)
{
front |= 0x20;
}
sv.sideamount = BoxSides[(front << 3) + 7];
uint32 back = front ^ 0x3f;
if (back & 0x01)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(-1, +0, +0), Occluder.min);
sv.nplanes++;
}
if (back & 0x02)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+1, +0, +0), Occluder.max);
sv.nplanes++;
}
if (back & 0x04)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, -1, +0), Occluder.min);
sv.nplanes++;
}
if (back & 0x08)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +1, +0), Occluder.max);
sv.nplanes++;
}
if (back & 0x10)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, -1), Occluder.min);
sv.nplanes++;
}
if (back & 0x20)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, +1), Occluder.max);
sv.nplanes++;
}
if (front == 0)
{
return; //light is inside occluder
}
//all 8 vertices of a AABB
Vec3 o[8] =
{
Vec3(Occluder.min.x, Occluder.min.y, Occluder.min.z),
Vec3(Occluder.max.x, Occluder.min.y, Occluder.min.z),
Vec3(Occluder.min.x, Occluder.max.y, Occluder.min.z),
Vec3(Occluder.max.x, Occluder.max.y, Occluder.min.z),
Vec3(Occluder.min.x, Occluder.min.y, Occluder.max.z),
Vec3(Occluder.max.x, Occluder.min.y, Occluder.max.z),
Vec3(Occluder.min.x, Occluder.max.y, Occluder.max.z),
Vec3(Occluder.max.x, Occluder.max.y, Occluder.max.z)
};
//---------------------------------------------------------------------
//--- find the silhouette-vertices of the occluder-AABB ---
//---------------------------------------------------------------------
uint32 p0 = BoxSides[(front << 3) + 0];
uint32 p1 = BoxSides[(front << 3) + 1];
uint32 p2 = BoxSides[(front << 3) + 2];
uint32 p3 = BoxSides[(front << 3) + 3];
uint32 p4 = BoxSides[(front << 3) + 4];
uint32 p5 = BoxSides[(front << 3) + 5];
float a;
if (sv.sideamount == 4)
{
//sv.oplanes[sv.nplanes+0] = Plane::CreatePlane( o[p0],o[p1], PointLight );
//sv.oplanes[sv.nplanes+1] = Plane::CreatePlane( o[p1],o[p2], PointLight );
//sv.oplanes[sv.nplanes+2] = Plane::CreatePlane( o[p2],o[p3], PointLight );
//sv.oplanes[sv.nplanes+3] = Plane::CreatePlane( o[p3],o[p0], PointLight );
sv.sideamount = 0;
a = (o[p1] - o[p0]) | (o[p0] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight);
sv.sideamount++;
}
a = (o[p2] - o[p1]) | (o[p1] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight);
sv.sideamount++;
}
a = (o[p3] - o[p2]) | (o[p2] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight);
sv.sideamount++;
}
a = (o[p0] - o[p3]) | (o[p3] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p0], PointLight);
sv.sideamount++;
}
}
if (sv.sideamount == 6)
{
//sv.oplanes[sv.nplanes+0] = Plane::CreatePlane( o[p0],o[p1], PointLight );
//sv.oplanes[sv.nplanes+1] = Plane::CreatePlane( o[p1],o[p2], PointLight );
//sv.oplanes[sv.nplanes+2] = Plane::CreatePlane( o[p2],o[p3], PointLight );
//sv.oplanes[sv.nplanes+3] = Plane::CreatePlane( o[p3],o[p4], PointLight );
//sv.oplanes[sv.nplanes+4] = Plane::CreatePlane( o[p4],o[p5], PointLight );
//sv.oplanes[sv.nplanes+5] = Plane::CreatePlane( o[p5],o[p0], PointLight );
sv.sideamount = 0;
a = (o[p1] - o[p0]) | (o[p0] - PointLight);
assert(sv.nplanes + sv.sideamount < 10);
PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight);
sv.sideamount++;
}
a = (o[p2] - o[p1]) | (o[p1] - PointLight);
assert(sv.nplanes + sv.sideamount < 10);
PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight);
sv.sideamount++;
}
a = (o[p3] - o[p2]) | (o[p2] - PointLight);
assert(sv.nplanes + sv.sideamount < 10);
PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight);
sv.sideamount++;
}
a = (o[p4] - o[p3]) | (o[p3] - PointLight);
assert(sv.nplanes + sv.sideamount < 10);
PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p4], PointLight);
sv.sideamount++;
}
a = (o[p5] - o[p4]) | (o[p4] - PointLight);
assert(sv.nplanes + sv.sideamount < 10);
PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p4], o[p5], PointLight);
sv.sideamount++;
}
a = (o[p0] - o[p5]) | (o[p5] - PointLight);
assert(sv.nplanes + sv.sideamount < 10);
PREFAST_ASSUME(sv.nplanes + sv.sideamount < 10);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p5], o[p0], PointLight);
sv.sideamount++;
}
}
}
inline void NAABB_SV::AABB_ShadowVolume(const Vec3& PointLight, const AABB& Occluder, Shadowvolume& sv, f32 lightrange)
{
sv.sideamount = 0;
sv.nplanes = 0;
//------------------------------------------------------------------------------
//-- check if PointLight is in front of any occluder plane or inside occluder --
//------------------------------------------------------------------------------
uint32 front = 0;
if (PointLight.x < Occluder.min.x)
{
front |= 0x01;
}
if (PointLight.x > Occluder.max.x)
{
front |= 0x02;
}
if (PointLight.y < Occluder.min.y)
{
front |= 0x04;
}
if (PointLight.y > Occluder.max.y)
{
front |= 0x08;
}
if (PointLight.z < Occluder.min.z)
{
front |= 0x10;
}
if (PointLight.z > Occluder.max.z)
{
front |= 0x20;
}
if (front == 0)
{
return; //light is inside occluder
}
sv.sideamount = BoxSides[(front << 3) + 7];
if (front & 0x01)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(-1, +0, +0), Occluder.min);
sv.nplanes++;
}
if (front & 0x02)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+1, +0, +0), Occluder.max);
sv.nplanes++;
}
if (front & 0x04)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, -1, +0), Occluder.min);
sv.nplanes++;
}
if (front & 0x08)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +1, +0), Occluder.max);
sv.nplanes++;
}
if (front & 0x10)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, -1), Occluder.min);
sv.nplanes++;
}
if (front & 0x20)
{
sv.oplanes[sv.nplanes].SetPlane(Vec3(+0, +0, +1), Occluder.max);
sv.nplanes++;
}
//all 8 vertices of a AABB
Vec3 o[8] =
{
Vec3(Occluder.min.x, Occluder.min.y, Occluder.min.z),
Vec3(Occluder.max.x, Occluder.min.y, Occluder.min.z),
Vec3(Occluder.min.x, Occluder.max.y, Occluder.min.z),
Vec3(Occluder.max.x, Occluder.max.y, Occluder.min.z),
Vec3(Occluder.min.x, Occluder.min.y, Occluder.max.z),
Vec3(Occluder.max.x, Occluder.min.y, Occluder.max.z),
Vec3(Occluder.min.x, Occluder.max.y, Occluder.max.z),
Vec3(Occluder.max.x, Occluder.max.y, Occluder.max.z)
};
//---------------------------------------------------------------------
//--- find the silhouette-vertices of the occluder-AABB ---
//---------------------------------------------------------------------
uint32 p0 = BoxSides[(front << 3) + 0];
uint32 p1 = BoxSides[(front << 3) + 1];
uint32 p2 = BoxSides[(front << 3) + 2];
uint32 p3 = BoxSides[(front << 3) + 3];
uint32 p4 = BoxSides[(front << 3) + 4];
uint32 p5 = BoxSides[(front << 3) + 5];
//the new center-position in world-space
Vec3 MiddleOfOccluder = (Occluder.max + Occluder.min) * 0.5f;
sv.oplanes[sv.nplanes] = Plane::CreatePlane((MiddleOfOccluder - PointLight).GetNormalized(), (MiddleOfOccluder - PointLight).GetNormalized() * lightrange + PointLight);
sv.nplanes++;
float a;
if (sv.sideamount == 4)
{
sv.sideamount = 0;
a = (o[p1] - o[p0]) | (o[p0] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight);
sv.sideamount++;
}
a = (o[p2] - o[p1]) | (o[p1] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight);
sv.sideamount++;
}
a = (o[p3] - o[p2]) | (o[p2] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight);
sv.sideamount++;
}
a = (o[p0] - o[p3]) | (o[p3] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p0], PointLight);
sv.sideamount++;
}
}
if (sv.sideamount == 6)
{
sv.sideamount = 0;
a = (o[p1] - o[p0]) | (o[p0] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p0], o[p1], PointLight);
sv.sideamount++;
}
a = (o[p2] - o[p1]) | (o[p1] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p1], o[p2], PointLight);
sv.sideamount++;
}
a = (o[p3] - o[p2]) | (o[p2] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p2], o[p3], PointLight);
sv.sideamount++;
}
a = (o[p4] - o[p3]) | (o[p3] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p3], o[p4], PointLight);
sv.sideamount++;
}
a = (o[p5] - o[p4]) | (o[p4] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p4], o[p5], PointLight);
sv.sideamount++;
}
a = (o[p0] - o[p5]) | (o[p5] - PointLight);
if (a)
{
sv.oplanes[sv.nplanes + sv.sideamount] = Plane::CreatePlane(o[p5], o[p0], PointLight);
sv.sideamount++;
}
}
}
inline bool NAABB_SV::Is_AABB_In_ShadowVolume(const Shadowvolume& sv, const AABB& Receiver)
{
uint32 pa = sv.sideamount + sv.nplanes;
f32 d;
const Vec3* pAABB = &Receiver.min;
union f32_u
{
float floatVal;
uint32 uintVal;
};
//------------------------------------------------------------------------------
//---- check if receiver-AABB is in front of any of these planes ------
//------------------------------------------------------------------------------
for (uint32 x = 0; x < pa; x++)
{
d = sv.oplanes[x].d;
//avoid breaking strict aliasing rules
f32_u ux;
ux.floatVal = sv.oplanes[x].n.x;
f32_u uy;
uy.floatVal = sv.oplanes[x].n.y;
f32_u uz;
uz.floatVal = sv.oplanes[x].n.z;
const uint32 bitX = ux.uintVal >> 31;
const uint32 bitY = uy.uintVal >> 31;
const uint32 bitZ = uz.uintVal >> 31;
d += sv.oplanes[x].n.x * pAABB[bitX].x;
d += sv.oplanes[x].n.y * pAABB[bitY].y;
d += sv.oplanes[x].n.z * pAABB[bitZ].z;
if (d > 0)
{
return CULL_EXCLUSION;
}
}
return CULL_OVERLAP;
}
inline char NAABB_SV::Is_AABB_In_ShadowVolume_hierarchical(const Shadowvolume& sv, const AABB& Receiver)
{
uint32 pa = sv.sideamount + sv.nplanes;
const Vec3* pAABB = &Receiver.min;
f32 dot1, dot2;
uint32 notOverlap = 0x80000000; // will be reset to 0 if there's at least one overlapping
union f32_u
{
float floatVal;
uint32 uintVal;
};
//------------------------------------------------------------------------------
//---- check if receiver-AABB is in front of any of these planes ------
//------------------------------------------------------------------------------
for (uint32 x = 0; x < pa; x++)
{
dot1 = dot2 = sv.oplanes[x].d;
//avoid breaking strict aliasing rules
f32_u ux;
ux.floatVal = sv.oplanes[x].n.x;
f32_u uy;
uy.floatVal = sv.oplanes[x].n.y;
f32_u uz;
uz.floatVal = sv.oplanes[x].n.z;
const uint32 bitX = ux.uintVal >> 31;
const uint32 bitY = uy.uintVal >> 31;
const uint32 bitZ = uz.uintVal >> 31;
dot1 += sv.oplanes[x].n.x * pAABB[0 + bitX].x;
dot2 += sv.oplanes[x].n.x * pAABB[1 - bitX].x;
dot1 += sv.oplanes[x].n.y * pAABB[0 + bitY].y;
dot2 += sv.oplanes[x].n.y * pAABB[1 - bitY].y;
dot1 += sv.oplanes[x].n.z * pAABB[0 + bitZ].z;
dot2 += sv.oplanes[x].n.z * pAABB[1 - bitZ].z;
PREFAST_SUPPRESS_WARNING(6001) f32_u d;
d.floatVal = dot1;
if (!(d.uintVal & 0x80000000))
{
return CULL_EXCLUSION;
}
PREFAST_SUPPRESS_WARNING(6001) f32_u d2;
d2.floatVal = dot2;
notOverlap &= d2.uintVal;
}
if (notOverlap)
{
return CULL_INCLUSION;
}
return CULL_OVERLAP;
}
#endif // CRYINCLUDE_CRYCOMMON_AABBSV_H
-74
View File
@@ -1,74 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef CRYINCLUDE_CRYCOMMON_ALGORITHM_H
#define CRYINCLUDE_CRYCOMMON_ALGORITHM_H
#pragma once
//short hand for using stl algorithms. same syntax (from users perspective) of c++17 range library. Only the shorthand algorithms from range library(N4128) though.
//Not all algorithms are covered. Add any as you need them. It would be a fair amount of work to add them all, so I'm just adding them as needed.
//Note Android doesn't have non member cbegin and cend yet.
#include <algorithm>
#include <numeric>
#include <iterator>
namespace std17
{
template<typename Container, typename Callable>
void for_each(const Container& con, Callable callable)
{
std::for_each(begin(con), end(con), callable);
}
template<typename Container, typename UnaryPredicate>
bool any_of(const Container& con, UnaryPredicate pred)
{
return std::any_of(begin(con), end(con), pred);
}
template<typename Container, typename UnaryPredicate>
bool all_of(const Container& con, UnaryPredicate pred)
{
return std::all_of(begin(con), end(con), pred);
}
template<typename Container, typename UnaryPredicate>
bool none_of(const Container& con, UnaryPredicate pred)
{
return std::none_of(begin(con), end(con), pred);
}
template<typename Container, typename UnaryPredicate>
typename Container::iterator find_if(Container& con, UnaryPredicate pred)
{
return std::find_if(begin(con), end(con), pred);
}
template <typename Container, typename T>
T accumulate(const Container& con, T init)
{
return std::accumulate(begin(con), end(con), init);
}
template <typename Container, typename T, class BinaryOperation>
T accumulate(const Container& con, T init, BinaryOperation binary_op)
{
return std::accumulate(begin(con), end(con), init, binary_op);
}
template <typename Container, typename UnaryPredicate>
auto count_if(const Container&con, UnaryPredicate pred)->decltype(std::count_if(begin(con), end(con), pred))
{
return std::count_if(begin(con), end(con), pred);
}
}
#endif // CRYINCLUDE_CRYCOMMON_ALGORITHM_H
-75
View File
@@ -1,75 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_ALLOCATOR_H
#define CRYINCLUDE_CRYCOMMON_ALLOCATOR_H
#pragma once
#include "CryMemoryAllocator.h"
////////////////////////////////////////////////////////////////////////
// Allocator default implementation
struct StdAllocator
{
// Class-specific alloc/free/size functions. Use aligned versions only when necessary.
template<class T>
static void* Allocate(T*& p)
{
return p = NeedAlign<T>() ?
(T*)CryModuleMemalign(sizeof(T), alignof(T)) :
(T*)CryModuleMalloc(sizeof(T));
}
template<class T>
static void Deallocate(T* p)
{
if (NeedAlign<T>())
{
CryModuleMemalignFree(p);
}
else
{
CryModuleFree(p);
}
}
template<class T>
static size_t GetMemSize(const T* p)
{
return NeedAlign<T>() ?
sizeof(T) + alignof(T) :
sizeof(T);
}
template<typename T>
void GetMemoryUsage(ICrySizer* pSizer) const { /*nothing*/}
protected:
template<class T>
static bool NeedAlign()
{ PREFAST_SUPPRESS_WARNING(6326); return alignof(T) > _ALIGNMENT; }
};
// Handy delete template function, for any allocator.
template<class TAlloc, class T>
void Delete(TAlloc& alloc, T* ptr)
{
if (ptr)
{
ptr->~T();
alloc.Deallocate(ptr);
}
}
#endif // CRYINCLUDE_CRYCOMMON_ALLOCATOR_H
-903
View File
@@ -1,903 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Describe contents on CGF file.
#ifndef CRYINCLUDE_CRYCOMMON_CGFCONTENT_H
#define CRYINCLUDE_CRYCOMMON_CGFCONTENT_H
#pragma once
#include <IIndexedMesh.h> // <> required for Interfuscator
#include <IChunkFile.h> // <> required for Interfuscator
#include <CryHeaders.h>
#include <Cry_Color.h>
#include <CryArray.h>
#include <StringUtils.h>
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/std/containers/unordered_map.h> //Required for LOD support for touch bending vegetation
#include <AzCore/std/string/string.h> //Required for LOD support for touch bending vegetation
const int CGF_NODE_NAME_LENGTH = 64;
//END: Add LOD support for touch bending vegetation
struct CMaterialCGF;
struct IConvertContext;
#define CGF_NODE_NAME_LOD_PREFIX "$lod"
//////////////////////////////////////////////////////////////////////////
// This structure represents CGF node.
//////////////////////////////////////////////////////////////////////////
struct CNodeCGF
: public _cfg_reference_target<CNodeCGF>
{
enum ENodeType
{
NODE_MESH,
NODE_LIGHT,
NODE_HELPER,
};
enum EPhysicalizeFlags
{
ePhysicsalizeFlag_MeshNotNeeded = BIT(2), // When set physics data doesn't need additional Mesh indices or vertices.
ePhysicsalizeFlag_NoBreaking = BIT(3), // node is unsuitable for procedural 3d breaking
};
ENodeType type;
//START: Add LOD support for touch bending vegetation
char name[CGF_NODE_NAME_LENGTH];
//END: Add LOD support for touch bending vegetation
string properties;
Matrix34 localTM; // Local space transformation matrix.
Matrix34 worldTM; // World space transformation matrix.
CNodeCGF* pParent; // Pointer to parent node.
CNodeCGF* pSharedMesh; // Not NULL if this node is sharing mesh and physics from referenced Node.
CMesh* pMesh; // Pointer to mesh loaded for this node. (Only when type == NODE_MESH)
HelperTypes helperType; // Only relevant if type==NODE_HELPER
Vec3 helperSize; // Only relevant if type==NODE_HELPER
CMaterialCGF* pMaterial; // Material node.
// Physical data of the node with mesh.
int nPhysicalizeFlags; // Saved into the nFlags2 chunk member.
AZStd::vector<char> physicalGeomData[4];
int nPhysTriCount; // Not saved! only used for statistics in RC
//////////////////////////////////////////////////////////////////////////
// Used internally.
int nChunkId; // Chunk id as loaded from CGF.
int nParentChunkId; // Chunk id of parent Node.
int nObjectChunkId; // Chunk id of the corresponding mesh.
int pos_cont_id; // position controller chunk id
int rot_cont_id; // rotation controller chunk id
int scl_cont_id; // scale controller chunk id
//////////////////////////////////////////////////////////////////////////
// True if worldTM is identity.
bool bIdentityMatrix;
// True when this node is invisible physics proxy.
bool bPhysicsProxy;
// These values are not saved, but are only used for loading empty mesh chunks.
struct MeshInfo
{
int nVerts;
int nIndices;
int nSubsets;
Vec3 bboxMin;
Vec3 bboxMax;
float fGeometricMean;
};
MeshInfo meshInfo;
CrySkinVtx* pSkinInfo; // for skinning with skeleton meshes (deformable objects)
//////////////////////////////////////////////////////////////////////////
// Constructor.
//////////////////////////////////////////////////////////////////////////
void Init()
{
type = NODE_MESH;
localTM.SetIdentity();
worldTM.SetIdentity();
pParent = 0;
pSharedMesh = 0;
pMesh = 0;
pMaterial = 0;
helperType = HP_POINT;
helperSize.Set(0, 0, 0);
nPhysicalizeFlags = 0;
nChunkId = 0;
nParentChunkId = 0;
nObjectChunkId = 0;
pos_cont_id = rot_cont_id = scl_cont_id = 0;
bIdentityMatrix = true;
bPhysicsProxy = false;
pSkinInfo = 0;
nPhysTriCount = 0;
ZeroStruct(meshInfo);
}
CNodeCGF()
{
Init();
}
explicit CNodeCGF(_cfg_reference_target<CNodeCGF>::DeleteFncPtr pDeleteFnc)
: _cfg_reference_target<CNodeCGF>(pDeleteFnc)
{
Init();
}
~CNodeCGF()
{
if (!pSharedMesh)
{
delete pMesh;
}
if (pSkinInfo)
{
delete[] pSkinInfo;
}
}
};
//////////////////////////////////////////////////////////////////////////
// structures for skinning
//////////////////////////////////////////////////////////////////////////
struct TFace
{
uint16 i0, i1, i2;
TFace() {}
TFace(uint16 v0, uint16 v1, uint16 v2) { i0 = v0; i1 = v1; i2 = v2; }
TFace(const CryFace& face) { i0 = aznumeric_caster(face[0]); i1 = aznumeric_caster(face[1]); i2 = aznumeric_caster(face[2]); }
void operator = (const TFace& f) { i0 = f.i0; i1 = f.i1; i2 = f.i2; }
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
AUTO_STRUCT_INFO
};
struct PhysicalProxy
{
uint32 ChunkID;
DynArray<Vec3> m_arrPoints;
DynArray<uint16> m_arrIndices;
DynArray<char> m_arrMaterials;
};
struct MorphTargets
{
uint32 MeshID;
string m_strName;
DynArray<SMeshMorphTargetVertex> m_arrIntMorph;
DynArray<SMeshMorphTargetVertex> m_arrExtMorph;
};
typedef MorphTargets* MorphTargetsPtr;
struct IntSkinVertex
{
Vec3 __obsolete0; // thin/fat vertex position. must be removed in the next RC refactoring
Vec3 pos; // vertex-position of model.2
Vec3 __obsolete2; // thin/fat vertex position. must be removed in the next RC refactoring
uint16 boneIDs[4];
f32 weights[4];
ColorB color; //index for blend-array
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
AUTO_STRUCT_INFO
};
//////////////////////////////////////////////////////////////////////////
// TCB Controller implementation.
//////////////////////////////////////////////////////////////////////////
// retrieves the position and orientation (in the logarithmic space, i.e. instead of quaternion, its logarithm is returned)
// may be optimal for motion interpolation
struct PQLog
{
Vec3 vPos;
Vec3 vRotLog; // logarithm of the rotation
void blendPQ (const PQLog& pqFrom, const PQLog& pqTo, f32 fBlend);
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
};
struct CControllerType
{
uint16 m_controllertype;
uint16 m_index;
CControllerType()
{
m_controllertype = 0xffff;
m_index = 0xffff;
}
};
struct TCBFlags
{
uint8 f0, f1;
TCBFlags() { f0 = f1 = 0; }
};
struct CStoredSkinningInfo
{
int32 m_nTicksPerFrame;
f32 m_secsPerTick;
int32 m_nStart;
int32 m_nEnd;
f32 m_Speed;
f32 m_Distance;
f32 m_Slope;
int m_nAssetFlags;
f32 m_LHeelStart, m_LHeelEnd;
f32 m_LToe0Start, m_LToe0End;
f32 m_RHeelStart, m_RHeelEnd;
f32 m_RToe0Start, m_RToe0End;
Vec3 m_MoveDirection; // raw storage
CStoredSkinningInfo()
: m_Speed(-1.0f)
, m_Distance(-1.0f)
, m_nAssetFlags(0)
, m_LHeelStart(-10000.0f)
, m_LHeelEnd(-10000.0f)
, m_LToe0Start(-10000.0f)
, m_LToe0End(-10000.0f)
, m_RHeelStart(-10000.0f)
, m_RHeelEnd(-10000.0f)
, m_RToe0Start(-10000.0f)
, m_RToe0End(-10000.0f)
, m_Slope(-1.0f)
{
}
AUTO_STRUCT_INFO
};
// structure for recreating controllers
struct CControllerInfo
{
uint32 m_nControllerID;
uint32 m_nPosKeyTimeTrack;
uint32 m_nPosTrack;
uint32 m_nRotKeyTimeTrack;
uint32 m_nRotTrack;
CControllerInfo()
: m_nControllerID(~0)
, m_nPosKeyTimeTrack(~0)
, m_nPosTrack(~0)
, m_nRotKeyTimeTrack(~0)
, m_nRotTrack(~0) {}
AUTO_STRUCT_INFO
};
struct MeshCollisionInfo
{
AABB m_aABB;
OBB m_OBB;
Vec3 m_Pos;
DynArray<int16> m_arrIndexes;
int32 m_iBoneId;
MeshCollisionInfo()
{
// This didn't help much.
// The BBs are reset to opposite infinites,
// but never clamped/grown by any member points.
m_aABB.min.zero();
m_aABB.max.zero();
m_OBB.m33.SetIdentity();
m_OBB.h.zero();
m_OBB.c.zero();
m_Pos.zero();
}
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_arrIndexes);
}
};
struct SJointsAimIK_Rot
{
const char* m_strJointName;
int16 m_nJointIdx;
int16 m_nPosIndex;
uint8 m_nPreEvaluate;
uint8 m_nAdditive;
int16 m_nRotJointParentIdx;
SJointsAimIK_Rot()
{
m_strJointName = 0;
m_nJointIdx = -1;
m_nPosIndex = -1;
m_nPreEvaluate = 0;
m_nAdditive = 0;
m_nRotJointParentIdx = -1;
};
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
};
struct SJointsAimIK_Pos
{
const char* m_strJointName;
int16 m_nJointIdx;
uint8 m_nAdditive;
uint8 m_nEmpty;
SJointsAimIK_Pos()
{
m_strJointName = 0;
m_nJointIdx = -1;
m_nAdditive = 0;
m_nEmpty = 0;
};
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const{}
};
struct DirectionalBlends
{
string m_AnimToken;
uint32 m_AnimTokenCRC32;
const char* m_strParaJointName;
int16 m_nParaJointIdx;
int16 m_nRotParaJointIdx;
const char* m_strStartJointName;
int16 m_nStartJointIdx;
int16 m_nRotStartJointIdx;
const char* m_strReferenceJointName;
int32 m_nReferenceJointIdx;
DirectionalBlends()
{
m_AnimTokenCRC32 = 0;
m_strParaJointName = 0;
m_nParaJointIdx = -1;
m_nRotParaJointIdx = -1;
m_strStartJointName = 0;
m_nStartJointIdx = -1;
m_nRotStartJointIdx = -1;
m_strReferenceJointName = 0;
m_nReferenceJointIdx = 1; //by default we use the Pelvis
};
void GetMemoryUsage([[maybe_unused]] ICrySizer* pSizer) const {}
};
struct CSkinningInfo
: public _reference_target_t
{
DynArray<CryBoneDescData> m_arrBonesDesc; //animation-bones
DynArray<SJointsAimIK_Rot> m_LookIK_Rot; //rotational joints used for Look-IK
DynArray<SJointsAimIK_Pos> m_LookIK_Pos; //positional joints used for Look-IK
DynArray<DirectionalBlends> m_LookDirBlends; //positional joints used for Look-IK
DynArray<SJointsAimIK_Rot> m_AimIK_Rot; //rotational joints used for Aim-IK
DynArray<SJointsAimIK_Pos> m_AimIK_Pos; //positional joints used for Aim-IK
DynArray<DirectionalBlends> m_AimDirBlends; //positional joints used for Aim-IK
DynArray<PhysicalProxy> m_arrPhyBoneMeshes; //collision proxi
DynArray<MorphTargetsPtr> m_arrMorphTargets;
DynArray<TFace> m_arrIntFaces;
DynArray<IntSkinVertex> m_arrIntVertices;
DynArray<uint16> m_arrExt2IntMap;
DynArray<BONE_ENTITY> m_arrBoneEntities; //physical-bones
DynArray<MeshCollisionInfo> m_arrCollisions;
uint32 m_numChunks{ 0 };
bool m_bRotatedMorphTargets;
bool m_bProperBBoxes;
CSkinningInfo()
: m_bRotatedMorphTargets(false)
, m_bProperBBoxes(false) {}
~CSkinningInfo()
{
for (DynArray<MorphTargetsPtr>::iterator it = m_arrMorphTargets.begin(), end = m_arrMorphTargets.end(); it != end; ++it)
{
delete *it;
}
}
int32 GetJointIDByName(const char* strJointName) const
{
uint32 numJoints = m_arrBonesDesc.size();
for (uint32 i = 0; i < numJoints; i++)
{
if (_stricmp(m_arrBonesDesc[i].m_arrBoneName, strJointName) == 0)
{
return i;
}
}
return -1;
}
// Return name of bone from bone table, return zero id nId is out of range
const char* GetJointNameByID(int32 nJointID) const
{
int32 numJoints = m_arrBonesDesc.size();
if (nJointID >= 0 && nJointID < numJoints)
{
return m_arrBonesDesc[nJointID].m_arrBoneName;
}
return ""; // invalid bone id
}
};
//////////////////////////////////////////////////////////////////////////
// This structure represents Material inside CGF.
//////////////////////////////////////////////////////////////////////////
struct CMaterialCGF
: public _cfg_reference_target<CMaterialCGF>
{
char name[128]; // Material name;
int nFlags; // Material flags.
int nPhysicalizeType;
bool bOldMaterial;
float shOpacity;
// Array of sub materials.
DynArray<CMaterialCGF*> subMaterials;
//////////////////////////////////////////////////////////////////////////
// Used internally.
int nChunkId;
//////////////////////////////////////////////////////////////////////////
void Init()
{
nFlags = 0;
nChunkId = 0;
bOldMaterial = false;
nPhysicalizeType = PHYS_GEOM_TYPE_DEFAULT;
shOpacity = 1.f;
}
CMaterialCGF() { Init(); }
explicit CMaterialCGF(_cfg_reference_target<CMaterialCGF>::DeleteFncPtr pDeleteFnc)
: _cfg_reference_target<CMaterialCGF>(pDeleteFnc)
{ Init(); }
};
//////////////////////////////////////////////////////////////////////////
// Info about physicalization of the CGF.
//////////////////////////////////////////////////////////////////////////
struct CPhysicalizeInfoCGF
{
bool bWeldVertices;
float fWeldTolerance; // Min Distance between vertices when they collapse to single vertex if bWeldVertices enabled.
// breakable physics
int nGranularity;
int nMode;
Vec3* pRetVtx;
int nRetVtx;
int* pRetTets;
int nRetTets;
CPhysicalizeInfoCGF()
: bWeldVertices(true)
, fWeldTolerance(0.01f)
, nMode(-1)
, nGranularity(-1)
, pRetVtx(0)
, nRetVtx(0)
, pRetTets(0)
, nRetTets(0){}
~CPhysicalizeInfoCGF()
{
if (pRetVtx)
{
delete []pRetVtx;
pRetVtx = 0;
}
if (pRetTets)
{
delete []pRetTets;
pRetTets = 0;
}
}
};
//////////////////////////////////////////////////////////////////////////
// Serialized skinnable foliage data
//////////////////////////////////////////////////////////////////////////
#define NODE_PROPERTY_STIFFNESS "stiffness"
#define NODE_PROPERTY_DAMPING "damping"
#define NODE_PROPERTY_THICKNESS "thickness"
struct SSpineRC
{
SSpineRC()
: pVtx(nullptr)
, pSegDim(nullptr)
, nVtx(0)
, len(0)
, pBoneIDs(nullptr)
, parentBoneID(-1)
, pStiffness(nullptr)
, pDamping(nullptr)
, pThickness(nullptr) {}
~SSpineRC()
{
if (pVtx)
{
delete[] pVtx;
}
if (pSegDim)
{
delete[] pSegDim;
}
if (pBoneIDs)
{
delete[] pBoneIDs;
}
if (pStiffness)
{
delete[] pStiffness;
}
if (pDamping)
{
delete[] pDamping;
}
if (pThickness)
{
delete[] pThickness;
}
}
/// Add Skinned Geometry (.CGF) export type (for touch bending vegetation)
static float GetDefaultStiffness() { return 0.5f; }
static float GetDefaultDamping() { return 0.5f; }
static float GetDefaultThickness() { return 0.03f; }
Vec3* pVtx;
Vec4* pSegDim;
int nVtx;
float len;
Vec3 navg;
int parentBoneID;
int* pBoneIDs;
//Per Bone parameters.
float* pStiffness;
float* pDamping;
float* pThickness;
int iAttachSpine;
int iAttachSeg;
};
struct SFoliageInfoCGF
{
SFoliageInfoCGF() { nSpines = 0; pSpines = 0; pBoneMapping = 0; }
~SFoliageInfoCGF()
{
if (pSpines)
{
for (int i = 1; i < nSpines; i++) // spines 1..n-1 use the same buffer, so make sure they don't delete it
{
pSpines[i].pVtx = nullptr;
pSpines[i].pSegDim = nullptr;
pSpines[i].pBoneIDs = nullptr;
pSpines[i].pStiffness = nullptr;
pSpines[i].pDamping = nullptr;
pSpines[i].pThickness = nullptr;
}
delete[] pSpines;
}
SAFE_DELETE_ARRAY(pBoneMapping);
AZStd::unordered_map<AZStd::string, SMeshBoneMappingInfo_uint8*>::iterator iter = boneMappings.begin();
while (iter != boneMappings.end())
{
if (iter->second != nullptr)
{
SAFE_DELETE_ARRAY(iter->second->pBoneMapping);
}
iter++;
}
}
SSpineRC* pSpines;
int nSpines;
///Bone mappings for each LOD level
AZStd::unordered_map<AZStd::string, SMeshBoneMappingInfo_uint8*> boneMappings;
///Bone mapping for legacy format
struct SMeshBoneMapping_uint8* pBoneMapping;
int nSkinnedVtx;
DynArray<uint16> chunkBoneIds;
};
//////////////////////////////////////////////////////////////////////////
struct CExportInfoCGF
{
bool bMergeAllNodes;
bool bUseCustomNormals;
bool bCompiledCGF;
bool bHavePhysicsProxy;
bool bHaveAutoLods;
bool bNoMesh;
bool bWantF32Vertices;
bool b8WeightsPerVertex;
/// Prevent reprocessing skinning data for skinned CGF
bool bSkinnedCGF;
bool bFromColladaXSI;
bool bFromColladaMAX;
bool bFromColladaMAYA;
unsigned int rc_version[4]; // Resource compiler version.
char rc_version_string[16]; // Version as a string.
unsigned int authorToolVersion;
};
//////////////////////////////////////////////////////////////////////////
// This class contain all info loaded from the CGF file.
//////////////////////////////////////////////////////////////////////////
class CContentCGF
{
public:
//////////////////////////////////////////////////////////////////////////
CContentCGF(const char* filename)
{
azstrcpy(m_filename, AZ_ARRAY_SIZE(m_filename), filename);
memset(&m_exportInfo, 0, sizeof(m_exportInfo));
m_exportInfo.bMergeAllNodes = true;
m_exportInfo.bUseCustomNormals = false;
m_exportInfo.bWantF32Vertices = false;
m_exportInfo.b8WeightsPerVertex = false;
m_exportInfo.bSkinnedCGF = false;
m_pCommonMaterial = 0;
m_bConsoleFormat = false;
m_pOwnChunkFile = 0;
}
//////////////////////////////////////////////////////////////////////////
virtual ~CContentCGF()
{
// Free nodes.
m_nodes.clear();
if (m_pOwnChunkFile)
{
m_pOwnChunkFile->Release();
}
}
//////////////////////////////////////////////////////////////////////////
const char* GetFilename() const
{
return m_filename;
}
void SetFilename(const char* filename)
{
azstrcpy(m_filename, AZ_ARRAY_SIZE(m_filename), filename);
}
//////////////////////////////////////////////////////////////////////////
// Access to CGF nodes.
void AddNode(CNodeCGF* pNode)
{
m_nodes.push_back(pNode);
}
int GetNodeCount() const
{
return m_nodes.size();
}
CNodeCGF* GetNode(int i)
{
return m_nodes[i];
}
const CNodeCGF* GetNode(int i) const
{
return m_nodes[i];
}
void ClearNodes()
{
m_nodes.clear();
}
void RemoveNode(CNodeCGF* pNode)
{
assert(pNode);
for (int i = 0; i < m_nodes.size(); ++i)
{
if (m_nodes[i] == pNode)
{
pNode->pParent = 0;
m_nodes.erase(i);
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Access to CGF materials.
void AddMaterial(CMaterialCGF* pNode)
{
m_materials.push_back(pNode);
}
int GetMaterialCount() const
{
return m_materials.size();
}
CMaterialCGF* GetMaterial(int i)
{
return m_materials[i];
}
void ClearMaterials()
{
m_materials.clear();
}
CMaterialCGF* GetCommonMaterial() const
{
return m_pCommonMaterial;
}
void SetCommonMaterial(CMaterialCGF* pMtl)
{
m_pCommonMaterial = pMtl;
}
DynArray<int>& GetUsedMaterialIDs()
{
return m_usedMaterialIds;
}
const DynArray<int>& GetUsedMaterialIDs() const
{
return m_usedMaterialIds;
}
//////////////////////////////////////////////////////////////////////////
CPhysicalizeInfoCGF* GetPhysicalizeInfo()
{
return &m_physicsInfo;
}
const CPhysicalizeInfoCGF* GetPhysicalizeInfo() const
{
return &m_physicsInfo;
}
CExportInfoCGF* GetExportInfo()
{
return &m_exportInfo;
}
const CExportInfoCGF* GetExportInfo() const
{
return &m_exportInfo;
}
CSkinningInfo* GetSkinningInfo()
{
return &m_SkinningInfo;
}
const CSkinningInfo* GetSkinningInfo() const
{
return &m_SkinningInfo;
}
SFoliageInfoCGF* GetFoliageInfo()
{
return &m_foliageInfo;
}
bool GetConsoleFormat()
{
return m_bConsoleFormat;
}
bool ValidateMeshes(const char** const ppErrorDescription) const
{
for (int i = 0; i < m_nodes.size(); ++i)
{
const CNodeCGF* const pNode = m_nodes[i];
if (pNode && pNode->pMesh && (!pNode->pMesh->Validate(ppErrorDescription)))
{
return false;
}
}
return true;
}
// Set chunk file that this CGF owns.
void SetChunkFile(IChunkFile* pChunkFile)
{
m_pOwnChunkFile = pChunkFile;
}
public:
bool m_bConsoleFormat;
private:
char m_filename[260];
CSkinningInfo m_SkinningInfo;
DynArray<_smart_ptr<CNodeCGF> > m_nodes;
DynArray<_smart_ptr<CMaterialCGF> > m_materials;
DynArray<int> m_usedMaterialIds;
_smart_ptr<CMaterialCGF> m_pCommonMaterial;
CPhysicalizeInfoCGF m_physicsInfo;
CExportInfoCGF m_exportInfo;
SFoliageInfoCGF m_foliageInfo;
IChunkFile* m_pOwnChunkFile;
};
namespace AZ
{
namespace SceneAPI
{
namespace DataTypes
{
class IAnimationGroup;
}
}
}
// Asset Writer interface for writing CContentCGF content to asset file
struct IAssetWriter
{
virtual ~IAssetWriter()
{
}
virtual bool WriteCGF(CContentCGF* content) = 0;
virtual bool WriteCHR(CContentCGF* content, IConvertContext* convertContext) = 0;
virtual bool WriteSKIN(CContentCGF* content, IConvertContext* convertContext, bool exportMorphTargets) = 0;
};
#endif // CRYINCLUDE_CRYCOMMON_CGFCONTENT_H
@@ -1,68 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include "TypeInfo_impl.h"
#include "CGFContent.h"
STRUCT_INFO_BEGIN(TFace)
STRUCT_VAR_INFO(i0, TYPE_INFO(uint16))
STRUCT_VAR_INFO(i1, TYPE_INFO(uint16))
STRUCT_VAR_INFO(i2, TYPE_INFO(uint16))
STRUCT_INFO_END(TFace)
STRUCT_INFO_BEGIN(IntSkinVertex)
STRUCT_VAR_INFO(__obsolete0, TYPE_INFO(Vec3))
STRUCT_VAR_INFO(pos, TYPE_INFO(Vec3))
STRUCT_VAR_INFO(__obsolete2, TYPE_INFO(Vec3))
STRUCT_VAR_INFO(boneIDs, TYPE_ARRAY(4, TYPE_INFO(uint16)))
STRUCT_VAR_INFO(weights, TYPE_ARRAY(4, TYPE_INFO(f32)))
STRUCT_VAR_INFO(color, TYPE_INFO(ColorB))
STRUCT_INFO_END(IntSkinVertex)
STRUCT_INFO_BEGIN(CStoredSkinningInfo)
STRUCT_VAR_INFO(m_nTicksPerFrame, TYPE_INFO(int32))
STRUCT_VAR_INFO(m_secsPerTick, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_nStart, TYPE_INFO(int32))
STRUCT_VAR_INFO(m_nEnd, TYPE_INFO(int32))
STRUCT_VAR_INFO(m_Speed, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_Distance, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_Slope, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_nAssetFlags, TYPE_INFO(int))
STRUCT_VAR_INFO(m_LHeelStart, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_LHeelEnd, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_LToe0Start, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_LToe0End, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_RHeelStart, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_RHeelEnd, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_RToe0Start, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_RToe0End, TYPE_INFO(f32))
STRUCT_VAR_INFO(m_MoveDirection, TYPE_INFO(Vec3))
STRUCT_INFO_END(CStoredSkinningInfo)
STRUCT_INFO_BEGIN(CControllerInfo)
STRUCT_VAR_INFO(m_nControllerID, TYPE_INFO(uint32))
STRUCT_VAR_INFO(m_nPosKeyTimeTrack, TYPE_INFO(uint32))
STRUCT_VAR_INFO(m_nPosTrack, TYPE_INFO(uint32))
STRUCT_VAR_INFO(m_nRotKeyTimeTrack, TYPE_INFO(uint32))
STRUCT_VAR_INFO(m_nRotTrack, TYPE_INFO(uint32))
STRUCT_INFO_END(CControllerInfo)
STRUCT_INFO_BEGIN(UCol)
STRUCT_VAR_INFO(dcolor, TYPE_INFO(uint32))
STRUCT_INFO_END(UCol)
STRUCT_INFO_BEGIN(SVF_P3S_C4B_T2S)
STRUCT_VAR_INFO(xyz, TYPE_INFO(Vec3f16))
STRUCT_VAR_INFO(color, TYPE_INFO(UCol))
STRUCT_VAR_INFO(st, TYPE_INFO(Vec2f16))
STRUCT_INFO_END(SVF_P3S_C4B_T2S)
-8
View File
@@ -9,23 +9,15 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
ly_get_pal_tool_dirs(pal_tool_dirs ${CMAKE_CURRENT_LIST_DIR}/Platform)
ly_add_target(
NAME CryCommon STATIC
NAMESPACE Legacy
FILES_CMAKE
crycommon_files.cmake
${pal_dir}/crycommon_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
PLATFORM_INCLUDE_FILES
${pal_dir}/crycommon_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PUBLIC
. # Lots of code without CryCommon/
.. # Dangerous since exports CryEngine's path (client code can do CrySystem/ without depending on that target)
${pal_dir}
${pal_tool_dirs}
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
-24
View File
@@ -1,24 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/PlatformRestrictedFileDef.h>
#include <memory>
namespace std
{
#if defined(AZ_RESTRICTED_PLATFORM)
#include AZ_RESTRICTED_FILE(Console_std_h)
#endif
}
-77
View File
@@ -1,77 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : A wrapper that counts the number of times the wrapped object
// has been set This is useful for netserializing an object
// that might be given a new value that s the same as the old value
#ifndef CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H
#define CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H
#pragma once
template <typename T>
struct CountedValue
{
public:
CountedValue()
: m_lastProducedId(0)
, m_lastConsumedId(0) {}
typedef uint32 TCountedID;
void SetAndDirty(const T& value)
{
m_value = value;
++m_lastProducedId;
CRY_ASSERT(m_lastProducedId > 0);
}
const T* GetLatestValue()
{
bool bHasNewValue = IsDirty(); // check for dirtiness before updating ids
m_lastConsumedId = m_lastProducedId;
return bHasNewValue ? &m_value : NULL;
}
inline bool IsDirty() const
{
return m_lastProducedId != m_lastConsumedId;
}
const T& Peek() const
{
return m_value;
}
TCountedID GetLatestID() const
{
return m_lastProducedId;
}
// This method should only be used to update the object during serialization!
void UpdateDuringSerializationOnly(const T& value, TCountedID lastProducedId)
{
m_value = value;
m_lastProducedId = lastProducedId;
}
private:
TCountedID m_lastProducedId;
TCountedID m_lastConsumedId;
T m_value;
};
#endif // CRYINCLUDE_CRYCOMMON_COUNTEDVALUE_H
-160
View File
@@ -1,160 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// support for leak dumping and statistics gathering using vs Crt Debug
// should be included in every DLL below DllMain()
#ifndef CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H
#define CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H
#pragma once
#ifdef WIN32
#ifdef _DEBUG
#include <ILog.h>
#include <ISystem.h> // CryLogAlways
#include <crtdbg.h>
// copied from DBGINT.H (not a public header!)
#define nNoMansLandSize 4
typedef struct _CrtMemBlockHeader
{
struct _CrtMemBlockHeader* pBlockHeaderNext;
struct _CrtMemBlockHeader* pBlockHeaderPrev;
char* szFileName;
int nLine;
size_t nDataSize;
int nBlockUse;
long lRequest;
unsigned char gap[nNoMansLandSize];
/* followed by:
* unsigned char data[nDataSize];
* unsigned char anotherGap[nNoMansLandSize];
*/
} _CrtMemBlockHeader;
struct SFileInfo
{
int blocks;
INT_PTR bytes; //AMD Port
SFileInfo(INT_PTR b) { blocks = 1; bytes = b; }; //AMD Port
};
_CrtMemState lastcheckpoint;
bool checkpointset = false;
extern "C" void __declspec(dllexport) CheckPoint()
{
_CrtMemCheckpoint(&lastcheckpoint);
checkpointset = true;
};
bool pairgreater(const std::pair<string, SFileInfo>& elem1, const std::pair<string, SFileInfo>& elem2)
{
return elem1.second.bytes > elem2.second.bytes;
}
extern "C" void __declspec(dllexport) UsageSummary([[maybe_unused]] ILog * log, char* modulename, int* extras)
{
_CrtMemState state;
if (checkpointset)
{
_CrtMemState recent;
_CrtMemCheckpoint(&recent);
_CrtMemDifference(&state, &lastcheckpoint, &recent);
}
else
{
_CrtMemCheckpoint(&state);
};
INT_PTR numblocks = state.lCounts[_NORMAL_BLOCK]; //AMD Port
INT_PTR totalalloc = state.lSizes[_NORMAL_BLOCK]; //AMD Port
check_convert(extras[0]) = totalalloc;
check_convert(extras[1]) = numblocks;
CryLogAlways("$5---------------------------------------------------------------------------------------------------");
if (!numblocks)
{
CryLogAlways("$3Module %s has no memory in use", modulename);
return;
}
;
CryLogAlways("$5Usage summary for module %s", modulename);
CryLogAlways("%d kbytes (peak %d) in %d objects of %d average bytes\n",
totalalloc / 1024, state.lHighWaterCount / 1024, numblocks, numblocks ? totalalloc / numblocks : 0);
CryLogAlways("%d kbytes allocated over time\n", state.lTotalCount / 1024);
typedef std::map<string, SFileInfo> FileMap;
FileMap fm;
for (_CrtMemBlockHeader* h = state.pBlockHeader; h; h = h->pBlockHeaderNext)
{
if (_BLOCK_TYPE(h->nBlockUse) != _NORMAL_BLOCK)
{
continue;
}
string s = h->szFileName ? h->szFileName : "NO_SOURCE";
if (h->nLine > 0)
{
char buf[16];
sprintf_s(buf, "_%d", h->nLine);
s += buf;
}
FileMap::iterator it = fm.find(s);
if (it != fm.end())
{
(*it).second.blocks++;
(*it).second.bytes += h->nDataSize;
}
else
{
fm.insert(FileMap::value_type(s, SFileInfo(h->nDataSize)));
};
}
;
typedef std::vector< std::pair<string, SFileInfo> > FileVector;
FileVector fv;
for (FileMap::iterator it = fm.begin(); it != fm.end(); ++it)
{
fv.push_back((*it));
}
std::sort(fv.begin(), fv.end(), pairgreater);
for (FileVector::iterator it = fv.begin(); it != fv.end(); ++it)
{
CryLogAlways("%6d kbytes / %6d blocks allocated from %s\n",
(*it).second.bytes / 1024, (*it).second.blocks, (*it).first.c_str());
}
;
};
#endif // _DEBUG
#if !defined(_RELEASE) && !defined(_DLL) && defined(HANDLE)
extern "C" HANDLE _crtheap;
extern "C" HANDLE __declspec(dllexport) GetDLLHeap() {
return _crtheap;
};
#endif
#endif // WIN32
#endif // CRYINCLUDE_CRYCOMMON_CRTDEBUGSTATS_H
+1 -152
View File
@@ -15,7 +15,7 @@
#define CRYINCLUDE_CRYCOMMON_CRYARRAY_H
#pragma once
#include <IGeneralMemoryHeap.h> // <> required for Interfuscator
#include "CryLegacyAllocator.h"
//---------------------------------------------------------------------------
// Convenient iteration macros
@@ -91,8 +91,6 @@ Public classes:
Array<T, [I, STORAGE]>
StaticArray<T, nSIZE, [I]>
DynArray<T, [I, STORAGE, ALLOC]>
FastDynArray<T, [I]>
FixedDynArray<T, [I]>
StaticDynArray<T, nSIZE, [I]>
Support classes are placed in namespaces NArray and NAlloc to reduce global name usage.
@@ -612,13 +610,6 @@ namespace NAlloc
//---------------------------------------------------------------------------
// Allocators for DynArray.
// No reallocation, for use in FixedDynArray
struct NullAlloc
{
static void* alloc(void* pMem, [[maybe_unused]] size_t& nSize, [[maybe_unused]] size_t nAlign, [[maybe_unused]] bool bSlack = false)
{ return pMem; }
};
// Standard CryModule memory allocation, using aligned versions
struct ModuleAlloc
{
@@ -655,128 +646,15 @@ namespace NAlloc
// Standard allocator for DynArray stores a compatibility pointer in the memory
typedef AllocCompatible<ModuleAlloc> StandardAlloc;
// Allocator using specific heaps
struct GeneralHeapAlloc
: ModuleAlloc
{
IGeneralMemoryHeap* m_pHeap;
GeneralHeapAlloc()
: m_pHeap(0) {}
explicit GeneralHeapAlloc(IGeneralMemoryHeap* pHeap)
: m_pHeap(pHeap) {}
void* alloc(void* pMem, size_t& nSize, size_t nAlign, bool bSlack = false) const
{
if (m_pHeap)
{
if (pMem)
{
if (!nSize)
{
// Dealloc
m_pHeap->Free(pMem);
return 0;
}
}
else if (nSize)
{
// Alloc
if (bSlack)
{
nSize = realloc_size(nSize);
}
return m_pHeap->Memalign(nAlign, nSize, "");
}
}
return ModuleAlloc::alloc(pMem, nSize, nAlign, bSlack);
}
};
};
//---------------------------------------------------------------------------
// Storage schemes for dynamic arrays
namespace NArray
{
/*---------------------------------------------------------------------------
// STORAGE prototype for DynArray<T,I,STORAGE>
// Extends ArrayStorage with resizing functionality.
struct DynStorage
{
struct Store<T,I>: ArrayStorage<T,I>::Store
{
I capacity() const;
size_t get_alloc_size() const;
void resize_raw( I new_size, bool allow_slack );
};
};
---------------------------------------------------------------------------*/
//---------------------------------------------------------------------------
// FastDynStorage: STORAGE scheme for DynArray<T,I,STORAGE>.
// Simple extension to ArrayStorage: size & capacity fields are inline, 3 words storage, fast access.
template<class A = NAlloc::StandardAlloc>
struct FastDynStorage
{
template<class T, class I>
struct Store
: private A
, public ArrayStorage::Store<T, I>
{
typedef ArrayStorage::Store<T, I> super_type;
using super_type::m_aElems;
using super_type::m_nCount;
// Construction.
Store()
: m_nCapacity(0)
{
}
Store(const A& a)
: A(a)
, m_nCapacity(0)
{
}
I capacity() const
{ return m_nCapacity; }
size_t get_alloc_size() const
{ return NAlloc::get_alloc_size(*this, m_aElems, capacity() * sizeof(T), alignof(T)); }
void resize_raw(I new_size, bool allow_slack = false)
{
if (allow_slack ? new_size > capacity() : new_size != capacity())
{
m_nCapacity = new_size;
m_aElems = NAlloc::reallocate(static_cast<A&>(*this), m_aElems, m_nCount, m_nCapacity, alignof(T), allow_slack);
}
set_size(new_size);
}
protected:
I m_nCapacity;
void set_size(I new_size)
{
assert(new_size >= 0 && new_size <= capacity());
m_nCount = new_size;
}
};
};
//---------------------------------------------------------------------------
// SmallDynStorage: STORAGE scheme for DynArray<T,I,STORAGE,ALLOC>.
// Array is just a single pointer, size and capacity information stored before the array data.
// Slightly slower than FastDynStorage, optimal for saving space, especially when array likely to be empty.
template<class A = NAlloc::StandardAlloc>
struct SmallDynStorage
@@ -1459,35 +1337,6 @@ struct LegacyDynArray
}
};
//---------------------------------------------------------------------------
template<class T, class I = int, class A = NAlloc::StandardAlloc>
struct FastDynArray
: DynArray< T, I, NArray::FastDynStorage<A> >
{
};
template<class T, class I = int>
struct FixedDynArray
: LegacyDynArray< T, I, NArray::FastDynStorage<NAlloc::NullAlloc> >
{
typedef NArray::ArrayStorage::Store<T, I> S;
void set(void* elems, I mem_size)
{
this->m_aElems = (T*)elems;
this->m_nCapacity = mem_size / sizeof(T);
this->m_nCount = 0;
}
void set(Array<T, I> array)
{
this->m_aElems = array.begin();
this->m_nCapacity = array.size();
this->m_nCount = 0;
}
};
template<class T, int nSIZE, class I = int>
struct StaticDynArray
: LegacyDynArray< T, I, NArray::StaticDynStorage<nSIZE> >
-19
View File
@@ -1207,23 +1207,4 @@ protected:
uint nPrefixLength;
};
// Define an irregular enum with TypeInfo
#define DEFINE_ENUM_VALS(EType, TInt, ...) \
struct EType \
{ \
enum E { __VA_ARGS__ }; \
DEFINE_ENUM_VALUE(EType, E, TInt) \
ILINE static uint Count() { return TypeInfo().Count(); } \
static const CEnumInfo<TInt>& TypeInfo() { \
static char enum_str[] = #__VA_ARGS__; \
static LegacyDynArray<CEnumDef::SElem> Elems; \
CEnumDef::SInit::Init(Elems); \
CEnumDef::SInit __VA_ARGS__; \
static CEnumInfo<TInt> info( #EType, Elems, enum_str); \
return info; \
} \
};
#endif // CRYINCLUDE_CRYCOMMON_CRYCUSTOMTYPES_H
-309
View File
@@ -1,309 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
/*
CryFixedArray.h
- no longer support being created on the stack (since the alignment code was changed to support adding CryFixedArrays into stl::vectors)
- performs construction or destruction only on elements as they become live/dead or are moved around during the RemoveAt() reshuffle
- just a range checked equivelant of a standard array
- for now only allows push_back() population of array
- if using as a class member variable ensure to put the CryFixedArrays after all other member variables at the bottom of your class
to ensure all members stay on the same cacheline
*/
#ifndef CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H
#define CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H
#pragma once
#define DEBUG_CRYFIXED_ARRAY _DEBUG
template<
unsigned int align >
struct CryFixedArrayDatum
{
};
template<>
struct CryFixedArrayDatum< 4 >
{
typedef uint32 TDatum;
};
template<>
struct CryFixedArrayDatum< 8 >
{
typedef uint64 TDatum;
};
template <class T, unsigned int N>
class CryFixedArray
{
protected:
enum
{
ALIGN = MAX(alignof(T), sizeof(unsigned int))
}; // ALIGN at least sizeof(unsigned int)
typedef typename CryFixedArrayDatum< ALIGN >::TDatum TDatum;
uint32 m_curSize[ sizeof (TDatum) / sizeof (uint32) ]; // Padded for alignment
TDatum m_data[(N * sizeof(T) + (sizeof(TDatum) - 1)) / sizeof(TDatum)]; // simple debugging - in VS: just add to a watch as "(T*)m_data, <N>" to see the array. ie. "(int*)m_data, 5" - the size of the array has to be a literal int
public:
typedef T* iterator;
typedef const T* const_iterator;
CryFixedArray()
{
#if DEBUG_CRYFIXED_ARRAY
if (((uintptr_t)m_data & (ALIGN - 1)) != 0)
{
CryLogAlways("CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported.");
}
#endif
CRY_ASSERT_MESSAGE(((uintptr_t)m_data & (ALIGN - 1)) == 0, "CryFixedArray() error - data is not aligned. This may happen if you are creating a CryFixedArray on the stack, which isn't supported.");
m_curSize[0] = 0;
}
CryFixedArray(const CryFixedArray& other)
{
// doesn't require clear() this is newly constructed
m_curSize[0] = other.m_curSize[0];
int size = m_curSize[0];
for (int i = 0; i < size; i++)
{
T& ele = operator[](i);
const T& otherEle = other.operator[](i);
new (&ele)T(otherEle); // placement new
}
}
CryFixedArray& operator=(const CryFixedArray& other)
{
if (this != &other)
{
clear(); // necessary to avoid potentially leaking within existing elements
m_curSize[0] = other.m_curSize[0];
int size = m_curSize[0];
for (int i = 0; i < size; i++)
{
T& ele = operator[](i);
const T& otherEle = other.operator[](i);
//ele = otherEle; // assignment instead of placement new to keep type of operation consistent - this cannot be done until this is rewritten to assign over existing elements and deconstruct any left overs, and placement new any new elements
new (&ele)T(otherEle); // placement new
}
}
return *this;
}
virtual ~CryFixedArray()
{
clear();
}
ILINE T& at(unsigned int i)
{
#if DEBUG_CRYFIXED_ARRAY
if (i < size())
{
return alias_cast<T*>(m_data)[i];
}
else
{
// Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!!
CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N);
CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N));
abort(); // better option than dereferncing a nullptr?
}
#else
return alias_cast<T*>(m_data)[i];
#endif
}
ILINE const T& at(unsigned int i) const
{
#if DEBUG_CRYFIXED_ARRAY
if (i < size())
{
return alias_cast<const T*>(m_data)[i];
}
else
{
// Log is required now as its possible to turn off assert output logging, yet you really want to know if this is happening!!!!
CryLogAlways("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d) - forcing a crash", i, m_curSize[0], N);
CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::at(i=%d) failed as i is out of range of curSize=%d (maxSize=%d)", i, m_curSize[0], N));
abort(); // better option than dereferncing a nullptr?
}
#else
return alias_cast<const T*>(m_data)[i];
#endif
}
ILINE const T& operator[](unsigned int i) const
{
return at(i);
}
ILINE T& operator[](unsigned int i)
{
return at(i);
}
ILINE void clear()
{
for (uint32 i = 0; i < m_curSize[0]; i++)
{
T& ele = operator[](i);
ele.~T();
}
m_curSize[0] = 0;
#if DEBUG_CRYFIXED_ARRAY
memset(m_data, 0, N * sizeof(T));
#endif
}
ILINE iterator begin()
{
return alias_cast<T*>(m_data);
}
ILINE const_iterator begin() const
{
return alias_cast<T*>(m_data);
}
ILINE iterator end()
{
return &(alias_cast<T*>(m_data))[m_curSize[0]];
}
ILINE const_iterator end() const
{
return &(alias_cast<T*>(m_data))[m_curSize[0]];
}
ILINE unsigned int max_size() const { return N; }
ILINE unsigned int size() const { return m_curSize[0]; }
ILINE bool empty() const { return size() == 0; }
ILINE unsigned int isfull() const { return (size() == max_size()); }
// allows you to push back default constructed elements
ILINE void push_back ()
{
unsigned int curSize = size();
if (curSize < N)
{
T* newT = &(alias_cast<T*>(m_data))[curSize];
new (newT) T();
m_curSize[0]++;
}
else
{
CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N);
CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N));
}
}
ILINE void push_back (const T& ele)
{
unsigned int curSize = size();
if (curSize < N)
{
T* newT = &(alias_cast<T*>(m_data))[curSize];
new (newT) T(ele); // placement new copy constructor - setup vtable etc
m_curSize[0]++;
}
else
{
CryLogAlways("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N);
CRY_ASSERT_TRACE(0, ("CryFixedArray::push_back() failing as array of size %u is full - NOT adding element", N));
}
}
ILINE void pop_back()
{
if (size() > 0)
{
back().~T(); // destruct back
m_curSize[0]--;
}
else
{
CryLogAlways("CryFixedArray::pop_back() failed as array is empty");
CRY_ASSERT_MESSAGE(0, "CryFixedArray::pop_back() failed as array is empty");
}
}
protected:
ILINE const T& backEx() const
{
#if DEBUG_CRYFIXED_ARRAY
if (m_curSize[0] > 0)
{
return (alias_cast<T*>(m_data))[m_curSize[0] - 1];
}
else
{
CryLogAlways("CryFixedArray::back() failed as array is empty");
CRY_ASSERT_MESSAGE(0, "CryFixedArray::back() failed as array is empty");
abort(); // better option than dereferncing a nullptr?
}
#else
return (alias_cast<T*>(m_data))[m_curSize[0] - 1];
#endif
}
public:
ILINE const T& back() const
{
return backEx();
}
ILINE T& back()
{
return (T&)(backEx());
}
// if returns true then an element has been swapped into the new element[i] and as such may need updating to reflect its new location in memory
ILINE bool removeAt(uint32 i)
{
bool swappedElement = false;
if (i < m_curSize[0])
{
if (i != m_curSize[0] - 1)
{
operator[](i).~T(); // destruct element being removed
// copy back() into element i
T* newT = &(alias_cast<T*>(m_data))[i];
new (newT) T(back()); // placement new copy constructor - setup vtable etc
swappedElement = true;
}
pop_back(); // will destruct back()
}
else
{
CryLog("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0]);
CRY_ASSERT_MESSAGE(0, string().Format("CryFixedArray::removeAt() failed as i=%d is out of range of curSize=%d", i, m_curSize[0]));
}
return swappedElement;
}
};
#endif // CRYINCLUDE_CRYCOMMON_CRYFIXEDARRAY_H
-15
View File
@@ -2019,21 +2019,6 @@ inline CryStackStringT<T, S> CryStackStringT<T, S>::Tokenize(const_str charSet,
return CryStackStringT<T, S>();
}
//////////////////////////////////////////////////////////////////////////
// Specialization providing efficient move semantics for array classes.
template <class T, size_t S>
bool raw_movable(const CryStackStringT<T, S>& str)
{
return false;
}
template <class T, size_t S>
void move_init(CryStackStringT<T, S>& dest, CryStackStringT<T, S>& source)
{
dest.move(source);
}
#if defined(_RELEASE)
#define ASSERT_LEN (void)(0)
#define ASSERT_WLEN (void)(0)
@@ -1,274 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
/*
* Part of this code coming from STLPort alloc
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Copyright (c) 1997
* Moscow Center for SPARC Technology
*
* Copyright (c) 1999
* Boris Fomitchev
*
*
*/
#ifndef CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H
#define CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H
#pragma once
#include <algorithm>
#define CRY_STL_ALLOC
#if defined(LINUX64) || defined(APPLE)
#include <sys/mman.h>
#endif
#include <string.h> // memset
// DON't USE _MAX_BYTES as identifier for Max Bytes, STLPORT defines the same enum
// this leads to situation where the wrong enum is choosen in different compilation units
// which in case leads to errors(The stlport one is defined as 128)
#if defined (__OS400__) || defined (_WIN64) || defined(MAC) || defined(LINUX64)
enum {_ALIGNMENT = 16, _ALIGN_SHIFT = 4, __MAX_BYTES = 512, NFREELISTS=32, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 40};
#else
enum {_ALIGNMENT = 8, _ALIGN_SHIFT = 3, __MAX_BYTES = 512, NFREELISTS = 64, ADDRESSSPACE = 2 * 1024 * 1024, ADDRESS_SHIFT = 20};
#endif /* __OS400__ */
#define CRY_MEMORY_ALLOCATOR
#define S_FREELIST_INDEX(__bytes) ((__bytes - size_t(1)) >> (int)_ALIGN_SHIFT)
class _Node_alloc_obj {
public:
_Node_alloc_obj * _M_next;
};
#if defined (_WIN64) || defined(APPLE) || defined(LINUX64)
#define MASK_COUNT 0x000000FFFFFFFFFF
#define MASK_VALUE 0xFFFFFF
#define MASK_NEXT 0xFFFFFFFFFF000000
#define MASK_SHIFT 24
#else
#define MASK_COUNT 0x000FFFFF
#define MASK_VALUE 0xFFF
#define MASK_NEXT 0xFFFFF000
#define MASK_SHIFT 12
#endif
#define NUM_OBJ 64
struct _Obj_Address {
// short int * _M_next;
// short int
size_t GetNext(size_t pBase) {
return pBase +(size_t)(_M_value >> MASK_SHIFT);
}
//size_t GetNext() {
// return (size_t)(_M_value >> 20);
//}
size_t GetCount() {
return _M_value & MASK_VALUE;
}
void SetNext(/*void **/size_t pNext) {
_M_value &= MASK_COUNT;
_M_value |= (size_t)pNext << MASK_SHIFT;
}
void SetCount(size_t count) {
_M_value &= MASK_NEXT;
_M_value |= count & MASK_VALUE;
}
private:
size_t _M_value;
// short int * _M_end;
};
//struct _Node_Allocations_Tree {
// enum { eListSize = _Size / (sizeof(void *) * _Num_obj); };
// _Obj_Address * _M_allocations_list[eListSize];
// int _M_Count;
// _Node_Allocations_Tree * _M_next;
//};
template<int _Size>
struct _Node_Allocations_Tree {
//Pointer to the end of the memory block
char *_M_end;
enum { eListSize = _Size / (sizeof(void *) * NUM_OBJ) };
// List of allocations
_Obj_Address _M_allocations_list[eListSize];
int _M_allocations_count;
//Pointer to the next memory block
_Node_Allocations_Tree *_M_Block_next;
};
struct _Node_alloc_Mem_block_Huge {
//Pointer to the end of the memory block
char *_M_end;
// number
int _M_count;
_Node_alloc_Mem_block_Huge *_M_next;
};
template<int _Size>
struct _Node_alloc_Mem_block {
//Pointer to the end of the memory block
char *_M_end;
//Pointer to the next memory block
_Node_alloc_Mem_block_Huge *_M_huge_block;
_Node_alloc_Mem_block *_M_next;
};
// Allocators!
enum EAllocFreeType
{
eCryDefaultMalloc,
eCryMallocCryFreeCRTCleanup,
};
template <EAllocFreeType type>
struct Node_Allocator
{
inline void * pool_alloc(size_t size)
{
return CryModuleMalloc(size);
};
inline void * cleanup_alloc(size_t size)
{
return CryCrtMalloc(size);
};
inline size_t pool_free(void * ptr)
{
CryModuleFree(ptr);
return 0;
};
inline void cleanup_free(void * ptr)
{
CryCrtFree(ptr);
};
inline size_t getSize(void * ptr)
{
return CryCrtSize(ptr);
}
};
// partial
template <>
struct Node_Allocator<eCryDefaultMalloc>
{
inline void * pool_alloc(size_t size)
{
return CryCrtMalloc(size);
};
inline void * cleanup_alloc(size_t size)
{
return CryCrtMalloc(size);
};
inline size_t pool_free(void * ptr)
{
size_t n = CryCrtSize(ptr);
CryCrtFree(ptr);
return n;
};
inline void cleanup_free(void * ptr)
{
CryCrtFree(ptr);
};
inline size_t getSize(void * ptr)
{
return CryCrtSize(ptr);
}
};
// partial
template <>
struct Node_Allocator<eCryMallocCryFreeCRTCleanup>
{
inline void * pool_alloc(size_t size)
{
return CryCrtMalloc(size);
};
inline void * cleanup_alloc(size_t size)
{
return CryCrtMalloc(size);
};
inline size_t pool_free(void * ptr)
{
return CryCrtFree(ptr);
};
inline void cleanup_free(void * ptr)
{
CryCrtFree(ptr);
};
inline size_t getSize(void * ptr)
{
return CryCrtSize(ptr);
}
};
#include "MultiThread.h"
struct InternalCriticalSectionDummy {
char padding[128];
} ;
inline void CryInternalCreateCriticalSection(void * pCS)
{
CryCreateCriticalSectionInplace(pCS);
}
// A class that forward node allocator calls directly to CRT
struct cry_crt_node_allocator
{
static const size_t MaxSize = ~0;
static void *alloc(size_t __n)
{
return CryCrtMalloc(__n);
}
static size_t dealloc( void *p )
{
return CryCrtFree(p);
}
static void *allocate(size_t __n)
{
return alloc(__n);
}
static void *allocate(size_t __n, [[maybe_unused]] size_t nAlignment)
{
return alloc(__n);
}
static size_t deallocate(void *__p)
{
return dealloc(__p);
}
void cleanup() {}
};
//#endif // WIN32|DEBUG
#endif // CRYINCLUDE_CRYCOMMON_CRYMEMORYALLOCATOR_H
-295
View File
@@ -1,295 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Defines functions for CryEngine custom memory manager.
#pragma once
// Section dictionary
#if defined(AZ_RESTRICTED_PLATFORM)
#define CRYMEMORYMANAGER_H_SECTION_TRAITS 1
#define CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY 2
#endif
#include <AzCore/PlatformRestrictedFileDef.h>
// Traits
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_TRAITS
#include AZ_RESTRICTED_FILE(CryMemoryManager_h)
#else
#if !defined(APPLE)
#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H 1
#endif
#if defined(LINUX) || defined(APPLE)
#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H 1
#endif
#if !defined(LINUX) && !defined(APPLE)
#define CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H 1
#endif
#if !defined(APPLE)
#define CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY 1
#endif
#endif
#include "platform.h"
#include <stdarg.h>
#include <algorithm>
#if defined(APPLE) || defined(ANDROID)
#include <AzCore/Memory/OSAllocator.h> // memalign
#endif // defined(APPLE)
#ifndef STLALLOCATOR_CLEANUP
#define STLALLOCATOR_CLEANUP
#endif
#define _CRY_DEFAULT_MALLOC_ALIGNMENT 4
#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_MALLOC_H
#include <malloc.h>
#endif
#if defined(__cplusplus)
#if CRYMEMORYMANAGER_H_TRAIT_INCLUDE_NEW_NOT_NEW_H
#include <new>
#else
#include <new.h>
#endif
#endif
#ifdef CRYSYSTEM_EXPORTS
#define CRYMEMORYMANAGER_API DLL_EXPORT
#else
#define CRYMEMORYMANAGER_API DLL_IMPORT
#endif
#ifdef __cplusplus
#if defined(_DEBUG) && CRYMEMORYMANAGER_H_TRAIT_INCLUDE_CRTDBG_H
#include <crtdbg.h>
#endif //_DEBUG
#include "LegacyAllocator.h"
namespace CryMemory
{
// checks if the heap is valid in debug; in release, this function shouldn't be called
// returns non-0 if it's valid and 0 if not valid
ILINE int IsHeapValid()
{
#if (defined(_DEBUG) && !defined(RELEASE_RUNTIME) && CRYMEMORYMANAGER_H_TRAIT_USE_CRTCHECKMEMORY) || (defined(DEBUG_MEMORY_MANAGER))
return _CrtCheckMemory();
#else
return true;
#endif
}
inline void* AllocPages(size_t size)
{
const size_t alignment = AZ_PAGE_SIZE;
void* ret = AZ::AllocatorInstance<AZ::LegacyAllocator>::Get().Allocate(size, alignment, 0, "AllocPages", __FILE__, __LINE__);
return ret;
}
inline void FreePages(void* p, size_t size)
{
const size_t alignment = AZ_PAGE_SIZE;
AZ::AllocatorInstance<AZ::LegacyAllocator>::Get().DeAllocate(p, size, alignment);
}
}
//////////////////////////////////////////////////////////////////////////
#endif //__cplusplus
struct ICustomMemoryHeap;
class IGeneralMemoryHeap;
class IPageMappingHeap;
class IMemoryAddressRange;
// Description:
// Interfaces that allow access to the CryEngine memory manager.
struct IMemoryManager
{
typedef unsigned char HeapHandle;
enum
{
BAD_HEAP_HANDLE = 0xFF
};
struct SProcessMemInfo
{
uint64 PageFaultCount;
uint64 PeakWorkingSetSize;
uint64 WorkingSetSize;
uint64 QuotaPeakPagedPoolUsage;
uint64 QuotaPagedPoolUsage;
uint64 QuotaPeakNonPagedPoolUsage;
uint64 QuotaNonPagedPoolUsage;
uint64 PagefileUsage;
uint64 PeakPagefileUsage;
uint64 TotalPhysicalMemory;
int64 FreePhysicalMemory;
uint64 TotalVideoMemory;
int64 FreeVideoMemory;
};
enum EAllocPolicy
{
eapDefaultAllocator,
eapPageMapped,
eapCustomAlignment,
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION CRYMEMORYMANAGER_H_SECTION_ALLOCPOLICY
#include AZ_RESTRICTED_FILE(CryMemoryManager_h)
#endif
};
virtual ~IMemoryManager(){}
virtual bool GetProcessMemInfo(SProcessMemInfo& minfo) = 0;
//////////////////////////////////////////////////////////////////////////
// Heap Tracing API
virtual HeapHandle TraceDefineHeap(const char* heapName, size_t size, const void* pBase) = 0;
virtual void TraceHeapAlloc(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint = 0) = 0;
virtual void TraceHeapFree(HeapHandle heap, void* mem, size_t blockSize) = 0;
virtual void TraceHeapSetColor(uint32 color) = 0;
virtual uint32 TraceHeapGetColor() = 0;
virtual void TraceHeapSetLabel(const char* sLabel) = 0;
//////////////////////////////////////////////////////////////////////////
// Create an instance of ICustomMemoryHeap
virtual ICustomMemoryHeap* const CreateCustomMemoryHeapInstance(EAllocPolicy const eAllocPolicy) = 0;
virtual IGeneralMemoryHeap* CreateGeneralExpandingMemoryHeap(size_t upperLimit, size_t reserveSize, const char* sUsage) = 0;
virtual IGeneralMemoryHeap* CreateGeneralMemoryHeap(void* base, size_t sz, const char* sUsage) = 0;
virtual IMemoryAddressRange* ReserveAddressRange(size_t capacity, const char* sName) = 0;
virtual IPageMappingHeap* CreatePageMappingHeap(size_t addressSpace, const char* sName) = 0;
};
// Global function implemented in CryMemoryManager_impl.h
IMemoryManager* CryGetIMemoryManager();
// Summary:
// Structure filled by call to CryModuleGetMemoryInfo().
struct CryModuleMemoryInfo
{
uint64 requested;
// Total Ammount of memory allocated.
uint64 allocated;
// Total Ammount of memory freed.
uint64 freed;
// Total number of memory allocations.
int num_allocations;
// Allocated in CryString.
uint64 CryString_allocated;
// Allocated in STL.
uint64 STL_allocated;
// Amount of memory wasted in pools in stl (not usefull allocations).
uint64 STL_wasted;
};
struct CryReplayInfo
{
uint64 uncompressedLength;
uint64 writtenLength;
uint32 trackingSize;
const char* filename;
};
//////////////////////////////////////////////////////////////////////////
// Extern declarations of globals inside CrySystem.
//////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif //__cplusplus
void* CryMalloc(size_t size, size_t& allocated, size_t alignment);
void* CryRealloc(void* memblock, size_t size, size_t& allocated, size_t& oldsize, size_t alignment);
size_t CryFree(void* p, size_t alignment);
size_t CryGetMemSize(void* p, size_t size);
int CryStats(char* buf);
void CryFlushAll();
void CryCleanup();
int CryGetUsedHeapSize();
int CryGetWastedHeapSize();
size_t CrySystemCrtGetUsedSpace();
CRYMEMORYMANAGER_API void CryGetIMemoryManagerInterface(void** pIMemoryManager);
#ifdef __cplusplus
}
#endif //__cplusplus
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Cry Memory Manager accessible in all build modes.
//////////////////////////////////////////////////////////////////////////
#if !defined(USING_CRY_MEMORY_MANAGER)
#define USING_CRY_MEMORY_MANAGER
#endif
#include "CryLegacyAllocator.h"
template<typename T, typename ... Args>
inline T* CryAlignedNew(Args&& ... args)
{
void* pAlignedMemory = CryModuleMemalign(sizeof(T), std::alignment_of<T>::value);
return new(pAlignedMemory) T(std::forward<Args>(args) ...);
}
// This utility function should be used for allocating arrays of objects with specific alignment requirements on the heap.
// Note: The caller must remember the number of items in the array, since CryAlignedDeleteArray needs this information.
template<typename T>
inline T* CryAlignedNewArray(size_t count)
{
T* const pAlignedMemory = reinterpret_cast<T*>(CryModuleMemalign(sizeof(T) * count, std::alignment_of<T>::value));
T* pCurrentItem = pAlignedMemory;
for (size_t i = 0; i < count; ++i, ++pCurrentItem)
{
new(static_cast<void*>(pCurrentItem))T();
}
return pAlignedMemory;
}
// Utility function that frees an object previously allocated with CryAlignedNew.
template<typename T>
inline void CryAlignedDelete(T* pObject)
{
if (pObject)
{
pObject->~T();
CryModuleMemalignFree(pObject);
}
}
// Utility function that frees an array of objects previously allocated with CryAlignedNewArray.
// The same count used to allocate the array must be passed to this function.
template<typename T>
inline void CryAlignedDeleteArray(T* pObject, size_t count)
{
if (pObject)
{
for (size_t i = 0; i < count; ++i)
{
(pObject + i)->~T();
}
CryModuleMemalignFree(pObject);
}
}
@@ -1,41 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Provides implementation for CryMemoryManager globally defined functions.
// This file included only by platform_impl.cpp, do not include it directly in code!
#pragma once
#ifdef AZ_MONOLITHIC_BUILD
#include <ISystem.h> // <> required for Interfuscator
#endif // AZ_MONOLITHIC_BUILD
#include "CryLibrary.h"
#include <AzCore/Module/Environment.h>
#define DLL_ENTRY_GETMEMMANAGER "CryGetIMemoryManagerInterface"
// Resolve IMemoryManager by looking in this DLL, then loading and rummaging through
// CrySystem. Cache the result per DLL, because this is not quick.
IMemoryManager* CryGetIMemoryManager()
{
static AZ::EnvironmentVariable<IMemoryManager*> memMan = nullptr;
if (!memMan)
{
memMan = AZ::Environment::FindVariable<IMemoryManager*>("CryIMemoryManagerInterface");
AZ_Assert(memMan, "Unable to find CryIMemoryManagerInterface via AZ::Environment");
}
return *memMan;
}
-1
View File
@@ -19,7 +19,6 @@
#include <StlUtils.h>
#include <CrySizer.h>
#include <CryCrc32.h>
#include <STLGlobalAllocator.h>
#include <AzCore/std/containers/unordered_map.h>
class CNameTable;
-21
View File
@@ -48,8 +48,6 @@ struct SPipTangents;
#include <string.h> // workaround for Amd64 compiler
#endif
#include <IResourceCollector.h> // <> required for Interfuscator. IResourceCollector
namespace AZ
{
class Vector3;
@@ -335,20 +333,6 @@ public:
}
}
template<typename T>
void AddObject(const TArray<T>& rVector)
{
if (!this->AddObject(rVector.begin(), rVector.capacity() * sizeof(T)))
{
return;
}
for (int i = 0, end = rVector.size(); i < end; ++i)
{
this->AddObject(rVector[i]);
}
}
template<typename T>
void AddObject(const PodArray<T>& rVector)
{
@@ -427,11 +411,6 @@ public:
return AddObject (&rObject, sizeof(T));
}
// used to collect the assets needed for streaming and to gather statistics
// always returns a valid reference
virtual IResourceCollector* GetResourceCollector() = 0;
virtual void SetResourceCollector(IResourceCollector* pColl) = 0;
bool Add (const char* szText)
{
return AddObject(szText, strlen(szText) + 1);
@@ -1,634 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Specialized Container for Renderer data with the following proberties:
// - Created during the 3DEngine Update, comsumed in the renderer in the following frame
// - This Container is very restricted and likely not optimal for other situations
#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H
#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H
#pragma once
// This container is specialized for data which is generated in the 3DEngine and consumed by the renderer
// in the following frame due to multithreaded rendering. To be useable by Jobs as well as other Threads
// some very specific desing choices were taken:
// First of the underlying continous memory block is only resized during a call to 'CoalesceMemory'
// to prevent freeing a memory block which could be used by another thread.
// If new memory is requiered, a page of 4 KB is allocated and used as a temp storage till the next
// call to 'CoalesceMemory' which then copies all page memory into one continous block.
// Also all threading relevant functions are implemented LockLess to prevent lock contention and make
// this container useable from Jobs
//
// Right now, the main usage pattern of this container is by the RenderThread, who calls at the beginning
// of its frame 'CoalesceMemory', since then we can be sure that the 3DEngine has finished creating it's elements.
//
// Since the main purpose of this container is multi-threading adding of elements, a slight change was done to the
// push_back interface compared to std::vector:
// All implemented push_back variants can return a pointer into the storage (safe since no memory is freed during adding)
// and a index for this elements. This is done since calling operator[] could be expensive when called before 'CoalesceMemory'
//
// For ease of implementation (and a little bit of speed), this container only supports POD types (which can be copied with memcpy)
// also note that this container only supports push_back (and resize back to 0) and no pop back due cost (performance and code complexity) of supporting lock-free in parallel pop_back
#define TSRC_ALIGN _MS_ALIGN(128)
template<typename T>
class TSRC_ALIGN CThreadSafeRendererContainer
{
public:
CThreadSafeRendererContainer();
~CThreadSafeRendererContainer();
//NOTE: be aware that these valus can potentially change if some objects are added in parallel
size_t size() const;
size_t empty() const;
size_t capacity() const;
//NOTE: be aware that this operator can be more expensive if the memory was not coalesced before
T& operator[](size_t n);
const T& operator[](size_t n) const;
T* push_back_new();
T* push_back_new(size_t& nIndex);
void push_back(const T&);
void push_back(const T&, size_t& nIndex);
// NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe
void clear();
void resize(size_t n);
void reserve(size_t n);
void CoalesceMemory();
void GetMemoryUsage(ICrySizer*) const;
// disable copy/assignment
CThreadSafeRendererContainer(const CThreadSafeRendererContainer& rOther) = delete;
CThreadSafeRendererContainer& operator=(const CThreadSafeRendererContainer& rOther) = delete;
private:
/////////////////////////////////////
// Struct to represent a memory chunk
// used in fallback allocations during 'Fill' phase
class CMemoryPage
{
public:
// size of a page to allocate, the CMemoryPage is just the header,
// the actual object data is stored in the 4KB chunk right
// after the header (while keeping the requiered alignment and so on)
enum
{
nMemoryPageSize = 4096
};
CMemoryPage();
// allocation functions
static CMemoryPage* AllocateNewPage();
bool TryAllocateElement(size_t& nIndex, T*& pObj);
// access to the elements
T& GetElement(size_t n);
T* GetData() const;
// information about the page (NOTE: not thread-safe in all combinations)
size_t Size() const;
size_t Capacity() const;
size_t GetDataSize() const;
CMemoryPage* m_pNext; // Pointer to next entry in single-linked list of CMemoryPages
private:
LONG m_nSize; // Number of elements currently in the page
LONG m_nCapacity; // Number of elements which could fit into the page
T* m_arrData; // Element memory, from the same memory chunk right after the CMemoryPage class
};
/////////////////////////////////////
// Private functions which do the lock-less updating
T* push_back_impl(size_t& nIndex);
bool try_append_to_continous_memory(size_t& nIndex, T*& pObj);
T& GetMemoryPageElement(size_t n);
/////////////////////////////////////
// Private Member Variables
T* m_arrData; // Storage for the continous memory part, during coalescing resized to hold all page memory
LONG m_nCapacity; // Avaible Memory in continous memory part, if exhausted during 'Fill' phase, pages as temp memory chunks are allocated
CMemoryPage* m_pMemoryPages; // Single linked list of memory chunks, used for fallback allocations during 'Fill' phase (to prevent changing the continous memory block during 'Fill'
LONG m_nSize; // Number of elements currently in the container, can be larger than m_nCapacity due the nonContinousPages
bool m_bElementAccessSafe; // bool to indicate if we are currently doing a 'CoalasceMemory' step, during which some operations are now allowed
} _ALIGN(128);
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline CThreadSafeRendererContainer<T>::CThreadSafeRendererContainer()
: m_arrData(NULL)
, m_nCapacity(0)
, m_pMemoryPages(NULL)
, m_nSize(0)
, m_bElementAccessSafe(true)
{
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline CThreadSafeRendererContainer<T>::~CThreadSafeRendererContainer()
{
clear();
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeRendererContainer<T>::size() const
{
return *const_cast<volatile LONG*>(&m_nSize);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeRendererContainer<T>::empty() const
{
return *const_cast<volatile LONG*>(&m_nSize) == 0;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeRendererContainer<T>::capacity() const
{
// capacity of continous memory block
LONG nCapacity = m_nCapacity;
// add capacity of all memory pages
CMemoryPage* pCurrentMemoryPage = m_pMemoryPages;
while (pCurrentMemoryPage)
{
nCapacity += pCurrentMemoryPage->Capacity();
pCurrentMemoryPage = pCurrentMemoryPage->m_pNext;
}
return nCapacity;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T& CThreadSafeRendererContainer<T>::operator[](size_t n)
{
assert(m_bElementAccessSafe);
T* pRet = NULL;
#if !defined(NULL_RENDERER)
assert((LONG)n < m_nSize);
#endif
if ((LONG)n < m_nCapacity)
{
pRet = &m_arrData[n];
}
else
{
pRet = &GetMemoryPageElement(n);
}
return *pRet;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline const T& CThreadSafeRendererContainer<T>::operator[](size_t n) const
{
return const_cast<const T&>(const_cast<CThreadSafeRendererContainer<T>*>(this)->operator[](n));
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T* CThreadSafeRendererContainer<T>::push_back_new()
{
assert(m_bElementAccessSafe);
size_t nUnused = ~0;
return push_back_impl(nUnused);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T* CThreadSafeRendererContainer<T>::push_back_new(size_t& nIndex)
{
assert(m_bElementAccessSafe);
return push_back_impl(nIndex);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeRendererContainer<T>::push_back(const T& rObj)
{
assert(m_bElementAccessSafe);
size_t nUnused = ~0;
T* pObj = push_back_impl(nUnused);
*pObj = rObj;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeRendererContainer<T>::push_back(const T& rObj, size_t& nIndex)
{
assert(m_bElementAccessSafe);
T* pObj = push_back_impl(nIndex);
*pObj = rObj;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeRendererContainer<T>::clear()
{
assert(m_bElementAccessSafe);
// free continous part
CryModuleMemalignFree(m_arrData);
m_arrData = NULL;
// free non-continous pages if we have some
CMemoryPage* pCurrentMemoryPage = m_pMemoryPages;
while (pCurrentMemoryPage)
{
CMemoryPage* pOldPage = pCurrentMemoryPage;
pCurrentMemoryPage = pCurrentMemoryPage->m_pNext;
CryModuleFree(pOldPage);
}
m_pMemoryPages = NULL;
m_nSize = 0;
m_nCapacity = 0;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeRendererContainer<T>::resize(size_t n)
{
assert(m_bElementAccessSafe);
CoalesceMemory();
size_t nOldSize = m_nSize;
m_nSize = n;
if ((LONG)n <= m_nCapacity)
{
return;
}
T* arrOldData = m_arrData;
m_arrData = reinterpret_cast<T*>(CryModuleMemalign(n * sizeof(T), alignof(T)));
memcpy(m_arrData, arrOldData, nOldSize * sizeof(T));
memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T));
CryModuleMemalignFree(arrOldData);
m_nCapacity = n;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeRendererContainer<T>::reserve(size_t n)
{
assert(m_bElementAccessSafe);
CoalesceMemory();
if ((LONG)n <= m_nCapacity)
{
return;
}
T* arrOldData = m_arrData;
m_arrData = reinterpret_cast<T*>(CryModuleMemalign(n * sizeof(T), alignof(T)));
memcpy(m_arrData, arrOldData, m_nSize * sizeof(T));
memset(&m_arrData[m_nCapacity], 0, (n - m_nCapacity) * sizeof(T));
CryModuleMemalignFree(arrOldData);
m_nCapacity = n;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline bool CThreadSafeRendererContainer<T>::try_append_to_continous_memory(size_t& nIndex, T*& pObj)
{
assert(m_bElementAccessSafe);
LONG nSize = ~0;
LONG nCapacity = ~0;
do
{
// read volatile the new size
nSize = *const_cast<volatile LONG*>(&m_nSize);
nCapacity = *const_cast<volatile LONG*>(&m_nCapacity);
if (nSize >= nCapacity)
{
return false;
}
} while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&m_nSize), nSize + 1, nSize) != nSize);
nIndex = nSize;
pObj = &m_arrData[nSize];
return true;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T* CThreadSafeRendererContainer<T>::push_back_impl(size_t& nIndex)
{
assert(m_bElementAccessSafe);
T* pObj = NULL;
// non atomic check to see if there is space in the continous array
if (try_append_to_continous_memory(nIndex, pObj))
{
return pObj;
}
// exhausted continous memory, falling back to page allocation
for (;; )
{
assert(m_bElementAccessSafe);
size_t nPageBaseIndex = 0;
// traverse the page list till the first page with free memory
CMemoryPage* pCurrentMemoryPage = m_pMemoryPages;
while (pCurrentMemoryPage)
{
size_t nAvaibleElements = pCurrentMemoryPage->Capacity() - pCurrentMemoryPage->Size();
if (nAvaibleElements)
{
break;
}
// no memory in this page, go to the next one
nPageBaseIndex += pCurrentMemoryPage->Capacity();
pCurrentMemoryPage = pCurrentMemoryPage->m_pNext;
}
// try to allocate a element on this page
if (pCurrentMemoryPage && pCurrentMemoryPage->TryAllocateElement(nIndex, pObj))
{
// update global elements counter
CryInterlockedIncrement(alias_cast<volatile int*>(&m_nSize));
// adjust in-page-index to global index
nIndex += nPageBaseIndex + m_nCapacity;
return pObj;
}
else
{
// all pages are empty, allocate and link a new one
CMemoryPage* pNewPage = CMemoryPage::AllocateNewPage();
void* volatile* ppLastMemoryPageAddress = NULL;
do
{
// find place to link in page
CMemoryPage* pLastMemoryPage = m_pMemoryPages;
ppLastMemoryPageAddress = alias_cast<void* volatile*>(&m_pMemoryPages);
while (pLastMemoryPage)
{
ppLastMemoryPageAddress = alias_cast<void* volatile*>(&(pLastMemoryPage->m_pNext));
pLastMemoryPage = pLastMemoryPage->m_pNext;
}
} while (CryInterlockedCompareExchangePointer(ppLastMemoryPageAddress, pNewPage, NULL) != NULL);
}
}
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T& CThreadSafeRendererContainer<T>::GetMemoryPageElement(size_t n)
{
assert(m_bElementAccessSafe);
size_t nFirstListIndex = m_nCapacity;
CMemoryPage* pCurrentMemoryPage = m_pMemoryPages;
size_t nPageCapacity = pCurrentMemoryPage->Capacity();
while (n >= (nFirstListIndex + nPageCapacity))
{
// this is threadsafe because we assume that if we want to get element 'n'
// the clientcode did already fill the container up to element 'n'
// thus up to 'n', m_pNonContinousList will have valid pages
// NOTE: This is not safe when trying to read a element behind the valid
// range (same as std::vector)
nFirstListIndex += nPageCapacity;
pCurrentMemoryPage = pCurrentMemoryPage->m_pNext;
// update page capacity, since it can differe due alignment
nPageCapacity = pCurrentMemoryPage->Capacity();
}
return pCurrentMemoryPage->GetElement(n - nFirstListIndex);
}
///////////////////////////////////////////////////////////////////////////////
// When not not in the 'Fill' phase, it is safe to colace all page entries into one continous memory block
template<typename T>
inline void CThreadSafeRendererContainer<T>::CoalesceMemory()
{
assert(m_bElementAccessSafe);
if (m_pMemoryPages == NULL)
{
return; // nothing to do
}
// mark state as not accessable
m_bElementAccessSafe = false;
#if !defined(NDEBUG)
size_t nOldSize = m_nSize;
#endif
// compute required memory
size_t nRequieredElements = 0;
{
CMemoryPage* pCurrentMemoryPage = m_pMemoryPages;
while (pCurrentMemoryPage)
{
nRequieredElements += pCurrentMemoryPage->Size();
pCurrentMemoryPage = pCurrentMemoryPage->m_pNext;
}
}
T* arrOldData = m_arrData;
m_arrData = reinterpret_cast<T*>(CryModuleMemalign((m_nCapacity + nRequieredElements) * sizeof(T), alignof(T)));
memcpy(m_arrData, arrOldData, m_nCapacity * sizeof(T));
CryModuleMemalignFree(arrOldData);
// copy page data into continous memory block
{
size_t nBeginToFillIndex = m_nCapacity;
CMemoryPage* pCurrentMemoryPage = m_pMemoryPages;
while (pCurrentMemoryPage)
{
// copy data
memcpy(&m_arrData[nBeginToFillIndex], pCurrentMemoryPage->GetData(), pCurrentMemoryPage->GetDataSize());
nBeginToFillIndex += pCurrentMemoryPage->Size();
// free page
CMemoryPage* pOldPage = pCurrentMemoryPage;
pCurrentMemoryPage = pCurrentMemoryPage->m_pNext;
CryModuleFree(pOldPage);
}
m_pMemoryPages = NULL;
}
assert(nOldSize == m_nSize);
m_nCapacity += nRequieredElements;
// the container can be used again
m_bElementAccessSafe = true;
}
///////////////////////////////////////////////////////////////////////////////
// Collect information about used memory
template<typename T>
void CThreadSafeRendererContainer<T>::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_arrData, m_nCapacity * sizeof(T));
CMemoryPage* pCurrentMemoryPage = m_pMemoryPages;
while (pCurrentMemoryPage)
{
pSizer->AddObject(pCurrentMemoryPage, CMemoryPage::nMemoryPageSize);
pCurrentMemoryPage = pCurrentMemoryPage->m_pNext;
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline CThreadSafeRendererContainer<T>::CMemoryPage::CMemoryPage()
: m_pNext(NULL)
, m_nSize(0)
{
// compute offset for actual data
size_t nObjectAlignment = alignof(T);
UINT_PTR nMemoryBlockBegin = alias_cast<UINT_PTR>(this);
UINT_PTR nMemoryBlockEnd = alias_cast<UINT_PTR>(this) + nMemoryPageSize;
nMemoryBlockBegin += sizeof(CMemoryPage);
nMemoryBlockBegin = (nMemoryBlockBegin + nObjectAlignment - 1) & ~(nObjectAlignment - 1);
// compute number of avaible elements
assert(nMemoryBlockEnd > nMemoryBlockBegin);
m_nCapacity = (LONG)((nMemoryBlockEnd - nMemoryBlockBegin) / sizeof(T));
// store pointer to store data to
m_arrData = alias_cast<T*>(nMemoryBlockBegin);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline typename CThreadSafeRendererContainer<T>::CMemoryPage * CThreadSafeRendererContainer<T>::CMemoryPage::AllocateNewPage()
{
void* pNewPageMemoryChunk = CryModuleMalloc(nMemoryPageSize);
assert(pNewPageMemoryChunk != NULL);
memset(pNewPageMemoryChunk, 0, nMemoryPageSize);
CMemoryPage* pNewPage = new(pNewPageMemoryChunk) CMemoryPage();
return pNewPage;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline bool CThreadSafeRendererContainer<T>::CMemoryPage::TryAllocateElement(size_t & nIndex, T * &pObj)
{
LONG nSize = ~0;
LONG nCapacity = ~0;
do
{
// read volatile the new size
nSize = *const_cast<volatile LONG*>(&m_nSize);
nCapacity = *const_cast<volatile LONG*>(&m_nCapacity);
// stop trying if this page is full
if (nSize >= nCapacity)
{
return false;
}
} while (CryInterlockedCompareExchange(alias_cast<volatile LONG*>(&m_nSize), nSize + 1, nSize) != nSize);
//Note: this is the index in the page and it is adjusted in the calling context
nIndex = nSize;
pObj = &m_arrData[nSize];
return true;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T&CThreadSafeRendererContainer<T>::CMemoryPage::GetElement(size_t n)
{
assert((LONG)n < m_nSize);
assert(m_nSize <= m_nCapacity);
return m_arrData[n];
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T * CThreadSafeRendererContainer<T>::CMemoryPage::GetData() const
{
return m_arrData;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeRendererContainer<T>::CMemoryPage::Size() const
{
return m_nSize;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeRendererContainer<T>::CMemoryPage::GetDataSize() const
{
return m_nSize * sizeof(T);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeRendererContainer<T>::CMemoryPage::Capacity() const
{
return m_nCapacity;
}
#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFERENDERERCONTAINER_H
@@ -1,602 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Specialized Container for Renderer data with the following properties:
// Created during the 3DEngine Update, consumed in the renderer in the following frame
// This Container is very restricted and likely not optimal for other situations
#ifndef CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H
#define CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H
#pragma once
#include "platform.h"
#include <vector>
#include <AzCore/Jobs/JobContext.h>
#include <AzCore/Jobs/JobManager.h>
#include <AzCore/std/typetraits/typetraits.h>
//
// !!! BE CAREFULL WHEN USING THIS CONTAINER !!!
//
// --- Properties: ---
// - Stores data local to worker thread to avoid thread-safety semantics
// - Allows for a single non-worker thread to be tracked which is stored in m_workers[0]
// Hence: As m_workers[0] is shared between all non-worker threads, ensure that only one additional non-worker thread may access this container e.g. MainThread
// - Coalesce memory to obtain a continues memory block
// - Coalesce memory to for faster element access to a continues memory block
//
// --- Restrictions:---
// - The workers own the memory structure
// - The coalesced memory stores a copy of the workers used memory
// Hence: Be careful when altering data within the coalesced memory.
// If the templated element is a pointer type than altering the memory pointed to, is not be an issue
// If the templated element is of type class or struct than ensure that data changes are done on the worker local data and not on the coalesced memory. Use worker encoded indices to do so.
//
template <class T>
class CThreadSafeWorkerContainer
{
public:
struct SDefaultNoOpFunctor
{
ILINE void operator()(T* pData) const{}
};
struct SDefaultDestructorFunctor
{
ILINE void operator()(T* pData) const
{
pData->~T();
}
};
public:
CThreadSafeWorkerContainer();
~CThreadSafeWorkerContainer();
void Init();
void SetNonWorkerThreadID(threadID nThreadId) { m_foreignThreadId = nThreadId; }
// Safe access of elements for calling thread via operator[]
uint32 ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const;
// Returns the number of threads that can use this container, including the one non-worker-thread.
uint32 GetNumWorkers() const;
// Returns the Worker ID for the current thread. Ranges from 0 to GetNumWorkers()-1.
// Note, WorkerId is not the same thing as JobManager's WorkerThreadId.
uint32 GetWorkerId_threadlocal() const;
//NOTE: be aware that these values can potentially change if some objects are added in parallel
size_t size() const;
size_t empty() const;
size_t capacity() const;
size_t size_threadlocal() const;
size_t empty_threadlocal() const;
size_t capacity_threadlocal() const;
//NOTE: be aware that this operator is more expensive if the memory was not coalesced before
T& operator[](size_t n);
const T& operator[](size_t n) const;
T* push_back_new();
T* push_back_new(size_t& nIndex);
void push_back(const T& rObj);
void push_back(const T& rObj, size_t& nIndex);
// NOTE: These functions are changing the size of the continous memory block and thus are *not* thread-safe
void clear();
template< class OnElementDeleteFunctor>
void clear(const OnElementDeleteFunctor& rFunctor = CThreadSafeWorkerContainer<T>::SDefaultNoOpFunctor());
void erase(const T& rObj);
void resize(size_t n);
void reserve(size_t n);
// *not* thread-safe functions
void PrefillContainer(T* pElement, size_t numElements);
void CoalesceMemory();
void GetMemoryUsage(ICrySizer* pSizer) const;
private:
void clear(AZStd::true_type);
void clear(AZStd::false_type);
class SWorker
{
public:
AZ_CLASS_ALLOCATOR(SWorker, AZ::LegacyAllocator, 0);
SWorker()
: m_dataSize(0) {}
uint32 m_dataSize;
AZStd::vector<T> m_data;
} _ALIGN(128);
T* push_back_impl(size_t& nIndex);
void ReserverCoalescedMemory(size_t n);
threadID m_foreignThreadId; // OS thread ID of the non-job-manager-worker-thread allowed to use this container, too.
AZStd::vector<SWorker> m_workers; // Holds data for each thread that can use this container. A non-worker-thread (Main) has data stored at 0. Actual worker threads range from 1 to m_nNumWorkers-1
uint32 m_nNumWorkers = 0; // The number of threads that can use this container, including one non-worker-thread.
uint32 m_coalescedArrCapacity;
T* m_coalescedArr;
bool m_isCoalesced;
};
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline CThreadSafeWorkerContainer<T>::CThreadSafeWorkerContainer()
: m_nNumWorkers(0)
, m_coalescedArrCapacity(0)
, m_coalescedArr(0)
, m_isCoalesced(false)
{
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline CThreadSafeWorkerContainer<T>::~CThreadSafeWorkerContainer()
{
clear();
m_workers.clear();
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::Init()
{
m_nNumWorkers = AZ::JobContext::GetGlobalContext()->GetJobManager().GetNumWorkerThreads() + 1;
m_workers.resize(m_nNumWorkers);
m_foreignThreadId = THREADID_NULL;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeWorkerContainer<T>::size() const
{
uint32 totalSize = 0;
for (int i = 0; i < m_nNumWorkers; ++i)
{
totalSize += m_workers[i].m_dataSize;
}
return totalSize;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeWorkerContainer<T>::empty() const
{
return size() == 0;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeWorkerContainer<T>::capacity() const
{
uint32 totalCapacity = 0;
for (int i = 0; i < m_nNumWorkers; ++i)
{
totalCapacity += m_workers[i].m_data.capacity();
}
return totalCapacity;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeWorkerContainer<T>::size_threadlocal() const
{
const uint32 nWorkerThreadId = GetWorkerId_threadlocal();
return m_workers[nWorkerThreadId].m_dataSize;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeWorkerContainer<T>::empty_threadlocal() const
{
const uint32 nWorkerThreadId = GetWorkerId_threadlocal();
return m_workers[nWorkerThreadId].m_data.empty();
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline size_t CThreadSafeWorkerContainer<T>::capacity_threadlocal() const
{
const uint32 nWorkerThreadId = GetWorkerId_threadlocal();
return m_workers[nWorkerThreadId].m_data.capacity();
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T& CThreadSafeWorkerContainer<T>::operator[](size_t n)
{
const uint32 nHasWorkerEncodedIndex = (n & 0x80000000) >> 31;
IF ((m_isCoalesced && !nHasWorkerEncodedIndex), 1)
{
AZ_Assert(m_coalescedArr, "null array");
AZ_Assert(n < m_coalescedArrCapacity, "Index out of bounds");
return m_coalescedArr[n];
}
else
{
const uint32 nWorkerThreadId = (n & 0x7F00007F) >> 24; // Mask bit 24-30 (0 is starting bit)
const uint32 nOffset = (n & ~0xFF000000); // Mask out top 8 bits
// Encoded offset into worker local array
if (nHasWorkerEncodedIndex)
{
return m_workers[nWorkerThreadId].m_data[nOffset];
}
else // None-coalesced and none worker encoded offset
{
uint32 nTotalOffset = nOffset;
for (int i = 0; i < m_nNumWorkers; ++i)
{
SWorker& worker = m_workers[i];
if (nTotalOffset < worker.m_dataSize)
{
return worker.m_data[nTotalOffset];
}
else
{
nTotalOffset -= worker.m_dataSize;
}
}
// Out of bound access detected!
CRY_ASSERT_MESSAGE(false, "CThreadSafeWorkerContainer::operator[] - Out of bounds access");
__debugbreak();
AZ_Assert(m_coalescedArr, "null array");
AZ_Assert(m_coalescedArrCapacity > 0, "Index out of bounds");
return m_coalescedArr[0];
}
}
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline const T& CThreadSafeWorkerContainer<T>::operator[](size_t n) const
{
return const_cast<const T&>(const_cast<CThreadSafeWorkerContainer<T>*>(this)->operator[](n));
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T* CThreadSafeWorkerContainer<T>::push_back_new()
{
size_t unused = ~0;
return push_back_impl(unused);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T* CThreadSafeWorkerContainer<T>::push_back_new(size_t& nIndex)
{
return push_back_impl(nIndex);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::push_back(const T& rObj)
{
size_t nUnused = ~0;
T* pObj = push_back_impl(nUnused);
*pObj = rObj;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::push_back(const T& rObj, size_t& nIndex)
{
T* pObj = push_back_impl(nIndex);
*pObj = rObj;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::clear()
{
clear(typename std::is_destructible<T>::type());
}
template<typename T>
void CThreadSafeWorkerContainer<T>::clear(AZStd::true_type)
{
clear(SDefaultDestructorFunctor());
}
template<typename T>
void CThreadSafeWorkerContainer<T>::clear(AZStd::false_type)
{
clear(SDefaultNoOpFunctor());
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
template<class OnElementDeleteFunctor>
inline void CThreadSafeWorkerContainer<T>::clear(const OnElementDeleteFunctor& rFunctor)
{
// Reset worker data
for (int i = 0; i < m_nNumWorkers; ++i)
{
// Delete elements
uint32 nSize = m_workers[i].m_data.size();
for (int j = 0; j < nSize; ++j)
{
// Call on element delete functor
// Note: Default functor will do nothing with the element
rFunctor(&m_workers[i].m_data[j]);
}
m_workers[i].m_data.clear();
m_workers[i].m_dataSize = 0;
}
// Reset container data
if (m_coalescedArr)
{
CryModuleMemalignFree(m_coalescedArr);
}
m_coalescedArr = 0;
m_coalescedArrCapacity = 0;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::erase(const T& rObj)
{
for (int i = 0; i < m_nNumWorkers; ++i)
{
typename std::vector<T>::iterator iter = m_workers[i].m_data.begin();
typename std::vector<T>::iterator iterEnd = m_workers[i].m_data.end();
for (; iter != iterEnd; ++iter)
{
if (rObj == *iter)
{
m_workers[i].m_data.erase(iter);
--m_workers[i].m_dataSize;
m_isCoalesced = false;
return;
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::resize(size_t n)
{
CoalesceMemory();
uint32 nSizePerWorker = n / m_nNumWorkers;
uint32 nExcessSize = n % m_nNumWorkers;
// Resize workers evenly
for (int i = 0; i < m_nNumWorkers; ++i)
{
uint32 nWorkerSize = nSizePerWorker + nExcessSize;
if (nWorkerSize > m_workers[i].m_data.size())
{
m_workers[i].m_data.resize(nWorkerSize);
}
m_workers[i].m_dataSize = nWorkerSize;
nExcessSize = 0; // First worker creates excess items
}
ReserverCoalescedMemory(n);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::reserve(size_t n)
{
CoalesceMemory();
uint32 nSizePerWorker = n / m_nNumWorkers;
uint32 nExcessSize = n % m_nNumWorkers;
// Resize workers evenly
for (int i = 0; i < m_nNumWorkers; ++i)
{
uint32 nWorkerSize = nSizePerWorker + nExcessSize;
if (nWorkerSize > m_workers[i].m_data.size())
{
m_workers[i].m_data.resize(nWorkerSize);
}
nExcessSize = 0; // First worker creates excess items
}
ReserverCoalescedMemory(n);
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::PrefillContainer(T* pElement, size_t numElements)
{
reserve(numElements);
uint32 nOffset = 0;
uint32 nNumItemPerWorker = numElements / m_nNumWorkers;
uint32 nNumExcessItems = numElements % m_nNumWorkers;
// Store items evenly in workers
for (int i = 0; i < m_nNumWorkers; ++i)
{
uint32 nNumItems = nNumItemPerWorker + nNumExcessItems;
for (int j = 0; j < nNumItems; ++j)
{
m_workers[i].m_data[j] = pElement[nOffset + j];
}
m_workers[i].m_dataSize = nNumItems;
nOffset += nNumItems;
nNumExcessItems = 0; // First worker stores excess items
}
m_isCoalesced = false;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::CoalesceMemory()
{
if (m_isCoalesced)
{
return;
}
// Ensure enough memory exists
uint32 minSizeNeeded = 0;
for (int i = 0; i < m_nNumWorkers; ++i)
{
minSizeNeeded += m_workers[i].m_dataSize;
}
IF (minSizeNeeded >= m_coalescedArrCapacity, 0)
{
ReserverCoalescedMemory(minSizeNeeded + (minSizeNeeded / 4));
}
// Copy data to coalesced array
uint32 nOffest = 0;
for (int i = 0; i < m_nNumWorkers; ++i)
{
SWorker& rWorker = m_workers[i];
if (rWorker.m_dataSize == 0)
{
continue;
}
AZ_Assert((nOffest + rWorker.m_dataSize) <= m_coalescedArrCapacity, "Index out of bounds");
memcpy(m_coalescedArr + nOffest, &rWorker.m_data[0], sizeof(T) * rWorker.m_dataSize);
nOffest += rWorker.m_dataSize;
}
m_isCoalesced = true;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
uint32 CThreadSafeWorkerContainer<T>::ConvertToEncodedWorkerId_threadlocal(uint32 nIndex) const
{
const uint32 workerId = GetWorkerId_threadlocal();
assert(nIndex < m_workers[workerId].m_dataSize);
return (uint32)((1 << 31) | (workerId << 24) | nIndex);
}
//////////////////////////////////////////////////////////////////////////
template<typename T>
uint32 CThreadSafeWorkerContainer<T>::GetNumWorkers() const
{
return m_nNumWorkers;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_coalescedArr, m_coalescedArrCapacity * sizeof(T));
for (int i = 0; i < m_nNumWorkers; ++i)
{
pSizer->AddContainer(m_workers[i].m_data);
}
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline void CThreadSafeWorkerContainer<T>::ReserverCoalescedMemory(size_t n)
{
if (n <= m_coalescedArrCapacity)
{
return;
}
T* arrOldData = m_coalescedArr;
m_coalescedArr = reinterpret_cast<T*>(CryModuleMemalign(n * sizeof(T), alignof(T)));
memcpy(m_coalescedArr, arrOldData, m_coalescedArrCapacity * sizeof(T));
if (arrOldData)
{
CryModuleMemalignFree(arrOldData);
}
m_coalescedArrCapacity = n;
}
///////////////////////////////////////////////////////////////////////////////
template<typename T>
inline T* CThreadSafeWorkerContainer<T>::push_back_impl(size_t& nIndex)
{
// Avoid writing to thread share resource and take hit of 'if statement to avoid false-sharing between threads
IF (m_isCoalesced, 0)
{
m_isCoalesced = false;
}
// Get worker id
const uint32 nWorkerThreadId = GetWorkerId_threadlocal();
SWorker& activeWorker = m_workers[nWorkerThreadId];
// Ensure enough space
if (activeWorker.m_dataSize >= activeWorker.m_data.size())
{
activeWorker.m_data.resize(activeWorker.m_data.size() + (activeWorker.m_data.size() / 2) + 1);
}
// Encode worker local offset into index and return
T* retItem = &activeWorker.m_data[activeWorker.m_dataSize];
nIndex = (size_t)((1 << 31) | (nWorkerThreadId << 24) | activeWorker.m_dataSize);
++activeWorker.m_dataSize;
return retItem;
}
template<typename T>
uint32 CThreadSafeWorkerContainer<T>::GetWorkerId_threadlocal() const
{
const uint32 workerThreadId = AZ::JobContext::GetGlobalContext()->GetJobManager().GetWorkerThreadId();
if (workerThreadId == AZ::JobManager::InvalidWorkerThreadId)
{
// Only one non-worker thread is allowed, so check to see if this is that thread.
const threadID currentThreadId = CryGetCurrentThreadId();
if (m_foreignThreadId != currentThreadId)
{
CryFatalError("Trying to access CThreadSafeWorkerContainer from an unspecified non-worker thread. The only non-worker threadId with access rights: %" PRI_THREADID ". Current threadId: %" PRI_THREADID, m_foreignThreadId, currentThreadId);
}
}
// Non-worker has id of ~0 ... add +1 to shift to 0. Worker0 will use slot 1 etc.
static_assert(AZ::JobManager::InvalidWorkerThreadId == ~0u, "Assumptions about InvalidWorkerId no longer hold true");
return workerThreadId + 1;
}
#endif // CRYINCLUDE_CRYCOMMON_CRYTHREADSAFEWORKERCONTAINER_H
@@ -1,79 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef __CustomMemoryHeap_h__
#define __CustomMemoryHeap_h__
#pragma once
#include "IMemory.h"
class CCustomMemoryHeap;
//////////////////////////////////////////////////////////////////////////
class CCustomMemoryHeapBlock
: public ICustomMemoryBlock
{
public:
CCustomMemoryHeapBlock(CCustomMemoryHeap* pHeap);
virtual ~CCustomMemoryHeapBlock();
//////////////////////////////////////////////////////////////////////////
// IMemoryBlock
//////////////////////////////////////////////////////////////////////////
virtual void* GetData();
virtual int GetSize() { return m_nSize; }
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// ICustomMemoryBlock
//////////////////////////////////////////////////////////////////////////
virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize);
//////////////////////////////////////////////////////////////////////////
private:
friend class CCustomMemoryHeap;
CCustomMemoryHeap* m_pHeap;
string m_sUsage;
void* m_pData;
uint32 m_nGPUHandle;
size_t m_nSize;
};
//////////////////////////////////////////////////////////////////////////
class CCustomMemoryHeap
: public ICustomMemoryHeap
{
public:
explicit CCustomMemoryHeap(IMemoryManager::EAllocPolicy const eAllocPolicy);
~CCustomMemoryHeap();
//////////////////////////////////////////////////////////////////////////
// ICustomMemoryHeap
//////////////////////////////////////////////////////////////////////////
virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16);
virtual void GetMemoryUsage(ICrySizer* pSizer);
virtual size_t GetAllocated();
//////////////////////////////////////////////////////////////////////////
void DeallocateBlock(CCustomMemoryHeapBlock* pBlock);
private:
friend class CCustomMemoryHeapBlock;
int m_nAllocatedSize;
IMemoryManager::EAllocPolicy m_eAllocPolicy;
IMemoryManager::HeapHandle m_nTraceHeapHandle;
};
#endif // __CustomMemoryHeap_h__
-1
View File
@@ -420,7 +420,6 @@ namespace stl
{
nInterval++;
nCount = 0;
assert(CryMemory::IsHeapValid());
}
#endif
}
@@ -572,7 +572,6 @@ struct IVoxelObject
: public IRenderNode
{
// <interfuscator:shuffle>
virtual struct IMemoryBlock* GetCompiledData(EEndian eEndian) = 0;
virtual void SetCompiledData(void* pData, int nSize, uint8 ucChildId, EEndian eEndian) = 0;
virtual void SetObjectName(const char* pName) = 0;
virtual void SetMatrix(const Matrix34& mat) = 0;
@@ -1,52 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H
#define CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H
#pragma once
namespace AZ
{
class IAllocator;
}
class IGeneralMemoryHeap
{
public:
// <interfuscator:shuffle>
virtual bool Cleanup() = 0;
virtual int AddRef() = 0;
virtual int Release() = 0;
virtual bool IsInAddressRange(void* ptr) const = 0;
virtual void* Calloc(size_t nmemb, size_t size, const char* sUsage) = 0;
virtual void* Malloc(size_t sz, const char* sUsage) = 0;
// Attempts to free the allocation. Returns the size of the allocation if successful, 0 if the heap doesn't own the address.
virtual size_t Free(void* ptr) = 0;
virtual void* Realloc(void* ptr, size_t sz, const char* sUsage) = 0;
virtual void* ReallocAlign(void* ptr, size_t size, size_t alignment, const char* sUsage) = 0;
virtual void* Memalign(size_t boundary, size_t size, const char* sUsage) = 0;
virtual AZ::IAllocator* GetAllocator() const = 0;
// Get the size of the allocation. Returns 0 if the ptr doesn't belong to the heap.
virtual size_t UsableSize(void* ptr) const = 0;
// </interfuscator:shuffle>
protected:
virtual ~IGeneralMemoryHeap() {}
};
#endif // CRYINCLUDE_CRYCOMMON_IGENERALMEMORYHEAP_H
-41
View File
@@ -1,41 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H
#define CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H
#pragma once
#include <memory>
/**
Utility for loading and saving images. only works with RGB data(no alpha), and lossless compressed tiff files for now.
*/
struct IImageHandler
{
struct IImage
{
virtual ~IImage() {}
virtual const std::vector<unsigned char>& GetData() const = 0;
virtual int GetWidth() const = 0;
virtual int GetHeight() const = 0;
};
virtual ~IImageHandler() {}
///data must be RGB, 3 bytes per pixel.
virtual std::unique_ptr<IImage> CreateImage(std::vector<unsigned char>&& data, int width, int height) const = 0;
virtual std::unique_ptr<IImage> LoadImage(const char* filename) const = 0;
virtual bool SaveImage(IImage* image, const char* filename) const = 0;
virtual std::unique_ptr<IImage> CreateDiffImage(IImage* image1, IImage* image2) const = 0;
virtual float CalculatePSNR(IImage* diffIimage) const = 0;
};
#endif // CRYINCLUDE_CRYCOMMON_IIMAGEHANDLER_H
-86
View File
@@ -1,86 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_IMEMORY_H
#define CRYINCLUDE_CRYCOMMON_IMEMORY_H
#pragma once
#include <smartptr.h>
#include <IGeneralMemoryHeap.h> // <> required for Interfuscator
#include <smartptr.h>
struct IMemoryBlock
: public CMultiThreadRefCount
{
// <interfuscator:shuffle>
virtual void* GetData() = 0;
virtual int GetSize() = 0;
// </interfuscator:shuffle>
};
TYPEDEF_AUTOPTR(IMemoryBlock);
//////////////////////////////////////////////////////////////////////////
struct ICustomMemoryBlock
: public IMemoryBlock
{
// Copy region from from source memory to the specified output buffer
virtual void CopyMemoryRegion(void* pOutputBuffer, size_t nOffset, size_t nSize) = 0;
};
//////////////////////////////////////////////////////////////////////////
struct ICustomMemoryHeap
: public CMultiThreadRefCount
{
// <interfuscator:shuffle>
virtual ICustomMemoryBlock* AllocateBlock(size_t const nAllocateSize, char const* const sUsage, size_t const nAlignment = 16) = 0;
virtual void GetMemoryUsage(ICrySizer* pSizer) = 0;
virtual size_t GetAllocated() = 0;
// </interfuscator:shuffle>
};
class IMemoryAddressRange
{
public:
// <interfuscator:shuffle>
virtual void Release() = 0;
virtual char* GetBaseAddress() const = 0;
virtual size_t GetPageCount() const = 0;
virtual size_t GetPageSize() const = 0;
virtual void* MapPage(size_t pageIdx) = 0;
virtual void UnmapPage(size_t pageIdx) = 0;
// </interfuscator:shuffle>
protected:
virtual ~IMemoryAddressRange() {}
};
class IPageMappingHeap
{
public:
// <interfuscator:shuffle>
virtual void Release() = 0;
virtual size_t GetGranularity() const = 0;
virtual bool IsInAddressRange(void* ptr) const = 0;
virtual size_t FindLargestFreeBlockSize() const = 0;
virtual void* Map(size_t sz) = 0;
virtual void Unmap(void* ptr, size_t sz) = 0;
// </interfuscator:shuffle>
protected:
virtual ~IPageMappingHeap() {}
};
#endif // CRYINCLUDE_CRYCOMMON_IMEMORY_H
-2
View File
@@ -1510,7 +1510,6 @@ struct IRenderer
// Summary:
// Loads lightmap for name.
virtual int EF_LoadLightmap (const char* name) = 0;
virtual bool EF_RenderEnvironmentCubeHDR (int size, Vec3& Pos, TArray<unsigned short>& vecData) = 0;
// Summary:
// Starts using of the shaders (return first index for allow recursions).
@@ -1547,7 +1546,6 @@ struct IRenderer
virtual int EF_AddDeferredLight(const CDLight& pLight, float fMult, const SRenderingPassInfo& passInfo, const SRendItemSorter& rendItemSorter) = 0;
virtual uint32 EF_GetDeferredLightsNum(eDeferredLightType eLightType = eDLT_DeferredLight) = 0;
virtual void EF_ClearDeferredLightsList() = 0;
virtual TArray<SRenderLight>* EF_GetDeferredLights(const SRenderingPassInfo& passInfo, eDeferredLightType eLightType = eDLT_DeferredLight) = 0;
virtual uint8 EF_AddDeferredClipVolume(const IClipVolume* pClipVolume) = 0;
virtual bool EF_SetDeferredClipVolumeBlendData(const IClipVolume* pClipVolume, const SClipVolumeBlendInfo& blendInfo) = 0;
@@ -1,64 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H
#define CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H
#pragma once
// used to collect the assets needed for streaming and to gather statistics
struct IResourceCollector
{
// <interfuscator:shuffle>
// Arguments:
// dwMemSize 0xffffffff if size is unknown
// Returns:
// true=new resource was added, false=resource was already registered
virtual bool AddResource(const char* szFileName, const uint32 dwMemSize) = 0;
// Arguments:
// szFileName - needs to be registered before with AddResource()
// pInstance - must not be 0
virtual void AddInstance(const char* szFileName, void* pInstance) = 0;
//
// Arguments:
// szFileName - needs to be registered before with AddResource()
virtual void OpenDependencies(const char* szFileName) = 0;
//
virtual void CloseDependencies() = 0;
// Resets the internal data structure for the resource collector.
virtual void Reset() = 0;
// </interfuscator:shuffle>
protected:
virtual ~IResourceCollector() {}
};
class NullResCollector
: public IResourceCollector
{
public:
virtual bool AddResource([[maybe_unused]] const char* szFileName, [[maybe_unused]] const uint32 dwMemSize) { return true; }
virtual void AddInstance([[maybe_unused]] const char* szFileName, [[maybe_unused]] void* pInstance) {}
virtual void OpenDependencies([[maybe_unused]] const char* szFileName) {}
virtual void CloseDependencies() {}
virtual void Reset() {}
virtual ~NullResCollector() {}
};
#endif // CRYINCLUDE_CRYCOMMON_IRESOURCECOLLECTOR_H
@@ -1,84 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// Description : Interface to the Resource Manager
#ifndef CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H
#define CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H
#pragma once
namespace AZ::IO
{
struct IResourceList;
}
struct SLayerPakStats
{
struct SEntry
{
string name;
size_t nSize;
string status;
bool bStreaming;
};
typedef std::vector<SEntry> TEntries;
TEntries m_entries;
size_t m_MaxSize;
size_t m_UsedSize;
};
//////////////////////////////////////////////////////////////////////////
// IResource manager interface
//////////////////////////////////////////////////////////////////////////
struct IResourceManager
{
// <interfuscator:shuffle>
virtual ~IResourceManager(){}
// Called by level system to set the level folder
virtual void PrepareLevel(const char* sLevelFolder, const char* sLevelName) = 0;
// Called by level system after the level has been unloaded.
virtual void UnloadLevel() = 0;
// Call to get current level resource list.
virtual AZ::IO::IResourceList* GetLevelResourceList() = 0;
// Load pak file from level cache to memory.
// sBindRoot is a path in virtual file system, where new pak will be mapper to (ex. LevelCache/mtl)
virtual bool LoadLevelCachePak(const char* sPakName, const char* sBindRoot, bool bOnlyDuringLevelLoading = true) = 0;
// Unloads level cache pak file from memory.
virtual void UnloadLevelCachePak(const char* sPakName) = 0;
//Loads the pak file for mode switching into memory e.g. Single player mode to Multiplayer mode
virtual bool LoadModeSwitchPak(const char* sPakName, const bool multiplayer) = 0;
//Unloads the mode switching pak file
virtual void UnloadModeSwitchPak(const char* sPakName, const char* sResourceListName, const bool multiplayer) = 0;
// Load general pak file to memory.
virtual bool LoadPakToMemAsync(const char* pPath, bool bLevelLoadOnly) = 0;
// Unload all aync paks
virtual void UnloadAllAsyncPaks() = 0;
// Load pak file from active layer to memory.
virtual bool LoadLayerPak(const char* sLayerName) = 0;
// Unloads layer pak file from memory if no more references.
virtual void UnloadLayerPak(const char* sLayerName) = 0;
// Retrieve stats on the layer pak
virtual void GetLayerPakStats(SLayerPakStats& stats, bool bCollectAllStats) const = 0;
// Return time it took to load and precache the level.
virtual CTimeValue GetLastLevelLoadTime() const = 0;
virtual void GetMemoryStatistics(ICrySizer* pSizer) = 0;
// </interfuscator:shuffle>
};
#endif // CRYINCLUDE_CRYCOMMON_IRESOURCEMANAGER_H
-53
View File
@@ -20,7 +20,6 @@
#include <Cry_Math.h>
#include <IXml.h>
#include "CountedValue.h"
#include "MiniQueue.h"
#include <VectorSet.h>
#include <VectorMap.h>
@@ -471,58 +470,6 @@ public:
}
}
template <class T>
void Value(const char* name, CountedValue<T>& countedValue)
{
if (!BeginOptionalGroup(name, true))
{
return;
}
if (IsWriting())
{
T rawValue = countedValue.Peek();
Value("Value", rawValue);
typename CountedValue<T>::TCountedID rawId = countedValue.GetLatestID();
Value("Id", rawId, 'ui32');
}
if (IsReading())
{
T rawValue;
Value("Value", rawValue);
typename CountedValue<T>::TCountedID rawId;
Value("Id", rawId, 'ui32');
countedValue.UpdateDuringSerializationOnly(rawValue, rawId);
}
EndGroup();
}
template <class T>
void Value(const char* name, CountedValue<T>& countedValue, int policy)
{
if (!BeginOptionalGroup(name, true))
{
return;
}
if (IsWriting())
{
T rawValue = countedValue.Peek();
Value("Value", rawValue, policy);
typename CountedValue<T>::TCountedID rawId = countedValue.GetLatestID();
Value("Id", rawId, 'ui32');
}
if (IsReading())
{
T rawValue;
Value("Value", rawValue, policy);
typename CountedValue<T>::TCountedID rawId;
Value("Id", rawId, 'ui32');
countedValue.UpdateDuringSerializationOnly(rawValue, rawId);
}
EndGroup();
}
bool ValueChar(const char* name, char* buffer, int len)
{
string temp;
-72
View File
@@ -36,8 +36,6 @@
#include <CrySizer.h>
#include <IMaterial.h>
#include <CryThreadSafeRendererContainer.h>
struct IMaterial;
class CRendElementBase;
class CRenderObject;
@@ -2238,74 +2236,6 @@ struct SShaderTexSlots
}
};
struct SShaderGenBit
{
SShaderGenBit()
{
m_Mask = 0;
m_Flags = 0;
m_nDependencySet = 0;
m_nDependencyReset = 0;
m_NameLength = 0;
m_dwToken = 0;
}
string m_ParamName;
string m_ParamProp;
string m_ParamDesc;
int m_NameLength;
uint64 m_Mask;
uint32 m_Flags;
uint32 m_dwToken;
std::vector<uint32> m_PrecacheNames;
std::vector<string> m_DependSets;
std::vector<string> m_DependResets;
uint32 m_nDependencySet;
uint32 m_nDependencyReset;
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_ParamName);
pSizer->AddObject(m_ParamProp);
pSizer->AddObject(m_ParamDesc);
pSizer->AddObject(m_PrecacheNames);
pSizer->AddObject(m_DependSets);
pSizer->AddObject(m_DependResets);
}
};
struct SShaderGen
{
uint32 m_nRefCount;
TArray<SShaderGenBit*> m_BitMask;
SShaderGen()
{
m_nRefCount = 1;
}
~SShaderGen()
{
uint32 i;
for (i = 0; i < m_BitMask.Num(); i++)
{
SShaderGenBit* pBit = m_BitMask[i];
SAFE_DELETE(pBit);
}
m_BitMask.Free();
}
void Release()
{
m_nRefCount--;
if (!m_nRefCount)
{
delete this;
}
}
void GetMemoryUsage(ICrySizer* pSizer) const
{
pSizer->AddObject(m_BitMask);
}
};
//===================================================================================
enum EShaderType
@@ -2570,7 +2500,6 @@ public:
virtual void SetFlags2(int Flags) = 0;
virtual void ClearFlags2(int Flags) = 0;
virtual bool Reload(int nFlags, const char* szShaderName) = 0;
virtual TArray<CRendElementBase*>* GetREs (int nTech) = 0;
virtual AZStd::vector<SShaderParam>& GetPublicParams() = 0;
virtual int GetTexId () = 0;
virtual ITexture* GetBaseTexture(int* nPass, int* nTU) = 0;
@@ -2579,7 +2508,6 @@ public:
virtual ECull GetCull(void) = 0;
virtual int Size(int Flags) = 0;
virtual uint64 GetGenerationMask() = 0;
virtual SShaderGen* GetGenerationParams() = 0;
virtual size_t GetNumberOfUVSets() = 0;
virtual int GetTechniqueID(int nTechnique, int nRegisteredTechnique) = 0;
virtual AZ::Vertex::Format GetVertexFormat(void) = 0;
-493
View File
@@ -1,493 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
// This is the prototypes of interfaces that will be used for asynchronous
// I/O (streaming).
// THIS IS NOT FINAL AND IS SUBJECT TO CHANGE WITHOUT NOTICE
// Some excerpts explaining basic ideas behind streaming design here:
/*
* The idea is that the data loaded is ready for usage and ideally doesn't need further transformation,
* therefore the client allocates the buffer (to avoid extra copy). All the data transformations should take place in the Resource Compiler. If you have to allocate a lot of small memory objects, you should revise this strategy in favor of one big allocation (again, that will be read directly from the compiled file).
* Anyway, we can negotiate that the streaming engine allocates this memory.
* In the end, it could make use of a memory pool, and copying data is not the bottleneck in our engine
*
* The client should take care of all fast operations. Looking up file size should be fast on the virtual
* file system in a pak file, because the directory should be preloaded in memory
*/
#ifndef CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H
#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H
#pragma once
#include <list>
#include "smartptr.h"
#include "CryThread.h"
#include "IStreamEngineDefs.h"
class IStreamCallback;
class ICrySizer;
#define STREAM_TASK_TYPE_AUDIO_ALL ((1 << eStreamTaskTypeMusic) | (1 << eStreamTaskTypeSound) | (1 << eStreamTaskTypeFSBCache))
// Description:
// This is used as parameter to the asynchronous read function
// all the unnecessary parameters go here, because there are many of them.
struct StreamReadParams
{
public:
StreamReadParams()
{
memset(this, 0, sizeof(*this));
ePriority = estpNormal;
}
StreamReadParams (
DWORD_PTR _dwUserData,
EStreamTaskPriority _ePriority = estpNormal,
unsigned _nLoadTime = 0,
unsigned _nMaxLoadTime = 0,
unsigned _nOffset = 0,
unsigned _nSize = 0,
void* _pBuffer = NULL,
unsigned _nFlags = 0
)
: dwUserData (_dwUserData)
, ePriority(_ePriority)
, nPerceptualImportance(0)
, nLoadTime(_nLoadTime)
, nMaxLoadTime(_nMaxLoadTime)
, pBuffer (_pBuffer)
, nOffset (_nOffset)
, nSize (_nSize)
, eMediaType(eStreamSourceTypeUnknown)
, nFlags (_nFlags)
{
}
// Summary:
// File name.
//const char* szFile;
// Summary:
// The callback.
//IStreamCallback* pAsyncCallback;
// Summary:
// The user data that'll be used to call the callback.
DWORD_PTR dwUserData;
// The priority of this read
EStreamTaskPriority ePriority;
// Value from 0-255 of the perceptual importance of the task (used for debugging task sheduling)
uint8 nPerceptualImportance;
// Description:
// The desirable loading time, in milliseconds, from the time of call
// 0 means as fast as possible (desirably in this frame).
unsigned nLoadTime;
// Description:
// The maximum load time, in milliseconds. 0 means forever. If the read lasts longer, it can be discarded.
// WARNING: avoid too small max times, like 1-10 ms, because many loads will be discarded in this case.
unsigned nMaxLoadTime;
// Description:
// The buffer into which to read the file or the file piece
// if this is NULL, the streaming engine will supply the buffer.
// Notes:
// DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption!
void* pBuffer;
// Description:
// Offset in the file to read; if this is not 0, then the file read
// occurs beginning with the specified offset in bytes.
// The callback interface receives the size of already read data as nSize
// and generally behaves as if the piece of file would be a file of its own.
unsigned nOffset;
// Description:
// Number of bytes to read; if this is 0, then the whole file is read,
// if nSize == 0 && nOffset != 0, then the file from the offset to the end is read.
// If nSize != 0, then the file piece from nOffset is read, at most nSize bytes
// (if less, an error is reported). So, from nOffset byte to nOffset + nSize - 1 byte in the file.
unsigned nSize;
// Description:
// Media type to use when starting file request - if wrong, the request may take longer to complete
EStreamSourceMediaType eMediaType;
// Description:
// The combination of one or several flags from the stream engine general purpose flags.
// See also:
// IStreamEngine::EFlags
unsigned nFlags;
};
struct StreamReadBatchParams
{
StreamReadBatchParams()
: tSource((EStreamTaskType)0)
, szFile(NULL)
, pCallback(NULL)
{
}
EStreamTaskType tSource;
const char* szFile;
IStreamCallback* pCallback;
StreamReadParams params;
};
struct IStreamEngineListener
{
// <interfuscator:shuffle>
virtual ~IStreamEngineListener() {}
virtual void OnStreamEnqueue(const void* pReq, const char* filename, EStreamTaskType source, const StreamReadParams& readParams) = 0;
virtual void OnStreamComputedSortKey(const void* pReq, uint64 key) = 0;
virtual void OnStreamBeginIO(const void* pReq, uint32 compressSize, uint32 readSize, EStreamSourceMediaType mediaType) = 0;
virtual void OnStreamEndIO(const void* pReq) = 0;
virtual void OnStreamBeginInflate(const void* pReq) = 0;
virtual void OnStreamEndInflate(const void* pReq) = 0;
virtual void OnStreamBeginAsyncCallback(const void* pReq) = 0;
virtual void OnStreamEndAsyncCallback(const void* pReq) = 0;
virtual void OnStreamDone(const void* pReq) = 0;
virtual void OnStreamPreempted(const void* pReq) = 0;
virtual void OnStreamResumed(const void* pReq) = 0;
// </interfuscator:shuffle>
};
// Description:
// The highest level. There is only one StreamingEngine in the application
// and it controls all I/O streams.
struct IStreamEngine
{
public:
enum EJobType
{
ejtStarted = 1 << 0,
ejtPending = 1 << 1,
ejtFinished = 1 << 2,
};
// Summary:
// General purpose flags.
enum EFlags
{
// Description:
// If this is set only asynchronous callback will be called.
FLAGS_NO_SYNC_CALLBACK = BIT(0),
// Description:
// If this is set the file will be read from disc directly, instead of from the pak system.
FLAGS_FILE_ON_DISK = BIT(1),
// Description:
// Ignore the tmp out of streaming memory for this request
FLAGS_IGNORE_TMP_OUT_OF_MEM = BIT(2),
// Description:
// External buffer is write only
FLAGS_WRITE_ONLY_EXTERNAL_BUFFER = BIT(3),
};
// <interfuscator:shuffle>
// Description:
// Starts asynchronous read from the specified file (the file may be on a
// virtual file system, in pak or zip file or wherever).
// Reads the file contents into the given buffer, up to the given size.
// Upon success, calls success callback. If the file is truncated or for other
// reason can not be read, calls error callback. The callback can be NULL (in this case, the client should poll
// the returned IReadStream object; the returned object must be locked for that)
// NOTE: the error/success/ progress callbacks can also be called from INSIDE this function.
// Arguments:
// tSource -
// szFile -
// pCallback -
// pParams - PLACEHOLDER for the future additional parameters (like priority), or really
// a pointer to a structure that will hold the parameters if there are too many of them.
// Return Value:
// IReadStream is reference-counted and will be automatically deleted if you don't refer to it;
// if you don't store it immediately in an auto-pointer, it may be deleted as soon as on the next line of code,
// because the read operation may complete immediately inside StartRead() and the object is self-disposed
// as soon as the callback is called.
// Remarks:
// In some implementations disposal of the old pointers happen synchronously
// (in the main thread) outside StartRead() (it happens in the entity update),
// so you're guaranteed that it won't trash inside the calling function. However, this may change in the future
// and you'll be required to assign it to IReadStream immediately (StartRead will return IReadStream_AutoPtr then).
// See also:
// IReadStream,IReadStream_AutoPtr
virtual IReadStreamPtr StartRead (const EStreamTaskType tSource, const char* szFile, IStreamCallback* pCallback = NULL, const StreamReadParams* pParams = NULL) = 0;
// Pass a callback to preRequestCallback if you need to execute code right before the requests get enqueued; the callback is called only once per execution
virtual size_t StartBatchRead(IReadStreamPtr* pStreamsOut, const StreamReadBatchParams* pReqs, size_t numReqs, AZStd::function<void ()>* preRequestCallback = nullptr) = 0;
// Call this methods before/after submitting large number of new requests.
virtual void BeginReadGroup() = 0;
virtual void EndReadGroup() = 0;
// Pause/resumes streaming of specific data types.
// nPauseTypesBitmask is a bit mask of data types (ex, 1<<eStreamTaskTypeGeometry)
virtual void PauseStreaming(bool bPause, uint32 nPauseTypesBitmask) = 0;
// Get pause bit mask
virtual uint32 GetPauseMask() const = 0;
// Pause/resumes any IO active from the streaming engine
virtual void PauseIO(bool bPause) = 0;
// Description:
// Is the streaming data available on harddisc for fast streaming
virtual bool IsStreamDataOnHDD() const = 0;
// Description:
// Inform streaming engine that the streaming data is available on HDD
virtual void SetStreamDataOnHDD(bool bFlag) = 0;
// Description:
// Per frame update ofthe streaming engine, synchronous events are dispatched from this function.
virtual void Update() = 0;
// Description:
// Per frame update of the streaming engine, synchronous events are dispatched from this function, by particular TypesBitmask.
virtual void Update(uint32 nUpdateTypesBitmask) = 0;
// Description:
// Waits until all submitted requests are complete. (can abort all reads which are currently in flight)
virtual void UpdateAndWait(bool bAbortAll = false) = 0;
// Description:
// Puts the memory statistics into the given sizer object.
// According to the specifications in interface ICrySizer.
// See also:
// ICrySizer
virtual void GetMemoryStatistics(ICrySizer* pSizer) = 0;
#if defined(STREAMENGINE_ENABLE_STATS)
// Description:
// Returns the streaming statistics collected from the previous call.
virtual SStreamEngineStatistics& GetStreamingStatistics() = 0;
virtual void ClearStatistics() = 0;
// Description:
// returns the bandwidth used for the given type of streaming task
virtual void GetBandwidthStats(EStreamTaskType type, float* bandwidth) = 0;
#endif
// Description:
// Returns the counts of open streaming requests.
virtual void GetStreamingOpenStatistics(SStreamEngineOpenStats& openStatsOut) = 0;
virtual const char* GetStreamTaskTypeName(EStreamTaskType type) = 0;
#if defined(STREAMENGINE_ENABLE_LISTENER)
// Description:
// Sets up a listener for stream events (used for statoscope)
virtual void SetListener(IStreamEngineListener* pListener) = 0;
virtual IStreamEngineListener* GetListener() = 0;
#endif
virtual ~IStreamEngine() {}
// </interfuscator:shuffle>
};
// Description:
// This is the file "handle" that can be used to query the status
// of the asynchronous operation on the file. The same object may be returned
// for the same file to multiple clients.
// Notes:
// It will actually represent the asynchronous object in memory, and will be
// thread-safe reference-counted (both AddRef() and Release() will be virtual
// and thread-safe, just like the others)
// Example:
// USE:
// IReadStream_AutoPtr pReadStream = pStreamEngine->StartRead ("bla.xxx", this);
// OR:
// pStreamEngine->StartRead ("MusicSystem","bla.xxx", this);
class IReadStream
{
public:
// <interfuscator:shuffle>
// Summary:
// Increment ref count, returns new count
virtual int AddRef() = 0;
// Summary:
// Decrement ref count, returns new count
virtual int Release() = 0;
// Summary:
// Returns true if the file read was not successful.
virtual bool IsError() = 0;
// Return Value:
// True if the file read was completed successfully.
// Summary:
// Checks IsError to check if the whole requested file (piece) was read.
virtual bool IsFinished() = 0;
// Description:
// Returns the number of bytes read so far (the whole buffer size if IsFinished())
// Arguments:
// bWait - if == true, then waits until the pending I/O operation completes.
// Return Value:
// The total number of bytes read (if it completes successfully, returns the size of block being read)
virtual unsigned int GetBytesRead(bool bWait = false) = 0;
// Description:
// Returns the buffer into which the data has been or will be read
// at least GetBytesRead() bytes in this buffer are guaranteed to be already read.
// Notes:
// DO NOT USE THIS BUFFER during read operation! DO NOT READ from it, it can lead to memory corruption!
virtual const void* GetBuffer () = 0;
// Description:
// Returns the transparent DWORD that was passed in the StreamReadParams::dwUserData field
// of the structure passed in the call to IStreamEngine::StartRead.
// See also:
// StreamReadParams::dwUserData,IStreamEngine::StartRead
virtual DWORD_PTR GetUserData() = 0;
// Summary:
// Set user defined data into stream's params.
virtual void SetUserData(DWORD_PTR dwUserData) = 0;
// Description:
// Tries to stop reading the stream; this is advisory and may have no effect
// but the callback will not be called after this. If you just destructing object,
// dereference this object and it will automatically abort and release all associated resources.
virtual void Abort() = 0;
// Description:
// Tries to stop reading the stream, as long as IO or the async callback is not currently
// in progress.
virtual bool TryAbort() = 0;
// Summary:
// Unconditionally waits until the callback is called.
// if nMaxWaitMillis is not negative wait for the specified ammount of milliseconds then exit.
// Example:
// If the stream hasn't yet finish, it's guaranteed that the user-supplied callback
// is called before return from this function (unless no callback was specified).
virtual void Wait(int nMaxWaitMillis = -1) = 0;
// Summary:
// Returns stream params.
virtual const StreamReadParams& GetParams() const = 0;
// Summary:
// Returns caller type.
virtual const EStreamTaskType GetCallerType() const = 0;
// Summary:
// Returns media type used to satisfy request - only valid once stream has begun read.
virtual EStreamSourceMediaType GetMediaType() const = 0;
// Summary:
// Returns pointer to callback routine(can be NULL).
virtual IStreamCallback* GetCallback() const = 0;
// Summary:
// Returns IO error #.
virtual unsigned GetError() const = 0;
// Summary:
// Returns IO error name
virtual const char* GetErrorName() const = 0;
// Summary:
// Returns stream name.
virtual const char* GetName() const = 0;
// Summary:
// Free temporary memory allocated for this stream, when not needed anymore.
// Can be called from Async callback, to free memory earlier, not waiting for synchrounus callback.
virtual void FreeTemporaryMemory() = 0;
// </interfuscator:shuffle>
protected:
// Summary:
// The clients are not allowed to destroy this object directly; only via Release().
virtual ~IReadStream() {}
};
TYPEDEF_AUTOPTR(IReadStream);
// Description:
// CryPak supports asynchronous reading through this interface. The callback
// is called from the main thread in the frame update loop.
//
// The callback receives packets through StreamOnComplete() and
// StreamOnProgress(). The second one can be used to update the asset based
// on the partial data that arrived. the callback that will be called by the
// streaming engine must be implemented by all clients that want to use
// StreamingEngine services
// Remarks:
// the pStream interface is guaranteed to be locked (have reference count > 0)
// while inside the function, but can vanish any time outside the function.
// If you need it, keep it from the beginning (after call to StartRead())
// some or all callbacks MAY be called from inside IStreamEngine::StartRead()
//
// Example:
// <code>
// IStreamEngine *pStreamEngine = g_pISystem->GetStreamEngine(); // get streaming engine
// IStreamCallback *pAsyncCallback = &MyClass; // user
//
// StreamReadParams params;
//
// params.dwUserData = 0;
// params.nSize = 0;
// params.pBuffer = NULL;
// params.nLoadTime = 10000;
// params.nMaxLoadTime = 10000;
//
// pStreamEngine->StartRead( .. pAsyncCallback .. params .. ); // registers callback
// </code>
class IStreamCallback
{
public:
// <interfuscator:shuffle>
virtual ~IStreamCallback(){}
// Description:
// Signals that the file length for the request has been found, and that storage is needed
// Either a pointer to a block of nSize bytes can be returned, into which the file will be
// streamed, or NULL can be returned, in which case temporary memory will be allocated
// internally by the stream engine (which will be freed upon job completion).
virtual void* StreamOnNeedStorage ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nSize, [[maybe_unused]] bool& bAbortOnFailToAlloc) {return NULL; }
// Description:
// Signals that reading the requested data has completed (with or without error).
// This callback is always called, whether an error occurs or not.
// pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released.
// GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end
// or the size of partially read data in case of error (0 if nothing was read).
// Pending status is true during this callback, because the callback itself is the part of IO operation.
// nError == 0 : Success
// nError != 0 : Error code
virtual void StreamAsyncOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {}
// Description:
// Signals that reading the requested data has completed (with or without error).
// This callback is always called, whether an error occurs or not.
// pStream will signal either IsFinished() or IsError() and will hold the (perhaps partially) read data until this interface is released.
// GetBytesRead() will return the size of the file (the completely read buffer) in case of successful operation end
// or the size of partially read data in case of error (0 if nothing was read).
// Pending status is true during this callback, because the callback itself is the part of IO operation.
// nError == 0 : Success
// nError != 0 : Error code
virtual void StreamOnComplete ([[maybe_unused]] IReadStream* pStream, [[maybe_unused]] unsigned nError) {}
// </interfuscator:shuffle>
};
#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINE_H
@@ -1,236 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H
#define CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H
#pragma once
#if defined(ENABLE_PROFILING_CODE)
#define STREAMENGINE_ENABLE_LISTENER
#define STREAMENGINE_ENABLE_STATS
#endif
enum : unsigned int
{
ERROR_UNKNOWN_ERROR = 0xF0000000,
ERROR_UNEXPECTED_DESTRUCTION = 0xF0000001,
ERROR_INVALID_CALL = 0xF0000002,
ERROR_CANT_OPEN_FILE = 0xF0000003,
ERROR_REFSTREAM_ERROR = 0xF0000004,
ERROR_OFFSET_OUT_OF_RANGE = 0xF0000005,
ERROR_REGION_OUT_OF_RANGE = 0xF0000006,
ERROR_SIZE_OUT_OF_RANGE = 0xF0000007,
ERROR_CANT_START_READING = 0xF0000008,
ERROR_OUT_OF_MEMORY = 0xF0000009,
ERROR_ABORTED_ON_SHUTDOWN = 0xF000000A,
ERROR_OUT_OF_MEMORY_QUOTA = 0xF000000B,
ERROR_ZIP_CACHE_FAILURE = 0xF000000C,
ERROR_USER_ABORT = 0xF000000D,
ERROR_MISSCHEDULED = 0xF000000F,
ERROR_VERIFICATION_FAIL = 0xF0000010,
ERROR_PREEMPTED = 0xF0000011,
ERROR_DECOMPRESSION_FAIL = 0xF0000012
};
// Summary:
// Types of streaming tasks
// Affects priority directly
enum EStreamTaskType
{
eStreamTaskTypeCount = 14,
eStreamTaskTypeGeomCache = 13,
eStreamTaskTypePak = 12,
eStreamTaskTypeFlash = 11,
eStreamTaskTypeVideo = 10,
eStreamTaskTypeMergedMesh = 9,
eStreamTaskTypeShader = 8,
eStreamTaskTypeSound = 7,
eStreamTaskTypeMusic = 6,
eStreamTaskTypeFSBCache = 5,
eStreamTaskTypeAnimation = 4,
eStreamTaskTypeTerrain = 3,
eStreamTaskTypeGeometry = 2,
eStreamTaskTypeTexture = 1,
};
// Summary:
// Priority types of streaming tasks
// Affects priority directly
// Limiting number of priority values allows streaming system to minimize seek time
enum EStreamTaskPriority
{
estpUrgent = 0,
estpPreempted = 1, //For internal use only
estpAboveNormal = 2,
estpNormal = 3,
estpBelowNormal = 4,
estpIdle = 5,
};
enum EStreamSourceMediaType : int32_t
{
eStreamSourceTypeUnknown = 0,
eStreamSourceTypeHDD,
eStreamSourceTypeDisc,
eStreamSourceTypeMemory,
};
#if defined(STREAMENGINE_ENABLE_STATS)
struct SStreamEngineStatistics
{
struct SMediaTypeInfo
{
SMediaTypeInfo()
{
ResetStats();
}
void ResetStats()
{
memset(this, 0, sizeof(SMediaTypeInfo));
}
float fActiveDuringLastSecond; // Amount of time media device was active during last second
float fAverageActiveTime; // Average time since last reset that the media device was active
uint32 nBytesRead; // Bytes read during last second.
uint32 nRequestCount; // Amount of requests during last second.
uint64 nTotalBytesRead; // Read bytes total from reset.
uint32 nTotalRequestCount; // Number of request from reset.
uint64 nSeekOffsetLastSecond; // Average seek offset during the last second
uint64 nAverageSeekOffset; // Average seek offset since last reset
uint32 nCurrentReadBandwidth; // Bytes/second for last second
uint32 nSessionReadBandwidth; // Bytes/second for last second
uint32 nActualReadBandwidth; // Bytes/second for last second - only taking actual reading into account
uint32 nAverageActualReadBandwidth; // Average read bandwidth in total from reset - only taking actual read time into account
};
SMediaTypeInfo hddInfo;
SMediaTypeInfo memoryInfo;
SMediaTypeInfo discInfo;
uint32 nTotalSessionReadBandwidth;// Average read bandwidth in total from reset - taking full time into account from reset
uint32 nTotalCurrentReadBandwidth;// Total bytes/sec over all types and systems.
int nPendingReadBytes; // How many bytes still need to be read
float fAverageCompletionTime; // Time in seconds on average takes to complete file request.
float fAverageRequestCount; // Average requests per second being done to streaming engine
uint64 nMainStreamingThreadWait;
uint64 nTotalBytesRead; // Read bytes total from reset.
uint32 nTotalRequestCount; // Number of request from reset to the streaming engine.
uint32 nTotalStreamingRequestCount; // Number of request from reset which actually resulted in streaming data.
int nCurrentDecompressCount; // Number of requests currently waiting to be decompresses
int nCurrentAsyncCount; // Number of requests currently waiting to be async callback
int nCurrentFinishedCount; // Number of requests currently waiting to be finished by mainthread
uint32 nDecompressBandwidth; // Bytes/second for last second
uint32 nVerifyBandwidth; // Bytes/second for last second
uint32 nDecompressBandwidthAverage; // Bytes/second in total.
uint32 nVerifyBandwidthAverage; // Bytes/second in total.
bool bTempMemOutOfBudget; // Was the temporary streaming memory out of budget during the last second
int nMaxTempMemory; // Maximum temporary memory used by the streaming system
int nTempMemory;
struct SRequestTypeInfo
{
SRequestTypeInfo()
: nPendingReadBytes(0)
{
ResetStats();
}
void ResetStats()
{
nTmpReadBytes = 0;
nTotalStreamingRequestCount = 0;
nTotalReadBytes = 0;
nTotalRequestDataSize = 0;
nTotalRequestCount = 0;
nCurrentReadBandwidth = 0;
nSessionReadBandwidth = 0;
fTotalCompletionTime = .0f;
fAverageCompletionTime = .0f;
}
void Merge(const SRequestTypeInfo& _other)
{
nPendingReadBytes += _other.nPendingReadBytes;
nTmpReadBytes += _other.nTmpReadBytes;
nTotalStreamingRequestCount += _other.nTotalStreamingRequestCount;
nTotalReadBytes += _other.nTotalReadBytes;
nTotalRequestDataSize += _other.nTotalRequestDataSize;
nTotalRequestCount += _other.nTotalRequestCount;
fTotalCompletionTime += _other.fTotalCompletionTime;
}
int nPendingReadBytes; // How many bytes still need to be read from media
uint64 nTmpReadBytes; // Read bytes since last update to compute current bandwidth
uint32 nTotalStreamingRequestCount; // Total actual streaming requests of this type
uint64 nTotalReadBytes; // Total actual read bytes (compressed data)
uint64 nTotalRequestDataSize; // Total requested bytes from client (uncompressed data)
uint32 nTotalRequestCount; // Total number of finished requests
uint32 nCurrentReadBandwidth; // Bytes/second for this type during last second
uint32 nSessionReadBandwidth; // Average read bandwidth in total from reset - taking full time into account from reset
float fTotalCompletionTime; // Time it took to finish all current requests
float fAverageCompletionTime; // Average time it takes to fully complete a request of this type
float fAverageRequestCount; // Average amount of requests made per second
};
SRequestTypeInfo typeInfo[eStreamTaskTypeCount];
struct SAsset
{
CryStringLocal m_sName;
int m_nSize;
const bool operator<(const SAsset& a) const { return m_nSize > a.m_nSize; }
SAsset() {}
SAsset(const CryStringLocal& sName, const int nSize)
: m_sName(sName)
, m_nSize(nSize) { }
friend void swap(SAsset& a, SAsset& b)
{
using std::swap;
a.m_sName.swap(b.m_sName);
swap(a.m_nSize, b.m_nSize);
}
};
DynArray<SAsset> vecHeavyAssets;
};
#endif
struct SStreamEngineOpenStats
{
int nOpenRequestCount;
int nOpenRequestCountByType[eStreamTaskTypeCount];
};
class IReadStream;
TYPEDEF_AUTOPTR(IReadStream);
// typedef IReadStream_AutoPtr auto ptr wrapper
typedef IReadStream_AutoPtr IReadStreamPtr;
#endif // CRYINCLUDE_CRYCOMMON_ISTREAMENGINEDEFS_H
-19
View File
@@ -65,12 +65,10 @@ struct IProcess;
struct ITimer;
struct ICryFont;
struct IMovieSystem;
struct IMemoryManager;
namespace Audio
{
struct IAudioSystem;
} // namespace Audio
struct IStreamEngine;
struct SFileVersion;
struct INameTable;
struct ILevelSystem;
@@ -78,7 +76,6 @@ struct IViewSystem;
class ICrySizer;
class IXMLBinarySerializer;
struct IReadWriteXMLSink;
struct IResourceManager;
struct ITextModeConsole;
struct IAVI_Reader;
class CPNoise3;
@@ -89,7 +86,6 @@ struct ILZ4Decompressor;
class IZStdDecompressor;
struct IOutputPrintSink;
struct IWindowMessageHandler;
struct IImageHandler;
namespace AZ
{
@@ -828,10 +824,6 @@ struct ISystem
virtual void DoWorkDuringOcclusionChecks() = 0;
virtual bool NeedDoWorkDuringOcclusionChecks() = 0;
// Summary:
// Returns the current used memory.
virtual uint32 GetUsedMemory() = 0;
// Summary:
// Retrieve the name of the user currently logged in to the computer.
virtual const char* GetUserName() = 0;
@@ -905,27 +897,18 @@ struct ISystem
virtual ILevelSystem* GetILevelSystem() = 0;
virtual INameTable* GetINameTable() = 0;
virtual IValidator* GetIValidator() = 0;
virtual IStreamEngine* GetStreamEngine() = 0;
virtual ICmdLine* GetICmdLine() = 0;
virtual ILog* GetILog() = 0;
virtual AZ::IO::IArchive* GetIPak() = 0;
virtual ICryFont* GetICryFont() = 0;
virtual IMemoryManager* GetIMemoryManager() = 0;
virtual IMovieSystem* GetIMovieSystem() = 0;
virtual ::IConsole* GetIConsole() = 0;
virtual IRemoteConsole* GetIRemoteConsole() = 0;
// Returns:
// Can be NULL, because it only exists when running through the editor, not in pure game mode.
virtual IResourceManager* GetIResourceManager() = 0;
virtual IProfilingSystem* GetIProfilingSystem() = 0;
virtual ISystemEventDispatcher* GetISystemEventDispatcher() = 0;
virtual ITimer* GetITimer() = 0;
virtual void DebugStats(bool checkpoint, bool leaks) = 0;
virtual void DumpWinHeaps() = 0;
virtual int DumpMMStats(bool log) = 0;
// Arguments:
// bValue - Set to true when running on a cheat protected server or a client that is connected to it (not used in singleplayer).
virtual void SetForceNonDevMode(bool bValue) = 0;
@@ -1166,8 +1149,6 @@ struct ISystem
// Initializes Steam if needed and returns if it was successful
virtual bool SteamInit() = 0;
virtual const IImageHandler* GetImageHandler() const = 0;
// Summary:
// Gets the root window message handler function
// The returned pointer is platform-specific:
@@ -1,86 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#include <CryCommon/ImageExtensionHelper.h>
namespace CImageExtensionHelper
{
ColorF GetAverageColor(uint8 const* pMem)
{
pMem = _findChunkStart(pMem, FOURCC_AvgC);
if (pMem)
{
ColorF ret = ColorF(SwapEndianValue(*(uint32*)pMem));
//flip red and blue
const float cRed = ret.r;
ret.r = ret.b;
ret.b = cRed;
return ret;
}
return Col_White; // chunk does not exist
}
bool IsRangeless(ETEX_Format eTF)
{
return (eTF == eTF_BC6UH ||
eTF == eTF_BC6SH ||
eTF == eTF_R9G9B9E5 ||
eTF == eTF_R16G16B16A16F ||
eTF == eTF_R32G32B32A32F ||
eTF == eTF_R16F ||
eTF == eTF_R32F ||
eTF == eTF_R16G16F ||
eTF == eTF_R11G11B10F);
}
bool IsQuantized(ETEX_Format eTF)
{
return (eTF == eTF_B4G4R4A4 ||
eTF == eTF_B5G6R5 ||
eTF == eTF_B5G5R5 ||
eTF == eTF_BC1 ||
eTF == eTF_BC2 ||
eTF == eTF_BC3 ||
eTF == eTF_BC4U ||
eTF == eTF_BC4S ||
eTF == eTF_BC5U ||
eTF == eTF_BC5S ||
eTF == eTF_BC6UH ||
eTF == eTF_BC6SH ||
eTF == eTF_BC7 ||
eTF == eTF_R9G9B9E5 ||
eTF == eTF_ETC2 ||
eTF == eTF_EAC_R11 ||
eTF == eTF_ETC2A ||
eTF == eTF_EAC_RG11 ||
eTF == eTF_PVRTC2 ||
eTF == eTF_PVRTC4 ||
eTF == eTF_ASTC_4x4 ||
eTF == eTF_ASTC_5x4 ||
eTF == eTF_ASTC_5x5 ||
eTF == eTF_ASTC_6x5 ||
eTF == eTF_ASTC_6x6 ||
eTF == eTF_ASTC_8x5 ||
eTF == eTF_ASTC_8x6 ||
eTF == eTF_ASTC_8x8 ||
eTF == eTF_ASTC_10x5 ||
eTF == eTF_ASTC_10x6 ||
eTF == eTF_ASTC_10x8 ||
eTF == eTF_ASTC_10x10 ||
eTF == eTF_ASTC_12x10 ||
eTF == eTF_ASTC_12x12
);
}
}
File diff suppressed because it is too large Load Diff
@@ -1,69 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H
#define CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H
#pragma once
#include "CryString.h"
#include "TypeInfo_decl.h"
#include "ImageExtensionHelper.h"
// Crytek specific image extensions
//
// usually added to the end of DDS files
STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_PIXELFORMAT)
STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwFlags, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwFourCC, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwRGBBitCount, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwRBitMask, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwGBitMask, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwBBitMask, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwABitMask, TYPE_INFO(DWORD))
STRUCT_INFO_END(CImageExtensionHelper::DDS_PIXELFORMAT)
STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER_DXT10)
STRUCT_VAR_INFO(dxgiFormat, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(resourceDimension, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(miscFlag, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(arraySize, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(reserved, TYPE_INFO(DWORD))
STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER_DXT10)
STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_HEADER)
STRUCT_VAR_INFO(dwSize, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwHeaderFlags, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwHeight, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwWidth, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwPitchOrLinearSize, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwDepth, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwMipMapCount, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwAlphaBitDepth, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwReserved1, TYPE_ARRAY(10, TYPE_INFO(DWORD)))
STRUCT_VAR_INFO(ddspf, TYPE_INFO(CImageExtensionHelper::DDS_PIXELFORMAT))
STRUCT_VAR_INFO(dwSurfaceFlags, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(dwCubemapFlags, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(bNumPersistentMips, TYPE_INFO(BYTE))
STRUCT_VAR_INFO(bReserved2, TYPE_ARRAY(7, TYPE_INFO(BYTE)))
STRUCT_VAR_INFO(dwTextureStage, TYPE_INFO(DWORD))
STRUCT_INFO_END(CImageExtensionHelper::DDS_HEADER)
STRUCT_INFO_BEGIN(CImageExtensionHelper::DDS_FILE_DESC)
STRUCT_VAR_INFO(dwMagic, TYPE_INFO(DWORD))
STRUCT_VAR_INFO(header, TYPE_INFO(CImageExtensionHelper::DDS_HEADER))
STRUCT_INFO_END(CImageExtensionHelper::DDS_FILE_DESC)
#endif // CRYINCLUDE_CRYCOMMON_IMAGEEXTENSIONHELPER_INFO_H
@@ -16,9 +16,6 @@
#include <LyShine/Bus/UiTransformBus.h>
#include <AzCore/Math/Vector2.h>
// forward declarations
class ITexture;
////////////////////////////////////////////////////////////////////////////////////////////////////
//! A sprite is a texture with extra information about how it behaves for 2D drawing
//! Currently a sprite exists on disk as a side car file next to the texture file.
@@ -80,9 +77,6 @@ public: // member functions
//! Set the borders of a given cell within the sprite-sheet.
virtual void SetCellBorders(int cellIndex, Borders borders) = 0;
//! Get the texture for this sprite
virtual ITexture* GetTexture() = 0;
//! Serialize this object for save/load
virtual void Serialize(TSerialize ser) = 0;
@@ -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.
*
*/
#pragma once
#include <CryMemoryManager.h>
class MemoryManagerMock
: public IMemoryManager
{
public:
MOCK_METHOD1(GetProcessMemInfo,
bool(SProcessMemInfo& minfo));
MOCK_METHOD3(TraceDefineHeap,
HeapHandle(const char* heapName, size_t size, const void* pBase));
MOCK_METHOD6(TraceHeapAlloc,
void(HeapHandle heap, void* mem, size_t size, size_t blockSize, const char* sUsage, const char* sNameHint));
MOCK_METHOD3(TraceHeapFree,
void(HeapHandle heap, void* mem, size_t blockSize));
MOCK_METHOD1(TraceHeapSetColor,
void(uint32 color));
MOCK_METHOD0(TraceHeapGetColor,
uint32());
MOCK_METHOD1(TraceHeapSetLabel,
void(const char* sLabel));
MOCK_METHOD1(CreateCustomMemoryHeapInstance,
ICustomMemoryHeap* const (EAllocPolicy const eAllocPolicy));
MOCK_METHOD3(CreateGeneralExpandingMemoryHeap,
IGeneralMemoryHeap* (size_t upperLimit, size_t reserveSize, const char* sUsage));
MOCK_METHOD3(CreateGeneralMemoryHeap,
IGeneralMemoryHeap* (void* base, size_t sz, const char* sUsage));
MOCK_METHOD2(ReserveAddressRange,
IMemoryAddressRange* (size_t capacity, const char* sName));
MOCK_METHOD2(CreatePageMappingHeap,
IPageMappingHeap* (size_t addressSpace, const char* sName));
};
@@ -1,47 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
struct NetworkMock : public INetwork
{
NetworkMock() : m_gridMate(nullptr)
{
}
GridMate::IGridMate* m_gridMate;
void Release() override {}
void GetMemoryStatistics([[maybe_unused]] ICrySizer* pSizer) override {}
void GetBandwidthStatistics([[maybe_unused]] SBandwidthStats* const pStats) override {}
void GetPerformanceStatistics([[maybe_unused]] SNetworkPerformance* pSizer) override {}
void GetProfilingStatistics([[maybe_unused]] SNetworkProfilingStats* const pStats) override {}
void SyncWithGame([[maybe_unused]] ENetworkGameSync syncType) override {}
const char* GetHostName() override { return "testhostname"; }
GridMate::IGridMate* GetGridMate() override
{
return m_gridMate;
}
ChannelId GetChannelIdForSessionMember([[maybe_unused]] GridMate::GridMember* member) const override { return ChannelId(); }
ChannelId GetServerChannelId() const override { return ChannelId(); }
ChannelId GetLocalChannelId() const override { return ChannelId(); }
CTimeValue GetSessionTime() override { return CTimeValue(); }
void ChangedAspects([[maybe_unused]] EntityId id, [[maybe_unused]] NetworkAspectType aspectBits) override {}
void SetDelegatableAspectMask([[maybe_unused]] NetworkAspectType aspectBits) override {}
void SetObjectDelegatedAspectMask([[maybe_unused]] EntityId entityId, [[maybe_unused]] NetworkAspectType aspects, [[maybe_unused]] bool set) override {}
void DelegateAuthorityToClient([[maybe_unused]] EntityId entityId, [[maybe_unused]] ChannelId clientChannelId) override {}
void InvokeActorRMI([[maybe_unused]] EntityId entityId, [[maybe_unused]] uint8 actorExtensionId, [[maybe_unused]] ChannelId targetChannelFilter, [[maybe_unused]] IActorRMIRep& rep) override {}
void InvokeScriptRMI([[maybe_unused]] ISerializable* serializable, [[maybe_unused]] bool isServerRMI, [[maybe_unused]] ChannelId toChannelId = kInvalidChannelId, [[maybe_unused]] ChannelId avoidChannelId = kInvalidChannelId) override {}
void RegisterActorRMI([[maybe_unused]] IActorRMIRep* rep) override {}
void UnregisterActorRMI([[maybe_unused]] IActorRMIRep* rep) override {}
EntityId LocalEntityIdToServerEntityId([[maybe_unused]] EntityId localId) const override { return EntityId(); }
EntityId ServerEntityIdToLocalEntityId([[maybe_unused]] EntityId serverId, [[maybe_unused]] bool allowForcedEstablishment = false) const override { return EntityId(); }
};
@@ -330,8 +330,6 @@ public:
ITexture * (const char* nameTex));
MOCK_METHOD1(EF_LoadLightmap,
int(const char* name));
MOCK_METHOD3(EF_RenderEnvironmentCubeHDR,
bool(int size, Vec3 & Pos, TArray<unsigned short>&vecData));
MOCK_METHOD1(EF_StartEf,
void(const SRenderingPassInfo& passInfo));
MOCK_METHOD3(EF_GetObjData,
@@ -360,8 +358,6 @@ public:
uint32(eDeferredLightType));
MOCK_METHOD0(EF_ClearDeferredLightsList,
void());
MOCK_METHOD2(EF_GetDeferredLights,
TArray<SRenderLight>*(const SRenderingPassInfo&, const eDeferredLightType));
MOCK_METHOD1(EF_AddDeferredClipVolume,
uint8(const IClipVolume * pClipVolume));
MOCK_METHOD2(EF_SetDeferredClipVolumeBlendData,
@@ -37,8 +37,6 @@ public:
bool());
MOCK_METHOD0(RenderStatistics,
void());
MOCK_METHOD0(GetUsedMemory,
uint32());
MOCK_METHOD0(GetUserName,
const char*());
MOCK_METHOD0(GetCPUFlags,
@@ -88,8 +86,6 @@ public:
INameTable * ());
MOCK_METHOD0(GetIValidator,
IValidator * ());
MOCK_METHOD0(GetStreamEngine,
IStreamEngine * ());
MOCK_METHOD0(GetICmdLine,
ICmdLine * ());
MOCK_METHOD0(GetILog,
@@ -98,8 +94,6 @@ public:
AZ::IO::IArchive * ());
MOCK_METHOD0(GetICryFont,
ICryFont * ());
MOCK_METHOD0(GetIMemoryManager,
IMemoryManager * ());
MOCK_METHOD0(GetIMovieSystem,
IMovieSystem * ());
MOCK_METHOD0(GetIAudioSystem,
@@ -108,20 +102,12 @@ public:
::IConsole * ());
MOCK_METHOD0(GetIRemoteConsole,
IRemoteConsole * ());
MOCK_METHOD0(GetIResourceManager,
IResourceManager * ());
MOCK_METHOD0(GetIProfilingSystem,
IProfilingSystem * ());
MOCK_METHOD0(GetISystemEventDispatcher,
ISystemEventDispatcher * ());
MOCK_METHOD0(GetITimer,
ITimer * ());
MOCK_METHOD2(DebugStats,
void(bool checkpoint, bool leaks));
MOCK_METHOD0(DumpWinHeaps,
void());
MOCK_METHOD1(DumpMMStats,
int(bool log));
MOCK_METHOD1(SetForceNonDevMode,
void(bool bValue));
MOCK_CONST_METHOD0(GetForceNonDevMode,
@@ -237,8 +223,6 @@ public:
MOCK_METHOD0(SteamInit,
bool());
MOCK_CONST_METHOD0(GetImageHandler,
const IImageHandler * ());
MOCK_METHOD0(GetRootWindowMessageHandler,
void*());
MOCK_METHOD1(RegisterWindowMessageHandler,
@@ -1,29 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzTest/AzTest.h>
#include <CGFContent.h>
class MockIAssetWriter
: public IAssetWriter
{
public:
~MockIAssetWriter() override = default;
MOCK_METHOD1(WriteCGF,
bool(CContentCGF* content));
MOCK_METHOD2(WriteCHR,
bool(CContentCGF* content, IConvertContext* convertContext));
MOCK_METHOD3(WriteSKIN,
bool(CContentCGF* content, IConvertContext* convertContext, bool exportMorphTargets));
};
@@ -1,11 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -1,14 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../../WinBase.cpp
)
@@ -1,13 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
)
@@ -1,11 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -1,13 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
)
@@ -1,11 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -1,14 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../../WinBase.cpp
)
@@ -1,11 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -1,14 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../../WinBase.cpp
)
@@ -1,11 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -1,13 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
)
@@ -1,13 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
)
@@ -1,11 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -1,14 +0,0 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../../WinBase.cpp
)
-3
View File
@@ -36,9 +36,6 @@
// require a pointer to the bucket be stored, whereas now no memory is used
// while the block is allocated.
//
// This allocator is suitable for use with STL lists - see STLPoolAllocator
// for an STL-compatible interface.
//
// The class can optionally support multi-threading, using the second
// template parameter. By default it is multithread-safe.
// See Synchronization.h.
@@ -1,185 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H
#define CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H
#pragma once
//---------------------------------------------------------------------------
// STL-compatible interface for an std::allocator using the global heap.
//---------------------------------------------------------------------------
#include <stddef.h>
#include <climits>
#include "CryMemoryManager.h"
#include <AzCore/Memory/AllocatorBase.h>
#include <AzCore/Memory/HphaSchema.h>
#include <AzCore/Memory/AllocatorManager.h>
struct CryLegacySTLAllocatorDescriptor
: public AZ::HphaSchema::Descriptor
{
CryLegacySTLAllocatorDescriptor()
{
m_systemChunkSize = 4 * 1024 * 1024; // Ask the OS for 4MB at a time
}
};
class CryLegacySTLAllocator
: public AZ::SimpleSchemaAllocator<AZ::HphaSchema, CryLegacySTLAllocatorDescriptor>
{
public:
AZ_TYPE_INFO(CryLegacySTLAllocator, "{87EE21F1-8215-4979-B493-AF13D8D91DAD}");
using Descriptor = CryLegacySTLAllocatorDescriptor;
using Base = AZ::SimpleSchemaAllocator<AZ::HphaSchema, CryLegacySTLAllocatorDescriptor>;
CryLegacySTLAllocator()
: Base("CryLegacySTLAllocator", "Allocator used to dodge limits on static init time allocations")
{
}
};
// Specialize for the CryLegacySTLAllocator to provide one per module that does not use the
// environment for its storage, since this thing is designed to get around the lack
// of static allocators
namespace AZ
{
template <>
class AllocatorInstance<CryLegacySTLAllocator> : public Internal::AllocatorInstanceBase<CryLegacySTLAllocator, AllocatorStorage::ModuleStoragePolicy<CryLegacySTLAllocator>>
{
};
}
class ICrySizer;
namespace stl
{
template <class T>
class STLGlobalAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U>
struct rebind
{
typedef STLGlobalAllocator<U> other;
};
STLGlobalAllocator() throw()
{
}
STLGlobalAllocator(const STLGlobalAllocator&) throw()
{
}
template <class U>
STLGlobalAllocator(const STLGlobalAllocator<U>&) throw()
{
}
~STLGlobalAllocator() throw()
{
}
pointer address(reference x) const
{
return &x;
}
const_pointer address(const_reference x) const
{
return &x;
}
pointer allocate(size_type n = 1, const void* hint = 0)
{
(void)hint;
pointer ret = static_cast<pointer>(AZ::AllocatorInstance<CryLegacySTLAllocator>::Get().Allocate(n * sizeof(T), 0));
return ret;
}
void deallocate(pointer p, [[maybe_unused]] size_type n = 1)
{
AZ::AllocatorInstance<CryLegacySTLAllocator>::Get().DeAllocate(p);
}
size_type max_size() const throw()
{
return INT_MAX;
}
#if !defined(_LIBCPP_VERSION)
void construct(pointer p, const T& val)
{
new(static_cast<void*>(p))T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p))T();
}
#endif // !_LIBCPP_VERSION
void destroy(pointer p)
{
p->~T();
}
pointer new_pointer()
{
return new(allocate())T();
}
pointer new_pointer(const T& val)
{
return new(allocate())T(val);
}
void delete_pointer(pointer p)
{
p->~T();
deallocate(p);
}
bool operator==(const STLGlobalAllocator&) const { return true; }
bool operator!=(const STLGlobalAllocator&) const { return false; }
static void GetMemoryUsage(ICrySizer* pSizer)
{
}
};
template <>
class STLGlobalAllocator<void>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template <class U>
struct rebind
{
typedef STLGlobalAllocator<U> other;
};
};
}
#endif // CRYINCLUDE_CRYCOMMON_STLGLOBALALLOCATOR_H
-208
View File
@@ -1,208 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H
#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H
#pragma once
//---------------------------------------------------------------------------
// STL-compatible interface for the pool allocator (see PoolAllocator.h).
//
// This class is suitable for use as an allocator for STL lists. Note it will
// not work with vectors, since it allocates fixed-size blocks, while vectors
// allocate elements in variable-sized contiguous chunks.
//
// To create a list of type UserDataType using this allocator, use the
// following syntax:
//
// std::list<UserDataType, STLPoolAllocator<UserDataType> > myList;
//---------------------------------------------------------------------------
#include "PoolAllocator.h"
#include "MetaUtils.h"
#include <stddef.h>
#include <climits>
namespace stl
{
namespace STLPoolAllocatorHelper
{
inline void destruct(char*) {}
inline void destruct(wchar_t*) {}
template <typename T>
inline void destruct(T* t) {t->~T(); }
}
template <size_t S, class L, size_t A, bool FreeWhenEmpty, typename T>
struct STLPoolAllocatorStatic
{
// Non-freeing stl pool allocators should just go on the global heap - only if they've been explicitly
// set to cleanup should they go on the default heap.
typedef SizePoolAllocator<
HeapAllocator<
L,
typename metautils::select<FreeWhenEmpty, HeapSysAllocator, GlobalHeapSysAllocator>::type>
> AllocatorType;
static AllocatorType* GetOrCreateAllocator()
{
if (allocator)
{
return allocator;
}
allocator = new AllocatorType(S, A, FHeap().FreeWhenEmpty(FreeWhenEmpty));
return allocator;
}
static AllocatorType* allocator;
};
template <class T, class L, size_t A, bool FreeWhenEmpty>
struct STLPoolAllocatorKungFu
: public STLPoolAllocatorStatic<sizeof(T), L, A, FreeWhenEmpty, T>
{
};
template <class T, class L = PSyncMultiThread, size_t A = 0, bool FreeWhenEmpty = false>
class STLPoolAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U>
struct rebind
{
typedef STLPoolAllocator<U, L, A, FreeWhenEmpty> other;
};
STLPoolAllocator() throw()
{
}
STLPoolAllocator(const STLPoolAllocator&) throw()
{
}
template <class U, class M, size_t B, bool FreeWhenEmptyA>
STLPoolAllocator(const STLPoolAllocator<U, M, B, FreeWhenEmptyA>&) throw()
{
}
~STLPoolAllocator() throw()
{
}
pointer address(reference x) const
{
return &x;
}
const_pointer address(const_reference x) const
{
return &x;
}
pointer allocate([[maybe_unused]] size_type n = 1, [[maybe_unused]] const void* hint = 0)
{
assert(n == 1);
typename STLPoolAllocatorKungFu<T, L, A, FreeWhenEmpty>::AllocatorType * allocator = STLPoolAllocatorKungFu<T, L, A, FreeWhenEmpty>::GetOrCreateAllocator();
return static_cast<T*>(allocator->Allocate());
}
void deallocate(pointer p, [[maybe_unused]] size_type n = 1)
{
assert(n == 1);
typename STLPoolAllocatorKungFu<T, L, A, FreeWhenEmpty>::AllocatorType * allocator = STLPoolAllocatorKungFu<T, L, A, FreeWhenEmpty>::allocator;
allocator->Deallocate(p);
}
size_type max_size() const throw()
{
return INT_MAX;
}
#ifndef _LIBCPP_VERSION
void construct(pointer p, const T& val)
{
new(static_cast<void*>(p))T(val);
}
void construct(pointer p)
{
new(static_cast<void*>(p))T();
}
#endif // !(_LIBCPP_VERSION)
void destroy(pointer p)
{
STLPoolAllocatorHelper::destruct(p);
}
pointer new_pointer()
{
return new(allocate())T();
}
pointer new_pointer(const T& val)
{
return new(allocate())T(val);
}
void delete_pointer(pointer p)
{
p->~T();
deallocate(p);
}
bool operator==(const STLPoolAllocator&) {return true; }
bool operator!=(const STLPoolAllocator&) {return false; }
static void GetMemoryUsage(ICrySizer* pSizer)
{
pSizer->AddObject(STLPoolAllocatorKungFu<T, L, A, FreeWhenEmpty>::allocator);
}
};
template <class T, size_t A = 0, bool FreeWhenEmpty = false>
class STLPoolAllocatorNoMT
: public STLPoolAllocator<T, PSyncNone, A, FreeWhenEmpty>
{
};
template <>
class STLPoolAllocator<void>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
template <class U, class L>
struct rebind
{
typedef STLPoolAllocator<U> other;
};
};
template <size_t S, typename L, size_t A, bool FreeWhenEmpty, typename T>
typename STLPoolAllocatorStatic<S, L, A, FreeWhenEmpty, T>::AllocatorType * STLPoolAllocatorStatic<S, L, A, FreeWhenEmpty, T>::allocator;
}
#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_H
@@ -1,107 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
// Original file Copyright Crytek GMBH or its affiliates, used under license.
#ifndef CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H
#define CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H
#pragma once
//---------------------------------------------------------------------------
// STL-compatible interface for the pool allocator (see PoolAllocator.h).
//
// this class acts like STLPoolAllocator, but it is also usable for vectors
// which means that it can be used as a more efficient allocator for many
// implementations of hash_map (typically this uses internally a vector and
// a list with the same allocator)
//---------------------------------------------------------------------------
#include "STLPoolAllocator.h"
namespace stl
{
template <size_t S, typename L, size_t A>
struct STLPoolAllocator_ManyElemsStatic
{
static PoolAllocator<S, L, A>* allocator;
};
template <typename T, typename L = PSyncMultiThread, size_t LargeAllocationSizeThreshold = 54* sizeof(void*), size_t A = 0>
class STLPoolAllocator_ManyElems
: public STLPoolAllocator<T, L, A>
{
typedef STLPoolAllocator<T, L, A> Super;
typedef PoolAllocator<LargeAllocationSizeThreshold, L, A> LargeAllocator;
public:
typedef typename Super::pointer pointer;
typedef typename Super::pointer pointer_type;
typedef typename Super::size_type size_type;
typedef AZStd::false_type allow_memory_leaks;
template <typename U>
struct rebind
{
typedef STLPoolAllocator_ManyElems<U, L, LargeAllocationSizeThreshold, A> other;
};
STLPoolAllocator_ManyElems() throw()
{
}
template <typename U, typename M, size_t C, size_t B>
STLPoolAllocator_ManyElems(const STLPoolAllocator_ManyElems<U, M, C, B>&) throw()
{
}
pointer allocate(size_type n = 1, const void* hint = 0)
{
if (n == 1)
{
return Super::allocate(n, hint);
}
else if (n * sizeof(T) <= LargeAllocationSizeThreshold)
{
if (!STLPoolAllocator_ManyElemsStatic<LargeAllocationSizeThreshold, L, A>::allocator)
{
STLPoolAllocator_ManyElemsStatic<LargeAllocationSizeThreshold, L, A>::allocator = new LargeAllocator();
}
return static_cast<T*>(STLPoolAllocator_ManyElemsStatic<LargeAllocationSizeThreshold, L, A>::allocator->Allocate());
}
else
{
return static_cast<pointer>(CryModuleMalloc(n * sizeof(T)));
}
}
void deallocate(pointer p, size_type n = 1)
{
if (n == 1)
{
Super::deallocate(p);
}
else if (n * sizeof(T) <= LargeAllocationSizeThreshold)
{
STLPoolAllocator_ManyElemsStatic<LargeAllocationSizeThreshold, L, A>::allocator->Deallocate(p);
}
else
{
CryModuleFree(p);
}
}
};
template <size_t S, typename L, size_t A>
PoolAllocator<S, L, A>* STLPoolAllocator_ManyElemsStatic<S, L, A>::allocator;
}
#endif // CRYINCLUDE_CRYCOMMON_STLPOOLALLOCATOR_MANYELEMS_H
-1
View File
@@ -27,7 +27,6 @@
#endif
#define STATIC_ASSERT(condition, errMessage) static_assert(condition, errMessage)
#include "STLGlobalAllocator.h"
#include <map>
#include <set>

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