Merge branch 'main' into Prefab/CreatePrefab
This commit is contained in:
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
# Test case ID : C18977329
|
||||
# Test Case Title : Add cloth simulation to a Mesh
|
||||
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977329
|
||||
|
||||
# fmt: off
|
||||
class Tests:
|
||||
|
||||
-1
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
# Test case ID : C18977330
|
||||
# Test Case Title : Add cloth simulation to an Actor
|
||||
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/18977330
|
||||
|
||||
# fmt: off
|
||||
class Tests:
|
||||
|
||||
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
# Test case ID : C28798177
|
||||
# Test Case Title : White Box Tool Component can be added to an Entity
|
||||
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798177
|
||||
|
||||
|
||||
# fmt:off
|
||||
|
||||
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
# Test case ID : C28798205
|
||||
# Test Case Title : From the White Box Component Card the White Box Mesh can be set to be invisible in Game View
|
||||
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/28798205
|
||||
|
||||
|
||||
# fmt:off
|
||||
|
||||
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
# Test case ID : C29279329
|
||||
# Test Case Title : White Box mesh shape can be changed with the Default Shape dropdown on the Component
|
||||
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/29279329
|
||||
|
||||
|
||||
# fmt:off
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ def C14976308_ScriptCanvas_SetKinematicTargetTransform():
|
||||
the script deactivates Signal, Sphere's transform will update to that of Transform_Target.
|
||||
NOTE: There is a known bug (LY-107723) which causes the rotation to update to a value that is not sufficiently close
|
||||
to the expected result when using Set Kinematic Target which will cause the test to fail:
|
||||
https://jira.agscollab.com/browse/LY-107723
|
||||
LY-107723
|
||||
|
||||
Test Steps:
|
||||
1) Open level and enter game mode
|
||||
|
||||
@@ -13,7 +13,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# Test case ID : C3510644
|
||||
# Test Case Title : Check that the collision layer and collision group of the terrain can be changed
|
||||
# and the collision behavior of the terrain changes accordingly
|
||||
# URL of the test case : https://testrail.agscollab.com/index.php?/cases/view/3510644
|
||||
|
||||
|
||||
# fmt: off
|
||||
|
||||
@@ -239,7 +239,7 @@ def C6321601_Force_HighValuesDirectionAxes():
|
||||
force_notification_handler.add_callback("OnCalculateNetForce", on_calc_net_force)
|
||||
|
||||
# Wait for 3 secs, because there is a known bug identified and filed in
|
||||
# JIRA https://jira.agscollab.com/browse/LY-107677
|
||||
# JIRA LY-107677
|
||||
# The error "[Error] Huge object being added to a COctreeNode, name: 'MeshComponentRenderNode', objBox:"
|
||||
# will show (if occured) in about 3 sec into the game mode.
|
||||
helper.wait_for_condition(has_physx_error, 3.0)
|
||||
|
||||
@@ -50,7 +50,7 @@ class TestAutomation(TestAutomationBase):
|
||||
unexpected_lines = ["Assert"]
|
||||
self._run_test(request, workspace, editor, test_module, expected_lines, unexpected_lines)
|
||||
|
||||
# BUG: https://jira.agscollab.com/browse/LY-107723")
|
||||
# BUG: LY-107723")
|
||||
def test_C14976308_ScriptCanvas_SetKinematicTargetTransform(self, request, workspace, editor):
|
||||
from . import C14976308_ScriptCanvas_SetKinematicTargetTransform as test_module
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
'''
|
||||
This unittest might have to be refactored once changes to Physmaterial_Editor.py are made.
|
||||
These changes will occur after the but, reverence below is resloved.
|
||||
Bug: https://jira.agscollab.com/browse/LY-107392
|
||||
Bug: LY-107392
|
||||
'''
|
||||
class Tests:
|
||||
opening_bad_file = ("Bad file could not be opened", "Bad file was opened")
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92569013
|
||||
Test Case Title: Script Event file can be created
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569013
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
Test case ID: T92568942
|
||||
Test Case Title: Clicking the "+" button and selecting "New Script Event" opens the
|
||||
Asset Editor with a new Script Event asset
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568942
|
||||
"""
|
||||
|
||||
from PySide2 import QtWidgets
|
||||
|
||||
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92568856
|
||||
Test Case Title: Multiple Entities can be targeted in the Debugger tool
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568856
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92569137
|
||||
Test Case Title: Multiple Graphs can be targeted in the Debugger tool
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569137
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: C1702824
|
||||
Test Case Title: Docking
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702824
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92569049
|
||||
Test Case Title: Edit > Undo undoes the last action
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569049
|
||||
Test case ID: T92569051
|
||||
Test Case Title: Edit > Redo redoes the last undone action
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569051
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92562978
|
||||
Test Case Title: Script Canvas Component can be added to an entity
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562978
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92569037
|
||||
Test Case Title: File > New Script creates a new script
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569037
|
||||
Test case ID: T92569039
|
||||
Test Case Title: File > Open opens the Open... dialog
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569039
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
@@ -11,11 +11,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92563070
|
||||
Test Case Title: Graphs can be closed by clicking X on the Graph name tab
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563070
|
||||
Test case ID: T92563068
|
||||
Test Case Title: Save Prompt: User is prompted to save a graph on close after
|
||||
creating a new graph
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563068
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
@@ -11,10 +11,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92569079
|
||||
Test Case Title: View > Zoom In zooms the graph in
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569079
|
||||
Test case ID: T92569081
|
||||
Test Case Title: View > Zoom In zooms the graph out
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569081
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ 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
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562988
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92568982
|
||||
Test Case Title: Renaming variables in the Node Inspector
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568982
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92562993
|
||||
Test Case Title: Clicking the X button on the Search Box clears the currently entered string
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562993
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests():
|
||||
set_search_string = ("Search string is set", "Search string is not set")
|
||||
search_string_deleted = ("Search string deleted as expected", "Search string not deleted")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def NodePalette_SearchText_Deletion():
|
||||
"""
|
||||
Summary:
|
||||
We enter some string in the Node Palette Search box, select that text and delete it.
|
||||
|
||||
Expected Behavior:
|
||||
After RightClick->Delete the text in the Searchbox should be deleted.
|
||||
|
||||
Test Steps:
|
||||
1) Open Script Canvas window (Tools > Script Canvas)
|
||||
2) Get the SC window object
|
||||
3) Open Node Manager if not opened already
|
||||
4) Set some string in the Search box
|
||||
5) Verify if the test string is set
|
||||
6) Delete search string using right click and verify if it is cleared
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
|
||||
from PySide2 import QtWidgets, QtTest, QtCore
|
||||
|
||||
from utils import TestHelper as helper
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
import pyside_utils
|
||||
|
||||
TEST_STRING = "TestString"
|
||||
|
||||
# 1) Open Script Canvas window (Tools > Script Canvas)
|
||||
general.idle_enable(True)
|
||||
general.open_pane("Script Canvas")
|
||||
helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 3.0)
|
||||
|
||||
# 2) Get the SC window object
|
||||
editor_window = pyside_utils.get_editor_main_window()
|
||||
sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
|
||||
|
||||
# 3) Open Node Manager if not opened already
|
||||
if sc.findChild(QtWidgets.QDockWidget, "NodePalette") is None:
|
||||
action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Palette", "type": QtWidgets.QAction})
|
||||
action.trigger()
|
||||
node_palette = sc.findChild(QtWidgets.QDockWidget, "NodePalette")
|
||||
search_frame = node_palette.findChild(QtWidgets.QFrame, "searchFrame")
|
||||
|
||||
# 4) Set some string in the Search box
|
||||
search_box = search_frame.findChild(QtWidgets.QLineEdit, "searchFilter")
|
||||
search_box.setText(TEST_STRING)
|
||||
|
||||
# 5) Verify if the test string is set
|
||||
result = helper.wait_for_condition(lambda: search_box.text() == TEST_STRING, 1.0)
|
||||
Report.result(Tests.set_search_string, result)
|
||||
|
||||
# 6) Delete search string using right click and verify if it is cleared
|
||||
QtTest.QTest.keyClick(search_box, QtCore.Qt.Key_A, QtCore.Qt.ControlModifier)
|
||||
pyside_utils.trigger_context_menu_entry(search_box, "Delete")
|
||||
result = helper.wait_for_condition(lambda: search_box.text() == "", 2.0)
|
||||
Report.result(Tests.search_string_deleted, result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import ImportPathHelper as imports
|
||||
|
||||
imports.init()
|
||||
from utils import Report
|
||||
|
||||
Report.start_test(NodePalette_SearchText_Deletion)
|
||||
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92568940
|
||||
Test Case Title: Categories and Nodes can be selected
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568940
|
||||
"""
|
||||
|
||||
|
||||
|
||||
-1
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92569253 // T92569254
|
||||
Test Case Title: On Entity Activated // On Entity Deactivated
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92569253 // https://testrail.agscollab.com/index.php?/tests/view/92569254
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: C1702834 // C1702823
|
||||
Test Case Title: Opening pane // Closing pane
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702834 and
|
||||
https://testrail.agscollab.com/index.php?/cases/view/1702823
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: C1702821 // C1702832
|
||||
Test Case Title: Retain visibility, size and location upon Script Canvas restart
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702821 and
|
||||
https://testrail.agscollab.com/index.php?/cases/view/1702832
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: C1702829
|
||||
Test Case Title: Resizing pane
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702829
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
Test case ID: T92562986
|
||||
Test Case Title: Changing the assigned Script Canvas Asset on an entity properly updates
|
||||
level functionality
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92562986
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92563190
|
||||
Test Case Title: A single Entity with two Script Canvas components works properly
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563190
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92563191
|
||||
Test Case Title: Two Entities can use the same Graph asset successfully at RunTime
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92563191
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92567321
|
||||
Test Case Title: Script Events: Can send and receive a script event across multiple entities successfully
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567321
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92567320
|
||||
Test Case Title: Script Events: Can send and receive a script event successfully
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92567320
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -195,6 +195,14 @@ 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)
|
||||
|
||||
def test_VariableManager_UnpinVariableType_Works(self, request, workspace, editor, launcher_platform):
|
||||
from . import VariableManager_UnpinVariableType_Works as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method
|
||||
# fails because of pyside_utils import
|
||||
|
||||
@@ -13,11 +13,6 @@ Test Case Title: Tools > Node Palette toggles the Node Palette
|
||||
Tools > Node Inspector toggles the Node Inspector
|
||||
Tools > Bookmarks toggles the Bookmarks
|
||||
Tools > Variable Manager toggles the Variable Manager
|
||||
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/92569165
|
||||
https://testrail.agscollab.com/index.php?/cases/view/92569167
|
||||
https://testrail.agscollab.com/index.php?/cases/view/92569168
|
||||
https://testrail.agscollab.com/index.php?/cases/view/92569170
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: C1702825 // C1702831
|
||||
Test Case Title: Undocking // Closing script canvas with the pane floating
|
||||
URLs of the test case: https://testrail.agscollab.com/index.php?/cases/view/1702825 &
|
||||
https://testrail.agscollab.com/index.php?/cases/view/1702831
|
||||
"""
|
||||
|
||||
|
||||
|
||||
@@ -10,10 +10,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
Test case ID: T92564789
|
||||
Test Case Title: Each Variable type can be created
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92564789
|
||||
Test case ID: T92568873
|
||||
Test Case Title: Each Variable type can be deleted
|
||||
URL of the test case: https://testrail.agscollab.com/index.php?/tests/view/92568873
|
||||
"""
|
||||
|
||||
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests():
|
||||
variable_manager_opened = ("VariableManager is opened successfully", "Failed to open VariableManager")
|
||||
variable_pinned = ("Variable is pinned", "Variable is not pinned, But it should be unpinned")
|
||||
variable_unpinned = ("Variable is unpinned", "Variable is not unpinned, But it should be pinned")
|
||||
variable_unpinned_after_reopen = ("Variable is unpinned after reopening create variable menu", "Variable is not unpinned after reopening create variable menu")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def VariableManager_UnpinVariableType_Works():
|
||||
"""
|
||||
Summary:
|
||||
Unpin variable types in create variable menu.
|
||||
Expected Behavior:
|
||||
The variable unpinned in create variable menu remains unpinned after reopening create variable menu.
|
||||
Test Steps:
|
||||
1) Open Script Canvas window (Tools > Script Canvas)
|
||||
2) Get the SC window object
|
||||
3) Open Variable Manager in Script Canvas window
|
||||
4) Create new graph
|
||||
5) Click on the Create Variable button in the Variable Manager
|
||||
6) Unpin Boolean by clicking the "Pin" icon on its left side
|
||||
7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu
|
||||
8) Restore default layout and close SC window
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
from PySide2 import QtWidgets
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
import pyside_utils
|
||||
from utils import TestHelper as helper
|
||||
from utils import Report
|
||||
from PySide2.QtCore import Qt
|
||||
|
||||
GENERAL_WAIT = 1.0 # seconds
|
||||
|
||||
def find_pane(window, pane_name):
|
||||
return window.findChild(QtWidgets.QDockWidget, pane_name)
|
||||
|
||||
def click_menu_option(window, option_text):
|
||||
action = pyside_utils.find_child_by_pattern(window, {"text": option_text, "type": QtWidgets.QAction})
|
||||
action.trigger()
|
||||
|
||||
# 1) Open Script Canvas window (Tools > Script Canvas)
|
||||
general.idle_enable(True)
|
||||
general.open_pane("Script Canvas")
|
||||
helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 6.0)
|
||||
|
||||
# 2) Get the SC window object
|
||||
editor_window = pyside_utils.get_editor_main_window()
|
||||
sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
|
||||
sc_main = sc.findChild(QtWidgets.QMainWindow)
|
||||
|
||||
# 3) Open Variable Manager in Script Canvas window
|
||||
pane = find_pane(sc, "VariableManager")
|
||||
if not pane.isVisible():
|
||||
click_menu_option(sc, "Variable Manager")
|
||||
pane = find_pane(sc, "VariableManager")
|
||||
Report.result(Tests.variable_manager_opened, pane.isVisible())
|
||||
|
||||
# 4) Create new graph
|
||||
create_new_graph = pyside_utils.find_child_by_pattern(
|
||||
sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction}
|
||||
)
|
||||
create_new_graph.trigger()
|
||||
|
||||
# 5) Click on the Create Variable button in the Variable Manager
|
||||
variable_manager = sc_main.findChild(QtWidgets.QDockWidget, "VariableManager")
|
||||
button = variable_manager.findChild(QtWidgets.QPushButton, "addButton")
|
||||
button.click()
|
||||
|
||||
# 6) Unpin Boolean by clicking the "Pin" icon on its left side
|
||||
table_view = variable_manager.findChild(QtWidgets.QTableView, "variablePalette")
|
||||
model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean")
|
||||
# Make sure Boolean is pinned
|
||||
is_boolean = model_index.siblingAtColumn(0)
|
||||
result = helper.wait_for_condition(lambda: is_boolean.data(Qt.DecorationRole) is not None, GENERAL_WAIT)
|
||||
Report.result(Tests.variable_pinned, result)
|
||||
# Unpin Boolean and make sure Boolean is unpinned.
|
||||
pyside_utils.item_view_index_mouse_click(table_view, is_boolean)
|
||||
result = helper.wait_for_condition(lambda: is_boolean.data(Qt.DecorationRole) is None, GENERAL_WAIT)
|
||||
Report.result(Tests.variable_unpinned, result)
|
||||
|
||||
# 7) Close and Reopen Create Variable menu and make sure Boolean is unpinned after reopening Create Variable menu
|
||||
button.click()
|
||||
button.click()
|
||||
model_index = pyside_utils.find_child_by_pattern(table_view, "Boolean")
|
||||
result = helper.wait_for_condition(
|
||||
lambda: model_index.siblingAtColumn(0).data(Qt.DecorationRole) is None, GENERAL_WAIT
|
||||
)
|
||||
Report.result(Tests.variable_unpinned_after_reopen, result)
|
||||
|
||||
# 8) Restore default layout and close SC window
|
||||
click_menu_option(sc, "Restore Default Layout")
|
||||
general.close_pane("Script Canvas")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import ImportPathHelper as imports
|
||||
|
||||
imports.init()
|
||||
|
||||
from utils import Report
|
||||
|
||||
Report.start_test(VariableManager_UnpinVariableType_Works)
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef __animtime_h__
|
||||
#define __animtime_h__
|
||||
|
||||
#include <IXml.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <Serialization/IArchive.h>
|
||||
|
||||
struct SAnimTime
|
||||
{
|
||||
static const uint numTicksPerSecond = 6000;
|
||||
|
||||
// List of possible frame rates (dividers of 6000). Most commonly used ones first.
|
||||
enum EFrameRate
|
||||
{
|
||||
// Common
|
||||
eFrameRate_30fps, eFrameRate_60fps, eFrameRate_120fps,
|
||||
|
||||
// Possible
|
||||
eFrameRate_10fps, eFrameRate_12fps, eFrameRate_15fps, eFrameRate_24fps,
|
||||
eFrameRate_25fps, eFrameRate_40fps, eFrameRate_48fps, eFrameRate_50fps,
|
||||
eFrameRate_75fps, eFrameRate_80fps, eFrameRate_100fps, eFrameRate_125fps,
|
||||
eFrameRate_150fps, eFrameRate_200fps, eFrameRate_240fps, eFrameRate_250fps,
|
||||
eFrameRate_300fps, eFrameRate_375fps, eFrameRate_400fps, eFrameRate_500fps,
|
||||
eFrameRate_600fps, eFrameRate_750fps, eFrameRate_1000fps, eFrameRate_1200fps,
|
||||
eFrameRate_1500fps, eFrameRate_2000fps, eFrameRate_3000fps, eFrameRate_6000fps,
|
||||
|
||||
eFrameRate_Num
|
||||
};
|
||||
|
||||
SAnimTime()
|
||||
: m_ticks(0) {}
|
||||
explicit SAnimTime(int32 ticks)
|
||||
: m_ticks(ticks) {}
|
||||
explicit SAnimTime(float time)
|
||||
: m_ticks(aznumeric_caster(std::lround(static_cast<double>(time) * numTicksPerSecond))) {}
|
||||
|
||||
static uint GetFrameRateValue(EFrameRate frameRate)
|
||||
{
|
||||
const uint frameRateValues[eFrameRate_Num] =
|
||||
{
|
||||
// Common
|
||||
30, 60, 120,
|
||||
|
||||
// Possible
|
||||
10, 12, 15, 24, 25, 40, 48, 50, 75, 80, 100, 125,
|
||||
150, 200, 240, 250, 300, 375, 400, 500, 600, 750,
|
||||
1000, 1200, 1500, 2000, 3000, 6000
|
||||
};
|
||||
|
||||
return frameRateValues[frameRate];
|
||||
}
|
||||
|
||||
static const char* GetFrameRateName(EFrameRate frameRate)
|
||||
{
|
||||
const char* frameRateNames[eFrameRate_Num] =
|
||||
{
|
||||
// Common
|
||||
"30 fps", "60 fps", "120 fps",
|
||||
|
||||
// Possible
|
||||
"10 fps", "12 fps", "15 fps", "24 fps",
|
||||
"25 fps", "40 fps", "48 fps", "50 fps",
|
||||
"75 fps", "80 fps", "100 fps", "125 fps",
|
||||
"150 fps", "200 fps", "240 fps", "250 fps",
|
||||
"300 fps", "375 fps", "400 fps", "500 fps",
|
||||
"600 fps", "750 fps", "1000 fps", "1200 fps",
|
||||
"1500 fps", "2000 fps", "3000 fps", "6000 fps"
|
||||
};
|
||||
|
||||
return frameRateNames[frameRate];
|
||||
}
|
||||
|
||||
float ToFloat() const { return static_cast<float>(m_ticks) / numTicksPerSecond; }
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(m_ticks, "ticks", "Ticks");
|
||||
}
|
||||
|
||||
// Helper to serialize from ticks or old float time
|
||||
void Serialize(XmlNodeRef keyNode, bool bLoading, const char* pName, const char* pLegacyName)
|
||||
{
|
||||
if (bLoading)
|
||||
{
|
||||
int32 ticks;
|
||||
if (!keyNode->getAttr(pName, ticks))
|
||||
{
|
||||
// Backwards compatibility
|
||||
float time = 0.0f;
|
||||
keyNode->getAttr(pLegacyName, time);
|
||||
*this = SAnimTime(time);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ticks = ticks;
|
||||
}
|
||||
}
|
||||
else if (m_ticks > 0)
|
||||
{
|
||||
keyNode->setAttr(pName, m_ticks);
|
||||
}
|
||||
}
|
||||
|
||||
int32 GetTicks() const { return m_ticks; }
|
||||
|
||||
static SAnimTime Min() { SAnimTime minTime; minTime.m_ticks = std::numeric_limits<int32>::lowest(); return minTime; }
|
||||
static SAnimTime Max() { SAnimTime maxTime; maxTime.m_ticks = (std::numeric_limits<int32>::max)(); return maxTime; }
|
||||
|
||||
SAnimTime operator-() const { return SAnimTime(-m_ticks); }
|
||||
SAnimTime operator-(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks -= r.m_ticks; return temp; }
|
||||
SAnimTime operator+(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks += r.m_ticks; return temp; }
|
||||
SAnimTime operator*(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks *= r.m_ticks; return temp; }
|
||||
SAnimTime operator/(SAnimTime r) const { SAnimTime temp; temp.m_ticks = static_cast<int32>((static_cast<int64>(m_ticks) * numTicksPerSecond) / r.m_ticks); return temp; }
|
||||
SAnimTime operator%(SAnimTime r) const { SAnimTime temp = *this; temp.m_ticks %= r.m_ticks; return temp; }
|
||||
SAnimTime operator*(float r) const { SAnimTime temp; temp.m_ticks = aznumeric_caster(std::lround(static_cast<double>(m_ticks) * r)); return temp; }
|
||||
SAnimTime operator/(float r) const { SAnimTime temp; temp.m_ticks = aznumeric_caster(std::lround(static_cast<double>(m_ticks) / r)); return temp; }
|
||||
SAnimTime& operator+=(SAnimTime r) { *this = *this + r; return *this; }
|
||||
SAnimTime& operator-=(SAnimTime r) { *this = *this - r; return *this; }
|
||||
SAnimTime& operator*=(SAnimTime r) { *this = *this * r; return *this; }
|
||||
SAnimTime& operator/=(SAnimTime r) { *this = *this / r; return *this; }
|
||||
SAnimTime& operator%=(SAnimTime r) { *this = *this % r; return *this; }
|
||||
SAnimTime& operator*=(float r) { *this = *this * r; return *this; }
|
||||
SAnimTime& operator/=(float r) { *this = *this / r; return *this; }
|
||||
|
||||
bool operator<(SAnimTime r) const { return m_ticks < r.m_ticks; }
|
||||
bool operator<=(SAnimTime r) const { return m_ticks <= r.m_ticks; }
|
||||
bool operator>(SAnimTime r) const { return m_ticks > r.m_ticks; }
|
||||
bool operator>=(SAnimTime r) const { return m_ticks >= r.m_ticks; }
|
||||
bool operator==(SAnimTime r) const { return m_ticks == r.m_ticks; }
|
||||
bool operator!=(SAnimTime r) const { return m_ticks != r.m_ticks; }
|
||||
|
||||
// Snap to nearest multiple of given frame rate
|
||||
SAnimTime SnapToNearest(const EFrameRate frameRate)
|
||||
{
|
||||
const int sign = sgn(m_ticks);
|
||||
const int32 absTicks = abs(m_ticks);
|
||||
|
||||
const int framesMod = numTicksPerSecond / GetFrameRateValue(frameRate);
|
||||
const int32 remainder = absTicks % framesMod;
|
||||
const bool bNextMultiple = remainder >= (framesMod / 2);
|
||||
return SAnimTime(sign * ((absTicks - remainder) + (bNextMultiple ? framesMod : 0)));
|
||||
}
|
||||
|
||||
private:
|
||||
int32 m_ticks;
|
||||
|
||||
friend bool Serialize(Serialization::IArchive& ar, SAnimTime& animTime, const char* name, const char* label);
|
||||
};
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, SAnimTime& animTime, const char* name, const char* label)
|
||||
{
|
||||
return ar(animTime.m_ticks, name, label);
|
||||
}
|
||||
|
||||
inline SAnimTime abs(SAnimTime time)
|
||||
{
|
||||
return (time >= SAnimTime(0)) ? time : -time;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,321 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef __BEZIER_H__
|
||||
#define __BEZIER_H__
|
||||
|
||||
#include <AnimTime.h>
|
||||
#include <Serialization/IArchive.h>
|
||||
#include <Serialization/Math.h>
|
||||
|
||||
struct SBezierControlPoint
|
||||
{
|
||||
SBezierControlPoint()
|
||||
: m_value(0.0f)
|
||||
, m_inTangent(ZERO)
|
||||
, m_outTangent(ZERO)
|
||||
, m_inTangentType(eTangentType_Auto)
|
||||
, m_outTangentType(eTangentType_Auto)
|
||||
, m_bBreakTangents(false)
|
||||
{
|
||||
}
|
||||
|
||||
enum ETangentType
|
||||
{
|
||||
eTangentType_Custom,
|
||||
eTangentType_Auto,
|
||||
eTangentType_Zero,
|
||||
eTangentType_Step,
|
||||
eTangentType_Linear,
|
||||
};
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(m_value, "value", "Value");
|
||||
|
||||
if (ar.IsOutput())
|
||||
{
|
||||
bool breakTangents = m_bBreakTangents;
|
||||
ar(breakTangents, "breakTangents", "Break Tangents");
|
||||
}
|
||||
else
|
||||
{
|
||||
bool breakTangents = false;
|
||||
ar(breakTangents, "breakTangents", "Break Tangents");
|
||||
m_bBreakTangents = breakTangents;
|
||||
}
|
||||
|
||||
if (ar.IsOutput())
|
||||
{
|
||||
ETangentType inTangentType = m_inTangentType;
|
||||
ar(inTangentType, "inTangentType", "Incoming tangent type");
|
||||
}
|
||||
else
|
||||
{
|
||||
ETangentType inTangentType = eTangentType_Auto;
|
||||
ar(inTangentType, "inTangentType", "Incoming tangent type");
|
||||
m_inTangentType = inTangentType;
|
||||
}
|
||||
|
||||
ar(m_inTangent, "inTangent", (m_inTangentType == eTangentType_Custom) ? "Incoming Tangent" : NULL);
|
||||
|
||||
if (ar.IsOutput())
|
||||
{
|
||||
ETangentType outTangentType = m_outTangentType;
|
||||
ar(outTangentType, "outTangentType", "Outgoing tangent type");
|
||||
}
|
||||
else
|
||||
{
|
||||
ETangentType outTangentType = eTangentType_Auto;
|
||||
ar(outTangentType, "outTangentType", "Outgoing tangent type");
|
||||
m_outTangentType = outTangentType;
|
||||
}
|
||||
|
||||
ar(m_outTangent, "outTangent", (m_outTangentType == eTangentType_Custom) ? "Outgoing Tangent" : NULL);
|
||||
}
|
||||
|
||||
float m_value;
|
||||
|
||||
// For 1D Bezier only the Y component is used
|
||||
Vec2 m_inTangent;
|
||||
Vec2 m_outTangent;
|
||||
|
||||
ETangentType m_inTangentType : 4;
|
||||
ETangentType m_outTangentType : 4;
|
||||
bool m_bBreakTangents : 1;
|
||||
};
|
||||
|
||||
struct SBezierKey
|
||||
{
|
||||
SBezierKey()
|
||||
: m_time(0) {}
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(m_time, "time", "Time");
|
||||
ar(m_controlPoint, "controlPoint", "Control Point");
|
||||
}
|
||||
|
||||
SAnimTime m_time;
|
||||
SBezierControlPoint m_controlPoint;
|
||||
};
|
||||
|
||||
namespace Bezier
|
||||
{
|
||||
inline float Evaluate(float t, float p0, float p1, float p2, float p3)
|
||||
{
|
||||
const float a = 1 - t;
|
||||
const float aSq = a * a;
|
||||
const float tSq = t * t;
|
||||
return (aSq * a * p0) + (3.0f * aSq * t * p1) + (3.0f * a * tSq * p2) + (tSq * t * p3);
|
||||
}
|
||||
|
||||
inline float EvaluateDeriv(float t, float p0, float p1, float p2, float p3)
|
||||
{
|
||||
const float a = 1 - t;
|
||||
const float ta = t * a;
|
||||
const float aSq = a * a;
|
||||
const float tSq = t * t;
|
||||
return 3.0f * ((-p2 * tSq) + (p3 * tSq) - (p0 * aSq) + (p1 * aSq) + 2.0f * ((-p1 * ta) + (p2 * ta)));
|
||||
}
|
||||
|
||||
inline float EvaluateX(const float t, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end)
|
||||
{
|
||||
const float p0 = 0.0f;
|
||||
const float p1 = p0 + start.m_outTangent.x;
|
||||
const float p3 = duration;
|
||||
const float p2 = p3 + end.m_inTangent.x;
|
||||
return Evaluate(t, p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
inline float EvaluateY(const float t, const SBezierControlPoint& start, const SBezierControlPoint& end)
|
||||
{
|
||||
const float p0 = start.m_value;
|
||||
const float p1 = p0 + start.m_outTangent.y;
|
||||
const float p3 = end.m_value;
|
||||
const float p2 = p3 + end.m_inTangent.y;
|
||||
return Evaluate(t, p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
// Duration = (time at end key) - (time at start key)
|
||||
inline float EvaluateDerivX(const float t, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end)
|
||||
{
|
||||
const float p0 = 0.0f;
|
||||
const float p1 = p0 + start.m_outTangent.x;
|
||||
const float p3 = duration;
|
||||
const float p2 = p3 + end.m_inTangent.x;
|
||||
return EvaluateDeriv(t, p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
inline float EvaluateDerivY(const float t, const SBezierControlPoint& start, const SBezierControlPoint& end)
|
||||
{
|
||||
const float p0 = start.m_value;
|
||||
const float p1 = p0 + start.m_outTangent.y;
|
||||
const float p3 = end.m_value;
|
||||
const float p2 = p3 + end.m_inTangent.y;
|
||||
return EvaluateDeriv(t, p0, p1, p2, p3);
|
||||
}
|
||||
|
||||
// Find interpolation factor where 2D bezier curve has the given x value. Works only for curves where x is monotonically increasing.
|
||||
// The passed x must be in range [0, duration]. Uses the Newton-Raphson root finding method. Usually takes 2 or 3 iterations.
|
||||
//
|
||||
// Note: This is for "1D" 2D bezier curves as used in TrackView. The curves are restricted by the curve editor to be monotonically increasing.
|
||||
//
|
||||
inline float InterpolationFactorFromX(const float x, const float duration, const SBezierControlPoint& start, const SBezierControlPoint& end)
|
||||
{
|
||||
float t = (x / duration);
|
||||
|
||||
const float epsilon = 0.00001f;
|
||||
const uint maxSteps = 10;
|
||||
|
||||
for (uint i = 0; i < maxSteps; ++i)
|
||||
{
|
||||
const float currentX = EvaluateX(t, duration, start, end) - x;
|
||||
if (fabs(currentX) <= epsilon)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
const float currentXDeriv = EvaluateDerivX(t, duration, start, end);
|
||||
t -= currentX / currentXDeriv;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
inline SBezierControlPoint CalculateInTangent(
|
||||
float time, const SBezierControlPoint& point,
|
||||
float leftTime, const SBezierControlPoint* pLeftPoint,
|
||||
float rightTime, const SBezierControlPoint* pRightPoint)
|
||||
{
|
||||
SBezierControlPoint newPoint = point;
|
||||
|
||||
// In tangent X can never be positive
|
||||
newPoint.m_inTangent.x = std::min(point.m_inTangent.x, 0.0f);
|
||||
|
||||
if (pLeftPoint)
|
||||
{
|
||||
switch (point.m_inTangentType)
|
||||
{
|
||||
case SBezierControlPoint::eTangentType_Custom:
|
||||
{
|
||||
// Need to clamp tangent if it is reaching over last point
|
||||
const float deltaTime = time - leftTime;
|
||||
if (deltaTime < -newPoint.m_inTangent.x)
|
||||
{
|
||||
if (newPoint.m_inTangent.x == 0)
|
||||
{
|
||||
newPoint.m_inTangent = Vec2(ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
float scaleFactor = deltaTime / -newPoint.m_inTangent.x;
|
||||
newPoint.m_inTangent.x = -deltaTime;
|
||||
newPoint.m_inTangent.y *= scaleFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SBezierControlPoint::eTangentType_Zero:
|
||||
// Fall through. Zero for y is same as Auto, x is set to 0.0f
|
||||
case SBezierControlPoint::eTangentType_Auto:
|
||||
{
|
||||
const SBezierControlPoint& rightPoint = pRightPoint ? *pRightPoint : point;
|
||||
const float deltaTime = (pRightPoint ? rightTime : time) - leftTime;
|
||||
if (deltaTime > 0.0f)
|
||||
{
|
||||
const float ratio = (time - leftTime) / deltaTime;
|
||||
const float deltaValue = rightPoint.m_value - pLeftPoint->m_value;
|
||||
const bool bIsZeroTangent = (point.m_inTangentType == SBezierControlPoint::eTangentType_Zero);
|
||||
newPoint.m_inTangent = Vec2(-(deltaTime * ratio) / 3.0f, bIsZeroTangent ? 0.0f : -(deltaValue * ratio) / 3.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPoint.m_inTangent = Vec2(ZERO);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SBezierControlPoint::eTangentType_Linear:
|
||||
newPoint.m_inTangent = Vec2((leftTime - time) / 3.0f,
|
||||
(pLeftPoint->m_value - point.m_value) / 3.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return newPoint;
|
||||
}
|
||||
|
||||
inline SBezierControlPoint CalculateOutTangent(
|
||||
float time, const SBezierControlPoint& point,
|
||||
float leftTime, const SBezierControlPoint* pLeftPoint,
|
||||
float rightTime, const SBezierControlPoint* pRightPoint)
|
||||
{
|
||||
SBezierControlPoint newPoint = point;
|
||||
|
||||
// Out tangent X can never be negative
|
||||
newPoint.m_outTangent.x = std::max(point.m_outTangent.x, 0.0f);
|
||||
|
||||
if (pRightPoint)
|
||||
{
|
||||
switch (point.m_outTangentType)
|
||||
{
|
||||
case SBezierControlPoint::eTangentType_Custom:
|
||||
{
|
||||
// Need to clamp tangent if it is reaching over next point
|
||||
const float deltaTime = rightTime - time;
|
||||
if (deltaTime < newPoint.m_outTangent.x)
|
||||
{
|
||||
if (newPoint.m_outTangent.x == 0)
|
||||
{
|
||||
newPoint.m_outTangent = Vec2(ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
float scaleFactor = deltaTime / newPoint.m_outTangent.x;
|
||||
newPoint.m_outTangent.x = deltaTime;
|
||||
newPoint.m_outTangent.y *= scaleFactor;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SBezierControlPoint::eTangentType_Zero:
|
||||
// Fall through. Zero for y is same as Auto, x is set to 0.0f
|
||||
case SBezierControlPoint::eTangentType_Auto:
|
||||
{
|
||||
const SBezierControlPoint& leftPoint = pLeftPoint ? *pLeftPoint : point;
|
||||
const float deltaTime = rightTime - (pLeftPoint ? leftTime : time);
|
||||
if (deltaTime > 0.0f)
|
||||
{
|
||||
const float ratio = (rightTime - time) / deltaTime;
|
||||
const float deltaValue = pRightPoint->m_value - leftPoint.m_value;
|
||||
const bool bIsZeroTangent = (point.m_outTangentType == SBezierControlPoint::eTangentType_Zero);
|
||||
newPoint.m_outTangent = Vec2((deltaTime * ratio) / 3.0f, bIsZeroTangent ? 0.0f : (deltaValue * ratio) / 3.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
newPoint.m_outTangent = Vec2(ZERO);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SBezierControlPoint::eTangentType_Linear:
|
||||
newPoint.m_outTangent = Vec2((rightTime - time) / 3.0f,
|
||||
(pRightPoint->m_value - point.m_value) / 3.0f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return newPoint;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "ICryUnknown.h"
|
||||
#include "ICryFactory.h"
|
||||
#include "ICryFactoryRegistry.h"
|
||||
#include <ISystem.h> // <> required for Interfuscator
|
||||
|
||||
|
||||
template <class T>
|
||||
bool CryCreateClassInstance(const CryClassID& cid, AZStd::shared_ptr<T>& p)
|
||||
{
|
||||
p = AZStd::shared_ptr<T>();
|
||||
ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry();
|
||||
if (pFactoryReg)
|
||||
{
|
||||
ICryFactory* pFactory = pFactoryReg->GetFactory(cid);
|
||||
if (pFactory && pFactory->ClassSupports(cryiidof<T>()))
|
||||
{
|
||||
ICryUnknownPtr pUnk = pFactory->CreateClassInstance();
|
||||
AZStd::shared_ptr<T> pT = cryinterface_cast<T>(pUnk);
|
||||
if (pT)
|
||||
{
|
||||
p = pT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return p.get() != NULL;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
bool CryCreateClassInstance(const char* cname, AZStd::shared_ptr<T>& p)
|
||||
{
|
||||
p = AZStd::shared_ptr<T>();
|
||||
ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry();
|
||||
if (pFactoryReg)
|
||||
{
|
||||
ICryFactory* pFactory = pFactoryReg->GetFactory(cname);
|
||||
if (pFactory != NULL && pFactory->ClassSupports(cryiidof<T>()))
|
||||
{
|
||||
ICryUnknownPtr pUnk = pFactory->CreateClassInstance();
|
||||
AZStd::shared_ptr<T> pT = cryinterface_cast<T>(pUnk);
|
||||
if (pT)
|
||||
{
|
||||
p = pT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return p.get() != NULL;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
bool CryCreateClassInstanceForInterface(const CryInterfaceID& iid, AZStd::shared_ptr<T>& p)
|
||||
{
|
||||
p = AZStd::shared_ptr<T>();
|
||||
ICryFactoryRegistry* pFactoryReg = gEnv->pSystem->GetCryFactoryRegistry();
|
||||
if (pFactoryReg)
|
||||
{
|
||||
size_t numFactories = 1;
|
||||
ICryFactory* pFactory = 0;
|
||||
pFactoryReg->IterateFactories(iid, &pFactory, numFactories);
|
||||
if (numFactories == 1 && pFactory)
|
||||
{
|
||||
ICryUnknownPtr pUnk = pFactory->CreateClassInstance();
|
||||
AZStd::shared_ptr<T> pT = cryinterface_cast<T>(pUnk);
|
||||
if (pT)
|
||||
{
|
||||
p = pT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return p.get() != NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_CRYCREATECLASSINSTANCE_H
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_CRYGUID_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_CRYGUID_H
|
||||
#pragma once
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Random.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
struct CryGUID
|
||||
{
|
||||
uint64 hipart;
|
||||
uint64 lopart;
|
||||
|
||||
// !!! Do NOT turn CryGUID into a non-aggregate !!!
|
||||
// It will prevent inlining and type list unrolling opportunities within
|
||||
// cryinterface_cast<T>() and cryiidof<T>(). As such prevent constructors,
|
||||
// non-public members, base classes and virtual functions!
|
||||
|
||||
//CryGUID() : hipart(0), lopart(0) {}
|
||||
//CryGUID(uint64 h, uint64 l) : hipart(h), lopart(l) {}
|
||||
|
||||
static CryGUID Construct(const uint64& hipart, const uint64& lopart)
|
||||
{
|
||||
CryGUID guid = {hipart, lopart};
|
||||
return guid;
|
||||
}
|
||||
|
||||
static CryGUID Create()
|
||||
{
|
||||
uint64 lopart = 0;
|
||||
uint64 hipart = 0;
|
||||
while (lopart == 0 || hipart == 0)
|
||||
{
|
||||
const uint32 a = cry_random_uint32();
|
||||
const uint32 b = cry_random_uint32();
|
||||
const uint32 c = cry_random_uint32();
|
||||
const uint32 d = cry_random_uint32();
|
||||
lopart = (uint64)a | ((uint64)b << 32);
|
||||
hipart = (uint64)c | ((uint64)d << 32);
|
||||
}
|
||||
|
||||
return Construct(lopart, hipart);
|
||||
}
|
||||
|
||||
static CryGUID Null()
|
||||
{
|
||||
return Construct(0, 0);
|
||||
}
|
||||
|
||||
bool operator ==(const CryGUID& rhs) const {return hipart == rhs.hipart && lopart == rhs.lopart; }
|
||||
bool operator !=(const CryGUID& rhs) const {return hipart != rhs.hipart || lopart != rhs.lopart; }
|
||||
bool operator <(const CryGUID& rhs) const {return hipart == rhs.hipart ? lopart < rhs.lopart : hipart < rhs.hipart; }
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
if (ar.IsInput())
|
||||
{
|
||||
uint32 dwords[4];
|
||||
ar(dwords, "guid");
|
||||
lopart = (((uint64)dwords[1]) << 32) | (uint64)dwords[0];
|
||||
hipart = (((uint64)dwords[3]) << 32) | (uint64)dwords[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 guid[4] = {
|
||||
(uint32)(lopart & 0xFFFFFFFF), (uint32)((lopart >> 32) & 0xFFFFFFFF),
|
||||
(uint32)(hipart & 0xFFFFFFFF), (uint32)((hipart >> 32) & 0xFFFFFFFF)
|
||||
};
|
||||
ar(guid, "guid");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// This is only used by the editor where we use C++ 11.
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<CryGUID>
|
||||
{
|
||||
public:
|
||||
size_t operator()(const CryGUID& guid) const
|
||||
{
|
||||
std::hash<uint64> hasher;
|
||||
return hasher(guid.lopart) ^ hasher(guid.hipart);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
template<>
|
||||
struct hash<CryGUID>
|
||||
{
|
||||
public:
|
||||
size_t operator()(const CryGUID& guid) const
|
||||
{
|
||||
std::hash<CryGUID> hasher;
|
||||
return hasher(guid);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#define MAKE_CRYGUID(high, low) CryGUID::Construct((uint64) high##LL, (uint64) low##LL)
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_CRYGUID_H
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CryGUID.h"
|
||||
|
||||
|
||||
typedef CryGUID CryInterfaceID;
|
||||
typedef CryGUID CryClassID;
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_CRYTYPEID_H
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CryTypeID.h"
|
||||
#include <SmartPointersHelpers.h>
|
||||
|
||||
struct ICryUnknown;
|
||||
DECLARE_SMART_POINTERS(ICryUnknown);
|
||||
|
||||
struct ICryFactory
|
||||
{
|
||||
virtual const char* GetName() const = 0;
|
||||
virtual const CryClassID& GetClassID() const = 0;
|
||||
virtual bool ClassSupports(const CryInterfaceID& iid) const = 0;
|
||||
virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const = 0;
|
||||
virtual ICryUnknownPtr CreateClassInstance() const = 0;
|
||||
|
||||
protected:
|
||||
// prevent explicit destruction from client side (delete, shared_ptr, etc)
|
||||
virtual ~ICryFactory() {}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_ICRYFACTORY_H
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CryTypeID.h"
|
||||
|
||||
|
||||
struct ICryFactory;
|
||||
|
||||
|
||||
struct ICryFactoryRegistry
|
||||
{
|
||||
virtual ICryFactory* GetFactory(const char* cname) const = 0;
|
||||
virtual ICryFactory* GetFactory(const CryClassID& cid) const = 0;
|
||||
/**
|
||||
* Iterates all factories implementing the interface specified by \p iid.
|
||||
* \param[in] iid ID of the interface to iterate. Often procured using cryiidof<...>().
|
||||
* \param[out] pFactories A pointer of the array of factories to fill in. May be nullptr (see below).
|
||||
* \param[in] Size (in elements) of the pFactories array [out] Number of elements actually written to pFactories or, when pFactories is null, the number of elements that would be written if sufficient storage was available.
|
||||
*
|
||||
* Example:
|
||||
* \code{.cpp}
|
||||
* size_t factoryCount = 0;
|
||||
* // Assigns the number of found factories to factoryCount
|
||||
* factoryRegistry->IterateFactories(cryiidof<TPointer>(), 0, factoryCount);
|
||||
* // Allocate an array of the proper length on the stack
|
||||
* ICryFactory** factories = static_cast<ICryFactory**>(alloca(sizeof(ICryFactory*) * factoryCount);
|
||||
* // Fill in factories with factoryCount results.
|
||||
* factoryRegistry->IterateFactories(cryiidof<TPointer>(), factories, factoryCount);
|
||||
* \endcode
|
||||
*/
|
||||
virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const = 0;
|
||||
|
||||
protected:
|
||||
// prevent explicit destruction from client side (delete, shared_ptr, etc)
|
||||
virtual ~ICryFactoryRegistry() {}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_ICRYFACTORYREGISTRY_H
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CryTypeID.h"
|
||||
#include <SmartPointersHelpers.h>
|
||||
|
||||
|
||||
struct ICryFactory;
|
||||
struct ICryUnknown;
|
||||
|
||||
namespace InterfaceCastSemantics
|
||||
{
|
||||
template <class T>
|
||||
const CryInterfaceID& cryiidof()
|
||||
{
|
||||
return T::IID();
|
||||
}
|
||||
|
||||
#define _BEFRIEND_CRYIIDOF() \
|
||||
template <class T> \
|
||||
friend const CryInterfaceID&InterfaceCastSemantics::cryiidof();
|
||||
|
||||
|
||||
template <class Dst, class Src>
|
||||
Dst* cryinterface_cast(Src* p)
|
||||
{
|
||||
return static_cast<Dst*>(p ? p->QueryInterface(cryiidof<Dst>()) : 0);
|
||||
}
|
||||
|
||||
template <class Dst, class Src>
|
||||
Dst* cryinterface_cast(const Src* p)
|
||||
{
|
||||
return static_cast<const Dst*>(p ? p->QueryInterface(cryiidof<Dst>()) : 0);
|
||||
}
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
template <class Dst, class Src>
|
||||
struct cryinterface_cast_shared_ptr_helper;
|
||||
|
||||
template <class Dst, class Src>
|
||||
struct cryinterface_cast_shared_ptr_helper
|
||||
{
|
||||
static AZStd::shared_ptr<Dst> Op(const AZStd::shared_ptr<Src>& p)
|
||||
{
|
||||
Dst* dp = cryinterface_cast<Dst>(p.get());
|
||||
return dp ? AZStd::shared_ptr<Dst>(p, dp) : AZStd::shared_ptr<Dst>();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Src>
|
||||
struct cryinterface_cast_shared_ptr_helper<ICryUnknown, Src>
|
||||
{
|
||||
static AZStd::shared_ptr<ICryUnknown> Op(const AZStd::shared_ptr<Src>& p)
|
||||
{
|
||||
ICryUnknown* dp = cryinterface_cast<ICryUnknown>(p.get());
|
||||
return dp ? AZStd::shared_ptr<ICryUnknown>(*((const AZStd::shared_ptr<ICryUnknown>*) & p), dp) : AZStd::shared_ptr<ICryUnknown>();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Src>
|
||||
struct cryinterface_cast_shared_ptr_helper<const ICryUnknown, Src>
|
||||
{
|
||||
static AZStd::shared_ptr<const ICryUnknown> Op(const AZStd::shared_ptr<Src>& p)
|
||||
{
|
||||
const ICryUnknown* dp = cryinterface_cast<const ICryUnknown>(p.get());
|
||||
return dp ? AZStd::shared_ptr<const ICryUnknown>(*((const AZStd::shared_ptr<const ICryUnknown>*) & p), dp) : AZStd::shared_ptr<const ICryUnknown>();
|
||||
}
|
||||
};
|
||||
} // namespace Internal
|
||||
|
||||
template <class Dst, class Src>
|
||||
AZStd::shared_ptr<Dst> cryinterface_cast(const AZStd::shared_ptr<Src>& p)
|
||||
{
|
||||
return Internal::cryinterface_cast_shared_ptr_helper<Dst, Src>::Op(p);
|
||||
}
|
||||
|
||||
#define _BEFRIEND_CRYINTERFACE_CAST() \
|
||||
template <class Dst, class Src> \
|
||||
friend Dst * InterfaceCastSemantics::cryinterface_cast(Src*); \
|
||||
template <class Dst, class Src> \
|
||||
friend Dst * InterfaceCastSemantics::cryinterface_cast(const Src*); \
|
||||
template <class Dst, class Src> \
|
||||
friend AZStd::shared_ptr<Dst> InterfaceCastSemantics::cryinterface_cast(const AZStd::shared_ptr<Src>&);
|
||||
} // namespace InterfaceCastSemantics
|
||||
|
||||
using InterfaceCastSemantics::cryiidof;
|
||||
using InterfaceCastSemantics::cryinterface_cast;
|
||||
|
||||
|
||||
template <class S, class T>
|
||||
bool CryIsSameClassInstance(S* p0, T* p1)
|
||||
{
|
||||
return static_cast<const void*>(p0) == static_cast<const void*>(p1) || cryinterface_cast<const ICryUnknown>(p0) == cryinterface_cast<const ICryUnknown>(p1);
|
||||
}
|
||||
|
||||
template <class S, class T>
|
||||
bool CryIsSameClassInstance(const AZStd::shared_ptr<S>& p0, T* p1)
|
||||
{
|
||||
return CryIsSameClassInstance(p0.get(), p1);
|
||||
}
|
||||
|
||||
template <class S, class T>
|
||||
bool CryIsSameClassInstance(S* p0, const AZStd::shared_ptr<T>& p1)
|
||||
{
|
||||
return CryIsSameClassInstance(p0, p1.get());
|
||||
}
|
||||
|
||||
template <class S, class T>
|
||||
bool CryIsSameClassInstance(const AZStd::shared_ptr<S>& p0, const AZStd::shared_ptr<T>& p1)
|
||||
{
|
||||
return CryIsSameClassInstance(p0.get(), p1.get());
|
||||
}
|
||||
|
||||
|
||||
namespace CompositeQuerySemantics
|
||||
{
|
||||
template <class Src>
|
||||
AZStd::shared_ptr<ICryUnknown> crycomposite_query(Src* p, const char* name, bool* pExposed = 0)
|
||||
{
|
||||
void* pComposite = p ? p->QueryComposite(name) : 0;
|
||||
pExposed ? *pExposed = pComposite != 0 : 0;
|
||||
return pComposite ? *static_cast<AZStd::shared_ptr<ICryUnknown>*>(pComposite) : AZStd::shared_ptr<ICryUnknown>();
|
||||
}
|
||||
|
||||
template <class Src>
|
||||
AZStd::shared_ptr<const ICryUnknown> crycomposite_query(const Src* p, const char* name, bool* pExposed = 0)
|
||||
{
|
||||
void* pComposite = p ? p->QueryComposite(name) : 0;
|
||||
pExposed ? *pExposed = pComposite != 0 : 0;
|
||||
return pComposite ? *static_cast<AZStd::shared_ptr<const ICryUnknown>*>(pComposite) : AZStd::shared_ptr<const ICryUnknown>();
|
||||
}
|
||||
|
||||
template <class Src>
|
||||
AZStd::shared_ptr<ICryUnknown> crycomposite_query(const AZStd::shared_ptr<Src>& p, const char* name, bool* pExposed = 0)
|
||||
{
|
||||
return crycomposite_query(p.get(), name, pExposed);
|
||||
}
|
||||
|
||||
template <class Src>
|
||||
AZStd::shared_ptr<const ICryUnknown> crycomposite_query(const AZStd::shared_ptr<const Src>& p, const char* name, bool* pExposed = 0)
|
||||
{
|
||||
return crycomposite_query(p.get(), name, pExposed);
|
||||
}
|
||||
|
||||
#define _BEFRIEND_CRYCOMPOSITE_QUERY() \
|
||||
template <class Src> \
|
||||
friend AZStd::shared_ptr<ICryUnknown> CompositeQuerySemantics::crycomposite_query(Src*, const char*, bool*); \
|
||||
template <class Src> \
|
||||
friend AZStd::shared_ptr<const ICryUnknown> CompositeQuerySemantics::crycomposite_query(const Src*, const char*, bool*); \
|
||||
template <class Src> \
|
||||
friend AZStd::shared_ptr<ICryUnknown> CompositeQuerySemantics::crycomposite_query(const AZStd::shared_ptr<Src>&, const char*, bool*); \
|
||||
template <class Src> \
|
||||
friend AZStd::shared_ptr<const ICryUnknown> CompositeQuerySemantics::crycomposite_query(const AZStd::shared_ptr<const Src>&, const char*, bool*);
|
||||
} // namespace CompositeQuerySemantics
|
||||
|
||||
using CompositeQuerySemantics::crycomposite_query;
|
||||
|
||||
|
||||
#define _BEFRIEND_MAKE_SHARED() \
|
||||
template <class T> \
|
||||
friend class AZStd::Internal::sp_ms_deleter; \
|
||||
template <class T> \
|
||||
friend AZStd::shared_ptr<T> AZStd::make_shared(); \
|
||||
template <class T, class A> \
|
||||
friend AZStd::shared_ptr<T> AZStd::allocate_shared(A const& a);
|
||||
|
||||
// prevent explicit destruction from client side
|
||||
#define _PROTECTED_DTOR(iname) \
|
||||
protected: \
|
||||
virtual ~iname() {}
|
||||
|
||||
|
||||
// Befriending cryinterface_cast<T>() and crycomposite_query() via CRYINTERFACE_DECLARE is actually only needed for ICryUnknown
|
||||
// since QueryInterface() and QueryComposite() are usually not redeclared in derived interfaces but it doesn't hurt either
|
||||
#define CRYINTERFACE_DECLARE(iname, iidHigh, iidLow) \
|
||||
_BEFRIEND_CRYIIDOF() \
|
||||
_BEFRIEND_CRYINTERFACE_CAST() \
|
||||
_BEFRIEND_CRYCOMPOSITE_QUERY() \
|
||||
_BEFRIEND_MAKE_SHARED() \
|
||||
_PROTECTED_DTOR(iname) \
|
||||
\
|
||||
private: \
|
||||
static const CryInterfaceID& IID() \
|
||||
{ \
|
||||
static const CryInterfaceID iid = {(uint64) iidHigh##LL, (uint64) iidLow##LL}; \
|
||||
return iid; \
|
||||
} \
|
||||
public:
|
||||
|
||||
|
||||
struct ICryUnknown
|
||||
{
|
||||
CRYINTERFACE_DECLARE(ICryUnknown, 0x1000000010001000, 0x1000100000000000)
|
||||
|
||||
virtual ICryFactory * GetFactory() const = 0;
|
||||
|
||||
protected:
|
||||
virtual void* QueryInterface(const CryInterfaceID& iid) const = 0;
|
||||
virtual void* QueryComposite(const char* name) const = 0;
|
||||
};
|
||||
|
||||
DECLARE_SMART_POINTERS(ICryUnknown);
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_ICRYUNKNOWN_H
|
||||
@@ -1,461 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H
|
||||
#pragma once
|
||||
|
||||
#include "TypeList.h"
|
||||
#include "Conversion.h"
|
||||
#include "RegFactoryNode.h"
|
||||
#include "../ICryUnknown.h"
|
||||
#include "../ICryFactory.h"
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
|
||||
namespace CW
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
template <class Dst>
|
||||
struct InterfaceCast;
|
||||
|
||||
template <class Dst>
|
||||
struct InterfaceCast
|
||||
{
|
||||
template <class T>
|
||||
static void* Op(T* p)
|
||||
{
|
||||
return (Dst*) p;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct InterfaceCast<ICryUnknown>
|
||||
{
|
||||
template <class T>
|
||||
static void* Op(T* p)
|
||||
{
|
||||
return const_cast<ICryUnknown*>(static_cast<const ICryUnknown*>(static_cast<const void*>(p)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class TList>
|
||||
struct InterfaceCast;
|
||||
|
||||
template <>
|
||||
struct InterfaceCast<TL::NullType>
|
||||
{
|
||||
template <class T>
|
||||
static void* Op(T*, const CryInterfaceID&)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Head, class Tail>
|
||||
struct InterfaceCast<TL::Typelist<Head, Tail> >
|
||||
{
|
||||
template <class T>
|
||||
static void* Op(T* p, const CryInterfaceID& iid)
|
||||
{
|
||||
if (cryiidof<Head>() == iid)
|
||||
{
|
||||
return Internal::InterfaceCast<Head>::Op(p);
|
||||
}
|
||||
return InterfaceCast<Tail>::Op(p, iid);
|
||||
}
|
||||
};
|
||||
|
||||
template <class TList>
|
||||
struct FillIIDs;
|
||||
|
||||
template <>
|
||||
struct FillIIDs<TL::NullType>
|
||||
{
|
||||
static void Op(CryInterfaceID*)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template <class Head, class Tail>
|
||||
struct FillIIDs<TL::Typelist<Head, Tail> >
|
||||
{
|
||||
static void Op(CryInterfaceID* p)
|
||||
{
|
||||
*p++ = cryiidof<Head>();
|
||||
FillIIDs<Tail>::Op(p);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
template <bool, typename S>
|
||||
struct PickList;
|
||||
|
||||
template <bool, typename S>
|
||||
struct PickList
|
||||
{
|
||||
typedef TL::BuildTypelist<>::Result Result;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct PickList<true, S>
|
||||
{
|
||||
typedef typename S::FullCompositeList Result;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct ProbeFullCompositeList
|
||||
{
|
||||
private:
|
||||
typedef char y[1];
|
||||
typedef char n[2];
|
||||
|
||||
template <typename S>
|
||||
static y& test(typename S::FullCompositeList*);
|
||||
|
||||
template <typename>
|
||||
static n& test(...);
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
listFound = sizeof(test<T>(0)) == sizeof(y)
|
||||
};
|
||||
|
||||
typedef typename Internal::PickList<listFound, T>::Result ListType;
|
||||
};
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
template <class TList>
|
||||
struct CompositeQuery;
|
||||
|
||||
template <>
|
||||
struct CompositeQuery<TL::NullType>
|
||||
{
|
||||
template<typename T>
|
||||
static void* Op(const T&, const char*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Head, class Tail>
|
||||
struct CompositeQuery<TL::Typelist<Head, Tail> >
|
||||
{
|
||||
template<typename T>
|
||||
static void* Op(const T& ref, const char* name)
|
||||
{
|
||||
void* p = ref.Head::CompositeQueryImpl(name);
|
||||
return p ? p : CompositeQuery<Tail>::Op(ref, name);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
struct CompositeQuery
|
||||
{
|
||||
template <typename T>
|
||||
static void* Op(const T& ref, const char* name)
|
||||
{
|
||||
return Internal::CompositeQuery<typename ProbeFullCompositeList<T>::ListType>::Op(ref, name);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool NameMatch(const char* name, const char* compositeName)
|
||||
{
|
||||
if (!name || !compositeName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
size_t i = 0;
|
||||
for (; name[i] && name[i] == compositeName[i]; ++i)
|
||||
{
|
||||
}
|
||||
return name[i] == compositeName[i];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void* CheckCompositeMatch(const char* name, const AZStd::shared_ptr<T>& composite, const char* compositeName)
|
||||
{
|
||||
typedef TC::SuperSubClass<ICryUnknown, T> Rel;
|
||||
COMPILE_TIME_ASSERT(Rel::exists);
|
||||
return NameMatch(name, compositeName) ? const_cast<void*>(static_cast<const void*>(&composite)) : 0;
|
||||
}
|
||||
} // namespace CW
|
||||
|
||||
|
||||
#define CRYINTERFACE_BEGIN() \
|
||||
private: \
|
||||
typedef TL::BuildTypelist < ICryUnknown
|
||||
|
||||
#define CRYINTERFACE_ADD(iname) , iname
|
||||
|
||||
#define CRYINTERFACE_END() > ::Result _UserDefinedPartialInterfaceList; \
|
||||
protected: \
|
||||
typedef TL::NoDuplicates<_UserDefinedPartialInterfaceList>::Result FullInterfaceList;
|
||||
|
||||
#define _CRY_TPL_APPEND0(base) TL::Append<base::FullInterfaceList, _UserDefinedPartialInterfaceList>::Result
|
||||
#define _CRY_TPL_APPEND(base, intermediate) TL::Append<base::FullInterfaceList, intermediate>::Result
|
||||
|
||||
#define CRYINTERFACE_ENDWITHBASE(base) > ::Result _UserDefinedPartialInterfaceList; \
|
||||
protected: \
|
||||
typedef TL::NoDuplicates<_CRY_TPL_APPEND0(base)>::Result FullInterfaceList;
|
||||
|
||||
#define CRYINTERFACE_ENDWITHBASE2(base0, base1) > ::Result _UserDefinedPartialInterfaceList; \
|
||||
protected: \
|
||||
typedef TL::NoDuplicates<_CRY_TPL_APPEND(base0, _CRY_TPL_APPEND0(base1))>::Result FullInterfaceList;
|
||||
|
||||
#define CRYINTERFACE_ENDWITHBASE3(base0, base1, base2) > ::Result _UserDefinedPartialInterfaceList; \
|
||||
protected: \
|
||||
typedef TL::NoDuplicates<_CRY_TPL_APPEND(base0, _CRY_TPL_APPEND(base1, _CRY_TPL_APPEND0(base2)))>::Result FullInterfaceList;
|
||||
|
||||
#define CRYINTERFACE_SIMPLE(iname) \
|
||||
CRYINTERFACE_BEGIN() \
|
||||
CRYINTERFACE_ADD(iname) \
|
||||
CRYINTERFACE_END()
|
||||
|
||||
#define CRYCOMPOSITE_BEGIN() \
|
||||
private: \
|
||||
void* CompositeQueryImpl(const char* name) const \
|
||||
{ \
|
||||
(void)(name); \
|
||||
void* res = 0; (void)(res); \
|
||||
|
||||
#define CRYCOMPOSITE_ADD(member, membername) \
|
||||
COMPILE_TIME_ASSERT((sizeof(membername) / sizeof(membername[0])) > 1); \
|
||||
if ((res = CW::CheckCompositeMatch(name, member, membername)) != 0) { \
|
||||
return res; }
|
||||
|
||||
#define _CRYCOMPOSITE_END(implclassname) \
|
||||
return 0; \
|
||||
}; \
|
||||
protected: \
|
||||
typedef TL::BuildTypelist<implclassname>::Result _PartialCompositeList; \
|
||||
\
|
||||
template <bool, typename S> \
|
||||
friend struct CW::Internal::PickList;
|
||||
|
||||
#define CRYCOMPOSITE_END(implclassname) \
|
||||
_CRYCOMPOSITE_END(implclassname) \
|
||||
protected: \
|
||||
typedef _PartialCompositeList FullCompositeList;
|
||||
|
||||
#define _CRYCOMPOSITE_APPEND0(base) TL::Append<_PartialCompositeList, CW::ProbeFullCompositeList<base>::ListType>::Result
|
||||
#define _CRYCOMPOSITE_APPEND(base, intermediate) TL::Append<intermediate, CW::ProbeFullCompositeList<base>::ListType>::Result
|
||||
|
||||
#define CRYCOMPOSITE_ENDWITHBASE(implclassname, base) \
|
||||
_CRYCOMPOSITE_END(implclassname) \
|
||||
protected: \
|
||||
typedef _CRYCOMPOSITE_APPEND0 (base) FullCompositeList;
|
||||
|
||||
#define CRYCOMPOSITE_ENDWITHBASE2(implclassname, base0, base1) \
|
||||
_CRYCOMPOSITE_END(implclassname) \
|
||||
protected: \
|
||||
typedef TL::NoDuplicates<_CRYCOMPOSITE_APPEND(base1, _CRYCOMPOSITE_APPEND0(base0))>::Result FullCompositeList;
|
||||
|
||||
#define CRYCOMPOSITE_ENDWITHBASE3(implclassname, base0, base1, base2) \
|
||||
_CRYCOMPOSITE_END(implclassname) \
|
||||
protected: \
|
||||
typedef TL::NoDuplicates<_CRYCOMPOSITE_APPEND(base2, _CRYCOMPOSITE_APPEND(base1, _CRYCOMPOSITE_APPEND0(base0)))>::Result FullCompositeList;
|
||||
|
||||
template<typename T>
|
||||
class CFactory
|
||||
: public ICryFactory
|
||||
{
|
||||
public:
|
||||
virtual const char* GetName() const
|
||||
{
|
||||
return T::GetCName();
|
||||
}
|
||||
|
||||
virtual const CryClassID& GetClassID() const
|
||||
{
|
||||
return T::GetCID();
|
||||
}
|
||||
|
||||
virtual bool ClassSupports(const CryInterfaceID& iid) const
|
||||
{
|
||||
for (size_t i = 0; i < m_numIIDs; ++i)
|
||||
{
|
||||
if (iid == m_pIIDs[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void ClassSupports(const CryInterfaceID*& pIIDs, size_t& numIIDs) const
|
||||
{
|
||||
pIIDs = m_pIIDs;
|
||||
numIIDs = m_numIIDs;
|
||||
}
|
||||
public:
|
||||
virtual ICryUnknownPtr CreateClassInstance() const
|
||||
{
|
||||
AZStd::shared_ptr<T> p = AZStd::make_shared<T>();
|
||||
return cryinterface_cast<ICryUnknown> (p);
|
||||
}
|
||||
|
||||
CFactory<T>()
|
||||
: m_numIIDs(0)
|
||||
, m_pIIDs(0)
|
||||
, m_regFactory()
|
||||
{
|
||||
static CryInterfaceID supportedIIDs[TL::Length < typename T::FullInterfaceList > ::value];
|
||||
CW::FillIIDs<typename T::FullInterfaceList>::Op(supportedIIDs);
|
||||
m_pIIDs = &supportedIIDs[0];
|
||||
m_numIIDs = TL::Length<typename T::FullInterfaceList>::value;
|
||||
new(&m_regFactory)SRegFactoryNode(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
CFactory(const CFactory&);
|
||||
CFactory& operator =(const CFactory&);
|
||||
|
||||
|
||||
size_t m_numIIDs;
|
||||
CryInterfaceID* m_pIIDs;
|
||||
SRegFactoryNode m_regFactory;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CSingletonFactory
|
||||
: public CFactory<T>
|
||||
{
|
||||
public:
|
||||
CSingletonFactory()
|
||||
: CFactory<T>()
|
||||
, m_csCreateClassInstance()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ICryUnknownPtr CreateClassInstance() const
|
||||
{
|
||||
CryAutoLock<CryCriticalSection> lock(m_csCreateClassInstance);
|
||||
// override the allocator. These function static instances are being destroyed after the AZ alloctor has been deleted.
|
||||
// On win, TerminateProcess() prevents these destructors from being called, but that is not the case on OSX.
|
||||
static typename AZStd::aligned_storage<sizeof(AZStd::Internal::sp_counted_impl_pda<T*, AZStd::Internal::sp_ms_deleter<T>,SingletonAllocator>), AZStd::alignment_of<T>::value>::type m_storage;
|
||||
static ICryUnknownPtr p = AZStd::allocate_shared<T>(SingletonAllocator(AZStd::addressof(m_storage)));
|
||||
return p;
|
||||
}
|
||||
|
||||
mutable CryCriticalSection m_csCreateClassInstance;
|
||||
|
||||
struct SingletonAllocator
|
||||
{
|
||||
SingletonAllocator(void* ptr) :
|
||||
m_data(ptr)
|
||||
{}
|
||||
void* allocate(size_t /*byteSize*/, size_t /*alignment*/, int /*flags*/ = 0)
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
void deallocate(void* /*ptr*/, size_t /*byteSize*/, size_t /*alignment*/)
|
||||
{
|
||||
// nothing to see here
|
||||
}
|
||||
void* m_data;
|
||||
};
|
||||
};
|
||||
|
||||
#define _CRYFACTORY_DECLARE(implclassname) \
|
||||
private: \
|
||||
friend class CFactory<implclassname>; \
|
||||
static CFactory<implclassname> s_factory;
|
||||
|
||||
#define _CRYFACTORY_DECLARE_SINGLETON(implclassname) \
|
||||
private: \
|
||||
friend class CFactory<implclassname>; \
|
||||
friend void* Get##implclassname##Factory(); \
|
||||
static CSingletonFactory<implclassname> s_factory;
|
||||
|
||||
#define _IMPLEMENT_ICRYUNKNOWN() \
|
||||
public: \
|
||||
virtual ICryFactory* GetFactory() const \
|
||||
{ \
|
||||
return &s_factory; \
|
||||
} \
|
||||
\
|
||||
protected: \
|
||||
virtual void* QueryInterface(const CryInterfaceID&iid) const \
|
||||
{ \
|
||||
return CW::InterfaceCast<FullInterfaceList>::Op(this, iid); \
|
||||
} \
|
||||
\
|
||||
template <class TList> \
|
||||
friend struct CW::Internal::CompositeQuery; \
|
||||
\
|
||||
virtual void* QueryComposite(const char* name) const \
|
||||
{ \
|
||||
return CW::CompositeQuery::Op(*this, name); \
|
||||
}
|
||||
|
||||
#define _ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow) \
|
||||
public: \
|
||||
static const char* GetCName() \
|
||||
{ \
|
||||
return cname; \
|
||||
} \
|
||||
static const CryClassID& GetCID() \
|
||||
{ \
|
||||
static const CryClassID cid = {(uint64) cidHigh##LL, (uint64) cidLow##LL}; \
|
||||
return cid; \
|
||||
} \
|
||||
static AZStd::shared_ptr<implclassname> CreateClassInstance() \
|
||||
{ \
|
||||
ICryUnknownPtr p = s_factory.CreateClassInstance(); \
|
||||
return AZStd::shared_ptr<implclassname>(*static_cast<AZStd::shared_ptr<implclassname>*>(static_cast<void*>(&p))); \
|
||||
} \
|
||||
\
|
||||
protected: \
|
||||
implclassname(); \
|
||||
virtual ~implclassname();
|
||||
|
||||
#define _BEFRIEND_OPS() \
|
||||
_BEFRIEND_CRYINTERFACE_CAST() \
|
||||
_BEFRIEND_CRYCOMPOSITE_QUERY() \
|
||||
_BEFRIEND_MAKE_SHARED()
|
||||
|
||||
#define CRYGENERATE_CLASS(implclassname, cname, cidHigh, cidLow) \
|
||||
_CRYFACTORY_DECLARE(implclassname) \
|
||||
_BEFRIEND_OPS() \
|
||||
_IMPLEMENT_ICRYUNKNOWN() \
|
||||
_ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow)
|
||||
|
||||
#define CRYGENERATE_SINGLETONCLASS(implclassname, cname, cidHigh, cidLow) \
|
||||
_CRYFACTORY_DECLARE_SINGLETON(implclassname) \
|
||||
_BEFRIEND_OPS() \
|
||||
_IMPLEMENT_ICRYUNKNOWN() \
|
||||
_ENFORCE_CRYFACTORY_USAGE(implclassname, cname, cidHigh, cidLow)
|
||||
|
||||
|
||||
#define CRYREGISTER_CLASS(implclassname) \
|
||||
CFactory<implclassname> implclassname::s_factory;
|
||||
|
||||
#define DECLARE_CRYREGISTER_SINGLETON_CLASS(implclassname) \
|
||||
void* Get##implclassname##Factory();
|
||||
|
||||
#define CRYREGISTER_SINGLETON_CLASS(implclassname) \
|
||||
CSingletonFactory<implclassname> implclassname::s_factory; \
|
||||
void* Get##implclassname##Factory() { \
|
||||
return &implclassname::s_factory; \
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CLASSWEAVER_H
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace TC
|
||||
{
|
||||
//template <class T, class U>
|
||||
//struct Conversion
|
||||
//{
|
||||
//private:
|
||||
// typedef char y[1];
|
||||
// typedef char n[2];
|
||||
// static y& Test(U);
|
||||
// static n& Test(...);
|
||||
// static T MakeT();
|
||||
|
||||
//public:
|
||||
// enum
|
||||
// {
|
||||
// exists = sizeof(Test(MakeT())) == sizeof(y),
|
||||
// sameType = false
|
||||
// };
|
||||
//};
|
||||
|
||||
//template <class T>
|
||||
//struct Conversion<T, T>
|
||||
//{
|
||||
//public:
|
||||
// enum
|
||||
// {
|
||||
// exists = true,
|
||||
// sameType = true
|
||||
// };
|
||||
//};
|
||||
|
||||
//template<typename Base, typename Derived>
|
||||
//struct CheckInheritance
|
||||
//{
|
||||
// enum
|
||||
// {
|
||||
// exists = Conversion<const Derived*, const Base*>::exists && !Conversion<const Base*, const void*>::sameType
|
||||
// };
|
||||
//};
|
||||
|
||||
//template<typename Base, typename Derived>
|
||||
//struct CheckStrictInheritance
|
||||
//{
|
||||
// enum
|
||||
// {
|
||||
// exists = CheckInheritance<Base, Derived>::exists && !Conversion<const Base*, const Derived*>::sameType
|
||||
// };
|
||||
//};
|
||||
|
||||
|
||||
template <typename Base, typename Derived>
|
||||
struct SuperSubClass
|
||||
{
|
||||
private:
|
||||
typedef char y[1];
|
||||
typedef char n[2];
|
||||
|
||||
template<typename T>
|
||||
static y& check(const volatile Derived&, T);
|
||||
static n& check(const volatile Base&, int);
|
||||
|
||||
struct C
|
||||
{
|
||||
operator const volatile Base&() const;
|
||||
operator const volatile Derived&();
|
||||
};
|
||||
|
||||
static C getC();
|
||||
|
||||
public:
|
||||
enum
|
||||
{
|
||||
exists = sizeof(check(getC(), 0)) == sizeof(y),
|
||||
sameType = false
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct SuperSubClass<T, T>
|
||||
{
|
||||
enum
|
||||
{
|
||||
exists = true
|
||||
};
|
||||
};
|
||||
} // namespace TC
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CONVERSION_H
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../CryGUID.h"
|
||||
#include "../../CryString.h"
|
||||
|
||||
|
||||
namespace CryGUIDHelper
|
||||
{
|
||||
string Print(const CryGUID& val)
|
||||
{
|
||||
char buf[39]; // sizeof("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}")
|
||||
|
||||
static const char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
char* p = buf;
|
||||
*p++ = '{';
|
||||
for (int i = 15; i >= 8; --i)
|
||||
{
|
||||
*p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)];
|
||||
}
|
||||
*p++ = '-';
|
||||
for (int i = 7; i >= 4; --i)
|
||||
{
|
||||
*p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)];
|
||||
}
|
||||
*p++ = '-';
|
||||
for (int i = 3; i >= 0; --i)
|
||||
{
|
||||
*p++ = hex[(unsigned char) ((val.hipart >> (i << 2)) & 0xF)];
|
||||
}
|
||||
*p++ = '-';
|
||||
for (int i = 15; i >= 12; --i)
|
||||
{
|
||||
*p++ = hex[(unsigned char) ((val.lopart >> (i << 2)) & 0xF)];
|
||||
}
|
||||
*p++ = '-';
|
||||
for (int i = 11; i >= 0; --i)
|
||||
{
|
||||
*p++ = hex[(unsigned char) ((val.lopart >> (i << 2)) & 0xF)];
|
||||
}
|
||||
*p++ = '}';
|
||||
*p++ = '\0';
|
||||
|
||||
return string(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_IMPL_CRYGUIDHELPER_H
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../ICryFactoryRegistry.h"
|
||||
|
||||
|
||||
struct SRegFactoryNode;
|
||||
|
||||
|
||||
struct ICryFactoryRegistryCallback
|
||||
{
|
||||
virtual void OnNotifyFactoryRegistered(ICryFactory* pFactory) = 0;
|
||||
virtual void OnNotifyFactoryUnregistered(ICryFactory* pFactory) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~ICryFactoryRegistryCallback() {}
|
||||
};
|
||||
|
||||
|
||||
struct ICryFactoryRegistryImpl
|
||||
: public ICryFactoryRegistry
|
||||
{
|
||||
virtual ICryFactory* GetFactory(const char* cname) const = 0;
|
||||
virtual ICryFactory* GetFactory(const CryClassID& cid) const = 0;
|
||||
virtual void IterateFactories(const CryInterfaceID& iid, ICryFactory** pFactories, size_t& numFactories) const = 0;
|
||||
|
||||
virtual void RegisterCallback(ICryFactoryRegistryCallback* pCallback) = 0;
|
||||
virtual void UnregisterCallback(ICryFactoryRegistryCallback* pCallback) = 0;
|
||||
|
||||
virtual void RegisterFactories(const SRegFactoryNode* pFactories) = 0;
|
||||
virtual void UnregisterFactories(const SRegFactoryNode* pFactories) = 0;
|
||||
|
||||
virtual void UnregisterFactory(ICryFactory* const pFactory) = 0;
|
||||
|
||||
protected:
|
||||
// prevent explicit destruction from client side (delete, shared_ptr, etc)
|
||||
virtual ~ICryFactoryRegistryImpl() {}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_IMPL_ICRYFACTORYREGISTRYIMPL_H
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H
|
||||
#pragma once
|
||||
|
||||
struct ICryFactory;
|
||||
struct SRegFactoryNode;
|
||||
|
||||
extern SRegFactoryNode* g_pHeadToRegFactories;
|
||||
|
||||
struct SRegFactoryNode
|
||||
{
|
||||
SRegFactoryNode()
|
||||
{
|
||||
}
|
||||
|
||||
SRegFactoryNode(ICryFactory* pFactory)
|
||||
: m_pFactory(pFactory)
|
||||
, m_pNext(g_pHeadToRegFactories)
|
||||
{
|
||||
g_pHeadToRegFactories = this;
|
||||
}
|
||||
|
||||
static void* operator new(size_t, void* p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
static void operator delete(void*, void*)
|
||||
{
|
||||
}
|
||||
|
||||
ICryFactory* m_pFactory;
|
||||
SRegFactoryNode* m_pNext;
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_IMPL_REGFACTORYNODE_H
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Part of CryEngine's extension framework.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYEXTENSION_TYPELIST_H
|
||||
#define CRYINCLUDE_CRYEXTENSION_TYPELIST_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace TL
|
||||
{
|
||||
// typelist terminator
|
||||
class NullType
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
// structure for typelist generation
|
||||
template <class T, class U = NullType>
|
||||
struct Typelist
|
||||
{
|
||||
typedef T Head;
|
||||
typedef U Tail;
|
||||
};
|
||||
|
||||
|
||||
// helper structure to automatically build typelists containing n types
|
||||
template
|
||||
<
|
||||
typename T0 = NullType, typename T1 = NullType, typename T2 = NullType, typename T3 = NullType, typename T4 = NullType,
|
||||
typename T5 = NullType, typename T6 = NullType, typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
|
||||
typename T10 = NullType, typename T11 = NullType, typename T12 = NullType, typename T13 = NullType, typename T14 = NullType,
|
||||
typename T15 = NullType, typename T16 = NullType, typename T17 = NullType, typename T18 = NullType, typename T19 = NullType
|
||||
>
|
||||
struct BuildTypelist
|
||||
{
|
||||
private:
|
||||
typedef typename BuildTypelist<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>::Result TailResult;
|
||||
|
||||
public:
|
||||
typedef Typelist<T0, TailResult> Result;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BuildTypelist<>
|
||||
{
|
||||
typedef NullType Result;
|
||||
};
|
||||
|
||||
// typelist operation : Length
|
||||
template <class TList>
|
||||
struct Length;
|
||||
|
||||
template <>
|
||||
struct Length<NullType>
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = 0
|
||||
};
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct Length<Typelist<T, U> >
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = 1 + Length<U>::value
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// typelist operation : TypeAt
|
||||
template <class TList, unsigned int index>
|
||||
struct TypeAt;
|
||||
|
||||
template <class Head, class Tail>
|
||||
struct TypeAt<Typelist<Head, Tail>, 0>
|
||||
{
|
||||
typedef Head Result;
|
||||
};
|
||||
|
||||
template <class Head, class Tail, unsigned int index>
|
||||
struct TypeAt<Typelist<Head, Tail>, index>
|
||||
{
|
||||
typedef typename TypeAt<Tail, index - 1>::Result Result;
|
||||
};
|
||||
|
||||
|
||||
// typelist operation : IndexOf
|
||||
template <class TList, class T>
|
||||
struct IndexOf;
|
||||
|
||||
template <class T>
|
||||
struct IndexOf<NullType, T>
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = -1
|
||||
};
|
||||
};
|
||||
|
||||
template <class T, class Tail>
|
||||
struct IndexOf<Typelist<T, Tail>, T>
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = 0
|
||||
};
|
||||
};
|
||||
|
||||
template <class Head, class Tail, class T>
|
||||
struct IndexOf<Typelist<Head, Tail>, T>
|
||||
{
|
||||
private:
|
||||
enum
|
||||
{
|
||||
temp = IndexOf<Tail, T>::value
|
||||
};
|
||||
public:
|
||||
enum
|
||||
{
|
||||
value = temp == -1 ? -1 : 1 + temp
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// typelist operation : Append
|
||||
template <class TList, class T>
|
||||
struct Append;
|
||||
|
||||
template <>
|
||||
struct Append<NullType, NullType>
|
||||
{
|
||||
typedef NullType Result;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct Append<NullType, T>
|
||||
{
|
||||
typedef Typelist<T, NullType> Result;
|
||||
};
|
||||
|
||||
template <class Head, class Tail>
|
||||
struct Append<NullType, Typelist<Head, Tail> >
|
||||
{
|
||||
typedef Typelist<Head, Tail> Result;
|
||||
};
|
||||
|
||||
template <class Head, class Tail, class T>
|
||||
struct Append<Typelist<Head, Tail>, T>
|
||||
{
|
||||
typedef Typelist<Head, typename Append<Tail, T>::Result> Result;
|
||||
};
|
||||
|
||||
|
||||
// typelist operation : Erase
|
||||
template <class TList, class T>
|
||||
struct Erase;
|
||||
|
||||
template <class T>
|
||||
struct Erase<NullType, T>
|
||||
{
|
||||
typedef NullType Result;
|
||||
};
|
||||
|
||||
template <class T, class Tail>
|
||||
struct Erase<Typelist<T, Tail>, T>
|
||||
{
|
||||
typedef Tail Result;
|
||||
};
|
||||
|
||||
template <class Head, class Tail, class T>
|
||||
struct Erase<Typelist<Head, Tail>, T>
|
||||
{
|
||||
typedef Typelist<Head, typename Erase<Tail, T>::Result> Result;
|
||||
};
|
||||
|
||||
|
||||
// typelist operation : Erase All
|
||||
template <class TList, class T>
|
||||
struct EraseAll;
|
||||
|
||||
template <class T>
|
||||
struct EraseAll<NullType, T>
|
||||
{
|
||||
typedef NullType Result;
|
||||
};
|
||||
|
||||
template <class T, class Tail>
|
||||
struct EraseAll<Typelist<T, Tail>, T>
|
||||
{
|
||||
typedef typename EraseAll<Tail, T>::Result Result;
|
||||
};
|
||||
|
||||
template <class Head, class Tail, class T>
|
||||
struct EraseAll<Typelist<Head, Tail>, T>
|
||||
{
|
||||
typedef Typelist<Head, typename EraseAll<Tail, T>::Result> Result;
|
||||
};
|
||||
|
||||
|
||||
// typelist operation : NoDuplicates
|
||||
template <class TList>
|
||||
struct NoDuplicates;
|
||||
|
||||
template <>
|
||||
struct NoDuplicates<NullType>
|
||||
{
|
||||
typedef NullType Result;
|
||||
};
|
||||
|
||||
template <class Head, class Tail>
|
||||
struct NoDuplicates<Typelist<Head, Tail> >
|
||||
{
|
||||
private:
|
||||
typedef typename NoDuplicates<Tail>::Result L1;
|
||||
typedef typename Erase<L1, Head>::Result L2;
|
||||
public:
|
||||
typedef Typelist<Head, L2> Result;
|
||||
};
|
||||
} // namespace TL
|
||||
|
||||
#endif // CRYINCLUDE_CRYEXTENSION_TYPELIST_H
|
||||
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_ALLOCATOR_H
|
||||
#define CRYINCLUDE_CRYPOOL_ALLOCATOR_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
template<class TPool, class TItem>
|
||||
class CFirstFit
|
||||
: public TPool
|
||||
{
|
||||
public:
|
||||
ILINE CFirstFit()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE T Allocate(size_t Size, size_t Align = 1)
|
||||
{
|
||||
//fastpath?
|
||||
if (TPool::m_pEmpty && TPool::m_pEmpty->Available(Size, Align))
|
||||
{
|
||||
TItem* pItem = TPool::Split(TPool::m_pEmpty, Size, Align);
|
||||
if (!pItem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pItem->InUse(Align);
|
||||
TPool::AllocatedMemory(pItem->MemSize());
|
||||
|
||||
//not fully occupied empty space?
|
||||
TPool::m_pEmpty = pItem != TPool::m_pEmpty ? TPool::m_pEmpty : 0;
|
||||
return TPool::Handle(pItem);
|
||||
}
|
||||
|
||||
TItem* pBestItem;
|
||||
for (pBestItem = TPool::m_Items.First(); pBestItem; pBestItem = pBestItem->Next())
|
||||
{
|
||||
if (pBestItem->Available(Size, Align)) // && (!pBestItem || pItem->MemSize()<pBestItem->MemSize()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pBestItem)
|
||||
{
|
||||
return 0; //out of mem
|
||||
}
|
||||
TItem* pItem = TPool::Split(pBestItem, Size, Align);
|
||||
if (!pItem) //no free node
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pItem->InUse(Align);
|
||||
TPool::AllocatedMemory(pItem->MemSize());
|
||||
|
||||
//not fully occupied empty space?
|
||||
TPool::m_pEmpty = pItem != pBestItem ? pBestItem : 0;
|
||||
return TPool::Handle(pItem);
|
||||
}
|
||||
template<class T>
|
||||
ILINE bool Free(T Handle, bool ForceBoundsCheck = false)
|
||||
{
|
||||
return Handle ? TPool::Free(Handle, ForceBoundsCheck) : false;
|
||||
}
|
||||
};
|
||||
|
||||
template<class TPool, class TItem>
|
||||
class CWorstFit
|
||||
: public TPool
|
||||
{
|
||||
public:
|
||||
ILINE CWorstFit()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE T Allocate(size_t Size, size_t Align = 1)
|
||||
{
|
||||
TItem* pBestItem = 0;
|
||||
for (TItem* pItem = TPool::m_Items.First(); pItem; pItem = pItem->Next())
|
||||
{
|
||||
if (pItem->IsFree() && (!pBestItem || pItem->MemSize() > pBestItem->MemSize()))
|
||||
{
|
||||
pBestItem = pItem;
|
||||
}
|
||||
}
|
||||
if (!pBestItem || !pBestItem->Available(Size, Align))
|
||||
{
|
||||
return 0; //out of mem
|
||||
}
|
||||
TItem* pItem = Split(pBestItem, Size, Align);
|
||||
if (!pItem) //no free node
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pItem->InUse(Align);
|
||||
AllocatedMemory(pItem->MemSize());
|
||||
return Handle(pItem);
|
||||
}
|
||||
};
|
||||
|
||||
template<class TPool, class TItem>
|
||||
class CBestFit
|
||||
: public TPool
|
||||
{
|
||||
public:
|
||||
ILINE CBestFit()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE T Allocate(size_t Size, size_t Align = 1)
|
||||
{
|
||||
TItem* pBestItem = 0;
|
||||
for (TItem* pItem = TPool::m_Items.First(); pItem; pItem = pItem->Next())
|
||||
{
|
||||
if ((!pBestItem || pItem->MemSize() < pBestItem->MemSize()) && pItem->Available(Size, Align))
|
||||
{
|
||||
if (pItem->MemSize() == Size)
|
||||
{
|
||||
pItem->InUse(Align);
|
||||
AllocatedMemory(pItem->MemSize());
|
||||
return (T)Handle(pItem);
|
||||
}
|
||||
pBestItem = pItem;
|
||||
}
|
||||
}
|
||||
if (!pBestItem)
|
||||
{
|
||||
return 0; //out of mem
|
||||
}
|
||||
TItem* pItem = Split(pBestItem, Size, Align);
|
||||
if (!pItem) //no free node
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
pItem->InUse(Align);
|
||||
AllocatedMemory(pItem->MemSize());
|
||||
return (T)Handle(pItem);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class TAllocator>
|
||||
class CReallocator
|
||||
: public TAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
template<class T>
|
||||
ILINE bool Reallocate(T* pData, size_t Size, size_t Alignment)
|
||||
{
|
||||
//special cases
|
||||
if (!Size) //just free?
|
||||
{
|
||||
TAllocator::Free(*pData);
|
||||
*pData = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!*pData) //just alloc?
|
||||
{
|
||||
*pData = TAllocator::template Allocate<T>(Size, Alignment);
|
||||
return *pData != 0;
|
||||
}
|
||||
|
||||
//same size, nothing to do at all?
|
||||
if (TAllocator::Item(*pData)->MemSize() == Size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (TAllocator::ReSize(pData, Size))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
T pNewData = TAllocator::template Allocate<T>(Size, Alignment);
|
||||
if (!pNewData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memcpy(TAllocator::template Resolve<uint8*>(pNewData),
|
||||
TAllocator::template Resolve<uint8*>(*pData), min(TAllocator::Item(*pData)->MemSize(), Size));
|
||||
TAllocator::template Free(*pData);
|
||||
*pData = pNewData;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_ALLOCATOR_H
|
||||
|
||||
@@ -1,655 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_CONTAINER_H
|
||||
#define CRYINCLUDE_CRYPOOL_CONTAINER_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
template<size_t TElementCount, class TElement>
|
||||
class CPool
|
||||
: public CMemoryStatic<TElementCount* sizeof(TElement)>
|
||||
{
|
||||
class CPoolNode;
|
||||
class CPoolNode
|
||||
: public CListItem<CPoolNode>
|
||||
{
|
||||
};
|
||||
CList<CPoolNode> m_List;
|
||||
public:
|
||||
ILINE CPool()
|
||||
{
|
||||
CPoolNode* pPrev = 0;
|
||||
CPoolNode* pNode = 0;
|
||||
for (size_t a = 1; a < TElementCount; a++) //skip first element as it would be counted as zero ptr
|
||||
{
|
||||
uint8* pData = &CMemoryStatic<TElementCount* sizeof(TElement)>::Data()[a * sizeof(TElement)];
|
||||
pNode = reinterpret_cast<CPoolNode*>(pData);
|
||||
pNode->Prev(pPrev);
|
||||
if (pPrev)
|
||||
{
|
||||
pPrev->Next(pNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_List.First(pNode);
|
||||
}
|
||||
pPrev = pNode;
|
||||
// m_List.AddLast(pNode);
|
||||
}
|
||||
if (pPrev)
|
||||
{
|
||||
pPrev->Next(0);
|
||||
m_List.Last(pPrev);
|
||||
}
|
||||
}
|
||||
ILINE uint8* Allocate([[maybe_unused]] size_t Size, [[maybe_unused]] size_t Align = 1)
|
||||
{
|
||||
CPoolNode* pNode = m_List.PopFirst();
|
||||
return reinterpret_cast<uint8*>(pNode);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE void Free(T* pData)
|
||||
{
|
||||
if (pData)
|
||||
{
|
||||
CPoolNode* pNode = reinterpret_cast<CPoolNode*>(pData);
|
||||
m_List.AddLast(pNode);
|
||||
}
|
||||
}
|
||||
|
||||
ILINE TElement& operator[](uint32 Idx)
|
||||
{
|
||||
uint8* pData = &CMemoryStatic<TElementCount* sizeof(TElement)>::Data()[Idx * sizeof(TElement)];
|
||||
return *reinterpret_cast<TElement*>(pData);
|
||||
}
|
||||
|
||||
ILINE const TElement& operator[](uint32 Idx) const
|
||||
{
|
||||
const uint8* pData = &CMemoryStatic<TElementCount* sizeof(TElement)>::Data()[Idx * sizeof(TElement)];
|
||||
return *reinterpret_cast<const TElement*>(pData);
|
||||
}
|
||||
};
|
||||
|
||||
template<class TMemory, bool BoundsCheck = false>
|
||||
class CInPlace
|
||||
: public TMemory
|
||||
{
|
||||
protected:
|
||||
CList<CListItemInPlace> m_Items;
|
||||
size_t m_Allocated;
|
||||
CListItemInPlace* m_pEmpty;
|
||||
|
||||
|
||||
ILINE void AllocatedMemory(size_t S)
|
||||
{
|
||||
m_Allocated += S + sizeof(CListItemInPlace);
|
||||
}
|
||||
ILINE void FreedMemory(size_t S)
|
||||
{
|
||||
m_Allocated -= S + sizeof(CListItemInPlace);
|
||||
}
|
||||
ILINE void Stack(CListItemInPlace* pItem)
|
||||
{
|
||||
}
|
||||
public:
|
||||
ILINE CInPlace()
|
||||
: m_Allocated(0)
|
||||
{
|
||||
}
|
||||
|
||||
ILINE void InitMem(const size_t S = 0, uint8* pData = 0)
|
||||
{
|
||||
TMemory::InitMem(S, pData);
|
||||
if (!TMemory::MemSize())
|
||||
{
|
||||
return;
|
||||
}
|
||||
pData = TMemory::Data();
|
||||
CListItemInPlace* pFirst = reinterpret_cast<CListItemInPlace*>(pData);
|
||||
CListItemInPlace* pFree = pFirst + 1;
|
||||
CListItemInPlace* pLast = reinterpret_cast<CListItemInPlace*>(pData + TMemory::MemSize()) - 1;
|
||||
m_Items.~CList<CListItemInPlace>();
|
||||
new (&m_Items)CList<CListItemInPlace>();
|
||||
m_Items.AddLast(pFirst);
|
||||
m_Items.AddLast(pFree);
|
||||
m_Items.AddLast(pLast);
|
||||
|
||||
pFirst->InUse(0); //static first item
|
||||
pFree->Free();
|
||||
pLast->InUse(0); //static last item
|
||||
m_pEmpty = pFree;
|
||||
m_Allocated = 0;
|
||||
}
|
||||
|
||||
ILINE size_t FragmentCount() const
|
||||
{
|
||||
return m_Items.Count();
|
||||
}
|
||||
|
||||
ILINE CListItemInPlace* Split(CListItemInPlace* pItem, size_t Size, size_t Align)
|
||||
{
|
||||
size_t Offset = reinterpret_cast<size_t>(pItem->Data());
|
||||
Offset += pItem->MemSize(); //ptr to end
|
||||
Offset -= Size; //minus size
|
||||
Size += Offset & (Align - 1); //adjust size to fit required alignment
|
||||
Offset -= Offset & (Align - 1);
|
||||
size_t TSize = sizeof(CListItemInPlace);
|
||||
Offset -= TSize; //header
|
||||
|
||||
if (Offset <= reinterpret_cast<size_t>(pItem + 1)) //not enough space for splitting?
|
||||
{
|
||||
return pItem;
|
||||
}
|
||||
|
||||
CListItemInPlace* pItemNext = reinterpret_cast<CListItemInPlace*>(Offset);
|
||||
|
||||
const size_t Offset2 = reinterpret_cast<size_t>(pItemNext->Data());
|
||||
CPA_ASSERT(!(Offset2 & (Align - 1)));
|
||||
m_Items.AddBehind(pItemNext, pItem);
|
||||
//pItemNext->Prev(pItem);
|
||||
//pItemNext->Next(pItem->Next());
|
||||
|
||||
// if(pItem->Next())
|
||||
// pItem->Next()->Prev(pItemNext);
|
||||
|
||||
// pItem->Next(pItemNext);
|
||||
pItemNext->Free();
|
||||
return pItemNext;
|
||||
}
|
||||
|
||||
ILINE void Merge(CListItemInPlace* pItem)
|
||||
{
|
||||
//merge with next if possible
|
||||
CListItemInPlace* pItemNext = pItem->Next();
|
||||
if (pItemNext->IsFree())
|
||||
{
|
||||
if (m_pEmpty == pItemNext)
|
||||
{
|
||||
m_pEmpty = pItem;
|
||||
}
|
||||
m_Items.Remove(pItemNext);
|
||||
//pItem->Next(pItemNext->Next());
|
||||
//pItem->Next()->Prev(pItem);
|
||||
}
|
||||
//merge with prev if possible
|
||||
CListItemInPlace* pItemPrev = pItem->Prev();
|
||||
if (pItemPrev->IsFree())
|
||||
{
|
||||
if (m_pEmpty == pItem)
|
||||
{
|
||||
m_pEmpty = pItemPrev;
|
||||
}
|
||||
m_Items.Remove(pItem);
|
||||
//pItemPrev->Next(pItem->Next());
|
||||
//pItem->Next()->Prev(pItemPrev);
|
||||
pItem = pItemPrev;
|
||||
}
|
||||
}
|
||||
template<class T>
|
||||
ILINE T Resolve(void* rItem) const
|
||||
{
|
||||
return reinterpret_cast<T>(rItem);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE size_t Size(const T* pData) const
|
||||
{
|
||||
const CListItemInPlace* pItem = Item(pData);
|
||||
return pItem->MemSize();
|
||||
}
|
||||
|
||||
bool InBounds(const void* pData, const bool Check) const
|
||||
{
|
||||
return !Check || (
|
||||
reinterpret_cast<size_t>(pData) >= reinterpret_cast<size_t>(TMemory::Data()) &&
|
||||
reinterpret_cast<size_t>(pData) < reinterpret_cast<size_t>(TMemory::Data()) + TMemory::MemSize());
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE bool Free(T* pData, bool ForceBoundsCheck = false)
|
||||
{
|
||||
if (pData && InBounds(pData, BoundsCheck | ForceBoundsCheck))
|
||||
{
|
||||
CListItemInPlace* pItem = Item(pData);
|
||||
FreedMemory(pItem->MemSize());
|
||||
pItem->Free();
|
||||
Merge(pItem);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ILINE bool Beat(){return false; }//dummy beat in case no defragmentator is wraping
|
||||
ILINE size_t MemFree() const{return TMemory::MemSize() - m_Allocated; }
|
||||
ILINE size_t MemSize() const{return TMemory::MemSize(); }
|
||||
|
||||
ILINE uint8* Handle(CListItemInPlace* pItem) const
|
||||
{
|
||||
return pItem->Data();
|
||||
}
|
||||
template<class T>
|
||||
ILINE CListItemInPlace* Item(T* pData)
|
||||
{
|
||||
return reinterpret_cast<CListItemInPlace*>(pData) - 1;
|
||||
}
|
||||
template<class T>
|
||||
ILINE const CListItemInPlace* Item(const T* pData) const
|
||||
{
|
||||
return reinterpret_cast<const CListItemInPlace*>(pData) - 1;
|
||||
}
|
||||
ILINE static bool Defragmentable(){return false; }
|
||||
|
||||
template<class T>
|
||||
ILINE bool ReSize(T* pData, size_t SizeNew)
|
||||
{
|
||||
//special cases
|
||||
CListItemInPlace* pItem = Item(*pData);
|
||||
const size_t SizeOld = pItem->MemSize();
|
||||
|
||||
//reduction
|
||||
if (SizeOld > SizeNew)
|
||||
{
|
||||
if (pItem->Next()->IsFree())
|
||||
{
|
||||
CListItemInPlace* pNextNext = pItem->Next()->Next();
|
||||
size_t Offset = reinterpret_cast<size_t>(pItem->Data());
|
||||
Offset += SizeNew; //Offset to next
|
||||
CListItemInPlace* pItemNext = reinterpret_cast<CListItemInPlace*>(Offset);
|
||||
pItem->Next(pItemNext);
|
||||
pNextNext->Prev(pItemNext);
|
||||
pItemNext->Prev(pItem);
|
||||
pItemNext->Next(pNextNext);
|
||||
pItemNext->Free();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SizeOld - SizeNew <= sizeof(CListItemInPlace))
|
||||
{
|
||||
return true; //header is bigger than the amount of freed memory
|
||||
}
|
||||
//split
|
||||
size_t Offset = reinterpret_cast<size_t>(pItem->Data());
|
||||
Offset += SizeNew; //Offset to next
|
||||
CListItemInPlace* pItemNext = reinterpret_cast<CListItemInPlace*>(Offset);
|
||||
m_Items.AddBehind(pItemNext, pItem);
|
||||
pItemNext->Free();
|
||||
return true;
|
||||
}
|
||||
|
||||
//SizeOld<SizeNew grow
|
||||
CListItemInPlace* pNext = pItem->Next();
|
||||
CListItemInPlace* pNextNext = pNext->Next();
|
||||
const size_t SizeNext = pNext->IsFree() ? pNext->MemSize() + sizeof(CListItemInPlace) : 0;
|
||||
if (SizeNew <= SizeNext + SizeOld)
|
||||
{
|
||||
if (SizeNew + sizeof(CListItemInPlace) + 1 < SizeNext + SizeOld)
|
||||
{
|
||||
size_t Offset = reinterpret_cast<size_t>(pItem->Data());
|
||||
Offset += SizeNew; //Offset to next
|
||||
CListItemInPlace* pItemNext = reinterpret_cast<CListItemInPlace*>(Offset);
|
||||
pItem->Next(pItemNext);
|
||||
pNextNext->Prev(pItemNext);
|
||||
pItemNext->Prev(pItem);
|
||||
pItemNext->Next(pNextNext);
|
||||
pItemNext->Free();
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem->Next(pNextNext);
|
||||
pNextNext->Prev(pItem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false; //no further in-place realloc possible
|
||||
}
|
||||
};
|
||||
|
||||
template<class TMemory, size_t TNodeCount, bool BoundsCheck = false>
|
||||
class CReferenced
|
||||
: public TMemory
|
||||
{
|
||||
typedef CPool<TNodeCount, CListItemReference> tdNodePool;
|
||||
|
||||
protected:
|
||||
tdNodePool m_NodePool;
|
||||
CList<CListItemReference> m_Items;
|
||||
size_t m_Allocated;
|
||||
CListItemReference* m_pEmpty;
|
||||
|
||||
ILINE void AllocatedMemory(size_t S)
|
||||
{
|
||||
m_Allocated += S;
|
||||
}
|
||||
ILINE void FreedMemory(size_t S)
|
||||
{
|
||||
m_Allocated -= S;
|
||||
}
|
||||
ILINE void Stack(CListItemReference* pItem)
|
||||
{
|
||||
m_Items.Validate(pItem);
|
||||
CListItemReference* pItem2 = 0;
|
||||
CListItemReference* pNext = pItem->Next();
|
||||
uint8* pData = pItem->Data(pNext->Align());
|
||||
if (pData != pItem->Data()) //needs splitting 'cause of alignment?
|
||||
{
|
||||
pItem2 = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
if (!pItem2) //no free node found for splitting?
|
||||
{
|
||||
return; //failed to stack -> return
|
||||
}
|
||||
}
|
||||
|
||||
memmove(pData, pNext->Data(), pNext->MemSize());
|
||||
|
||||
if (pItem2) //was not aligned?
|
||||
{
|
||||
//then keep the current ITem
|
||||
const size_t SizeItem = pItem->MemSize();
|
||||
const size_t SizeNext = pNext->MemSize();
|
||||
m_Items.AddBehind(pItem2, pNext);
|
||||
pItem2->Data(pData + SizeNext);
|
||||
pNext->Data(pData);
|
||||
pItem2->MemSize(pItem2->Next()->Data() - pItem2->Data());
|
||||
pNext->MemSize(SizeNext);
|
||||
pItem->MemSize(pNext->Data() - pItem->Data());
|
||||
m_Items.Validate(pItem);
|
||||
m_Items.Validate(pItem2);
|
||||
m_Items.Validate(pNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t SizeItem = pItem->MemSize();
|
||||
const size_t SizeNext = pNext->MemSize();
|
||||
m_Items.Remove(pItem);
|
||||
m_Items.AddBehind(pItem, pNext);
|
||||
pItem->Data(pNext->Data());
|
||||
pNext->Data(pData);
|
||||
pNext->MemSize(SizeItem);
|
||||
pItem->MemSize(SizeNext);
|
||||
m_Items.Validate(pItem);
|
||||
m_Items.Validate(pNext);
|
||||
}
|
||||
}
|
||||
public:
|
||||
ILINE CReferenced()
|
||||
: m_Allocated(0)
|
||||
{
|
||||
}
|
||||
|
||||
ILINE void InitMem(const size_t S = 0, uint8* pData = 0)
|
||||
{
|
||||
TMemory::InitMem(S, pData);
|
||||
if (!TMemory::MemSize())
|
||||
{
|
||||
return;
|
||||
}
|
||||
pData = TMemory::Data();
|
||||
CListItemReference* pItem = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
CListItemReference* pLast = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
m_Items.AddFirst(pItem);
|
||||
m_Items.AddLast(pLast);
|
||||
pLast->Init(pData + TMemory::MemSize(), 0, pItem, 0);
|
||||
pLast->InUse(0);
|
||||
pItem->Init(pData, TMemory::MemSize(), 0, pLast);
|
||||
pItem->Free();
|
||||
m_pEmpty = pItem;
|
||||
m_Allocated = 0;
|
||||
}
|
||||
|
||||
ILINE size_t FragmentCount() const
|
||||
{
|
||||
return m_Items.Count();
|
||||
}
|
||||
|
||||
ILINE CListItemReference* Split(CListItemReference* pItem, size_t Size, size_t Align)
|
||||
{
|
||||
size_t Offset = reinterpret_cast<size_t>(pItem->Data());
|
||||
if (!(Offset & (Align - 1))) //perfectly aligned?
|
||||
{
|
||||
if (pItem->MemSize() != Size) //not perfectly fitting?
|
||||
{ //then split
|
||||
CListItemReference* pItemPrev = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
if (!pItemPrev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const size_t OrgSize = pItem->MemSize();
|
||||
m_Items.AddBefore(pItemPrev, pItem);
|
||||
pItemPrev->Data(pItem->Data());
|
||||
pItem->Data(pItem->Data() + Size);
|
||||
pItem->MemSize(OrgSize - Size);
|
||||
pItemPrev->MemSize(Size);
|
||||
pItem = pItemPrev;
|
||||
}
|
||||
return pItem;
|
||||
}
|
||||
|
||||
//not aligned to block start
|
||||
//then lets try to align to block end
|
||||
Offset += pItem->MemSize(); //ptr to end
|
||||
Offset -= Size; //minus size
|
||||
if (!(Offset & (Align - 1))) //perfectly aligned?
|
||||
{
|
||||
CListItemReference* pItemPrev = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
if (!pItemPrev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const size_t OrgSize = pItem->MemSize();
|
||||
m_Items.AddBefore(pItemPrev, pItem);
|
||||
pItemPrev->Data(pItem->Data());
|
||||
pItem->Data(reinterpret_cast<uint8*>(Offset));
|
||||
pItemPrev->MemSize(OrgSize - Size);
|
||||
pItem->MemSize(Size);
|
||||
pItemPrev->Free();
|
||||
return pItem;
|
||||
}
|
||||
//last resort, fragment it into 3 parts
|
||||
|
||||
//Size +=Offset&(Align-1); //adjust size to fit required alignment
|
||||
Offset -= Offset & (Align - 1);
|
||||
|
||||
CListItemReference* pItemPrev = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
CListItemReference* pItemNext = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
if (!pItemPrev || !pItemNext)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const size_t OrgSize = pItem->MemSize();
|
||||
|
||||
m_Items.AddBefore(pItemPrev, pItem);
|
||||
m_Items.AddBehind(pItemNext, pItem);
|
||||
|
||||
pItemPrev->Data(pItem->Data());
|
||||
pItem->Data(reinterpret_cast<uint8*>(Offset));
|
||||
pItemNext->Data(pItem->Data() + Size);
|
||||
pItemPrev->MemSize(pItem->Data() - pItemPrev->Data());
|
||||
pItemNext->MemSize(OrgSize - pItemPrev->MemSize() - Size);
|
||||
pItem->MemSize(Size);
|
||||
|
||||
pItemPrev->Free();
|
||||
pItemNext->Free();
|
||||
return pItem;
|
||||
}
|
||||
|
||||
ILINE void Merge(CListItemReference* pItem)
|
||||
{
|
||||
m_Items.Validate(pItem);
|
||||
|
||||
//merge with next if possible
|
||||
CListItemReference* pItemNext = pItem->Next();
|
||||
if (pItemNext && pItemNext->IsFree())
|
||||
{
|
||||
if (m_pEmpty == pItemNext)
|
||||
{
|
||||
m_pEmpty = pItem;
|
||||
}
|
||||
const size_t OrgSize = pItem->MemSize();
|
||||
const size_t NextSize = pItemNext->MemSize();
|
||||
m_Items.Remove(pItemNext);
|
||||
pItem->MemSize(OrgSize + NextSize);
|
||||
m_NodePool.Free(pItemNext);
|
||||
}
|
||||
//merge with prev if possible
|
||||
CListItemReference* pItemPrev = pItem->Prev();
|
||||
if (pItemPrev && pItemPrev->IsFree())
|
||||
{
|
||||
if (m_pEmpty == pItem)
|
||||
{
|
||||
m_pEmpty = pItemPrev;
|
||||
}
|
||||
const size_t OrgSize = pItem->MemSize();
|
||||
const size_t PrevSize = pItemPrev->MemSize();
|
||||
m_Items.Remove(pItem);
|
||||
pItemPrev->MemSize(PrevSize + OrgSize);
|
||||
m_NodePool.Free(pItem);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE T Resolve(const uint32 ID)
|
||||
{
|
||||
CPA_ASSERT(ID); //0 is invalid
|
||||
return reinterpret_cast<T>(Item(ID)->Data());
|
||||
}
|
||||
|
||||
ILINE uint32 AddressToHandle(void* pData)
|
||||
{
|
||||
for (CListItemReference* pItem = m_Items.First(); pItem; pItem = pItem->Next())
|
||||
{
|
||||
if (pItem->Data() == pData)
|
||||
{
|
||||
return Handle(pItem);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE size_t Size(T ID) const
|
||||
{
|
||||
CPA_ASSERT(ID); //0 is invalid
|
||||
return Item(ID)->MemSize();
|
||||
}
|
||||
template<class T>
|
||||
bool InBounds([[maybe_unused]] T ID, [[maybe_unused]] const bool Check) const
|
||||
{
|
||||
//boundscheck doesn't work for Referenced containers
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE bool Free(T ID, bool ForceBoundsCheck = false)
|
||||
{
|
||||
IF (!ID, false)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
IF (!InBounds(ID, BoundsCheck | ForceBoundsCheck), false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CListItemReference* pItem = Item(ID);
|
||||
FreedMemory(pItem->MemSize());
|
||||
pItem->Free();
|
||||
Merge(pItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
ILINE bool Beat(){return false; }//dummy beat in case no defragmentator is wraping
|
||||
|
||||
ILINE size_t MemFree() const{return TMemory::MemSize() - m_Allocated; }
|
||||
|
||||
ILINE size_t MemSize() const{return TMemory::MemSize(); }
|
||||
|
||||
ILINE uint32 Handle(CListItemReference* pItem) const
|
||||
{
|
||||
return static_cast<uint32>(pItem - &m_NodePool[0]);
|
||||
}
|
||||
ILINE CListItemReference* Item(uint32 ID)
|
||||
{
|
||||
return &m_NodePool[ID];
|
||||
}
|
||||
ILINE const CListItemReference* Item(uint32 ID) const
|
||||
{
|
||||
return &m_NodePool[ID];
|
||||
}
|
||||
ILINE static bool Defragmentable(){return true; }
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
ILINE bool ReSize(T* pData, size_t SizeNew)
|
||||
{
|
||||
CListItemReference* pItem = Item(*pData);
|
||||
const size_t SizeOld = pItem->MemSize();
|
||||
|
||||
//reduction
|
||||
if (SizeOld > SizeNew)
|
||||
{
|
||||
if (pItem->Next()->IsFree())
|
||||
{
|
||||
CListItemReference* pNext = pItem->Next();
|
||||
const size_t NextSize = pNext->MemSize();
|
||||
pNext->Data(pNext->Data() + SizeNew - SizeOld);
|
||||
pNext->MemSize(NextSize - SizeNew + SizeOld);
|
||||
pItem->MemSize(SizeNew);
|
||||
return true;
|
||||
}
|
||||
|
||||
//split
|
||||
CListItemReference* pItemNext = reinterpret_cast<CListItemReference*>(m_NodePool.Allocate(1, 1));
|
||||
m_Items.AddBehind(pItemNext, pItem);
|
||||
pItemNext->Data(pItem->Data() + SizeNew);
|
||||
pItem->MemSize(SizeNew);
|
||||
pItemNext->MemSize(SizeOld - SizeNew);
|
||||
pItemNext->Free();
|
||||
return true;
|
||||
}
|
||||
|
||||
//SizeOld<SizeNew grow
|
||||
CListItemReference* pNext = pItem->Next();
|
||||
const size_t SizeNext = pNext->IsFree() ? pNext->MemSize() : 0;
|
||||
if (SizeNew <= SizeNext + SizeOld)
|
||||
{
|
||||
if (SizeNew == SizeNext + SizeOld)
|
||||
{
|
||||
m_Items.Remove(pNext);
|
||||
m_NodePool.Free(pNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
pNext->Data(pNext->Data() + SizeNew - SizeOld);
|
||||
pNext->MemSize(SizeNext - SizeNew + SizeOld);
|
||||
}
|
||||
pItem->MemSize(SizeNew);
|
||||
return true;
|
||||
}
|
||||
return false; //no further in-place realloc possible
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_CONTAINER_H
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_DEFRAG_H
|
||||
#define CRYINCLUDE_CRYPOOL_DEFRAG_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
template<class T>
|
||||
class CDefragStacked
|
||||
: public T
|
||||
{
|
||||
template<class TItem>
|
||||
ILINE bool DefragElement(TItem* pItem)
|
||||
{
|
||||
T::m_Items.Validate();
|
||||
if (pItem)
|
||||
{
|
||||
for (; pItem->Next(); pItem = pItem->Next())
|
||||
{
|
||||
if (!pItem->IsFree())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pItem->Next()->Locked())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!pItem->Available(pItem->Next()->Align(), pItem->Next()->Align()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
T::m_Items.Validate(pItem);
|
||||
Stack(pItem);
|
||||
T::m_Items.Validate(pItem);
|
||||
Merge(pItem);
|
||||
T::m_Items.Validate();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public:
|
||||
ILINE bool Beat()
|
||||
{
|
||||
return T::Defragmentable() && DefragElement(T::m_Items.First());
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_DEFRAG_H
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_FALLBACK_H
|
||||
#define CRYINCLUDE_CRYPOOL_FALLBACK_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
enum EFallbackMode
|
||||
{
|
||||
EFM_DISABLED,
|
||||
EFM_ENABLED,
|
||||
EFM_ALWAYS
|
||||
};
|
||||
template<class TAllocator>
|
||||
class CFallback
|
||||
: public TAllocator
|
||||
{
|
||||
EFallbackMode m_Fallback;
|
||||
public:
|
||||
ILINE CFallback()
|
||||
: m_Fallback(EFM_DISABLED)
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE T Allocate(size_t Size, size_t Align = 1)
|
||||
{
|
||||
if (EFM_ALWAYS == m_Fallback)
|
||||
{
|
||||
return reinterpret_cast<T>(CPA_ALLOC(Align, Size));
|
||||
}
|
||||
T pRet = TAllocator::template Allocate<T>(Size, Align);
|
||||
if (!pRet && EFM_ENABLED == m_Fallback)
|
||||
{
|
||||
return reinterpret_cast<T>(CPA_ALLOC(Align, Size));
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE bool Free(T Handle)
|
||||
{
|
||||
if (!Handle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (EFM_ALWAYS == m_Fallback)
|
||||
{
|
||||
CPA_FREE(Handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (EFM_ENABLED == m_Fallback && TAllocator::InBounds(Handle, true))
|
||||
{
|
||||
CPA_FREE(Handle);
|
||||
return true;
|
||||
}
|
||||
return TAllocator::template Free<T>(Handle);
|
||||
}
|
||||
|
||||
void FallbackMode(EFallbackMode M){m_Fallback = M; }
|
||||
EFallbackMode FallbaclMode() const{return m_Fallback; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_FALLBACK_H
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_INSPECTOR_H
|
||||
#define CRYINCLUDE_CRYPOOL_INSPECTOR_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
template<class TAllocator>
|
||||
class CInspector
|
||||
: public TAllocator
|
||||
{
|
||||
enum
|
||||
{
|
||||
EITableSize = 30
|
||||
};
|
||||
size_t m_Allocations[EITableSize];
|
||||
size_t m_Alignment[EITableSize];
|
||||
char m_LogFileName[1024];
|
||||
size_t m_AllocCount;
|
||||
size_t m_FreeCount;
|
||||
size_t m_ResizeCount;
|
||||
size_t m_FailAllocCount;
|
||||
size_t m_FailFreeCount;
|
||||
size_t m_FailResizeCount;
|
||||
|
||||
void WriteOut(const char* pFileName, uint32 Stack, const char* pFormat, ...) const
|
||||
{
|
||||
/*
|
||||
if(!pFileName)
|
||||
{
|
||||
if(!*m_LogFileName)
|
||||
return;
|
||||
pFileName = m_LogFileName;
|
||||
}
|
||||
FILE* File = fopen(pFileName,"a");
|
||||
if(File)
|
||||
{
|
||||
|
||||
char Buffer[1024];
|
||||
for(uint32 a=0;a<Stack;a++)
|
||||
Buffer[a]=' ';
|
||||
va_list args;
|
||||
va_start(args,pFormat);
|
||||
vsprintf(Buffer+Stack,pFormat,args);
|
||||
fwrite(Buffer,1,strlen(Buffer),File);
|
||||
fclose(File);
|
||||
va_end(args);
|
||||
}
|
||||
*/
|
||||
}
|
||||
size_t Bit(size_t C) const
|
||||
{
|
||||
size_t Count = 0;
|
||||
C >>= 1;
|
||||
while (C)
|
||||
{
|
||||
Count++;
|
||||
C >>= 1;
|
||||
}
|
||||
return Count >= EITableSize ? EITableSize - 1 : Count;
|
||||
}
|
||||
public:
|
||||
CInspector()
|
||||
{
|
||||
for (size_t a = 0; a < EITableSize; a++)
|
||||
{
|
||||
m_Allocations[a] = m_Alignment[a] = 0;
|
||||
}
|
||||
|
||||
m_LogFileName[0] = 0;
|
||||
m_AllocCount = 0;
|
||||
m_FreeCount = 0;
|
||||
m_ResizeCount = 0;
|
||||
m_FailAllocCount = 0;
|
||||
m_FailFreeCount = 0;
|
||||
m_FailResizeCount = 0;
|
||||
}
|
||||
|
||||
bool LogFileName(const char* pFileName)
|
||||
{
|
||||
const size_t Size = strlen(pFileName) + 1;
|
||||
if (Size > sizeof(m_LogFileName))
|
||||
{
|
||||
m_LogFileName[0] = 0;
|
||||
return false;
|
||||
}
|
||||
memcpy(m_LogFileName, pFileName, Size);
|
||||
WriteOut(0, "[log start]\n");
|
||||
return true;
|
||||
}
|
||||
void SaveStats(const char* pFileName) const
|
||||
{
|
||||
WriteOut(pFileName, 0, "stats:\n");
|
||||
|
||||
WriteOut(pFileName, 1, "Counter calls|fails\n");
|
||||
WriteOut(pFileName, 2, "Alloc: %6d|%6d\n", m_AllocCount, m_FailAllocCount);
|
||||
WriteOut(pFileName, 2, "Free: %6d|%6d\n", m_FreeCount, m_FailFreeCount);
|
||||
WriteOut(pFileName, 2, "Resize:%6d|%6d\n", m_ResizeCount, m_FailResizeCount);
|
||||
|
||||
WriteOut(pFileName, 1, "Allocations:\n");
|
||||
for (size_t a = 0; a < EITableSize; a++)
|
||||
{
|
||||
WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Allocations[a]);
|
||||
}
|
||||
|
||||
WriteOut(pFileName, 1, "Alignment:\n");
|
||||
for (size_t a = 0; a < EITableSize; a++)
|
||||
{
|
||||
WriteOut(pFileName, 2, "%9dByte: %8d\n", 1 << a, m_Alignment[a]);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE T Allocate(size_t Size, size_t Align = 1)
|
||||
{
|
||||
m_AllocCount++;
|
||||
m_Allocations[Bit(Size)]++;
|
||||
m_Alignment[Bit(Align)]++;
|
||||
T pData = TAllocator::template Allocate<T>(Size, Align);
|
||||
WriteOut(0, 0, "[A|%d|%d|%d]", (int)pData, Size, Align);
|
||||
if (!pData)
|
||||
{
|
||||
m_FailAllocCount++;
|
||||
WriteOut(0, 0, "[failed]", Size, Align);
|
||||
}
|
||||
return pData;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
ILINE bool Free(T pData, bool ForceBoundsCheck = false)
|
||||
{
|
||||
m_FreeCount++;
|
||||
const bool Ret = TAllocator::Free(pData, ForceBoundsCheck);
|
||||
WriteOut(0, 0, "[F|%d|%d|%d]", (int)pData, (int)ForceBoundsCheck, (int)Ret);
|
||||
m_FailFreeCount += !Ret;
|
||||
return Ret;
|
||||
}
|
||||
//template<class T>
|
||||
//ILINE bool Free(T pData)
|
||||
// {
|
||||
// m_FreeCount++;
|
||||
// const bool Ret = TAllocator::Free(pData);
|
||||
// WriteOut(0,0,"[F|%d|%d|%d]",(int)pData,(int)-1,(int)Ret);
|
||||
// m_FailFreeCount+=!Ret;
|
||||
// return Ret;
|
||||
// }
|
||||
|
||||
template<class T>
|
||||
ILINE bool Resize(T** pData, size_t Size, size_t Alignment)
|
||||
{
|
||||
m_ResizeCount++;
|
||||
const bool Ret = TAllocator::Resize(pData, Size, Alignment);
|
||||
WriteOut(0, 0, "[R|%d|%d|%d]", (int)*pData, (int)-1, (int)Ret);
|
||||
m_FailResizeCount += !Ret;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE size_t FindBiggest(const T* pItem)
|
||||
{
|
||||
size_t Biggest = 0;
|
||||
while (pItem)
|
||||
{
|
||||
if (pItem->IsFree() && pItem->MemSize() > Biggest)
|
||||
{
|
||||
Biggest = pItem->MemSize();
|
||||
}
|
||||
pItem = pItem->Next();
|
||||
}
|
||||
return Biggest;
|
||||
}
|
||||
|
||||
ILINE size_t BiggestFreeBlock()
|
||||
{
|
||||
return FindBiggest(TAllocator::m_Items.First());
|
||||
}
|
||||
|
||||
ILINE uint8* FirstItem()
|
||||
{
|
||||
return TAllocator::m_Items.First()->Data();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_INSPECTOR_H
|
||||
|
||||
@@ -1,366 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_LIST_H
|
||||
#define CRYINCLUDE_CRYPOOL_LIST_H
|
||||
#pragma once
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
class CListItemInPlace;
|
||||
class CListItemReference;
|
||||
|
||||
template<typename TItem>
|
||||
class CListItem
|
||||
{
|
||||
TItem* m_pPrev;
|
||||
TItem* m_pNext;
|
||||
public:
|
||||
|
||||
ILINE TItem* Prev(){return m_pPrev; }
|
||||
ILINE TItem* Next(){return m_pNext; }
|
||||
ILINE const TItem* Prev() const{return m_pPrev; }
|
||||
ILINE const TItem* Next() const{return m_pNext; }
|
||||
ILINE void Prev(TItem* pPrev){ m_pPrev = pPrev; }
|
||||
ILINE void Next(TItem* pNext){ m_pNext = pNext; }
|
||||
|
||||
//debugging
|
||||
void Validate();
|
||||
};
|
||||
|
||||
template<typename TItem>
|
||||
class CListItemFlagged
|
||||
: public CListItem<TItem>
|
||||
{
|
||||
enum
|
||||
{
|
||||
ELIF_INUSE = (1 << 0),
|
||||
ELIF_LOCKED = (1 << 1),
|
||||
};
|
||||
uint32 m_Flags : 8;
|
||||
uint32 m_Align : 24;
|
||||
public:
|
||||
ILINE CListItemFlagged()
|
||||
: m_Flags(0)
|
||||
{
|
||||
}
|
||||
ILINE bool IsFree() const{return (m_Flags & ELIF_INUSE) != ELIF_INUSE; }
|
||||
ILINE void Free(){m_Flags &= ~ELIF_INUSE; }
|
||||
ILINE void InUse(uint32 A){m_Flags |= ELIF_INUSE; m_Align = A; }
|
||||
ILINE bool Locked() const{return ELIF_LOCKED == (m_Flags & ELIF_LOCKED); }
|
||||
ILINE void Lock(){m_Flags |= ELIF_LOCKED; }
|
||||
ILINE void Unlock(){m_Flags &= ~ELIF_LOCKED; }
|
||||
ILINE uint32 Align() const{return m_Align; }
|
||||
};
|
||||
|
||||
class CListItemInPlace
|
||||
: public CListItemFlagged<CListItemInPlace>
|
||||
{
|
||||
public:
|
||||
ILINE void Init([[maybe_unused]] uint8* pData, [[maybe_unused]] size_t Size, CListItemInPlace* pPrev, CListItemInPlace* pNext)
|
||||
{
|
||||
Prev(pPrev);
|
||||
Next(pNext);
|
||||
CPA_ASSERT(Size == MemSize());
|
||||
}
|
||||
|
||||
ILINE bool Available(size_t Size, size_t Align) const
|
||||
{
|
||||
size_t Offset = reinterpret_cast<size_t>(Data());
|
||||
if (Offset & (Align - 1)) //not aligned?
|
||||
{
|
||||
Size += sizeof(CListItemInPlace) + Align - 1; //then an intermedian node needs to fit
|
||||
}
|
||||
return Size <= MemSize() && IsFree();
|
||||
}
|
||||
ILINE uint8* Data(){return reinterpret_cast<uint8*>(this) + sizeof(CListItemInPlace); }
|
||||
ILINE const uint8* Data() const{return reinterpret_cast<const uint8*>(this) + sizeof(CListItemInPlace); }
|
||||
ILINE size_t MemSize() const
|
||||
{
|
||||
const uint8* pNext = reinterpret_cast<const uint8*>(Next());
|
||||
const uint8* pThis = reinterpret_cast<const uint8*>(this);
|
||||
const size_t ESize = sizeof(CListItemInPlace);
|
||||
size_t Delta = pNext - pThis;
|
||||
Delta -= ESize;
|
||||
return Delta;
|
||||
}
|
||||
};
|
||||
|
||||
class CListItemReference
|
||||
: public CListItemFlagged<CListItemReference>
|
||||
{
|
||||
uint8* m_pData;
|
||||
// size_t m_Size;
|
||||
public:
|
||||
ILINE void Init(uint8* pData, size_t Size, CListItemReference* pPrev, CListItemReference* pNext)
|
||||
{
|
||||
Data(pData);
|
||||
Prev(pPrev);
|
||||
Next(pNext);
|
||||
MemSize(Size);
|
||||
}
|
||||
ILINE bool Available(size_t Size, size_t Align) const
|
||||
{
|
||||
size_t Offset = reinterpret_cast<size_t>(Data());
|
||||
if ((Offset & (Align - 1)))
|
||||
{
|
||||
Size += Align - (Offset & (Align - 1));
|
||||
}
|
||||
return Size <= MemSize() && IsFree();
|
||||
}
|
||||
ILINE void Data(uint8* pData){m_pData = pData; }
|
||||
ILINE uint8* Data(size_t Align)
|
||||
{
|
||||
Align--;
|
||||
size_t Offset = reinterpret_cast<size_t>(m_pData);
|
||||
Offset = (Offset + Align) & ~Align;
|
||||
return reinterpret_cast<uint8*>(Offset);
|
||||
}
|
||||
ILINE uint8* Data(){return m_pData; }
|
||||
ILINE const uint8* Data() const{return m_pData; }
|
||||
ILINE void MemSize([[maybe_unused]] size_t Size) { }
|
||||
ILINE size_t MemSize() const
|
||||
{
|
||||
const size_t T = reinterpret_cast<size_t>(Data());
|
||||
const size_t N = Next() ? reinterpret_cast<size_t>(Next()->Data()) : T;
|
||||
return N - T;
|
||||
}
|
||||
//ILINE void MemSize(size_t Size){m_Size=Size;}
|
||||
//ILINE size_t MemSize()const{return m_Size;}
|
||||
};
|
||||
|
||||
template<class TItem, bool VALIDATE = false>
|
||||
class CList
|
||||
{
|
||||
TItem* m_pFirst;
|
||||
TItem* m_pLast;
|
||||
size_t m_Count;
|
||||
public:
|
||||
ILINE CList()
|
||||
: m_pFirst(0)
|
||||
, m_pLast(0)
|
||||
, m_Count(0)
|
||||
{
|
||||
}
|
||||
|
||||
ILINE void First(TItem* pItem){m_pFirst = pItem; }
|
||||
ILINE TItem* First(){return m_pFirst; }
|
||||
ILINE void Last(TItem* pItem){m_pLast = pItem; }
|
||||
ILINE TItem* Last(){return m_pLast; }
|
||||
ILINE bool Empty() const{return m_pFirst == 0; }
|
||||
|
||||
ILINE TItem* PopFirst()
|
||||
{
|
||||
Validate();
|
||||
|
||||
if (!m_pFirst)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TItem* pRet = m_pFirst;
|
||||
|
||||
m_pFirst = m_pFirst->Next();
|
||||
|
||||
if (m_pFirst) //if any element exists
|
||||
{
|
||||
m_pFirst->Prev(0); //set prev ptr of this element to 0
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLast = 0; //set ptr to last element to 0 if ptr to first is zero as well
|
||||
}
|
||||
Validate();
|
||||
m_Count--;
|
||||
return pRet;
|
||||
}
|
||||
|
||||
ILINE TItem* PopLast()
|
||||
{
|
||||
Validate();
|
||||
|
||||
if (!m_pLast)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
TItem* pRet = m_pLast;
|
||||
|
||||
m_pLast = m_pLast->Prev();
|
||||
|
||||
if (m_pLast) //if any element exists
|
||||
{
|
||||
m_pLast->Next(0); //set prev ptr of this element to 0
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFirst = 0; //set ptr to last element to 0 if ptr to first is zero as well
|
||||
}
|
||||
Validate();
|
||||
m_Count--;
|
||||
return pRet;
|
||||
}
|
||||
|
||||
ILINE void AddFirst(TItem* pItem)
|
||||
{
|
||||
CPA_ASSERT(pItem); //ERROR AddFirst got 0 pointer
|
||||
|
||||
Validate();
|
||||
|
||||
pItem->Prev(0);
|
||||
pItem->Next(m_pFirst);
|
||||
if (!m_pFirst)
|
||||
{
|
||||
m_pLast = pItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFirst->Prev(pItem);
|
||||
}
|
||||
m_pFirst = pItem;
|
||||
|
||||
m_Count++;
|
||||
Validate();
|
||||
}
|
||||
|
||||
ILINE void AddLast(TItem* pItem)
|
||||
{
|
||||
CPA_ASSERT(pItem); //ERROR AddLast got 0 pointer
|
||||
|
||||
Validate();
|
||||
|
||||
pItem->Prev(m_pLast);
|
||||
pItem->Next(0);
|
||||
if (!m_pLast)
|
||||
{
|
||||
m_pFirst = pItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pLast->Next(pItem);
|
||||
}
|
||||
m_pLast = pItem;
|
||||
|
||||
m_Count++;
|
||||
Validate();
|
||||
}
|
||||
ILINE void AddBefore(TItem* pItem, TItem* pItemSuccessor)
|
||||
{
|
||||
CPA_ASSERT(pItem);
|
||||
CPA_ASSERT(pItemSuccessor);
|
||||
|
||||
Validate();
|
||||
|
||||
pItem->Next(pItemSuccessor);
|
||||
pItem->Prev(pItemSuccessor->Prev());
|
||||
pItemSuccessor->Prev(pItem);
|
||||
|
||||
if (pItemSuccessor == m_pFirst)
|
||||
{
|
||||
m_pFirst = pItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem->Prev()->Next(pItem);
|
||||
}
|
||||
|
||||
m_Count++;
|
||||
Validate();
|
||||
}
|
||||
ILINE void AddBehind(TItem* pItem, TItem* pItemPredecessor)
|
||||
{
|
||||
CPA_ASSERT(pItem);
|
||||
CPA_ASSERT(pItemPredecessor);
|
||||
|
||||
Validate();
|
||||
|
||||
pItem->Next(pItemPredecessor->Next());
|
||||
pItem->Prev(pItemPredecessor);
|
||||
pItemPredecessor->Next(pItem);
|
||||
|
||||
if (pItemPredecessor == m_pLast)
|
||||
{
|
||||
m_pLast = pItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
pItem->Next()->Prev(pItem);
|
||||
}
|
||||
|
||||
m_Count++;
|
||||
Validate();
|
||||
}
|
||||
|
||||
ILINE void Remove(TItem* pItem)
|
||||
{
|
||||
CPA_ASSERT(pItem); //ERROR releasing empty item
|
||||
|
||||
if (pItem == m_pFirst)
|
||||
{
|
||||
PopFirst();
|
||||
return;
|
||||
}
|
||||
if (pItem == m_pLast)
|
||||
{
|
||||
PopLast();
|
||||
return;
|
||||
}
|
||||
|
||||
Validate(pItem);
|
||||
|
||||
pItem->Prev()->Next(pItem->Next());
|
||||
pItem->Next()->Prev(pItem->Prev());
|
||||
|
||||
m_Count--;
|
||||
Validate();
|
||||
}
|
||||
|
||||
//debug
|
||||
ILINE void Validate(TItem* pReferenceItem = 0)
|
||||
{
|
||||
if (!VALIDATE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//one-sided empty?
|
||||
CPA_ASSERT((!First() && !Last()) || (First() && Last())); //ERROR validating item-list, just one end is 0
|
||||
|
||||
// endles linking?
|
||||
TItem* pPrev = 0;
|
||||
TItem* pItem = First();
|
||||
while (pItem)
|
||||
{
|
||||
if (pReferenceItem == pItem)
|
||||
{
|
||||
pReferenceItem = 0;
|
||||
}
|
||||
CPA_ASSERT(pPrev == pItem->Prev()); //ERROR validating item-list, endless linking NULL
|
||||
pPrev = pItem;
|
||||
pItem = pItem->Next();
|
||||
}
|
||||
|
||||
CPA_ASSERT(pPrev == Last()); //ERROR validating item-list, broken list, does not end at specified Last item
|
||||
CPA_ASSERT(!pReferenceItem); //ERROR reference item not found in the item-list
|
||||
}
|
||||
ILINE size_t Count() const{return m_Count; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_LIST_H
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_MEMORY_H
|
||||
#define CRYINCLUDE_CRYPOOL_MEMORY_H
|
||||
#pragma once
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
class CMemoryDynamic
|
||||
{
|
||||
size_t m_Size;
|
||||
uint8* m_pData;
|
||||
|
||||
protected:
|
||||
ILINE CMemoryDynamic()
|
||||
: m_Size(0)
|
||||
, m_pData(0){}
|
||||
|
||||
public:
|
||||
ILINE void InitMem(const size_t S, uint8* pData)
|
||||
{
|
||||
m_Size = S;
|
||||
m_pData = pData;
|
||||
CPA_ASSERT(S);
|
||||
CPA_ASSERT(pData);
|
||||
}
|
||||
|
||||
ILINE size_t MemSize() const{return m_Size; }
|
||||
ILINE uint8* Data(){return m_pData; }
|
||||
ILINE const uint8* Data() const{return m_pData; }
|
||||
};
|
||||
|
||||
template<size_t TSize>
|
||||
class CMemoryStatic
|
||||
{
|
||||
uint8 m_Data[TSize];
|
||||
|
||||
protected:
|
||||
ILINE CMemoryStatic()
|
||||
{
|
||||
}
|
||||
public:
|
||||
ILINE void InitMem(const size_t S, uint8* pData)
|
||||
{
|
||||
}
|
||||
ILINE size_t MemSize() const{return TSize; }
|
||||
ILINE uint8* Data(){return m_Data; }
|
||||
ILINE const uint8* Data() const{return m_Data; }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_MEMORY_H
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(POOLALLOCTESTSUIT)
|
||||
//cheat just for unit testing on windows
|
||||
#include "BaseTypes.h"
|
||||
#define ILINE inline
|
||||
#endif
|
||||
|
||||
// Traits
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#include AZ_RESTRICTED_FILE(CryPool/PoolAlloc_h)
|
||||
#elif defined(APPLE) || defined(LINUX)
|
||||
#define POOLALLOC_H_TRAIT_USE_MEMALIGN 1
|
||||
#endif
|
||||
|
||||
|
||||
#if POOLALLOC_H_TRAIT_USE_MEMALIGN
|
||||
#define CPA_ALLOC memalign
|
||||
#define CPA_FREE free
|
||||
#else
|
||||
#define CPA_ALLOC _aligned_malloc
|
||||
#define CPA_FREE _aligned_free
|
||||
#endif
|
||||
#define CPA_ASSERT assert
|
||||
#define CPA_ASSERT_STATIC(X) {uint8 assertdata[(X) ? 0 : 1]; }
|
||||
#define CPA_BREAK __debugbreak()
|
||||
|
||||
#include "List.h"
|
||||
#include "Memory.h"
|
||||
#include "Container.h"
|
||||
#include "Allocator.h"
|
||||
#include "Defrag.h"
|
||||
#include "STLWrapper.h"
|
||||
#include "Inspector.h"
|
||||
#include "Fallback.h"
|
||||
#if !defined(POOLALLOCTESTSUIT)
|
||||
#include "ThreadSafe.h"
|
||||
#endif
|
||||
|
||||
#undef CPA_ASSERT
|
||||
#undef CPA_ASSERT_STATIC
|
||||
#undef CPA_BREAK
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_STLWRAPPER_H
|
||||
#define CRYINCLUDE_CRYPOOL_STLWRAPPER_H
|
||||
#pragma once
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
//namespace CSTLPoolAllocWrapperHelper
|
||||
//{
|
||||
// inline void destruct(char *) {}
|
||||
// inline void destruct(wchar_t*) {}
|
||||
// template <typename T>
|
||||
// inline void destruct(T *t) {t->~T();}
|
||||
//}
|
||||
|
||||
//template <size_t S, class L, size_t A, typename T>
|
||||
//struct CSTLPoolAllocWrapperStatic
|
||||
//{
|
||||
// static PoolAllocator<S, L, A> * allocator;
|
||||
//};
|
||||
|
||||
//template <class T, class L, size_t A>
|
||||
//struct CSTLPoolAllocWrapperKungFu : public CSTLPoolAllocWrapperStatic<sizeof(T),L,A,T>
|
||||
//{
|
||||
//};
|
||||
|
||||
template <class T, class TCont>
|
||||
class CSTLPoolAllocWrapper
|
||||
{
|
||||
private:
|
||||
static TCont* m_pContainer;
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
static TCont* Container(){return m_pContainer; }
|
||||
static void Container(TCont* pContainer){m_pContainer = pContainer; }
|
||||
|
||||
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef CSTLPoolAllocWrapper<T, TCont> other;
|
||||
};
|
||||
|
||||
CSTLPoolAllocWrapper() throw()
|
||||
{
|
||||
}
|
||||
|
||||
CSTLPoolAllocWrapper(const CSTLPoolAllocWrapper&) throw()
|
||||
{
|
||||
}
|
||||
|
||||
template <class TTemp, class TTempCont>
|
||||
CSTLPoolAllocWrapper(const CSTLPoolAllocWrapper<TTemp, TTempCont>&) throw()
|
||||
{
|
||||
}
|
||||
|
||||
~CSTLPoolAllocWrapper() throw()
|
||||
{
|
||||
}
|
||||
|
||||
pointer address(reference x) const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
const_pointer address(const_reference x) const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
pointer allocate(size_type n = 1, const_pointer hint = 0)
|
||||
{
|
||||
TCont* pContainer = Container();
|
||||
uint8* pData = pContainer->TCont::template Allocate<uint8*>(n * sizeof(T), sizeof(T));
|
||||
return pContainer->TCont::template Resolve<pointer>(pData);
|
||||
// return Container()?Container()->Allocate<void*>(n*sizeof(T),sizeof(T)):0
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n = 1)
|
||||
{
|
||||
if (Container())
|
||||
{
|
||||
Container()->Free(p);
|
||||
}
|
||||
}
|
||||
|
||||
size_type max_size() const throw()
|
||||
{
|
||||
return Container() ? Container()->MemSize() : 0;
|
||||
}
|
||||
|
||||
void construct(pointer p, const T& val)
|
||||
{
|
||||
new(static_cast<void*>(p))T(val);
|
||||
}
|
||||
|
||||
void construct(pointer p)
|
||||
{
|
||||
new(static_cast<void*>(p))T();
|
||||
}
|
||||
|
||||
void destroy(pointer p)
|
||||
{
|
||||
p->~T();
|
||||
}
|
||||
|
||||
pointer new_pointer()
|
||||
{
|
||||
return new(allocate())T();
|
||||
}
|
||||
|
||||
pointer new_pointer(const T& val)
|
||||
{
|
||||
return new(allocate())T(val);
|
||||
}
|
||||
|
||||
void delete_pointer(pointer p)
|
||||
{
|
||||
p->~T();
|
||||
deallocate(p);
|
||||
}
|
||||
|
||||
bool operator==(const CSTLPoolAllocWrapper&) {return true; }
|
||||
bool operator!=(const CSTLPoolAllocWrapper&) {return false; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_STLWRAPPER_H
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_THREADSAFE_H
|
||||
#define CRYINCLUDE_CRYPOOL_THREADSAFE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <CryThread.h>
|
||||
|
||||
namespace NCryPoolAlloc
|
||||
{
|
||||
template<class TAllocator>
|
||||
class CThreadSafe
|
||||
: public TAllocator
|
||||
{
|
||||
CryCriticalSection m_Mutex;
|
||||
public:
|
||||
|
||||
template<class T>
|
||||
ILINE T Allocate(size_t Size, size_t Align = 1)
|
||||
{
|
||||
CryAutoLock<CryCriticalSection> lock(m_Mutex);
|
||||
return TAllocator::template Allocate<T>(Size, Align);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
ILINE bool Free(T pData, bool ForceBoundsCheck = false)
|
||||
{
|
||||
CryAutoLock<CryCriticalSection> lock(m_Mutex);
|
||||
return TAllocator::Free(pData, ForceBoundsCheck);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ILINE bool Resize(T** pData, size_t Size, size_t Alignment)
|
||||
{
|
||||
CryAutoLock<CryCriticalSection> lock(m_Mutex);
|
||||
return TAllocator::Resize(pData, Size, Alignment);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_THREADSAFE_H
|
||||
|
||||
@@ -1,287 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYPOOL_EXAMPLE_H
|
||||
#define CRYINCLUDE_CRYPOOL_EXAMPLE_H
|
||||
#pragma once
|
||||
|
||||
|
||||
//The documentation is split up into 3 main parts, so strg+f for
|
||||
// -Theory
|
||||
// -Building blocks
|
||||
// -Usage
|
||||
// -FAQ
|
||||
// -Realloc/Resize
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// -Theory
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//this includes the 3 major parts of the allocate suite
|
||||
//1. the memory location templates
|
||||
//2. container types
|
||||
//3. some allocator version
|
||||
//addtional you get
|
||||
//4. a simple stack based defragmentation template
|
||||
//5. helper
|
||||
|
||||
//1. memory location templates
|
||||
// There are two types of them, static and dynamic
|
||||
//1.1 CMemoryStatic<size> allows you do define on compile time what size
|
||||
// it should have, suitable for pool you know that they won't grow or
|
||||
// shrink
|
||||
//1.2 CMemoryDynamic, this one has no template parameter, it has just one
|
||||
// indirection via ptr to the memory location and size, that you will
|
||||
// set during initialization.
|
||||
|
||||
//2. Container types
|
||||
// We have also two container types, one so called "In Place"
|
||||
// and one "Referenced".
|
||||
//2.1 "In Place" means that a header is placed above every allocation,
|
||||
// this is the usual way most allocators work.
|
||||
//2.2 "Referenced", has an extra pool of headers that point to the actual
|
||||
// memory. This is suitable for
|
||||
// - external memory locations that are not directly accessable by the
|
||||
// cpu. E.g. pools on disk, networks, rsx memory..
|
||||
// - defragmentation, because you don't save a ptr to the real memory
|
||||
// location, just a "handle" of the referencing item.
|
||||
// - big alignments, having 4kb of alignment would waste also
|
||||
// - 4kb for ever "In Place" header, you might not want that.
|
||||
|
||||
//3. Allocators
|
||||
// This time we have 3 of them, "BestFit", "WorstFit" and "FirstFit"
|
||||
//3.1 FirstFit just seeks for any location big enought to fit your
|
||||
// requested size of memory. Internally it also saves the last used
|
||||
// free memory area to speed up allocations.
|
||||
// Use this also if you have just one particular allocation size.
|
||||
//3.2 WorstFit, although it might sound illogical, WorstFit can reduce
|
||||
// memory fragmentation in a cases with very random allocation sizes,
|
||||
// because it gives smaller free blocks the chance to concatenate to
|
||||
// bigger free blocks again while filling up those previously
|
||||
// generated big blocks. The bad side is that it takes quite some time
|
||||
// to find the biggest block as this needs to be done every time you
|
||||
// allocate, so use this just when having a low amount of allocations
|
||||
// or you're really desperately looking for mem.
|
||||
//3.3 BestFit, it's best used if you don't have just one allocation size,
|
||||
// but still very few varying sizes. Previously released blocks of
|
||||
// the currently allocating sizes will be seeked and reused, this
|
||||
// strongly helps to reduce fragmentation. While this might be slow
|
||||
// in some cases, it can save you from doing any defragmentation.
|
||||
|
||||
//4. Defragmentation
|
||||
// At the moment just one defragmentation algorithm is implemented:
|
||||
// "Stack defragmentator"
|
||||
// If you don't want some block to be moved, "Lock" it using your
|
||||
// memory handle.
|
||||
//4.1 Stack based
|
||||
// To reduce fragmentation, holes are filled up with the next used,
|
||||
// memory area. This defragmentation sheme is useful when you have
|
||||
// some long living locations as well as very short living ones.
|
||||
// At some point all long live memory will end up at the bottom of
|
||||
// the stack, while leaving empty memory areas at the top for short
|
||||
// living allocations.
|
||||
|
||||
//5. Helper
|
||||
// this should be filled up with some handy helper tools for this
|
||||
// pool suite.
|
||||
// The first tool is a wrapper for the usage with stl
|
||||
//5.1 Wrapper for STL
|
||||
// As you know, you can pass your own allocator as the last
|
||||
// parameter of stl containers, with this helper you can use a pool
|
||||
// created with this suite and wrap it for the stl.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// -Building blocks
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//That's the theory, so how does it work?
|
||||
//It's pretty simple, you compose the pool of your dreams by cascading
|
||||
//templates.
|
||||
//Lets start with an exmaple
|
||||
//Per level you want to allocate a fixed amount of memory for your
|
||||
//textures.
|
||||
CMemoryDynamic
|
||||
//- They are placed in some memory you can access directly with the cpu:
|
||||
CInPlace
|
||||
//- and you don't want to defragmentate, so you prefer an allocation
|
||||
// sheme that reduces fragmentation.
|
||||
CBestFit
|
||||
//now you combine them
|
||||
typedef CBestFit<CInPlace<CMemoryDynamic>, CListItemInPlace> TMyOwnPool;
|
||||
|
||||
//Yes, it's that simple.
|
||||
//ok, ok, texture memory is usually nothing you want to access directly
|
||||
//with your cpu, so let's create a referencing pool. Therefor you need
|
||||
//to also specify how many nodes that can reference your pool will have.
|
||||
//We won't have more than 4000 textures, so let's start with
|
||||
{
|
||||
enum TEXTURE_NODE_COUNT = 4096
|
||||
};
|
||||
//and now our referencing pool
|
||||
typedef CBestFit < CReferenced<CMemoryDynamic, TEXTURE_NODE_COUNT> TMyOwnPool;
|
||||
|
||||
//But yeah, you're right, texture memory has also a fixed size, lets
|
||||
//assume it's 128MB.
|
||||
{
|
||||
enum TEXTURE_MEMORY_SIZE = 128 * 1024 * 1024
|
||||
};
|
||||
//and our fixed sized memory pool
|
||||
typedef CBestFit < CReferenced<CMemoryStatic<TEXTURE_MEMORY_SIZE>, TEXTURE_NODE_COUNT> TMyOwnPool;
|
||||
|
||||
//ok, but you don't trust the best fit allocator in all cases, you prefer
|
||||
//a fast one and you accept the slow down for defragmentation incase the
|
||||
//allocation fails.
|
||||
//So lets created a straight First Fit allocator with defragmentation:
|
||||
typedef CDefragStacked < CFirstFit<CReferenced<CMemoryStatic<TEXTURE_MEMORY_SIZE>, TEXTURE_NODE_COUNT> > TMyOwnPool;
|
||||
|
||||
//here you see how simple you can add defragmentation, but be careful, it
|
||||
//works of course just on Reference based memory containers, if you have
|
||||
//Direct pointers to In Place allocation, we cannot shuffle them around.
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// -Usage
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//it all starts by including the meain header
|
||||
#include "PoolAlloc.h"
|
||||
|
||||
//Define your dream allocator, preferably using a typedef (or macro)
|
||||
typedef CBestFit<CInPlace<CMemoryDynamic>, CListItemInPlace> TMyOwnPool;
|
||||
//also typedef (or macro) your handle
|
||||
typedef uint8* TMyHandle; //in case of "In Place" allocations
|
||||
typedef uint32 TMyHandle; //in case of "Referenced"
|
||||
|
||||
//Instantiate it
|
||||
TMyOwnPool g_MyMemory;
|
||||
|
||||
//now you need to initialize it,
|
||||
g_MyMemory.InitMem(pMemoryArea, MemorySize); //in case you use "CMemoryDynamic"
|
||||
g_MyMemory.InitMem(); //in case you use "CmemoryStatic,
|
||||
//altough you could pass the same
|
||||
//parameters, they'd be ignored.
|
||||
//Use this also to flush the pool
|
||||
//quickly
|
||||
|
||||
|
||||
//now allocate
|
||||
TMyHandle MemID = g_MyMemory.Allocate<TMyHandle>(Size);
|
||||
//optionally alignment can be passed as 2nd parameter
|
||||
TMyHandle MemID = g_MyMemory.Allocate<TMyHandle>(Size, Align);
|
||||
|
||||
//free it simply by calling
|
||||
g_Memory.Free(MemID);
|
||||
|
||||
//you might want to call the beat function to defragment the memory
|
||||
//on regular base
|
||||
g_Memory.Beat();
|
||||
//you might also want to call it just when an allocation failed to
|
||||
//defragmentate the memory as good as possible
|
||||
if (!(MemID = g_Memoery.Allocate<TMyHandle>(Size)))
|
||||
{
|
||||
while (g_Memory.Beat())
|
||||
{
|
||||
;
|
||||
}
|
||||
MemID = g_Memoery.Allocate<TMyHandle>(Size);
|
||||
}
|
||||
|
||||
//To acquire the pointer to your data, you need to resolve the handle
|
||||
MyObject* pObject = g_Memory.Resolve<MyOBject*>(MemID);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// -Realloc/Resize
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The Containers provide a "resize" function. This one does nothing else
|
||||
// than the name suggest, it is freeing some memory at the end of your
|
||||
// allocation or, if free memory is available, allocates some memory to
|
||||
// the end of your buffer. But it may also fail, if not enough memory
|
||||
// available to allocate.
|
||||
// "Realloc" on the other side requires an extra template that you wrap
|
||||
// around your existing one like:
|
||||
typedef CReallocator<TMyOwnPool> TMyOwnPoolWithReallocation;
|
||||
// This one will first try to use resize, but in case it fails, it will
|
||||
// allocate a seperate memory area, copy the data and free the old one.
|
||||
//
|
||||
// But this may fail as well, therefor the result is not a pointer to the
|
||||
// allocation, but true/false.
|
||||
// There for you need to pass a pointer to your pointer to the memory area
|
||||
// or handle you deal with.
|
||||
Handle = rMemory.Allocate<TPtr>(10, 1);
|
||||
if (!rMemory.Reallocate<TPtr>(&Handles, 11, 1))
|
||||
{
|
||||
//handle realloc failure
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// -FAQ
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//"DO I HAVE TO ALWAYS RESOLVE?"
|
||||
//if you use "In Place" memory, not at all, all resolve does is to
|
||||
//cast your handle to your object ptr and returns it.
|
||||
//if you use "Referenced" memory and you don't defragmentate, you
|
||||
//can do it once and keep the ptr, but you also need to keep the
|
||||
//handle to free the memory later on.
|
||||
|
||||
//"any reason I should resolve?"
|
||||
//Yes, first of all, it makes it very easy to switch between various
|
||||
//pool configuration for testing, you simply change some params of
|
||||
//your typedef (or macro) and it should work out of the box.
|
||||
//second, for defragmentation it's the only way to go and for future
|
||||
//things it might be needed as well
|
||||
|
||||
//"but isn't resolving just overhead?"
|
||||
//in case of "In Place": no, the resolve function just returns the
|
||||
//pointer, casting to your wanted type
|
||||
//in case of "Referenced": it cost you one indirection.
|
||||
|
||||
|
||||
//"How do I flush the whole pool without freeing all items?"
|
||||
g_Memory.InitMem()
|
||||
//yes, you can call "InitMem" once again, you need to pass the mem
|
||||
//ptr and size if using CMemoryDynamic e.g.
|
||||
g_Memory.Init(g_Memory.Size(), g_Memory.Data());
|
||||
|
||||
//"How do I lock the allocated memory to avoid any reallocation"
|
||||
g_Memory.Item(ptr)->Lock();
|
||||
|
||||
|
||||
//"How do I get the size of a memory block?"
|
||||
g_Memory.Item(ptr)->MemSize();
|
||||
|
||||
|
||||
|
||||
|
||||
//"Is there any example?"
|
||||
//for a real life example check PAUnitTest.cpp used to validate all
|
||||
//functions of this pool.
|
||||
|
||||
|
||||
//bug reports? questions? support?
|
||||
//just ask me :) (michael kopietz)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYPOOL_EXAMPLE_H
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H
|
||||
#define CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H
|
||||
#pragma once
|
||||
|
||||
#include "CryExtension/CryGUID.h"
|
||||
|
||||
#if !defined(LINUX)
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
#define PACK_GCC
|
||||
#else
|
||||
#define PACK_GCC __attribute__ ((packed))
|
||||
#endif
|
||||
|
||||
namespace GeomCacheFile
|
||||
{
|
||||
// Important: The enums are serialized, don't change the values
|
||||
// without increasing the file version, conversion code etc!
|
||||
|
||||
typedef Vec3_tpl<uint16> Position;
|
||||
typedef Vec2_tpl<int16> Texcoords;
|
||||
typedef Vec4_tpl<int16> QTangent;
|
||||
typedef uint8 Color;
|
||||
|
||||
// ASCII "CAXCACHE"
|
||||
const uint64 kFileSignature = 0x4548434143584143ull;
|
||||
|
||||
// The smallest 'UVmax' we'll support - this avoids division by zero when encoding/decoding UVs
|
||||
const float kMinUVrange = .01f;
|
||||
|
||||
// Bit Precision of tangents quaternions
|
||||
const uint kTangentQuatPrecision = 10;
|
||||
|
||||
// Current file version GUID. Files with other GUIDs will not be loaded by the engine.
|
||||
const CryGUID kCurrentVersion = MAKE_CRYGUID(0x1641defe440af501, 0x7ec5e9164c8c2d1c);
|
||||
|
||||
// Mesh prediction look back array size
|
||||
const uint kMeshPredictorLookBackMaxDist = 4096;
|
||||
|
||||
// Number of frames between index frames. Needs to be <= g_kMaxBufferedFrames.
|
||||
const uint kMaxIFrameDistance = 30;
|
||||
|
||||
enum EFileHeaderFlags
|
||||
{
|
||||
eFileHeaderFlags_PlaybackFromMemory = BIT(0),
|
||||
eFileHeaderFlags_32BitIndices = BIT(1)
|
||||
};
|
||||
|
||||
enum EBlockCompressionFormat
|
||||
{
|
||||
eBlockCompressionFormat_None = 0,
|
||||
eBlockCompressionFormat_Deflate = 1, // zlib
|
||||
eBlockCompressionFormat_LZ4HC = 2, // LZ4 HC
|
||||
eBlockCompressionFormat_ZSTD = 3, //ZStandard
|
||||
};
|
||||
|
||||
enum EStreams
|
||||
{
|
||||
eStream_Indices = BIT(0),
|
||||
eStream_Positions = BIT(1),
|
||||
eStream_Texcoords = BIT(2),
|
||||
eStream_QTangents = BIT(3),
|
||||
eStream_Colors = BIT(4)
|
||||
};
|
||||
|
||||
enum ETransformType
|
||||
{
|
||||
eTransformType_Constant,
|
||||
eTransformType_Animated
|
||||
};
|
||||
|
||||
enum ENodeType
|
||||
{
|
||||
eNodeType_Transform = 0, // Transforms all sub nodes
|
||||
eNodeType_Mesh = 1,
|
||||
eNodeType_PhysicsGeometry = 2,
|
||||
};
|
||||
|
||||
// Common frame
|
||||
enum EFrameType
|
||||
{
|
||||
eFrameType_IFrame = 0,
|
||||
eFrameType_BFrame = 1
|
||||
};
|
||||
|
||||
// Common frame flags
|
||||
enum EFrameFlags
|
||||
{
|
||||
eFrameFlags_Hidden = BIT(0)
|
||||
};
|
||||
|
||||
// Flags for mesh index frames
|
||||
enum EMeshIFrameFlags
|
||||
{
|
||||
eMeshIFrameFlags_UsePredictor = BIT(1)
|
||||
};
|
||||
|
||||
struct SHeader
|
||||
{
|
||||
SHeader()
|
||||
: m_signature(0)
|
||||
, m_version(kCurrentVersion)
|
||||
, m_blockCompressionFormat(0)
|
||||
, m_flags(0)
|
||||
, m_numFrames(0) {}
|
||||
|
||||
uint64 m_signature;
|
||||
CryGUID m_version;
|
||||
uint16 m_blockCompressionFormat;
|
||||
uint32 m_flags;
|
||||
uint32 m_numFrames;
|
||||
uint64 m_totalUncompressedAnimationSize;
|
||||
float m_aabbMin[3];
|
||||
float m_aabbMax[3];
|
||||
} PACK_GCC;
|
||||
|
||||
struct SFrameInfo
|
||||
{
|
||||
uint32 m_frameType;
|
||||
uint32 m_frameSize;
|
||||
uint64 m_frameOffset;
|
||||
float m_frameTime;
|
||||
} PACK_GCC;
|
||||
|
||||
struct SCompressedBlockHeader
|
||||
{
|
||||
uint32 m_uncompressedSize;
|
||||
uint32 m_compressedSize;
|
||||
} PACK_GCC;
|
||||
|
||||
struct SFrameHeader
|
||||
{
|
||||
uint32 m_nodeDataOffset;
|
||||
float m_frameAABBMin[3];
|
||||
float m_frameAABBMax[3];
|
||||
uint32 m_padding;
|
||||
} PACK_GCC;
|
||||
|
||||
struct STemporalPredictorControl
|
||||
{
|
||||
uint8 m_acceleration;
|
||||
uint8 m_indexFrameLerpFactor;
|
||||
uint8 m_combineFactor;
|
||||
uint8 m_padding;
|
||||
} PACK_GCC;
|
||||
|
||||
struct SMeshFrameHeader
|
||||
{
|
||||
uint32 m_flags;
|
||||
STemporalPredictorControl m_positionStreamPredictorControl;
|
||||
STemporalPredictorControl m_texcoordStreamPredictorControl;
|
||||
STemporalPredictorControl m_qTangentStreamPredictorControl;
|
||||
STemporalPredictorControl m_colorStreamPredictorControl[4];
|
||||
} PACK_GCC;
|
||||
|
||||
struct SMeshInfo
|
||||
{
|
||||
uint8 m_constantStreams;
|
||||
uint8 m_animatedStreams;
|
||||
uint8 m_positionPrecision[3];
|
||||
float m_uvMax;
|
||||
uint8 m_padding;
|
||||
uint16 m_numMaterials;
|
||||
uint32 m_numVertices;
|
||||
uint32 m_flags;
|
||||
float m_aabbMin[3];
|
||||
float m_aabbMax[3];
|
||||
uint32 m_nameLength;
|
||||
uint64 m_hash;
|
||||
} PACK_GCC;
|
||||
|
||||
struct SNodeInfo
|
||||
{
|
||||
uint8 m_type;
|
||||
uint8 m_bVisible;
|
||||
uint16 m_transformType;
|
||||
uint32 m_meshIndex;
|
||||
uint32 m_numChildren;
|
||||
uint32 m_nameLength;
|
||||
} PACK_GCC;
|
||||
}
|
||||
|
||||
#undef PACK_GCC
|
||||
|
||||
#if !defined(LINUX)
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_GEOMCACHEFILEFORMAT_H
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Defines the extension interface for the CryEngine modules.
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H
|
||||
#pragma once
|
||||
|
||||
#include <CryExtension/ICryUnknown.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzCore/Console/ConsoleFunctor.h>
|
||||
|
||||
struct SSystemInitParams;
|
||||
|
||||
// Base Interface for all engine module extensions
|
||||
struct IEngineModule
|
||||
: public ICryUnknown
|
||||
{
|
||||
CRYINTERFACE_DECLARE(IEngineModule, 0xf899cf661df04f61, 0xa341a8a7ffdf9de4);
|
||||
|
||||
// <interfuscator:shuffle>
|
||||
// Retrieve name of the extension module.
|
||||
virtual const char* GetName() const = 0;
|
||||
|
||||
// Retrieve category for the extension module (CryEngine for standard modules).
|
||||
virtual const char* GetCategory() const = 0;
|
||||
|
||||
// This is called to initialize the new module.
|
||||
virtual bool Initialize(SSystemGlobalEnvironment& env, const SSystemInitParams& initParams) = 0;
|
||||
// </interfuscator:shuffle>
|
||||
|
||||
// This is called to register any AZ console vars declared within this engine module
|
||||
virtual void RegisterConsoleVars()
|
||||
{
|
||||
AZ::ConsoleFunctorBase*& deferredHead = AZ::ConsoleFunctorBase::GetDeferredHead();
|
||||
AZ::Interface<AZ::IConsole>::Get()->LinkDeferredFunctors(deferredHead);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IENGINEMODULE_H
|
||||
@@ -1,763 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Service network interface
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H
|
||||
#define CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H
|
||||
#pragma once
|
||||
|
||||
#include <CryString.h>
|
||||
#include <BaseTypes.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Helpers for writing/reading command data stream from network message packets.
|
||||
// Those interfaces automatically handle byteswapping for big endian systems.
|
||||
// The native format for data inside the messages is little endian.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Write stream interface
|
||||
struct IDataWriteStream
|
||||
{
|
||||
public:
|
||||
virtual ~IDataWriteStream() {};
|
||||
|
||||
public:
|
||||
// Virtualized write method for general data buffer
|
||||
virtual void Write(const void* pData, const uint32 size) = 0;
|
||||
|
||||
// Virtualized write method for types with size 8 (support byteswapping, a little bit faster than general case)
|
||||
virtual void Write8(const void* pData) = 0;
|
||||
|
||||
// Virtualized write method for types with size 4 (support byteswapping, a little bit faster than general case)
|
||||
virtual void Write4(const void* pData) = 0;
|
||||
|
||||
// Virtualized write method for types with size 2 (support byteswapping, a little bit faster than general case)
|
||||
virtual void Write2(const void* pData) = 0;
|
||||
|
||||
// Virtualized write method for types with size 1 (a little bit faster than general case)
|
||||
virtual void Write1(const void* pData) = 0;
|
||||
|
||||
// Get number of bytes written
|
||||
virtual const uint32 GetSize() const = 0;
|
||||
|
||||
// Convert to service network message
|
||||
virtual struct IServiceNetworkMessage* BuildMessage() const = 0;
|
||||
|
||||
// Save the data from this writer stream to the provided buffer
|
||||
virtual void CopyToBuffer(void* pData) const = 0;
|
||||
|
||||
// Destroy object (if dynamically created)
|
||||
virtual void Delete() = 0;
|
||||
|
||||
public:
|
||||
IDataWriteStream& operator<<(const uint8& val)
|
||||
{
|
||||
Write1(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const uint16& val)
|
||||
{
|
||||
Write2(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const uint32& val)
|
||||
{
|
||||
Write4(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const uint64& val)
|
||||
{
|
||||
Write8(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const int8& val)
|
||||
{
|
||||
Write1(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const int16& val)
|
||||
{
|
||||
Write2(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const int32& val)
|
||||
{
|
||||
Write4(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const int64& val)
|
||||
{
|
||||
Write8(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataWriteStream& operator<<(const float& val)
|
||||
{
|
||||
Write4(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Bool is saved by writing an 8 bit value to make it portable
|
||||
IDataWriteStream& operator<<(const bool& val)
|
||||
{
|
||||
const uint8 uVal = val ? 1 : 0;
|
||||
Write1(&uVal);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
// Write C string to stream
|
||||
void WriteString(const char* str);
|
||||
|
||||
// Write string to stream
|
||||
void WriteString(const string& str);
|
||||
|
||||
// Write int8 value to stream
|
||||
void WriteInt8(const int8 val)
|
||||
{
|
||||
Write1(&val);
|
||||
}
|
||||
|
||||
// Write int16 value to stream
|
||||
void WriteInt16(const int16 val)
|
||||
{
|
||||
Write2(&val);
|
||||
}
|
||||
|
||||
// Write int32 value to stream
|
||||
void WriteInt32(const int32 val)
|
||||
{
|
||||
Write4(&val);
|
||||
}
|
||||
|
||||
// Write int64 value to stream
|
||||
void WriteInt64(const int64 val)
|
||||
{
|
||||
Write8(&val);
|
||||
}
|
||||
|
||||
// Write uint8 value to stream
|
||||
void WriteUint8(const uint8 val)
|
||||
{
|
||||
Write1(&val);
|
||||
}
|
||||
|
||||
// Write uint16 value to stream
|
||||
void WriteUint16(const uint16 val)
|
||||
{
|
||||
Write2(&val);
|
||||
}
|
||||
|
||||
// Write uint32 value to stream
|
||||
void WriteUint32(const uint32 val)
|
||||
{
|
||||
Write4(&val);
|
||||
}
|
||||
|
||||
// Write uint64 value to stream
|
||||
void WriteUint64(const uint64 val)
|
||||
{
|
||||
Write8(&val);
|
||||
}
|
||||
|
||||
// Write float value to stream
|
||||
void WriteFloat(const float val)
|
||||
{
|
||||
Write4(&val);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Read stream interface
|
||||
/// This interface should support endianess swapping
|
||||
struct IDataReadStream
|
||||
{
|
||||
public:
|
||||
virtual ~IDataReadStream() {};
|
||||
|
||||
public:
|
||||
// Destroy object (if dynamically created)
|
||||
virtual void Delete() = 0;
|
||||
|
||||
// Skip given amount of data without reading it
|
||||
virtual void Skip(const uint32 size) = 0;
|
||||
|
||||
// Virtualized read method (for general buffers)
|
||||
virtual void Read(void* pData, const uint32 size) = 0;
|
||||
|
||||
// Virtualized read method for types with size 8 (a little bit faster than general method, supports byte swapping for BE systems)
|
||||
virtual void Read8(void* pData) = 0;
|
||||
|
||||
// Virtualized read method for types with size 4 (a little bit faster than general method, supports byte swapping for BE systems)
|
||||
virtual void Read4(void* pData) = 0;
|
||||
|
||||
// Virtualized read method for types with size 2 (a little bit faster than general method, supports byte swapping for BE systems)
|
||||
virtual void Read2(void* pData) = 0;
|
||||
|
||||
// Virtualized read method for types with size 1 (a little bit faster than general method, supports byte swapping for BE systems)
|
||||
virtual void Read1(void* pData) = 0;
|
||||
|
||||
// Optimization case - get direct pointer to the underlying buffer
|
||||
virtual const void* GetPointer() = 0;
|
||||
|
||||
public:
|
||||
IDataReadStream& operator<<(uint8& val)
|
||||
{
|
||||
Read1(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(uint16& val)
|
||||
{
|
||||
Read2(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(uint32& val)
|
||||
{
|
||||
Read4(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(uint64& val)
|
||||
{
|
||||
Read8(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(int8& val)
|
||||
{
|
||||
Read1(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(int16& val)
|
||||
{
|
||||
Read2(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(int32& val)
|
||||
{
|
||||
Read4(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(int64& val)
|
||||
{
|
||||
Read8(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IDataReadStream& operator<<(float& val)
|
||||
{
|
||||
Read4(&val);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Bool is saved by writing an 8 bit value to make it portable
|
||||
IDataReadStream& operator<<(bool& val)
|
||||
{
|
||||
uint8 uVal = 0;
|
||||
Read1(&uVal);
|
||||
val = (uVal != 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
// Read string from stream
|
||||
string ReadString();
|
||||
|
||||
// Skip string data in a stream without loading the data
|
||||
void SkipString();
|
||||
|
||||
// Read int8 from stream
|
||||
int8 ReadInt8()
|
||||
{
|
||||
int8 val = 0;
|
||||
Read1(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read int16 from stream
|
||||
int16 ReadInt16()
|
||||
{
|
||||
int16 val = 0;
|
||||
Read2(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read int32 from stream
|
||||
int32 ReadInt32()
|
||||
{
|
||||
int32 val = 0;
|
||||
Read4(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read int64 from stream
|
||||
int64 ReadInt64()
|
||||
{
|
||||
int64 val = 0;
|
||||
Read8(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read uint8 from stream
|
||||
uint8 ReadUint8()
|
||||
{
|
||||
uint8 val = 0;
|
||||
Read1(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read uint16 from stream
|
||||
uint16 ReadUint16()
|
||||
{
|
||||
uint16 val = 0;
|
||||
Read2(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read uint32 from stream
|
||||
uint32 ReadUint32()
|
||||
{
|
||||
uint32 val = 0;
|
||||
Read4(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read int64 from stream
|
||||
uint64 ReadUint64()
|
||||
{
|
||||
uint64 val = 0;
|
||||
Read8(&val);
|
||||
return val;
|
||||
}
|
||||
|
||||
// Read float from stream
|
||||
float ReadFloat()
|
||||
{
|
||||
float val = 0.0f;
|
||||
Read4(&val);
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Remote command class info (simple RTTI)
|
||||
struct IRemoteCommandClass
|
||||
{
|
||||
public:
|
||||
virtual ~IRemoteCommandClass() {};
|
||||
|
||||
// Get class name
|
||||
virtual const char* GetName() const = 0;
|
||||
|
||||
// Create command instance
|
||||
virtual struct IRemoteCommand* CreateObject() = 0;
|
||||
};
|
||||
|
||||
/// Remote command interface
|
||||
struct IRemoteCommand
|
||||
{
|
||||
protected:
|
||||
virtual ~IRemoteCommand() {};
|
||||
|
||||
public:
|
||||
// Get command class
|
||||
virtual IRemoteCommandClass* GetClass() const = 0;
|
||||
|
||||
// Save to data stream
|
||||
virtual void SaveToStream(struct IDataWriteStream& writeStream) const = 0;
|
||||
|
||||
// Load from data stream
|
||||
virtual void LoadFromStream(struct IDataReadStream& readStream) = 0;
|
||||
|
||||
// Execute (remote call) = 0;
|
||||
virtual void Execute() = 0;
|
||||
|
||||
// Delete the command object (can be allocated from different heap)
|
||||
virtual void Delete() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// This is a implementation of a synchronous listener (limited to the engine tick rate)
|
||||
// that processes and responds to the raw messages received from clients.
|
||||
struct IRemoteCommandListenerSync
|
||||
{
|
||||
public:
|
||||
virtual ~IRemoteCommandListenerSync() {};
|
||||
|
||||
// Process a raw message and optionally provide an answer to the request, return true if you have processed the message.
|
||||
// Messages is accessible via the data reader. Response can be written to a data writer.
|
||||
virtual bool OnRawMessageSync(const class ServiceNetworkAddress& remoteAddress, struct IDataReadStream& msg, struct IDataWriteStream& response) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// This is a implementation of a asynchronous listener (called from network thread)
|
||||
// that processes and responds to the raw messages received from clients.
|
||||
struct IRemoteCommandListenerAsync
|
||||
{
|
||||
public:
|
||||
virtual ~IRemoteCommandListenerAsync() {};
|
||||
|
||||
// Process a raw message and optionally provide an answer to the request, return true if you have processed the message.
|
||||
// Messages is accessible via the data reader. Response can be written to a data writer.
|
||||
virtual bool OnRawMessageAsync(const class ServiceNetworkAddress& remoteAddress, struct IDataReadStream& msg, struct IDataWriteStream& response) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Remote command server
|
||||
struct IRemoteCommandServer
|
||||
{
|
||||
protected:
|
||||
virtual ~IRemoteCommandServer() {};
|
||||
|
||||
public:
|
||||
// Execute all of the received pending commands
|
||||
// This should be called from a safe place (main thread)
|
||||
virtual void FlushCommandQueue() = 0;
|
||||
|
||||
// Suppress command execution
|
||||
virtual void SuppressCommands() = 0;
|
||||
|
||||
// Resume command execution
|
||||
virtual void ResumeCommands() = 0;
|
||||
|
||||
// Register/Unregister synchronous message listener (limited to tick rate)
|
||||
virtual void RegisterSyncMessageListener(IRemoteCommandListenerSync* pListener) = 0;
|
||||
virtual void UnregisterSyncMessageListener(IRemoteCommandListenerSync* pListener) = 0;
|
||||
|
||||
// Register/Unregister asynchronous message listener (called from network thread)
|
||||
virtual void RegisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) = 0;
|
||||
virtual void UnregisterAsyncMessageListener(IRemoteCommandListenerAsync* pListener) = 0;
|
||||
|
||||
// Broadcast a message to all connected clients
|
||||
virtual void Broadcast(IServiceNetworkMessage* pMessage) = 0;
|
||||
|
||||
// Do we have any clients connected ?
|
||||
virtual bool HasConnectedClients() const = 0;
|
||||
|
||||
// Delete the client
|
||||
virtual void Delete() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Connection to remote command server
|
||||
struct IRemoteCommandConnection
|
||||
{
|
||||
protected:
|
||||
virtual ~IRemoteCommandConnection() {};
|
||||
|
||||
public:
|
||||
// Are we connected ?
|
||||
// This returns false when the underlying network connection has failed (sockets error).
|
||||
// Also, this returns false if the remote connection was closed by remote peer.
|
||||
virtual bool IsAlive() const = 0;
|
||||
|
||||
// Get address of remote command server
|
||||
// This returns the full address of the endpoint (with valid port)
|
||||
virtual const ServiceNetworkAddress& GetRemoteAddress() const = 0;
|
||||
|
||||
// Send raw message to the other side of this connection.
|
||||
// Raw messages are not buffer and are sent right away,
|
||||
// they also have precedence over internal command traffic.
|
||||
// The idea is that you need some kind of bidirectional signaling
|
||||
// channel to extend the rather one-directional nature of commands.
|
||||
// Returns true if message was added to the send queue.
|
||||
virtual bool SendRawMessage(IServiceNetworkMessage* pMessage) = 0;
|
||||
|
||||
// See if there's a raw message waiting for us and if it is, get it
|
||||
// Be aware that messages are reference counted.
|
||||
virtual IServiceNetworkMessage* ReceiveRawMessage() = 0;
|
||||
|
||||
// Close connection
|
||||
// - pending commands are not sent
|
||||
// - pending raw messages are sent or not (depending on the flag)
|
||||
virtual void Close(bool bFlushQueueBeforeClosing = false) = 0;
|
||||
|
||||
// Add internal reference to object (Refcounting interface)
|
||||
virtual void AddRef() = 0;
|
||||
|
||||
// Release internal reference to object (Refcounting interface)
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Remote command client
|
||||
struct IRemoteCommandClient
|
||||
{
|
||||
protected:
|
||||
virtual ~IRemoteCommandClient() {};
|
||||
|
||||
public:
|
||||
// Connect to remote server, returns true on success, false on failure
|
||||
virtual IRemoteCommandConnection* ConnectToServer(const class ServiceNetworkAddress& serverAddress) = 0;
|
||||
|
||||
// Schedule command to be executed on the all of the remote servers
|
||||
virtual bool Schedule(const IRemoteCommand& command) = 0;
|
||||
|
||||
// Delete the client object
|
||||
virtual void Delete() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Remote command manager
|
||||
struct IRemoteCommandManager
|
||||
{
|
||||
public:
|
||||
virtual ~IRemoteCommandManager() {};
|
||||
|
||||
// Set debug message verbose level
|
||||
virtual void SetVerbosityLevel(const uint32 level) = 0;
|
||||
|
||||
// Create local server for executing remote commands on given local port
|
||||
virtual IRemoteCommandServer* CreateServer(uint16 localPort) = 0;
|
||||
|
||||
// Create client interface for executing remote commands on remote servers
|
||||
virtual IRemoteCommandClient* CreateClient() = 0;
|
||||
|
||||
// Register command class (will be accessible by both clients and server)
|
||||
virtual void RegisterCommandClass(IRemoteCommandClass& commandClass) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Class RTTI wrapper for remote command classes
|
||||
template< typename T >
|
||||
class CRemoteCommandClass
|
||||
: public IRemoteCommandClass
|
||||
{
|
||||
private:
|
||||
const char* m_szName;
|
||||
|
||||
public:
|
||||
CRemoteCommandClass(const char* szName)
|
||||
: m_szName(szName)
|
||||
{}
|
||||
|
||||
virtual const char* GetName() const
|
||||
{
|
||||
return m_szName;
|
||||
}
|
||||
|
||||
virtual struct IRemoteCommand* CreateObject()
|
||||
{
|
||||
return new T();
|
||||
}
|
||||
};
|
||||
|
||||
#define DECLARE_REMOTE_COMMAND(x) \
|
||||
public: static IRemoteCommandClass& GetStaticClass() { \
|
||||
static IRemoteCommandClass* theClass = new CRemoteCommandClass<x>(#x); return *theClass; } \
|
||||
public: virtual IRemoteCommandClass* GetClass() const { return &GetStaticClass(); } \
|
||||
public: virtual void Delete() { delete this; } \
|
||||
public: virtual void SaveToStream(IDataWriteStream & writeStream) const { const_cast<x*>(this)->Serialize<IDataWriteStream>(writeStream); } \
|
||||
public: virtual void LoadFromStream(IDataReadStream & readStream) { Serialize<IDataReadStream>(readStream); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// CryString serialization helper (read)
|
||||
inline IDataReadStream& operator<<(IDataReadStream& stream, string& outString)
|
||||
{
|
||||
const uint32 kMaxTempString = 256;
|
||||
|
||||
// read length
|
||||
uint32 length = 0;
|
||||
stream << length;
|
||||
|
||||
// load string
|
||||
if (length > 0)
|
||||
{
|
||||
if (length < kMaxTempString)
|
||||
{
|
||||
// load the string into temporary buffer
|
||||
char temp[kMaxTempString];
|
||||
stream.Read(&temp, length);
|
||||
temp[length] = 0;
|
||||
|
||||
// set the string with new value
|
||||
outString = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
// allocate temporary memory and load the string
|
||||
std::vector<char> temp;
|
||||
temp.resize(length + 1, 0);
|
||||
stream.Read(&temp[0], length);
|
||||
|
||||
// set the string with new value
|
||||
outString = &temp[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// empty string
|
||||
outString.clear();
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
/// CryString serialization helper (write)
|
||||
inline IDataWriteStream& operator<<(IDataWriteStream& stream, const string& str)
|
||||
{
|
||||
// write length
|
||||
const uint32 length = static_cast<uint32>(str.length());
|
||||
stream << length;
|
||||
|
||||
// write string data
|
||||
if (length > 0)
|
||||
{
|
||||
stream.Write(str.c_str(), length);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/// Vector serialization helper (reading)
|
||||
template< class T >
|
||||
IDataReadStream& operator<<(IDataReadStream& ar, std::vector<T>& outVector)
|
||||
{
|
||||
// Load item count
|
||||
uint32 count = 0;
|
||||
ar << count;
|
||||
|
||||
// Adapt the vector size (exact fit)
|
||||
outVector.resize(count);
|
||||
|
||||
// Load items
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
ar << outVector[i];
|
||||
}
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
/// Vector serialization helper (writing)
|
||||
template< class T >
|
||||
IDataWriteStream& operator<<(IDataWriteStream& ar, const std::vector<T>& vec)
|
||||
{
|
||||
// Save item count
|
||||
const uint32 count = vec.size();
|
||||
ar << count;
|
||||
|
||||
// Save items
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
ar << const_cast<T&>(vec[i]);
|
||||
}
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
inline void IDataWriteStream::WriteString(const char* str)
|
||||
{
|
||||
string tempString(str);
|
||||
*this << tempString;
|
||||
}
|
||||
|
||||
inline void IDataWriteStream::WriteString(const string& str)
|
||||
{
|
||||
*this << str;
|
||||
}
|
||||
|
||||
inline string IDataReadStream::ReadString()
|
||||
{
|
||||
string ret;
|
||||
*this << ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void IDataReadStream::SkipString()
|
||||
{
|
||||
// read length
|
||||
uint32 length = 0;
|
||||
*this << length;
|
||||
Skip(length);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Helper class for using the data reader and writer classes
|
||||
// The only major differce betwen auto_ptr is that we call Delete() instead of operator delete
|
||||
template<class T>
|
||||
class TAutoDelete
|
||||
{
|
||||
public:
|
||||
T* m_ptr;
|
||||
|
||||
public:
|
||||
TAutoDelete(T* ptr)
|
||||
: m_ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
~TAutoDelete()
|
||||
{
|
||||
if (NULL != m_ptr)
|
||||
{
|
||||
m_ptr->Delete();
|
||||
m_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return (NULL != m_ptr);
|
||||
}
|
||||
|
||||
operator T& ()
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
T* operator->()
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
TAutoDelete(const TAutoDelete& other)
|
||||
: m_ptr(NULL){};
|
||||
TAutoDelete& operator=(const TAutoDelete& other) { return *this; }
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_IREMOTECOMMAND_H
|
||||
@@ -1,344 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
// Description : Service network interface
|
||||
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H
|
||||
#define CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <CryExtension/CryGUID.h>
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Service network is a simple abstract interface for connecting between instances
|
||||
// of the editor and game running on various platforms. It implements it's own
|
||||
// small message based communication layer and shall not be used for raw communication
|
||||
// with anything else.
|
||||
//
|
||||
// Features currently implemented by the service network:
|
||||
// - Completely thread safe (so can be used from within other threads)
|
||||
// - Completely asynchronous (only one thread)
|
||||
// - Message based approach (both on the send and receive ends)
|
||||
// - Automatic and transparent reconnection
|
||||
// - Debug-friendly (will not time-out easily when one of the endpoints is being debugged)
|
||||
// - Easy to use
|
||||
//
|
||||
// Usage case (server)
|
||||
// - Create listener (IServiceListener) on some pre-defined port
|
||||
// - Poll the incoming connections by calling Accept() method
|
||||
// - Service the traffic by calling connection's ReceiveMessage()/SendMessage() methods
|
||||
// - Close() and Release() connections
|
||||
// - Close() and Release() listener
|
||||
//
|
||||
// Usage case (client)
|
||||
// - Connect to a remote listener by calling Connect() method
|
||||
// - Service the traffic by calling connection's ReceiveMessage()/SendMessage() methods
|
||||
// - Close() and Release() connection
|
||||
//
|
||||
// Both sending and receiving is asynchronous. Calling the SendMessage()/ReceiveMessage() methods
|
||||
// only pushes/pops the message buffers to/from the queue.
|
||||
// NOTE: Message buffers are internally reference counted by the network system and they are kept around
|
||||
// untill they are sent (in case of outgoing traffic) or untill they are polled by ReceiveMessage().
|
||||
// Be aware that this can cause memory spikes, especially when incoming traffic is not serviced fast enough.
|
||||
// There are customizable limits (around 1MB) on the amount of data that can be buffered internally by
|
||||
// the service network before the new messages are rejected.
|
||||
// It's up to the higher layer to ensure damage control in such situation.
|
||||
//
|
||||
// NOTE: connection is also a reference counted object, make sure to call Close() before calling Release().
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Network address abstraction
|
||||
class ServiceNetworkAddress
|
||||
{
|
||||
public:
|
||||
struct StringAddress
|
||||
{
|
||||
char m_data[32];
|
||||
|
||||
ILINE const char* c_str() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
};
|
||||
|
||||
struct Address
|
||||
{
|
||||
uint8 m_ip0;
|
||||
uint8 m_ip1;
|
||||
uint8 m_ip2;
|
||||
uint8 m_ip3;
|
||||
uint16 m_port;
|
||||
|
||||
ILINE Address()
|
||||
: m_ip0(0)
|
||||
, m_ip1(0)
|
||||
, m_ip2(0)
|
||||
, m_ip3(0)
|
||||
, m_port(0)
|
||||
{}
|
||||
};
|
||||
|
||||
private:
|
||||
Address m_address;
|
||||
|
||||
public:
|
||||
// By default creates ("invalid address")
|
||||
ILINE ServiceNetworkAddress()
|
||||
{
|
||||
}
|
||||
|
||||
// Copy (with optional port change)
|
||||
ILINE ServiceNetworkAddress(const ServiceNetworkAddress& other, uint16 newPort = 0)
|
||||
: m_address(other.m_address)
|
||||
{
|
||||
if (newPort != 0)
|
||||
{
|
||||
m_address.m_port = newPort;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize from ip:host pattern (if you want to initialize from host name use the DebugNetwork interface)
|
||||
ILINE ServiceNetworkAddress(uint8 ip0, uint8 ip1, uint8 ip2, uint8 ip3, uint16 port)
|
||||
{
|
||||
m_address.m_ip0 = ip0;
|
||||
m_address.m_ip1 = ip1;
|
||||
m_address.m_ip2 = ip2;
|
||||
m_address.m_ip3 = ip3;
|
||||
m_address.m_port = port;
|
||||
}
|
||||
|
||||
// Set new port value
|
||||
ILINE void SetPort(uint16 port)
|
||||
{
|
||||
m_address.m_port = port;
|
||||
}
|
||||
|
||||
// Is this a valid address
|
||||
ILINE bool IsValid() const
|
||||
{
|
||||
return (m_address.m_ip0 != 0) &&
|
||||
(m_address.m_ip1 != 1) &&
|
||||
(m_address.m_ip2 != 1) &&
|
||||
(m_address.m_ip3 != 1) &&
|
||||
(m_address.m_port != 0);
|
||||
}
|
||||
|
||||
// Convert to human readable string
|
||||
ILINE StringAddress ToString() const
|
||||
{
|
||||
// format the string buffer
|
||||
StringAddress ret;
|
||||
sprintf_s(ret.m_data, sizeof(ret.m_data),
|
||||
"%d.%d.%d.%d:%d",
|
||||
m_address.m_ip0, m_address.m_ip1, m_address.m_ip2, m_address.m_ip3,
|
||||
m_address.m_port);
|
||||
|
||||
// return as managed string
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the literal data
|
||||
ILINE const Address& GetAddress() const
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
public:
|
||||
// Compare base address (IP only) of two connections
|
||||
static bool CompareBaseAddress(const ServiceNetworkAddress& a, const ServiceNetworkAddress& b)
|
||||
{
|
||||
return (a.m_address.m_ip0 == b.m_address.m_ip0) &&
|
||||
(a.m_address.m_ip1 == b.m_address.m_ip1) &&
|
||||
(a.m_address.m_ip2 == b.m_address.m_ip2) &&
|
||||
(a.m_address.m_ip3 == b.m_address.m_ip3);
|
||||
}
|
||||
|
||||
// Compare full address (IP+port) of two connections
|
||||
static bool CompareFullAddress(const ServiceNetworkAddress& a, const ServiceNetworkAddress& b)
|
||||
{
|
||||
return (a.m_address.m_ip0 == b.m_address.m_ip0) &&
|
||||
(a.m_address.m_ip1 == b.m_address.m_ip1) &&
|
||||
(a.m_address.m_ip2 == b.m_address.m_ip2) &&
|
||||
(a.m_address.m_ip3 == b.m_address.m_ip3) &&
|
||||
(a.m_address.m_port == b.m_address.m_port);
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Message buffer used by the network system
|
||||
struct IServiceNetworkMessage
|
||||
{
|
||||
protected:
|
||||
IServiceNetworkMessage() {};
|
||||
virtual ~IServiceNetworkMessage() {};
|
||||
|
||||
public:
|
||||
// Get unique message ID (message ID is used just once)
|
||||
virtual uint32 GetId() const = 0;
|
||||
|
||||
// Get the size of message buffer
|
||||
virtual uint32 GetSize() const = 0;
|
||||
|
||||
// Get pointer to the message data
|
||||
virtual void* GetPointer() = 0;
|
||||
|
||||
// Get pointer to the message data
|
||||
virtual const void* GetPointer() const = 0;
|
||||
|
||||
// Create reader interface for reading message data, returned object is not
|
||||
// reference counted but it will hold a reference to the message.
|
||||
virtual struct IDataReadStream* CreateReader() const = 0;
|
||||
|
||||
// Add reference (buffer is internally refcounted)
|
||||
virtual void AddRef() = 0;
|
||||
|
||||
// Release reference
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// General network TCP/IP connection
|
||||
struct IServiceNetworkConnection
|
||||
{
|
||||
protected:
|
||||
IServiceNetworkConnection() {};
|
||||
virtual ~IServiceNetworkConnection() {};
|
||||
|
||||
public:
|
||||
static const uint32 kDefaultFlushTime = 10000; // ms
|
||||
|
||||
// Get the unique connection ID (is shared between host and client)
|
||||
virtual const CryGUID& GetGUID() const = 0;
|
||||
|
||||
// Get remote endpoint address
|
||||
virtual const ServiceNetworkAddress& GetRemoteAddress() const = 0;
|
||||
|
||||
// Get local endpoint address
|
||||
virtual const ServiceNetworkAddress& GetLocalAddress() const = 0;
|
||||
|
||||
// Add a message buffer to the connection send queue.
|
||||
// Connection can refuse to send the buffer if it's full or invalid.
|
||||
// If a message is rejected this function returns false.
|
||||
virtual bool SendMsg(IServiceNetworkMessage* message) = 0;
|
||||
|
||||
// Get a message from connection receive queue.
|
||||
// If there are no pending messages a NULL is returned.
|
||||
// Since message is a ref-counted you need to call Release() when you are done with the buffer.
|
||||
virtual IServiceNetworkMessage* ReceiveMsg() = 0;
|
||||
|
||||
// Checks if connection is still alive.
|
||||
// Returns false only if connection has been damaged beyond repair.
|
||||
virtual bool IsAlive() const = 0;
|
||||
|
||||
// Get number of messages sent by this connection so far
|
||||
virtual uint32 GetMessageSendCount() const = 0;
|
||||
|
||||
// Get number of messages received by this connection so far
|
||||
virtual uint32 GetMessageReceivedCount() const = 0;
|
||||
|
||||
// Get size of data sent by this connection so far
|
||||
virtual uint64 GetMessageSendDataSize() const = 0;
|
||||
|
||||
// Get size of data received by this connection so far
|
||||
virtual uint64 GetMessageReceivedDataSize() const = 0;
|
||||
|
||||
// Request connection to be closed but not before sending out all of the pending messages. Incoming messages are ignored.
|
||||
// Processing and sending the messages is done on the networking thread so this function will not block.
|
||||
// As an option, connection can be forcefully closed after given amount of time (in ms).
|
||||
virtual void FlushAndClose(const uint32 timeoutMs = kDefaultFlushTime) = 0;
|
||||
|
||||
// Synchronous wait for the connection to send all outgoing messages
|
||||
virtual void FlushAndWait() = 0;
|
||||
|
||||
// Request connection to be closed now. All pending messages are discarded.
|
||||
virtual void Close() = 0;
|
||||
|
||||
// Add reference (connection is an internally reference counted object)
|
||||
virtual void AddRef() = 0;
|
||||
|
||||
// Release reference
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// General listening socket (async)
|
||||
struct IServiceNetworkListener
|
||||
{
|
||||
protected:
|
||||
IServiceNetworkListener() {};
|
||||
virtual ~IServiceNetworkListener() {};
|
||||
|
||||
public:
|
||||
// Get the local address
|
||||
virtual const ServiceNetworkAddress& GetLocalAddress() const = 0;
|
||||
|
||||
// Get number of active connections handled by this listener
|
||||
virtual uint GetConnectionCount() const = 0;
|
||||
|
||||
// Accept incoming connection (asynchronously)
|
||||
// Will return NULL if there's nothing to accept
|
||||
// Will return new IDebugNetworkConnection if something was received
|
||||
virtual IServiceNetworkConnection* Accept() = 0;
|
||||
|
||||
// Is listener able to accept connections ?
|
||||
virtual bool IsAlive() const = 0;
|
||||
|
||||
// Request listener to be closed (closes the socket)
|
||||
virtual void Close() = 0;
|
||||
|
||||
// Add reference (listener is an internally reference counted object)
|
||||
virtual void AddRef() = 0;
|
||||
|
||||
// Release reference
|
||||
virtual void Release() = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// General service (background) network interface
|
||||
struct IServiceNetwork
|
||||
{
|
||||
public:
|
||||
virtual ~IServiceNetwork() {};
|
||||
|
||||
// Set verbosity level of debug messages that got printed to log, levels 0-3 are commonly used
|
||||
virtual void SetVerbosityLevel(const uint32 level) = 0;
|
||||
|
||||
// Allocate empty message buffer of given size, message buffer is a reference counted object
|
||||
virtual IServiceNetworkMessage* AllocMessageBuffer(const uint32 size) = 0;
|
||||
|
||||
// Create general message writer stream, object is not reference counted
|
||||
virtual struct IDataWriteStream* CreateMessageWriter() = 0;
|
||||
|
||||
// Create general message reader stream and initialize it with data
|
||||
virtual struct IDataReadStream* CreateMessageReader(const void* pData, const uint32 dataSize) = 0;
|
||||
|
||||
// Translate host address (string:port) to network address
|
||||
virtual ServiceNetworkAddress GetHostAddress(const string& addressString, uint16 optionalPort = 0) const = 0;
|
||||
|
||||
// Create network listener on given local port, listening and accepting connections is done on network thread
|
||||
virtual IServiceNetworkListener* CreateListener(uint16 localPort) = 0;
|
||||
|
||||
// Connect to remote address (will block until connection is made or refused)
|
||||
virtual IServiceNetworkConnection* Connect(const ServiceNetworkAddress& remoteAddress) = 0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_ISERVICENETWORK_H
|
||||
@@ -91,7 +91,6 @@ struct IAVI_Reader;
|
||||
class CPNoise3;
|
||||
struct IVisualLog;
|
||||
struct ILocalizationManager;
|
||||
struct ICryFactoryRegistry;
|
||||
struct ISoftCodeMgr;
|
||||
struct IZLibCompressor;
|
||||
struct IZLibDecompressor;
|
||||
@@ -99,8 +98,6 @@ struct ILZ4Decompressor;
|
||||
class IZStdDecompressor;
|
||||
struct IOutputPrintSink;
|
||||
struct IThreadManager;
|
||||
struct IServiceNetwork;
|
||||
struct IRemoteCommandManager;
|
||||
struct IWindowMessageHandler;
|
||||
struct IImageHandler;
|
||||
class IResourceCompilerHelper;
|
||||
@@ -798,8 +795,6 @@ struct SSystemGlobalEnvironment
|
||||
IRenderer* pRenderer;
|
||||
IMaterialEffects* pMaterialEffects;
|
||||
ISoftCodeMgr* pSoftCodeMgr;
|
||||
IServiceNetwork* pServiceNetwork;
|
||||
IRemoteCommandManager* pRemoteCommandManager;
|
||||
ILyShine* pLyShine;
|
||||
IResourceCompilerHelper* pResourceCompilerHelper;
|
||||
SharedEnvironmentInstance* pSharedEnvironment;
|
||||
@@ -1244,10 +1239,6 @@ struct ISystem
|
||||
// Retrieves access to XML utilities interface.
|
||||
virtual IXmlUtils* GetXmlUtils() = 0;
|
||||
|
||||
// Summary:
|
||||
// Interface to access different implementations of Serialization::IArchive in a centralized way.
|
||||
virtual Serialization::IArchiveHost* GetArchiveHost() const = 0;
|
||||
|
||||
virtual void SetViewCamera(CCamera& Camera) = 0;
|
||||
virtual CCamera& GetViewCamera() = 0;
|
||||
|
||||
@@ -1368,10 +1359,6 @@ struct ISystem
|
||||
// Retrieves system update counter.
|
||||
virtual uint64 GetUpdateCounter() = 0;
|
||||
|
||||
// Summary:
|
||||
// Gets access to all registered factories.
|
||||
virtual ICryFactoryRegistry* GetCryFactoryRegistry() const = 0;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Error callback handling
|
||||
|
||||
@@ -1491,15 +1478,6 @@ struct ISystem
|
||||
|
||||
virtual const IImageHandler* GetImageHandler() const = 0;
|
||||
|
||||
// Summary:
|
||||
// Loads a dynamic library, creates and initializes an instance of the module class
|
||||
|
||||
virtual bool InitializeEngineModule(const char* dllName, const char* moduleClassName, const SSystemInitParams& initParams) = 0;
|
||||
|
||||
// Summary:
|
||||
// Unloads a dynamic library as well as the corresponding instance of the module class
|
||||
virtual bool UnloadEngineModule(const char* dllName, const char* moduleClassName) = 0;
|
||||
|
||||
// Summary:
|
||||
// Gets the root window message handler function
|
||||
// The returned pointer is platform-specific:
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#define CRYINCLUDE_CRYCOMMON_ICONSOLEMOCK_H
|
||||
#pragma once
|
||||
|
||||
#include <IRemoteCommand.h>
|
||||
#include <IConsole.h>
|
||||
#include <AzTest/AzTest.h>
|
||||
|
||||
|
||||
@@ -164,8 +164,6 @@ public:
|
||||
XmlNodeRef(const char*, bool));
|
||||
MOCK_METHOD0(GetXmlUtils,
|
||||
IXmlUtils * ());
|
||||
MOCK_CONST_METHOD0(GetArchiveHost,
|
||||
Serialization::IArchiveHost * ());
|
||||
MOCK_METHOD1(SetViewCamera,
|
||||
void(CCamera & Camera));
|
||||
MOCK_METHOD0(GetViewCamera,
|
||||
@@ -223,8 +221,6 @@ public:
|
||||
CPNoise3 * ());
|
||||
MOCK_METHOD0(GetUpdateCounter,
|
||||
uint64());
|
||||
MOCK_CONST_METHOD0(GetCryFactoryRegistry,
|
||||
ICryFactoryRegistry * ());
|
||||
MOCK_METHOD1(RegisterErrorObserver,
|
||||
bool(IErrorObserver * errorObserver));
|
||||
MOCK_METHOD1(UnregisterErrorObserver,
|
||||
@@ -287,10 +283,6 @@ public:
|
||||
bool());
|
||||
MOCK_CONST_METHOD0(GetImageHandler,
|
||||
const IImageHandler * ());
|
||||
MOCK_METHOD3(InitializeEngineModule,
|
||||
bool(const char* dllName, const char* moduleClassName, const SSystemInitParams&initParams));
|
||||
MOCK_METHOD2(UnloadEngineModule,
|
||||
bool(const char* dllName, const char* moduleClassName));
|
||||
MOCK_METHOD0(GetRootWindowMessageHandler,
|
||||
void*());
|
||||
MOCK_METHOD1(RegisterWindowMessageHandler,
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H
|
||||
#pragma once
|
||||
|
||||
#ifdef SERIALIZATION_STANDALONE
|
||||
#include <assert.h>
|
||||
#else
|
||||
#include <platform.h>
|
||||
#endif
|
||||
|
||||
#ifdef YASLI_ASSERT
|
||||
# undef YASLI_ASSERT
|
||||
#endif
|
||||
|
||||
#ifdef YASLI_VERIFY
|
||||
# undef YASLI_VERIFY
|
||||
#endif
|
||||
|
||||
#ifdef YASLI_ESCAPE
|
||||
# undef YASLI_ESCAPE
|
||||
#endif
|
||||
|
||||
#ifdef SERIALIZATION_STANDALONE
|
||||
#define YASLI_ASSERT(x) assert(x)
|
||||
#define YASLI_ASSERT_STR(x, str) assert(x && str)
|
||||
#define YASLI_ESCAPE(x, action) if (!(x)) { YASLI_ASSERT(0 && #x); action; };
|
||||
#else
|
||||
#define YASLI_ASSERT(x) CRY_ASSERT(x)
|
||||
#define YASLI_ASSERT_STR(x, str) CRY_ASSERT_MESSAGE(x, str)
|
||||
#define YASLI_ESCAPE(x, action) if (!(x)) { YASLI_ASSERT(0 && #x); action; };
|
||||
#endif // SERIALIZATION_STANDALONE
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_ASSERT_H
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) 2012 Crytek GmbH
|
||||
// Authors: Evgeny Andreeshchev, Alexander Kotliar
|
||||
// Based on: Yasli - the serialization library.
|
||||
// Modifications copyright Amazon.com, Inc. or its affiliates
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace Serialization{
|
||||
|
||||
class IArchive;
|
||||
template<class Enum>
|
||||
class BitVector
|
||||
{
|
||||
public:
|
||||
BitVector(int value = 0) : value_(value) {}
|
||||
|
||||
operator int&() { return value_; }
|
||||
operator int() const { return value_; }
|
||||
|
||||
BitVector& operator|= (Enum value) { value_ |= value; return *this; }
|
||||
BitVector& operator|= (int value) { value_ |= value; return *this; }
|
||||
BitVector& operator&= (int value) { value_ &= value; return *this; }
|
||||
|
||||
void Serialize(IArchive& ar);
|
||||
private:
|
||||
int value_;
|
||||
};
|
||||
|
||||
template<class Enum>
|
||||
bool Serialize(Serialization::IArchive& ar, Serialization::BitVector<Enum>& value, const char* name, const char* label);
|
||||
|
||||
}
|
||||
|
||||
#include "BitVectorImpl.h"
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTOR_H
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "Serialization/BitVector.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/Enum.h"
|
||||
|
||||
namespace Serialization {
|
||||
struct BitVectorWrapper
|
||||
{
|
||||
int* valuePointer;
|
||||
int value;
|
||||
const CEnumDescription* description;
|
||||
|
||||
explicit BitVectorWrapper(int* _value = 0, const CEnumDescription* _description = 0)
|
||||
: valuePointer(_value)
|
||||
, description(_description)
|
||||
{
|
||||
if (valuePointer)
|
||||
{
|
||||
value = *valuePointer;
|
||||
}
|
||||
}
|
||||
BitVectorWrapper(const BitVectorWrapper& _rhs)
|
||||
: value(_rhs.value)
|
||||
, description(0)
|
||||
, valuePointer(0)
|
||||
{
|
||||
}
|
||||
|
||||
~BitVectorWrapper()
|
||||
{
|
||||
if (valuePointer)
|
||||
{
|
||||
* valuePointer = value;
|
||||
}
|
||||
}
|
||||
BitVectorWrapper& operator=(const BitVectorWrapper& rhs)
|
||||
{
|
||||
value = rhs.value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void Serialize(IArchive& ar)
|
||||
{
|
||||
ar(value, "value", "Value");
|
||||
}
|
||||
};
|
||||
|
||||
template<class Enum>
|
||||
void BitVector<Enum>::Serialize(IArchive& ar)
|
||||
{
|
||||
ar(value_, "value", "Value");
|
||||
}
|
||||
}
|
||||
|
||||
template<class Enum>
|
||||
bool Serialize(Serialization::IArchive& ar, Serialization::BitVector<Enum>& value, const char* name, const char* label)
|
||||
{
|
||||
using namespace Serialization;
|
||||
CEnumDescription& desc = getEnumDescription<Enum>();
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(BitVectorWrapper(&static_cast<int&>(value), &desc), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
return desc.serializeBitVector(ar, static_cast<int&>(value), name, label);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BITVECTORIMPL_H
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h> // for malloc and free
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
// Black box is used to store opaque data blobs in a format internal to
|
||||
// specific Archive. For example it can be used to store sections of the JSON
|
||||
// or binary archive.
|
||||
//
|
||||
// This is useful for the Editor to store portions of files with unfamiliar
|
||||
// structure.
|
||||
//
|
||||
// We store deallocation function here so we can safely pass the blob
|
||||
// across DLLs with different memory allocators.
|
||||
struct SBlackBox
|
||||
{
|
||||
const char* format;
|
||||
void* data;
|
||||
size_t size;
|
||||
typedef void(* FreeFunction)(void*);
|
||||
FreeFunction freeFunction;
|
||||
|
||||
SBlackBox()
|
||||
: format("")
|
||||
, data(0)
|
||||
, size(0)
|
||||
, freeFunction(0)
|
||||
{
|
||||
}
|
||||
|
||||
SBlackBox(const SBlackBox& rhs)
|
||||
: format("")
|
||||
, data(0)
|
||||
, size(0)
|
||||
, freeFunction(0)
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
void set(const char* _format, const void* _data, size_t _size)
|
||||
{
|
||||
if (_data && freeFunction)
|
||||
{
|
||||
freeFunction(this->data);
|
||||
this->data = 0;
|
||||
this->size = 0;
|
||||
freeFunction = 0;
|
||||
}
|
||||
this->format = _format;
|
||||
if (_data && _size)
|
||||
{
|
||||
this->data = CryModuleMalloc(_size);
|
||||
memcpy(this->data, _data, _size);
|
||||
this->size = _size;
|
||||
freeFunction = &Free;
|
||||
}
|
||||
}
|
||||
|
||||
SBlackBox& operator=(const SBlackBox& rhs)
|
||||
{
|
||||
set(rhs.format, rhs.data, rhs.size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~SBlackBox()
|
||||
{
|
||||
set("", 0, 0);
|
||||
}
|
||||
|
||||
static void Free(void* ptr)
|
||||
{
|
||||
CryModuleFree(ptr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_BLACKBOX_H
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Serialization/Serializer.h>
|
||||
|
||||
#include "ClassFactory.h"
|
||||
|
||||
template <class T>
|
||||
class BoostSharedPtrSerializer
|
||||
: public Serialization::IPointer
|
||||
{
|
||||
public:
|
||||
BoostSharedPtrSerializer(AZStd::shared_ptr<T>& ptr)
|
||||
: m_ptr(ptr)
|
||||
{
|
||||
}
|
||||
|
||||
const char* registeredTypeName() const override
|
||||
{
|
||||
if (m_ptr)
|
||||
{
|
||||
return factoryOverride().getRegisteredTypeName(m_ptr.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void create(const char* registeredTypeName) const override
|
||||
{
|
||||
CRY_ASSERT(!m_ptr || m_ptr.use_count() == 1);
|
||||
if (registeredTypeName && registeredTypeName[0] != '\0')
|
||||
{
|
||||
m_ptr.reset(factoryOverride().create(registeredTypeName));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ptr.reset();
|
||||
}
|
||||
}
|
||||
|
||||
Serialization::TypeID baseType() const override
|
||||
{
|
||||
return Serialization::TypeID::get<T>();
|
||||
}
|
||||
|
||||
virtual Serialization::SStruct serializer() const override
|
||||
{
|
||||
return Serialization::SStruct(*m_ptr);
|
||||
}
|
||||
|
||||
void* get() const
|
||||
{
|
||||
return reinterpret_cast<void*>(m_ptr.get());
|
||||
}
|
||||
|
||||
const void* handle() const
|
||||
{
|
||||
return &m_ptr;
|
||||
}
|
||||
|
||||
Serialization::TypeID pointerType() const override
|
||||
{
|
||||
return Serialization::TypeID::get<AZStd::shared_ptr<T> >();
|
||||
}
|
||||
|
||||
Serialization::ClassFactory<T>* factory() const override
|
||||
{
|
||||
return &factoryOverride();
|
||||
}
|
||||
|
||||
virtual Serialization::ClassFactory<T>& factoryOverride() const
|
||||
{
|
||||
return Serialization::ClassFactory<T>::the();
|
||||
}
|
||||
|
||||
protected:
|
||||
AZStd::shared_ptr<T>& m_ptr;
|
||||
};
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
template <class T>
|
||||
bool Serialize(Serialization::IArchive& ar, AZStd::shared_ptr<T>& ptr, const char* name, const char* label)
|
||||
{
|
||||
BoostSharedPtrSerializer<T> serializer(ptr);
|
||||
return ar(static_cast<Serialization::IPointer&>(serializer), name, label);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H
|
||||
#pragma once
|
||||
|
||||
template <uint32 StoreStrings, typename THash>
|
||||
struct SCRCRef;
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
class IArchive;
|
||||
}
|
||||
|
||||
template <uint32 StoreStrings, typename THash>
|
||||
bool Serialize(Serialization::IArchive& ar, SCRCRef<StoreStrings, THash>& crcRef, const char* name, const char* label);
|
||||
|
||||
#include "CRCRefImpl.h"
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREF_H
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "Serializer.h"
|
||||
|
||||
template <typename TCRCRef>
|
||||
class CRCRefSerializer
|
||||
: public Serialization::IString
|
||||
{
|
||||
public:
|
||||
CRCRefSerializer(TCRCRef& crcRef)
|
||||
: m_crcRef(crcRef)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void set(const char* value)
|
||||
{
|
||||
m_crcRef.SetByString(value);
|
||||
}
|
||||
|
||||
virtual const char* get() const
|
||||
{
|
||||
return m_crcRef.c_str();
|
||||
}
|
||||
|
||||
const void* handle() const
|
||||
{
|
||||
return &m_crcRef;
|
||||
}
|
||||
|
||||
Serialization::TypeID type() const
|
||||
{
|
||||
return Serialization::TypeID::get<TCRCRef>();
|
||||
}
|
||||
|
||||
|
||||
TCRCRef& m_crcRef;
|
||||
};
|
||||
|
||||
|
||||
template <uint32 StoreStrings, typename THash>
|
||||
class CCRCRefSerializerNoStrings
|
||||
{
|
||||
public:
|
||||
CCRCRefSerializerNoStrings(struct SCRCRef<StoreStrings, THash>& crcRef)
|
||||
: crc(crcRef.crc)
|
||||
{
|
||||
}
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
return ar(crc, "CRC", "CRC");
|
||||
}
|
||||
|
||||
typedef typename THash::TInt TInt;
|
||||
TInt& crc;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template <uint32 StoreStrings, typename THash>
|
||||
bool Serialize(Serialization::IArchive& ar, struct SCRCRef<StoreStrings, THash>& crcRef, const char* name, const char* label)
|
||||
{
|
||||
if (StoreStrings == 0)
|
||||
{
|
||||
if (ar.IsInput())
|
||||
{
|
||||
SCRCRef<StoreStrings, THash> crcCopy;
|
||||
ar(CCRCRefSerializerNoStrings<StoreStrings, THash>(crcCopy), name, label);
|
||||
if (crcCopy.crc != THash::INVALID)
|
||||
{
|
||||
crcRef = crcCopy;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (ar.IsOutput())
|
||||
{
|
||||
return ar(CCRCRefSerializerNoStrings<StoreStrings, THash>(crcRef), name, label);
|
||||
}
|
||||
}
|
||||
|
||||
CRCRefSerializer<SCRCRef<StoreStrings, THash> > crcRefSerializer(crcRef);
|
||||
return ar(static_cast<Serialization::IString&>(crcRefSerializer), name, label);
|
||||
}
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRCREFIMPL_H
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
struct ICallback
|
||||
{
|
||||
virtual bool SerializeValue(IArchive& ar, const char* name, const char* value) = 0;
|
||||
virtual ICallback* Clone() = 0;
|
||||
virtual void Release() = 0;
|
||||
virtual TypeID Type() const = 0;
|
||||
|
||||
typedef AZStd::function<void(void*, const TypeID&)> ApplyFunction;
|
||||
virtual void Call(const ApplyFunction&) = 0;
|
||||
};
|
||||
|
||||
template<class T, class Decorator = T>
|
||||
struct CallbackSimple
|
||||
: ICallback
|
||||
{
|
||||
typedef AZStd::function<void(const T&)> CallbackFunction;
|
||||
T* value;
|
||||
T oldValue;
|
||||
CallbackFunction callback;
|
||||
|
||||
CallbackSimple(T* value, const T& oldValue, const AZStd::function<void(const T&)>& callback)
|
||||
: value(value)
|
||||
, oldValue(oldValue)
|
||||
, callback(callback)
|
||||
{
|
||||
}
|
||||
|
||||
ICallback* Clone() { return new CallbackSimple<T>(0, oldValue, callback); }
|
||||
void Release() { delete this; }
|
||||
bool SerializeValue(IArchive& ar, const char* name, const char* label) { return ar(*value, name, label); }
|
||||
TypeID Type() const{ return TypeID::get<T>(); }
|
||||
|
||||
void Call(const ApplyFunction& applyFunction)
|
||||
{
|
||||
T newValue;
|
||||
applyFunction((void*)&newValue, TypeID::get<T>());
|
||||
if (oldValue != newValue)
|
||||
{
|
||||
callback(newValue);
|
||||
oldValue = newValue;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class Decorator = T>
|
||||
struct CallbackWithDecorator
|
||||
: ICallback
|
||||
{
|
||||
typedef AZStd::function<void(const T&)> CallbackFunction;
|
||||
typedef AZStd::function<Decorator (T&)> DecoratorFunction;
|
||||
|
||||
T oldValue;
|
||||
T* value;
|
||||
CallbackFunction callback;
|
||||
DecoratorFunction decorator;
|
||||
|
||||
CallbackWithDecorator(T* value,
|
||||
const T& oldValue,
|
||||
const CallbackFunction& callback,
|
||||
const DecoratorFunction& decorator)
|
||||
: value(value)
|
||||
, oldValue(oldValue)
|
||||
, callback(callback)
|
||||
, decorator(decorator)
|
||||
{
|
||||
}
|
||||
|
||||
ICallback* Clone() { return new CallbackWithDecorator<T, Decorator>(0, oldValue, callback, decorator); }
|
||||
void Release() { delete this; }
|
||||
bool SerializeValue(IArchive& ar, const char* name, const char* label) { return ar(decorator(*value), name, label); }
|
||||
TypeID Type() const{ return TypeID::get<Decorator>(); }
|
||||
|
||||
void Call(const ApplyFunction& applyFunction)
|
||||
{
|
||||
T newValue;
|
||||
Decorator dec = decorator(newValue);
|
||||
applyFunction((void*)&dec, TypeID::get<Decorator>());
|
||||
if (oldValue != newValue)
|
||||
{
|
||||
callback(newValue);
|
||||
oldValue = newValue;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
template <typename T>
|
||||
struct MethodReturnType
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename ClassType, typename ReturnType, typename Arg0>
|
||||
struct MethodReturnType<ReturnType(ClassType::*)(Arg0) const>
|
||||
{
|
||||
typedef ReturnType type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct OperatorBracketsReturnType
|
||||
{
|
||||
typedef typename MethodReturnType<decltype(& T::operator())>::type Type;
|
||||
};
|
||||
}
|
||||
|
||||
template<class T, class CallbackFunc>
|
||||
CallbackSimple<T>
|
||||
Callback(T& value, const CallbackFunc& callback)
|
||||
{
|
||||
return CallbackSimple<T>(&value, value, AZStd::function<void(const T&)>(callback));
|
||||
}
|
||||
|
||||
|
||||
template<class T, class CallbackFunc, class DecoratorFunc>
|
||||
CallbackWithDecorator<T, typename Detail::OperatorBracketsReturnType<DecoratorFunc>::Type>
|
||||
Callback(T& value, const CallbackFunc& callback, const DecoratorFunc& decorator)
|
||||
{
|
||||
typedef typename Detail::OperatorBracketsReturnType<DecoratorFunc>::Type Decorator;
|
||||
return CallbackWithDecorator<T, Decorator>(&value, value,
|
||||
AZStd::function<void(const T&)>(callback),
|
||||
AZStd::function<Decorator(T&)>(decorator));
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Serialize(IArchive& ar, CallbackSimple<T>& callback, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(static_cast<ICallback&>(callback), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ar(*callback.value, name, label))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class Decorator>
|
||||
bool Serialize(IArchive& ar, CallbackWithDecorator<T, Decorator>& callback, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(static_cast<ICallback&>(callback), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ar(*callback.value, name, label))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CALLBACK_H
|
||||
@@ -1,376 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "Serialization/Assert.h"
|
||||
#include "Serialization/IClassFactory.h"
|
||||
#include "Serialization/TypeID.h"
|
||||
|
||||
namespace Serialization {
|
||||
class IArchive;
|
||||
|
||||
class ClassFactoryManager
|
||||
{
|
||||
public:
|
||||
static ClassFactoryManager& the()
|
||||
{
|
||||
static ClassFactoryManager factoryManager;
|
||||
return factoryManager;
|
||||
}
|
||||
|
||||
const IClassFactory* find(TypeID baseType) const
|
||||
{
|
||||
lazyRegisterFactories();
|
||||
Factories::const_iterator it = factories_.find(baseType);
|
||||
if (it == factories_.end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void registerFactory([[maybe_unused]] TypeID type, IClassFactory* factory)
|
||||
{
|
||||
factory->m_next = m_head;
|
||||
m_head = factory;
|
||||
}
|
||||
protected:
|
||||
void lazyRegisterFactories() const
|
||||
{
|
||||
if (m_head)
|
||||
{
|
||||
IClassFactory* factory = m_head;
|
||||
while (factory)
|
||||
{
|
||||
const_cast<ClassFactoryManager*>(this)->factories_[factory->baseType_] = factory;
|
||||
factory = factory->m_next;
|
||||
}
|
||||
const_cast<ClassFactoryManager*>(this)->m_head = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
typedef AZStd::unordered_map<TypeID, const IClassFactory*, AZStd::hash<TypeID>, AZStd::equal_to<TypeID>, AZ::StdLegacyAllocator> Factories;
|
||||
Factories factories_;
|
||||
IClassFactory* m_head = nullptr;
|
||||
};
|
||||
|
||||
template<class BaseType>
|
||||
class ClassFactory
|
||||
: public IClassFactory
|
||||
{
|
||||
public:
|
||||
static ClassFactory& the()
|
||||
{
|
||||
static AZStd::aligned_storage_for_t<ClassFactory> storage;
|
||||
if (s_instance != (decltype(s_instance))&storage)
|
||||
{
|
||||
s_instance = new(&storage) ClassFactory();
|
||||
}
|
||||
return *s_instance;
|
||||
}
|
||||
|
||||
static void destroy()
|
||||
{
|
||||
if (s_instance)
|
||||
{
|
||||
s_instance->~ClassFactory();
|
||||
s_instance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
class CreatorBase
|
||||
{
|
||||
public:
|
||||
virtual ~CreatorBase() {}
|
||||
virtual BaseType* create() const = 0;
|
||||
virtual const TypeDescription& description() const{ return *description_; }
|
||||
virtual void* vptr() const { return vptr_; }
|
||||
virtual TypeID typeID() const = 0;
|
||||
protected:
|
||||
const TypeDescription* description_ = nullptr;
|
||||
void* vptr_ = nullptr;
|
||||
public:
|
||||
CreatorBase* next;
|
||||
};
|
||||
|
||||
static void* extractVPtr(BaseType* ptr)
|
||||
{
|
||||
return *((void**)ptr);
|
||||
}
|
||||
|
||||
template<class Derived>
|
||||
struct Annotation
|
||||
{
|
||||
Annotation(IClassFactory* factory, const char* name, const char* value) { static_cast<ClassFactory<BaseType>*>(factory)->addAnnotation<Derived>(name, value); }
|
||||
};
|
||||
|
||||
template<class Derived>
|
||||
class Creator
|
||||
: public CreatorBase
|
||||
{
|
||||
public:
|
||||
Creator(const TypeDescription* description, ClassFactory* factory = nullptr)
|
||||
{
|
||||
this->description_ = description;
|
||||
|
||||
if (!factory)
|
||||
{
|
||||
factory = &ClassFactory::the();
|
||||
}
|
||||
|
||||
factory->registerCreator(this);
|
||||
}
|
||||
|
||||
void* vptr() const override
|
||||
{
|
||||
if (!this->vptr_)
|
||||
{
|
||||
Derived vptrProbe;
|
||||
const_cast<Creator*>(this)->vptr_ = extractVPtr(&vptrProbe);
|
||||
}
|
||||
return this->vptr_;
|
||||
}
|
||||
|
||||
BaseType* create() const override { return new Derived(); }
|
||||
TypeID typeID() const override { return Serialization::TypeID::get<Derived>(); }
|
||||
};
|
||||
|
||||
ClassFactory()
|
||||
: IClassFactory(TypeID::get<BaseType>())
|
||||
{
|
||||
ClassFactoryManager::the().registerFactory(baseType_, this);
|
||||
}
|
||||
|
||||
~ClassFactory()
|
||||
{
|
||||
m_data->~Data();
|
||||
m_data = nullptr;
|
||||
}
|
||||
|
||||
typedef AZStd::unordered_map<string, const CreatorBase*, AZStd::hash<string>, AZStd::equal_to<string>, AZ::StdLegacyAllocator> TypeToCreatorMap;
|
||||
typedef AZStd::unordered_map<void*, CreatorBase*, AZStd::hash<void*>, AZStd::equal_to<void*>, AZ::StdLegacyAllocator> VPtrToCreatorMap;
|
||||
typedef AZStd::unordered_map<string, TypeID, AZStd::hash<string>, AZStd::equal_to<string>, AZ::StdLegacyAllocator> RegisteredNameToTypeID;
|
||||
typedef AZStd::unordered_map<TypeID, std::vector<std::pair<const char*, const char*> >, AZStd::hash<TypeID>, AZStd::equal_to<TypeID>, AZ::StdLegacyAllocator> AnnotationMap;
|
||||
|
||||
virtual BaseType* create(const char* registeredName) const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
if (!registeredName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (registeredName[0] == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
typename TypeToCreatorMap::const_iterator it = m_data->typeToCreatorMap_.find(registeredName);
|
||||
if (it != m_data->typeToCreatorMap_.end())
|
||||
{
|
||||
return it->second->create();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char* getRegisteredTypeName(BaseType* ptr) const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
if (ptr == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
void* vptr = extractVPtr(ptr);
|
||||
typename VPtrToCreatorMap::const_iterator it = m_data->vptrToCreatorMap_.find(vptr);
|
||||
if (it == m_data->vptrToCreatorMap_.end())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return it->second->description().name();
|
||||
}
|
||||
|
||||
BaseType* createByIndex(int index) const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
YASLI_ASSERT(size_t(index) < m_data->creators_.size());
|
||||
return m_data->creators_[index]->create();
|
||||
}
|
||||
|
||||
void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label)
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
YASLI_ESCAPE(size_t(index) < m_data->creators_.size(), return );
|
||||
BaseType* ptr = m_data->creators_[index]->create();
|
||||
ar(*ptr, name, label);
|
||||
delete ptr;
|
||||
}
|
||||
// from ClassFactoryInterface:
|
||||
size_t size() const{ return m_data->creators_.size(); }
|
||||
const TypeDescription* descriptionByIndex(int index) const override
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
if (size_t(index) >= int(m_data->creators_.size()))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return &m_data->creators_[index]->description();
|
||||
}
|
||||
|
||||
const TypeDescription* descriptionByRegisteredName(const char* name) const override
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
const size_t numCreators = m_data->creators_.size();
|
||||
for (size_t i = 0; i < numCreators; ++i)
|
||||
{
|
||||
if (strcmp(m_data->creators_[i]->description().name(), name) == 0)
|
||||
{
|
||||
return &m_data->creators_[i]->description();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// ^^^
|
||||
|
||||
TypeID typeIDByRegisteredName(const char* registeredTypeName) const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
RegisteredNameToTypeID::const_iterator it = m_data->registeredNameToTypeID_.find(registeredTypeName);
|
||||
if (it == m_data->registeredNameToTypeID_.end())
|
||||
{
|
||||
return TypeID();
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const char* findAnnotation(const char* registeredTypeName, const char* name) const
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
TypeID typeID = typeIDByRegisteredName(registeredTypeName);
|
||||
AnnotationMap::const_iterator it = m_data->annotations_.find(typeID);
|
||||
if (it == m_data->annotations_.end())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
for (size_t i = 0; i < it->second.size(); ++i)
|
||||
{
|
||||
if (strcmp(it->second[i].first, name) == 0)
|
||||
{
|
||||
return it->second[i].second;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
void unregisterCreator(const TypeDescription& typeDescription)
|
||||
{
|
||||
auto creator = m_data->typeToCreatorMap_.find(typeDescription.name());
|
||||
if (creator != m_data->typeToCreatorMap_.end())
|
||||
{
|
||||
m_data->creators_.erase(std::find(m_data->creators_.begin(), m_data->creators_.end(), m_data->creator->second));
|
||||
m_data->vptrToCreatorMap_.erase(m_data->vptrToCreatorMap_.find(creator->second->vptr()));
|
||||
m_data->typeToCreatorMap_.erase(creator);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void registerCreator(CreatorBase* creator)
|
||||
{
|
||||
creator->next = creatorsList;
|
||||
creatorsList = creator;
|
||||
}
|
||||
|
||||
void lazyRegisterCreators() const
|
||||
{
|
||||
if (!m_data)
|
||||
{
|
||||
const_cast<ClassFactory*>(this)->m_data = ::new((void*)&m_dataStorage) Data();
|
||||
for (CreatorBase* creator = creatorsList; creator; creator = creator->next)
|
||||
{
|
||||
if (!const_cast<ClassFactory*>(this)->m_data->typeToCreatorMap_.insert(AZStd::make_pair(creator->description().name(), creator)).second)
|
||||
{
|
||||
YASLI_ASSERT(0 && "Type registered twice in the same factory. Was SERIALIZATION_CLASS_NAME put into header file by mistake?");
|
||||
}
|
||||
const_cast<ClassFactory*>(this)->m_data->creators_.push_back(creator);
|
||||
const_cast<ClassFactory*>(this)->m_data->registeredNameToTypeID_[creator->description().name()] = creator->typeID();
|
||||
const_cast<ClassFactory*>(this)->m_data->vptrToCreatorMap_[creator->vptr()] = creator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void addAnnotation(const char* name, const char* value)
|
||||
{
|
||||
addAnnotation(Serialization::TypeID::get<T>(), name, value);
|
||||
}
|
||||
|
||||
virtual void addAnnotation(const Serialization::TypeID& id, const char* name, const char* value)
|
||||
{
|
||||
lazyRegisterCreators();
|
||||
m_data->annotations_[id].push_back(std::make_pair(name, value));
|
||||
}
|
||||
|
||||
CreatorBase* creatorsList = nullptr;
|
||||
static ClassFactory* s_instance;
|
||||
|
||||
struct Data
|
||||
{
|
||||
TypeToCreatorMap typeToCreatorMap_;
|
||||
AZStd::vector<CreatorBase*, AZ::StdLegacyAllocator> creators_;
|
||||
VPtrToCreatorMap vptrToCreatorMap_;
|
||||
RegisteredNameToTypeID registeredNameToTypeID_;
|
||||
AnnotationMap annotations_;
|
||||
};
|
||||
Data* m_data = nullptr;
|
||||
AZStd::aligned_storage_for_t<Data> m_dataStorage;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
ClassFactory<T>* ClassFactory<T>::s_instance = nullptr;
|
||||
}
|
||||
|
||||
#define SERIALIZATION_CLASS_NULL(BaseType, name) \
|
||||
namespace { \
|
||||
bool BaseType##_NullRegistered = Serialization::ClassFactory<BaseType>::the().setNullLabel(name); \
|
||||
}
|
||||
|
||||
#define SERIALIZATION_CLASS_NAME(BaseType, Type, name, label) \
|
||||
static const Serialization::TypeDescription Type##BaseType##_DerivedDescription(name, label); \
|
||||
static Serialization::ClassFactory<BaseType>::Creator<Type> Type##BaseType##_Creator(&Type##BaseType##_DerivedDescription); \
|
||||
int dummyForType_##Type##BaseType;
|
||||
|
||||
#define SERIALIZATION_CLASS_NAME_FOR_FACTORY(Factory, BaseType, Type, name, label) \
|
||||
static const Serialization::TypeDescription Type##BaseType##_DerivedDescription(name, label); \
|
||||
static Serialization::ClassFactory<BaseType>::Creator<Type> Type##BaseType##_Creator(&Type##BaseType##_DerivedDescription, &(Factory));
|
||||
|
||||
#define SERIALIZATION_CLASS_ANNOTATION(BaseType, Type, attributeName, attributeValue) \
|
||||
static Serialization::ClassFactory<BaseType>::Annotation<Type> Type##BaseType##_Annotation(&Serialization::ClassFactory<BaseType>::the(), attributeName, attributeValue);
|
||||
|
||||
#define SERIALIZATION_CLASS_ANNOTATION_FOR_FACTORY(factory, BaseType, Type, attributeName, attributeValue) \
|
||||
static Serialization::ClassFactory<BaseType>::Annotation<Type> Type##BaseType##_Annotation(&factory, attributeName, attributeValue);
|
||||
|
||||
#define SERIALIZATION_FORCE_CLASS(BaseType, Type) \
|
||||
extern int dummyForType_##Type##BaseType; \
|
||||
int* dummyForTypePtr_##Type##BaseType = &dummyForType_##Type##BaseType + 1;
|
||||
|
||||
#include "ClassFactoryImpl.h"
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORY_H
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "IArchive.h"
|
||||
#include "IClassFactory.h"
|
||||
#include "STL.h"
|
||||
#include "ClassFactory.h"
|
||||
#include "Strings.h"
|
||||
|
||||
namespace Serialization {
|
||||
inline bool Serialize(Serialization::IArchive& ar, Serialization::TypeNameWithFactory& value, const char* name, [[maybe_unused]] const char* label)
|
||||
{
|
||||
if (!ar(value.registeredName, name))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ar.IsInput())
|
||||
{
|
||||
const TypeDescription* desc = value.factory->descriptionByRegisteredName(value.registeredName.c_str());
|
||||
if (!desc)
|
||||
{
|
||||
ar.Error(value, "Unable to read TypeID: unregistered type name: \'%s\'", value.registeredName.c_str());
|
||||
value.registeredName.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CLASSFACTORYIMPL_H
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H
|
||||
#pragma once
|
||||
|
||||
#include <Serialization/IArchive.h>
|
||||
#include <Serialization/Decorators/Range.h>
|
||||
|
||||
template<typename T>
|
||||
inline bool Serialize(Serialization::IArchive& ar, Color_tpl<T>& c, const char* name, const char* label);
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
struct Vec3AsColor
|
||||
{
|
||||
Vec3& v;
|
||||
Vec3AsColor(Vec3& v)
|
||||
: v(v) {}
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(Range(v.x, 0.0f, 1.0f), "r", "^");
|
||||
ar(Range(v.y, 0.0f, 1.0f), "g", "^");
|
||||
ar(Range(v.z, 0.0f, 1.0f), "b", "^");
|
||||
}
|
||||
};
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, Vec3AsColor& c, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(Serialization::SStruct(c), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef float (* Array)[3];
|
||||
return ar(*((Array) & c.v.x), name, label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "ColorImpl.h"
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLOR_H
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "Color.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template<typename T>
|
||||
struct SerializableColor_tpl
|
||||
: Color_tpl<T>
|
||||
{
|
||||
static float ColorRangeMin(float) { return 0.0f; }
|
||||
static float ColorRangeMax(float) { return 1.0f; }
|
||||
static unsigned char ColorRangeMin(unsigned char) { return 0; }
|
||||
static unsigned char ColorRangeMax(unsigned char) { return 255; }
|
||||
|
||||
void Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(Serialization::Range(Color_tpl<T>::r, ColorRangeMin(Color_tpl<T>::r), ColorRangeMax(Color_tpl<T>::r)), "r", "^");
|
||||
ar(Serialization::Range(Color_tpl<T>::g, ColorRangeMin(Color_tpl<T>::g), ColorRangeMax(Color_tpl<T>::g)), "g", "^");
|
||||
ar(Serialization::Range(Color_tpl<T>::b, ColorRangeMin(Color_tpl<T>::b), ColorRangeMax(Color_tpl<T>::b)), "b", "^");
|
||||
ar(Serialization::Range(Color_tpl<T>::a, ColorRangeMin(Color_tpl<T>::a), ColorRangeMax(Color_tpl<T>::a)), "a", "^");
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool Serialize(Serialization::IArchive& ar, Color_tpl<T>& c, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return Serialize(ar, static_cast<SerializableColor_tpl<T>&>(c), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
typedef T (& Array)[4];
|
||||
return ar((Array)c, name, label);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_COLORIMPL_H
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H
|
||||
#pragma once
|
||||
|
||||
#ifdef GetClassName
|
||||
#undef GetClassName
|
||||
#endif
|
||||
#include <CryExtension/ICryFactory.h>
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
// Allows to have AZStd::shared_ptr<TPointer> but serialize it by
|
||||
// interface-casting to TSerializable, i.e. implementing Serialization through
|
||||
// separate interface.
|
||||
template<class TPointer, class TSerializable = TPointer>
|
||||
struct CryExtensionPointer
|
||||
{
|
||||
AZStd::shared_ptr<TPointer>& ptr;
|
||||
|
||||
CryExtensionPointer(AZStd::shared_ptr<TPointer>& _ptr)
|
||||
: ptr(_ptr) {}
|
||||
void Serialize(Serialization::IArchive& ar);
|
||||
};
|
||||
}
|
||||
|
||||
// This function treats T as a type derived from CryUnknown type.
|
||||
template<class T>
|
||||
bool Serialize(Serialization::IArchive& ar, AZStd::shared_ptr<T>& ptr, const char* name, const char* label);
|
||||
|
||||
#include "CryExtensionImpl.h"
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSION_H
|
||||
@@ -1,281 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include <Serialization/StringList.h>
|
||||
#include <CryExtension/ICryFactoryRegistry.h>
|
||||
#include <CryExtension/CryTypeID.h>
|
||||
#include <ISystem.h>
|
||||
|
||||
namespace Serialization {
|
||||
// Generate user-friendly class name, e.g. convert
|
||||
// "AnimationPoseModifier_FootStore" -> "Foot Store"
|
||||
inline string MakePrettyClassName(const char* className)
|
||||
{
|
||||
const char* firstSep = strchr(className, '_');
|
||||
if (!firstSep)
|
||||
{
|
||||
// name doesn't follow expected convention, return as is
|
||||
return className;
|
||||
}
|
||||
|
||||
const char* start = firstSep + 1;
|
||||
string result;
|
||||
result.reserve(strlen(start) + 4);
|
||||
|
||||
const char* p = start;
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (*p >= 'A' && *p <= 'Z' &&
|
||||
*(p - 1) >= 'a' && *(p - 1) <= 'z')
|
||||
{
|
||||
result += ' ';
|
||||
}
|
||||
if (*p == '_')
|
||||
{
|
||||
result += ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
result += *p;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Provides Serialization::IClassFactory interface for classes
|
||||
// registered with CryExtension to IArchive.
|
||||
//
|
||||
// TSerializable can be used to expose Serialize method through
|
||||
// a separate interface, rathern than TBase. Safe to missing
|
||||
// as QueryInterface is used to check its presence.
|
||||
template<class TBase, class TSerializable = TBase>
|
||||
class CryExtensionClassFactory
|
||||
: public Serialization::IClassFactory
|
||||
{
|
||||
public:
|
||||
size_t size() const override
|
||||
{
|
||||
return m_types.size();
|
||||
}
|
||||
|
||||
static CryExtensionClassFactory& the()
|
||||
{
|
||||
static CryExtensionClassFactory instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
CryExtensionClassFactory()
|
||||
: IClassFactory(Serialization::TypeID::get<TBase>())
|
||||
{
|
||||
setNullLabel("[ None ]");
|
||||
ICryFactoryRegistry* factoryRegistry = gEnv->pSystem->GetCryFactoryRegistry();
|
||||
|
||||
size_t factoryCount = 0;
|
||||
factoryRegistry->IterateFactories(cryiidof<TBase>(), 0, factoryCount);
|
||||
|
||||
if (factoryCount)
|
||||
{
|
||||
string sharedPrefix;
|
||||
bool hasSharedPrefix = true;
|
||||
AZStd::unique_ptr<ICryFactory*[]> factories(new ICryFactory*[factoryCount]);
|
||||
factoryRegistry->IterateFactories(cryiidof<TBase>(), factories.get(), factoryCount);
|
||||
|
||||
for (size_t i = 0; i < factoryCount; ++i)
|
||||
{
|
||||
ICryFactory* factory = factories[i];
|
||||
if (factory->ClassSupports(cryiidof<TSerializable>()))
|
||||
{
|
||||
m_factories.push_back(factory);
|
||||
if (hasSharedPrefix)
|
||||
{
|
||||
// make sure that shared prefix is the same for all the names
|
||||
const char* name = factory->GetName();
|
||||
const char* lastPrefixCharacter = strchr(name, '_');
|
||||
if (lastPrefixCharacter == 0)
|
||||
{
|
||||
hasSharedPrefix = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sharedPrefix.empty())
|
||||
{
|
||||
if (strncmp(name, sharedPrefix.c_str(), sharedPrefix.size()) != 0)
|
||||
{
|
||||
hasSharedPrefix = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sharedPrefix.assign(name, lastPrefixCharacter + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t usableFactoriesCount = m_factories.size();
|
||||
m_types.reserve(usableFactoriesCount);
|
||||
m_labels.reserve(usableFactoriesCount);
|
||||
|
||||
for (size_t i = 0; i < usableFactoriesCount; ++i)
|
||||
{
|
||||
ICryFactory* factory = m_factories[i];
|
||||
m_classIds.push_back(factory->GetClassID());
|
||||
const char* name = factory->GetName();
|
||||
m_labels.push_back(MakePrettyClassName(name));
|
||||
if (hasSharedPrefix)
|
||||
{
|
||||
name += sharedPrefix.size();
|
||||
}
|
||||
m_types.push_back(Serialization::TypeDescription(name, m_labels.back().c_str()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Serialization::TypeDescription* descriptionByIndex(int index) const override
|
||||
{
|
||||
if (size_t(index) >= m_types.size())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return &m_types[index];
|
||||
}
|
||||
|
||||
const Serialization::TypeDescription* descriptionByRegisteredName(const char* registeredName) const override
|
||||
{
|
||||
size_t count = m_types.size();
|
||||
for (size_t i = 0; i < m_types.size(); ++i)
|
||||
{
|
||||
if (strcmp(m_types[i].name(), registeredName) == 0)
|
||||
{
|
||||
return &m_types[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* findAnnotation(const char* typeName, const char* name) const override { return ""; }
|
||||
|
||||
void serializeNewByIndex(IArchive& ar, int index, const char* name, const char* label) override
|
||||
{
|
||||
if (size_t(index) >= m_types.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
AZStd::shared_ptr<TBase> ptr(create(m_types[index].name()));
|
||||
if (TSerializable* ser = cryinterface_cast<TSerializable>(ptr.get()))
|
||||
{
|
||||
ar(*ser, name, label);
|
||||
}
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<TBase> create(const char* registeredName)
|
||||
{
|
||||
size_t count = m_types.size();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (strcmp(m_types[i].name(), registeredName) == 0)
|
||||
{
|
||||
return AZStd::static_pointer_cast<TBase>(m_factories[i]->CreateClassInstance());
|
||||
}
|
||||
}
|
||||
return AZStd::shared_ptr<TBase>();
|
||||
}
|
||||
|
||||
const char* getRegisteredTypeName(const AZStd::shared_ptr<TBase>& ptr) const
|
||||
{
|
||||
if (!ptr.get())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
CryInterfaceID id = AZStd::static_pointer_cast<TBase>(ptr)->GetFactory()->GetClassID();
|
||||
size_t count = m_classIds.size();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (m_classIds[i] == id)
|
||||
{
|
||||
return m_types[i].name();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Serialization::TypeDescription> m_types;
|
||||
std::vector<string> m_labels;
|
||||
std::vector<ICryFactory*> m_factories;
|
||||
std::vector<CryInterfaceID> m_classIds;
|
||||
};
|
||||
|
||||
// Exposes CryExtension shared_ptr<> as serializeable type for Serialization::IArchive
|
||||
template<class T, class TSerializable>
|
||||
class CryExtensionSharedPtr
|
||||
: public Serialization::IPointer
|
||||
{
|
||||
public:
|
||||
CryExtensionSharedPtr(AZStd::shared_ptr<T>& ptr)
|
||||
: m_ptr(ptr)
|
||||
{}
|
||||
|
||||
const char* registeredTypeName() const override
|
||||
{
|
||||
if (m_ptr)
|
||||
{
|
||||
return factory()->getRegisteredTypeName(m_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
void create(const char* registeredTypeName) const override
|
||||
{
|
||||
if (registeredTypeName[0] != '\0')
|
||||
{
|
||||
m_ptr = factory()->create(registeredTypeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ptr.reset((T*)0);
|
||||
}
|
||||
}
|
||||
|
||||
Serialization::TypeID baseType() const{ return Serialization::TypeID::get<T>(); }
|
||||
virtual Serialization::SStruct serializer() const override
|
||||
{
|
||||
if (TSerializable* ser = cryinterface_cast<TSerializable>(m_ptr.get()))
|
||||
{
|
||||
return Serialization::SStruct(*ser);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Serialization::SStruct();
|
||||
}
|
||||
}
|
||||
void* get() const override { return reinterpret_cast<void*>(m_ptr.get()); }
|
||||
const void* handle() const override { return &m_ptr; }
|
||||
Serialization::TypeID pointerType() const override { return Serialization::TypeID::get<AZStd::shared_ptr<T> >(); }
|
||||
CryExtensionClassFactory<T, TSerializable>* factory() const override { return &CryExtensionClassFactory<T, TSerializable>::the(); }
|
||||
protected:
|
||||
AZStd::shared_ptr<T>& m_ptr;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYEXTENSIONIMPL_H
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H
|
||||
#pragma once
|
||||
|
||||
namespace Serialization {
|
||||
class IArchive;
|
||||
}
|
||||
|
||||
inline bool Serialize(Serialization::IArchive & ar, class CCryName & cryName, const char* name, const char* label);
|
||||
|
||||
#include "CryNameImpl.h"
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAME_H
|
||||
@@ -1,61 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "CryName.h"
|
||||
#include "IArchive.h"
|
||||
|
||||
class CryNameSerializer
|
||||
: public Serialization::IString
|
||||
{
|
||||
public:
|
||||
CryNameSerializer(CCryName& s)
|
||||
: m_s(s)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void set(const char* value)
|
||||
{
|
||||
m_s = value;
|
||||
}
|
||||
|
||||
virtual const char* get() const
|
||||
{
|
||||
return m_s.c_str();
|
||||
}
|
||||
|
||||
virtual const void* handle() const
|
||||
{
|
||||
return &m_s;
|
||||
}
|
||||
|
||||
virtual Serialization::TypeID type() const
|
||||
{
|
||||
return Serialization::TypeID::get<CCryName>();
|
||||
}
|
||||
|
||||
CCryName& m_s;
|
||||
};
|
||||
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, CCryName& cryName, const char* name, const char* label)
|
||||
{
|
||||
CryNameSerializer serializer(cryName);
|
||||
return ar(static_cast<Serialization::IString&>(serializer), name, label);
|
||||
}
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_CRYNAMEIMPL_H
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CryFixedString.h"
|
||||
|
||||
#include "Serialization/Serializer.h"
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
class IArchive;
|
||||
}
|
||||
|
||||
// Note : if you are looking for the CryStringT serialization, it is handled in Serialization/STL.h
|
||||
|
||||
template< size_t N >
|
||||
bool Serialize(Serialization::IArchive& ar, CryFixedStringT< N >& value, const char* name, const char* label);
|
||||
|
||||
template< size_t N >
|
||||
bool Serialize(Serialization::IArchive& ar, CryStackStringT< char, N >& value, const char* name, const char* label);
|
||||
|
||||
template< size_t N >
|
||||
bool Serialize(Serialization::IArchive& ar, CryStackStringT< wchar_t, N >& value, const char* name, const char* label);
|
||||
|
||||
#include "Serialization/CryStringsImpl.h"
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/CryStrings.h"
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
template< class TFixedStringClass >
|
||||
class CFixedStringSerializer
|
||||
: public IString
|
||||
{
|
||||
public:
|
||||
CFixedStringSerializer(TFixedStringClass& str)
|
||||
: str_(str) { }
|
||||
|
||||
void set(const char* value) { str_ = value; }
|
||||
const char* get() const { return str_.c_str(); }
|
||||
const void* handle() const { return &str_; }
|
||||
TypeID type() const { return TypeID::get<TFixedStringClass>(); }
|
||||
private:
|
||||
TFixedStringClass& str_;
|
||||
};
|
||||
|
||||
template< class TFixedStringClass >
|
||||
class CFixedWStringSerializer
|
||||
: public IWString
|
||||
{
|
||||
public:
|
||||
CFixedWStringSerializer(TFixedStringClass& str)
|
||||
: str_(str) { }
|
||||
|
||||
void set(const wchar_t* value) { str_ = value; }
|
||||
const wchar_t* get() const { return str_.c_str(); }
|
||||
const void* handle() const { return &str_; }
|
||||
TypeID type() const { return TypeID::get<TFixedStringClass>(); }
|
||||
private:
|
||||
TFixedStringClass& str_;
|
||||
};
|
||||
}
|
||||
|
||||
template< size_t N >
|
||||
inline bool Serialize(Serialization::IArchive& ar, CryFixedStringT< N >& value, const char* name, const char* label)
|
||||
{
|
||||
Serialization::CFixedStringSerializer< CryFixedStringT< N > > str(value);
|
||||
return ar(static_cast<Serialization::IString&>(str), name, label);
|
||||
}
|
||||
|
||||
template< size_t N >
|
||||
inline bool Serialize(Serialization::IArchive& ar, CryStackStringT< char, N >& value, const char* name, const char* label)
|
||||
{
|
||||
Serialization::CFixedStringSerializer< CryStackStringT< char, N > > str(value);
|
||||
return ar(static_cast<Serialization::IString&>(str), name, label);
|
||||
}
|
||||
|
||||
template< size_t N >
|
||||
inline bool Serialize(Serialization::IArchive& ar, CryStackStringT< wchar_t, N >& value, const char* name, const char* label)
|
||||
{
|
||||
Serialization::CFixedWStringSerializer< CryStackStringT< wchar_t, N > > str(value);
|
||||
return ar(static_cast<Serialization::IWString&>(str), name, label);
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SmartPointersHelpers.h>
|
||||
#include <Serialization/IArchive.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
struct IActionButton;
|
||||
|
||||
DECLARE_SMART_POINTERS(IActionButton)
|
||||
|
||||
struct IActionButton
|
||||
{
|
||||
virtual ~IActionButton() {}
|
||||
|
||||
virtual void Callback() const = 0;
|
||||
virtual const char* Icon() const = 0;
|
||||
virtual IActionButtonPtr Clone() const = 0;
|
||||
};
|
||||
|
||||
typedef AZStd::function<void()> FunctorActionButtonCallback;
|
||||
|
||||
struct FunctorActionButton
|
||||
: public IActionButton
|
||||
{
|
||||
FunctorActionButtonCallback callback;
|
||||
string icon;
|
||||
|
||||
explicit FunctorActionButton(const FunctorActionButtonCallback& callback, const char* icon = "")
|
||||
: callback(callback)
|
||||
, icon(icon)
|
||||
{
|
||||
}
|
||||
|
||||
// IActionButton
|
||||
|
||||
virtual void Callback() const override
|
||||
{
|
||||
if (callback)
|
||||
{
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
virtual const char* Icon() const override
|
||||
{
|
||||
return icon.c_str();
|
||||
}
|
||||
|
||||
virtual IActionButtonPtr Clone() const override
|
||||
{
|
||||
return IActionButtonPtr(new FunctorActionButton(callback, icon.c_str()));
|
||||
}
|
||||
|
||||
// ~IActionButton
|
||||
};
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, FunctorActionButton& button, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(Serialization::SStruct::ForEdit(static_cast<Serialization::IActionButton&>(button)), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline FunctorActionButton ActionButton(const FunctorActionButtonCallback& callback, const char* icon = "")
|
||||
{
|
||||
return FunctorActionButton(callback, icon);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H
|
||||
#pragma once
|
||||
|
||||
#include <Serialization/Enum.h>
|
||||
|
||||
namespace Serialization {
|
||||
class IArchive;
|
||||
|
||||
struct BitFlagsWrapper
|
||||
{
|
||||
int* variable;
|
||||
unsigned int visibleMask;
|
||||
const CEnumDescription* description;
|
||||
|
||||
void Serialize(IArchive& ar);
|
||||
};
|
||||
|
||||
template<class Enum>
|
||||
BitFlagsWrapper BitFlags(Enum& value)
|
||||
{
|
||||
BitFlagsWrapper wrapper;
|
||||
wrapper.variable = (int*)&value;
|
||||
wrapper.visibleMask = ~0U;
|
||||
wrapper.description = &getEnumDescription<Enum>();
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
template<class Enum>
|
||||
BitFlagsWrapper BitFlags(int& value, int visibleMask = ~0)
|
||||
{
|
||||
BitFlagsWrapper wrapper;
|
||||
wrapper.variable = &value;
|
||||
wrapper.visibleMask = visibleMask;
|
||||
wrapper.description = &getEnumDescription<Enum>();
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
template<class Enum>
|
||||
BitFlagsWrapper BitFlags(unsigned int& value, unsigned int visibleMask = ~0)
|
||||
{
|
||||
BitFlagsWrapper wrapper;
|
||||
wrapper.variable = (int*)&value;
|
||||
wrapper.visibleMask = visibleMask;
|
||||
wrapper.description = &getEnumDescription<Enum>();
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
#include "BitFlagsImpl.h"
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGS_H
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "Serialization/IArchive.h"
|
||||
|
||||
namespace Serialization {
|
||||
inline void BitFlagsWrapper::Serialize(IArchive& ar)
|
||||
{
|
||||
const Serialization::CEnumDescription& desc = *description;
|
||||
int count = desc.count();
|
||||
if (ar.IsInput())
|
||||
{
|
||||
int previousValue = *variable;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
int flagValue = desc.valueByIndex(i);
|
||||
if (!(flagValue & visibleMask))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool flag = (previousValue & flagValue) == flagValue;
|
||||
bool previousFlag = flag;
|
||||
ar(flag, desc.nameByIndex(i), desc.labelByIndex(i));
|
||||
if (flag != previousFlag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
*variable |= flagValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
*variable &= ~flagValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
int flagValue = desc.valueByIndex(i);
|
||||
if (!(flagValue & visibleMask))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bool flag = (*variable & flagValue) == flagValue;
|
||||
ar(flag, desc.nameByIndex(i), desc.labelByIndex(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_BITFLAGSIMPL_H
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H
|
||||
#pragma once
|
||||
|
||||
#include <Cry_Math.h>
|
||||
#include <Cry_Color.h>
|
||||
|
||||
#include <ISystem.h>
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
class IArchive;
|
||||
|
||||
struct ColorPicker
|
||||
{
|
||||
ColorF* color;
|
||||
|
||||
explicit ColorPicker(ColorF& color_)
|
||||
: color(&color_)
|
||||
{
|
||||
}
|
||||
|
||||
// the function should stay virtual to ensure cross-dll calls are using right heap
|
||||
virtual void SetColor(const ColorF* color_){* color = *color_; }
|
||||
};
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, Serialization::ColorPicker& value, const char* name, const char* label);
|
||||
} // namespace Serialization
|
||||
|
||||
#include "ColorPickerImpl.h"
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKER_H
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "../Color.h"
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
inline bool Serialize(Serialization::IArchive& ar, Serialization::ColorPicker& value, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(Serialization::SStruct::ForEdit(value), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ar(*value.color, name, label);
|
||||
}
|
||||
}
|
||||
} // namespace Serialization
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_COLORPICKERIMPL_H
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H
|
||||
#pragma once
|
||||
|
||||
#include <Serialization/Decorators/Resources.h>
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAME_H
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H
|
||||
#pragma once
|
||||
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_JOINTNAMEIMPL_H
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H
|
||||
#pragma once
|
||||
|
||||
#include <Cry_Math.h>
|
||||
#include "Serialization/Math.h"
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
class IArchive;
|
||||
|
||||
struct LocalPosition
|
||||
{
|
||||
Vec3* value;
|
||||
int space;
|
||||
const char* parentName;
|
||||
const void* handle;
|
||||
|
||||
LocalPosition(Vec3& _vec, int _space, const char* _parentName, const void* _handle)
|
||||
: value(&_vec)
|
||||
, space(_space)
|
||||
, parentName(_parentName)
|
||||
, handle(_handle)
|
||||
{
|
||||
}
|
||||
|
||||
void Serialize(IArchive& ar);
|
||||
};
|
||||
|
||||
struct LocalOrientation
|
||||
{
|
||||
Quat* value;
|
||||
int space;
|
||||
const char* parentName;
|
||||
const void* handle;
|
||||
|
||||
LocalOrientation(Quat& _vec, int _space, const char* _parentName, const void* _handle)
|
||||
: value(&_vec)
|
||||
, space(_space)
|
||||
, parentName(_parentName)
|
||||
, handle(_handle)
|
||||
{
|
||||
}
|
||||
|
||||
void Serialize(IArchive& ar);
|
||||
};
|
||||
|
||||
struct LocalFrame
|
||||
{
|
||||
Quat* rotation;
|
||||
Vec3* position;
|
||||
const char* parentName;
|
||||
int rotationSpace;
|
||||
int positionSpace;
|
||||
const void* handle;
|
||||
|
||||
LocalFrame(Quat* _rotation, int _rotationSpace, Vec3* _position, int _positionSpace, const char* _parentName, const void* _handle)
|
||||
: rotation(_rotation)
|
||||
, position(_position)
|
||||
, parentName(_parentName)
|
||||
, rotationSpace(_rotationSpace)
|
||||
, positionSpace(_positionSpace)
|
||||
, handle(_handle)
|
||||
{
|
||||
}
|
||||
|
||||
void Serialize(IArchive& ar);
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SPACE_JOINT,
|
||||
SPACE_ENTITY,
|
||||
SPACE_JOINT_WITH_PARENT_ROTATION,
|
||||
SPACE_JOINT_WITH_CHARACTER_ROTATION,
|
||||
SPACE_SOCKET_RELATIVE_TO_JOINT,
|
||||
SPACE_SOCKET_RELATIVE_TO_BINDPOSE
|
||||
};
|
||||
|
||||
|
||||
|
||||
//position
|
||||
inline LocalPosition LocalToEntity(Vec3& position, const void* handle = 0)
|
||||
{
|
||||
return LocalPosition(position, SPACE_ENTITY, "", handle ? handle : &position);
|
||||
}
|
||||
inline LocalPosition LocalToJoint(Vec3& position, const string& jointName, const void* handle = 0)
|
||||
{
|
||||
return LocalPosition(position, SPACE_JOINT, jointName.c_str(), handle ? handle : &position);
|
||||
}
|
||||
|
||||
inline LocalPosition LocalToJointCharacterRotation(Vec3& position, const string& jointName, const void* handle = 0)
|
||||
{
|
||||
return LocalPosition(position, SPACE_JOINT_WITH_CHARACTER_ROTATION, jointName.c_str(), handle ? handle : &position);
|
||||
}
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, Serialization::LocalPosition& value, const char* name, const char* label);
|
||||
bool Serialize(Serialization::IArchive& ar, Serialization::LocalOrientation& value, const char* name, const char* label);
|
||||
bool Serialize(Serialization::IArchive& ar, Serialization::LocalFrame& value, const char* name, const char* label);
|
||||
}
|
||||
|
||||
#include "LocalFrameImpl.h"
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAME_H
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAMEIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAMEIMPL_H
|
||||
#pragma once
|
||||
|
||||
#include "LocalFrame.h"
|
||||
#include "Serialization/IArchive.h"
|
||||
#include "Serialization/MathImpl.h"
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
inline void LocalPosition::Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(value->x, "x", "^");
|
||||
ar(value->y, "y", "^");
|
||||
ar(value->z, "z", "^");
|
||||
}
|
||||
|
||||
inline void LocalOrientation::Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(Serialization::AsAng3(*value), "q", "^");
|
||||
}
|
||||
|
||||
inline void LocalFrame::Serialize(Serialization::IArchive& ar)
|
||||
{
|
||||
ar(*position, "t", "<T");
|
||||
ar(AsAng3(*rotation), "q", "<R");
|
||||
}
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, Serialization::LocalPosition& value, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(Serialization::SStruct(value), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ar(*value.value, name, label);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, Serialization::LocalOrientation& value, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(Serialization::SStruct(value), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ar(*value.value, name, label);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Serialize(Serialization::IArchive& ar, Serialization::LocalFrame& value, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(Serialization::SStruct(value), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
QuatT t(*value.rotation, *value.position);
|
||||
if (!ar(t, name, label))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (ar.IsInput())
|
||||
{
|
||||
*value.position = t.t;
|
||||
*value.rotation = t.q;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_LOCALFRAMEIMPL_H
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATH_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATH_H
|
||||
#pragma once
|
||||
|
||||
#include "Serialization/Strings.h"
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
class IArchive;
|
||||
|
||||
struct OutputFilePath
|
||||
{
|
||||
string* m_path;
|
||||
// if we don't use dynamic filters we could replace following two with const char*
|
||||
string filter;
|
||||
string startFolder;
|
||||
|
||||
// filters are defined in the following format:
|
||||
// "All Images (bmp, jpg, tga)|*.bmp;*.jpg;*.tga|Targa (tga)|*.tga"
|
||||
explicit OutputFilePath(string& path, const char* filter = "All files|*.*", const char* startFolder = "")
|
||||
: m_path(&path)
|
||||
, filter(filter)
|
||||
, startFolder(startFolder)
|
||||
{
|
||||
}
|
||||
|
||||
// the function should stay virtual to ensure cross-dll calls are using right heap
|
||||
virtual void SetPath(const char* path) { *this->m_path = path; }
|
||||
};
|
||||
|
||||
bool Serialize(Serialization::IArchive& ar, Serialization::OutputFilePath& value, const char* name, const char* label);
|
||||
}
|
||||
|
||||
#include "OutputFilePathImpl.h"
|
||||
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATH_H
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
||||
|
||||
#ifndef CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H
|
||||
#define CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H
|
||||
#pragma once
|
||||
|
||||
namespace Serialization
|
||||
{
|
||||
inline bool Serialize(Serialization::IArchive& ar, Serialization::OutputFilePath& value, const char* name, const char* label)
|
||||
{
|
||||
if (ar.IsEdit())
|
||||
{
|
||||
return ar(Serialization::SStruct::ForEdit(value), name, label);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ar(*value.m_path, name, label);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // CRYINCLUDE_CRYCOMMON_SERIALIZATION_DECORATORS_OUTPUTFILEPATHIMPL_H
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user