Compare commits
77 Commits
v0.2.0
...
c379c00a3f
| Author | SHA1 | Date | |
|---|---|---|---|
| c379c00a3f | |||
| 37b8f2d023 | |||
| d2a9b18ede | |||
| 8bc0792f1e | |||
| 6d41e593bc | |||
| 10d5d8f002 | |||
| d3af894d2f | |||
| 1eb9d3f805 | |||
| 11abbe2c35 | |||
| 2240f55964 | |||
| 7b40c64470 | |||
| 58ee7accff | |||
| c11220d54b | |||
| e6e714f2c9 | |||
| 4985c6d3d0 | |||
| 37904fd5a4 | |||
| a654370b82 | |||
| 90fe7ddcaf | |||
| b06bd587f6 | |||
| ebbea473a4 | |||
| def46d1b8f | |||
| c664eaba0e | |||
| 8f5cc51de4 | |||
| 103cb496a2 | |||
| 8dfa4bd039 | |||
| 6b0d73177b | |||
| 2f59e16590 | |||
| 2b9c0296d1 | |||
| 333ff0ab17 | |||
| 6f10f96f97 | |||
| 07d180f2cb | |||
| ada432fbe7 | |||
| ca4fab4612 | |||
| 307676f9c8 | |||
| e53195fa1d | |||
| 52ad4cec99 | |||
| 29d98edbdc | |||
| 69ac25a70b | |||
| f5645a06de | |||
| 0202266ce5 | |||
| 3152d7dd52 | |||
| f601782370 | |||
| 0419dc3939 | |||
| 9cb4d50f22 | |||
| c68bdce37b | |||
| e0e5c9b090 | |||
| fd591f8a62 | |||
| a79d09a66c | |||
| 97b33b131a | |||
| 9319425237 | |||
| 09ca976fd9 | |||
| 5477072d70 | |||
| 940ffeecf2 | |||
| 440bc63432 | |||
| f7acb3bfa9 | |||
| 43984685bc | |||
| c2dafab217 | |||
| 34de35dd31 | |||
| ff2600c8fb | |||
| 9228f343ff | |||
| f9ab66dfc2 | |||
| af6a50c2f9 | |||
| 0bf0519c4c | |||
| c18ff8f2e3 | |||
| fe4a58e864 | |||
| eaeaf956b5 | |||
| 6bb2421e1f | |||
| ead22d13ff | |||
| aeb2e86b14 | |||
| 86b27557c9 | |||
| eef3a352d9 | |||
| b74f1b965c | |||
| c235524403 | |||
| 4bfc4782b5 | |||
| 3eeb1f6cb6 | |||
| ff5a590cf4 | |||
| d29d40448b |
317
.clang-format
Normal file
317
.clang-format
Normal file
@@ -0,0 +1,317 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/clang-format.json
|
||||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveShortCaseStatements:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCaseArrows: false
|
||||
AlignCaseColons: false
|
||||
AlignConsecutiveTableGenBreakingDAGArgColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveTableGenCondOperatorColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignConsecutiveTableGenDefinitionColons:
|
||||
Enabled: false
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: false
|
||||
AlignFunctionPointers: false
|
||||
PadOperators: false
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AlignOperands: Align
|
||||
AlignTrailingComments:
|
||||
Kind: Always
|
||||
OverEmptyLines: 0
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowBreakBeforeNoexceptSpecifier: Never
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseExpressionOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortCompoundRequirementOnASingleLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BitFieldColonSpacing: Both
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterExternBlock: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakAdjacentStringLiterals: true
|
||||
BreakAfterAttributes: Leave
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakAfterReturnType: None
|
||||
BreakArrays: true
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeConceptDeclarations: Always
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeInlineASMColon: OnlyMultiline
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakFunctionDefinitionParameters: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakStringLiterals: false
|
||||
BreakTemplateDeclarations: Yes
|
||||
ColumnLimit: 140
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: true
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- forever
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^<Q.*'
|
||||
Priority: 200
|
||||
SortPriority: 200
|
||||
CaseSensitive: true
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentRequiresClause: true
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertBraces: false
|
||||
InsertNewlineAtEOF: false
|
||||
InsertTrailingCommas: None
|
||||
IntegerLiteralSeparator:
|
||||
Binary: 0
|
||||
BinaryMinDigits: 0
|
||||
Decimal: 0
|
||||
DecimalMinDigits: 0
|
||||
Hex: 0
|
||||
HexMinDigits: 0
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLines:
|
||||
AtEndOfFile: false
|
||||
AtStartOfBlock: false
|
||||
AtStartOfFile: false
|
||||
LambdaBodyIndentation: Signature
|
||||
LineEnding: DeriveLF
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MainIncludeChar: Quote
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: All
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PackConstructorInitializers: BinPack
|
||||
PenaltyBreakAssignment: 150
|
||||
PenaltyBreakBeforeFirstCallParameter: 300
|
||||
PenaltyBreakComment: 500
|
||||
PenaltyBreakFirstLessLess: 400
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakScopeResolution: 500
|
||||
PenaltyBreakString: 600
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 50
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PenaltyReturnTypeOnItsOwnLine: 300
|
||||
PointerAlignment: Left
|
||||
PPIndentWidth: -1
|
||||
QualifierAlignment: Leave
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: false
|
||||
RemoveBracesLLVM: false
|
||||
RemoveParentheses: Leave
|
||||
RemoveSemicolon: false
|
||||
RequiresClausePosition: OwnLine
|
||||
RequiresExpressionIndentation: OuterScope
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SkipMacroDefinitionBody: false
|
||||
SortIncludes: Never
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: Lexicographic
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeJsonColon: false
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
AfterPlacementOperator: true
|
||||
AfterRequiresInClause: false
|
||||
AfterRequiresInExpression: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParens: Never
|
||||
SpacesInParensOptions:
|
||||
ExceptDoubleParentheses: false
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: false
|
||||
InEmptyParentheses: false
|
||||
Other: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Auto
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
- emit
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
- Q_CLASSINFO
|
||||
- Q_ENUM
|
||||
- Q_ENUM_NS
|
||||
- Q_FLAG
|
||||
- Q_FLAG_NS
|
||||
- Q_GADGET
|
||||
- Q_GADGET_EXPORT
|
||||
- Q_INTERFACES
|
||||
- Q_LOGGING_CATEGORY
|
||||
- Q_MOC_INCLUDE
|
||||
- Q_NAMESPACE
|
||||
- Q_NAMESPACE_EXPORT
|
||||
- Q_OBJECT
|
||||
- Q_PROPERTY
|
||||
- Q_REVISION
|
||||
- Q_DISABLE_COPY
|
||||
- Q_DISABLE_COPY_MOVE
|
||||
- Q_SET_OBJECT_NAME
|
||||
- QT_BEGIN_NAMESPACE
|
||||
- QT_END_NAMESPACE
|
||||
- QML_ADDED_IN_MINOR_VERSION
|
||||
- QML_ANONYMOUS
|
||||
- QML_ATTACHED
|
||||
- QML_DECLARE_TYPE
|
||||
- QML_DECLARE_TYPEINFO
|
||||
- QML_ELEMENT
|
||||
- QML_EXTENDED
|
||||
- QML_EXTENDED_NAMESPACE
|
||||
- QML_EXTRA_VERSION
|
||||
- QML_FOREIGN
|
||||
- QML_FOREIGN_NAMESPACE
|
||||
- QML_IMPLEMENTS_INTERFACES
|
||||
- QML_INTERFACE
|
||||
- QML_NAMED_ELEMENT
|
||||
- QML_REMOVED_IN_MINOR_VERSION
|
||||
- QML_SINGLETON
|
||||
- QML_UNAVAILABLE
|
||||
- QML_UNCREATABLE
|
||||
- QML_VALUE_TYPE
|
||||
- YYCC_DELETE_COPY
|
||||
- YYCC_DELETE_MOVE
|
||||
- YYCC_DELETE_COPY_MOVE
|
||||
- YYCC_DEFAULT_COPY
|
||||
- YYCC_DEFAULT_MOVE
|
||||
- YYCC_DEFAULT_COPY_MOVE
|
||||
- YYCC_DECL_COPY
|
||||
- YYCC_DECL_MOVE
|
||||
- YYCC_DECL_COPY_MOVE
|
||||
TableGenBreakInsideDAGArg: DontBreak
|
||||
TabWidth: 4
|
||||
UseTab: ForIndentation
|
||||
VerilogBreakBetweenInstancePorts: true
|
||||
WhitespaceSensitiveMacros:
|
||||
- BOOST_PP_STRINGIZE
|
||||
- CF_SWIFT_NAME
|
||||
- NS_SWIFT_NAME
|
||||
- PP_STRINGIZE
|
||||
- STRINGIZE
|
||||
...
|
||||
|
||||
4
.github/scripts/README.md
vendored
Normal file
4
.github/scripts/README.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# GitHub Scripts
|
||||
|
||||
These script files should be only used by GitHub Action.
|
||||
These script files should be executed at the root directory of each project respectively.
|
||||
19
.github/scripts/linux.sh
vendored
Normal file
19
.github/scripts/linux.sh
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Create build directory and enter it
|
||||
mkdir bin
|
||||
cd bin
|
||||
# Create internal build and install directory
|
||||
mkdir build
|
||||
mkdir install
|
||||
|
||||
# Build in Release mode
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BALLANCE=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_BMAPINSPECTOR=ON -DYYCCommonplace_ROOT=$YYCCommonplace_ROOT -DSTB_ROOT=$STB_ROOT -DZLIB_ROOT=$ZLIB_ROOT ../..
|
||||
cmake --build .
|
||||
cmake --install . --prefix=../install
|
||||
cd ..
|
||||
|
||||
# Back to root directory
|
||||
cd ..
|
||||
19
.github/scripts/macos.sh
vendored
Normal file
19
.github/scripts/macos.sh
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Create build directory and enter it
|
||||
mkdir bin
|
||||
cd bin
|
||||
# Create internal build and install directory
|
||||
mkdir build
|
||||
mkdir install
|
||||
|
||||
# Build in Release mode
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BALLANCE=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_BMAPINSPECTOR=ON -DYYCCommonplace_ROOT=$YYCCommonplace_ROOT -DSTB_ROOT=$STB_ROOT -DZLIB_ROOT=$ZLIB_ROOT ../..
|
||||
cmake --build .
|
||||
cmake --install . --prefix=../install
|
||||
cd ..
|
||||
|
||||
# Back to root directory
|
||||
cd ..
|
||||
5
.github/scripts/stb/linux.sh
vendored
Normal file
5
.github/scripts/stb/linux.sh
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Just directly record self as root directory
|
||||
export STB_ROOT=$(pwd)
|
||||
5
.github/scripts/stb/macos.sh
vendored
Normal file
5
.github/scripts/stb/macos.sh
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Just directly record self as root directory
|
||||
export STB_ROOT=$(pwd)
|
||||
4
.github/scripts/stb/windows.bat
vendored
Normal file
4
.github/scripts/stb/windows.bat
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
@ECHO OFF
|
||||
|
||||
:: Just directly record self as root directory
|
||||
SET STB_ROOT=%CD%
|
||||
18
.github/scripts/windows.bat
vendored
Normal file
18
.github/scripts/windows.bat
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
@ECHO OFF
|
||||
|
||||
:: Create build directory and enter it
|
||||
MKDIR bin
|
||||
CD bin
|
||||
:: Create internal build and install directory
|
||||
MKDIR build
|
||||
MKDIR install
|
||||
|
||||
:: Build with x64 architecture in Release mode
|
||||
CD build
|
||||
cmake -A x64 -DCMAKE_CXX_STANDARD=23 -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BALLANCE=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_BMAPINSPECTOR=ON -DYYCCommonplace_ROOT=%YYCCommonplace_ROOT% -DSTB_ROOT=%STB_ROOT% -DZLIB_ROOT=%ZLIB_ROOT% ../..
|
||||
cmake --build . --config Release
|
||||
cmake --install . --prefix=../install --config Release
|
||||
CD ..
|
||||
|
||||
:: Back to root directory
|
||||
CD ..
|
||||
24
.github/scripts/yycc/linux.sh
vendored
Normal file
24
.github/scripts/yycc/linux.sh
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Create build directory and enter it
|
||||
mkdir bin
|
||||
cd bin
|
||||
# Create internal build and install directory
|
||||
mkdir build
|
||||
mkdir install
|
||||
|
||||
# Build in Release mode
|
||||
cd build
|
||||
cmake -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=True ../..
|
||||
cmake --build .
|
||||
cmake --install . --prefix=../install
|
||||
cd ..
|
||||
|
||||
# Record install directory
|
||||
cd install
|
||||
export YYCCommonplace_ROOT=$(pwd)
|
||||
cd ..
|
||||
|
||||
# Back to root directory
|
||||
cd ..
|
||||
24
.github/scripts/yycc/macos.sh
vendored
Normal file
24
.github/scripts/yycc/macos.sh
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Create build directory and enter it
|
||||
mkdir bin
|
||||
cd bin
|
||||
# Create internal build and install directory
|
||||
mkdir build
|
||||
mkdir install
|
||||
|
||||
# Build in Release mode
|
||||
cd build
|
||||
cmake -DCMAKE_CXX_STANDARD=23 -DCMAKE_BUILD_TYPE=Release -DCMAKE_POSITION_INDEPENDENT_CODE=True ../..
|
||||
cmake --build .
|
||||
cmake --install . --prefix=../install
|
||||
cd ..
|
||||
|
||||
# Record install directory
|
||||
cd install
|
||||
export YYCCommonplace_ROOT=$(pwd)
|
||||
cd ..
|
||||
|
||||
# Back to root directory
|
||||
cd ..
|
||||
23
.github/scripts/yycc/windows.bat
vendored
Normal file
23
.github/scripts/yycc/windows.bat
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
@ECHO OFF
|
||||
|
||||
:: Create build directory and enter it
|
||||
MKDIR bin
|
||||
CD bin
|
||||
:: Create internal build and install directory
|
||||
MKDIR build
|
||||
MKDIR install
|
||||
|
||||
:: Build with x64 architecture in Release mode
|
||||
CD build
|
||||
cmake -A x64 -DCMAKE_CXX_STANDARD=23 ../..
|
||||
cmake --build . --config Release
|
||||
cmake --install . --prefix=../install --config Release
|
||||
CD ..
|
||||
|
||||
:: Record install directory
|
||||
CD install
|
||||
SET YYCCommonplace_ROOT=%CD%
|
||||
CD ..
|
||||
|
||||
:: Back to root directory
|
||||
CD ..
|
||||
18
.github/scripts/zlib/linux.sh
vendored
Normal file
18
.github/scripts/zlib/linux.sh
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Create build and install directory
|
||||
mkdir build
|
||||
mkdir install
|
||||
|
||||
# Record install directory first because build step require it
|
||||
cd install
|
||||
export ZLIB_ROOT=$(pwd)
|
||||
cd ..
|
||||
|
||||
# Build in Release mode
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 -DZLIB_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=$ZLIB_ROOT ..
|
||||
cmake --build .
|
||||
cmake --install .
|
||||
cd ..
|
||||
18
.github/scripts/zlib/macos.sh
vendored
Normal file
18
.github/scripts/zlib/macos.sh
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Create build and install directory
|
||||
mkdir build
|
||||
mkdir install
|
||||
|
||||
# Record install directory first because build step require it
|
||||
cd install
|
||||
export ZLIB_ROOT=$(pwd)
|
||||
cd ..
|
||||
|
||||
# Build in Release mode
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=23 -DZLIB_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=$ZLIB_ROOT ..
|
||||
cmake --build .
|
||||
cmake --install .
|
||||
cd ..
|
||||
17
.github/scripts/zlib/windows.bat
vendored
Normal file
17
.github/scripts/zlib/windows.bat
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
@ECHO OFF
|
||||
|
||||
:: Create build and install directory
|
||||
MKDIR build
|
||||
MKDIR install
|
||||
|
||||
:: Record install directory first because build step require it
|
||||
CD install
|
||||
SET ZLIB_ROOT=%CD%
|
||||
CD ..
|
||||
|
||||
:: Build with x64 architecture in Release mode
|
||||
CD build
|
||||
cmake -A x64 -DCMAKE_CXX_STANDARD=23 -DZLIB_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=%ZLIB_ROOT% ..
|
||||
cmake --build . --config Release
|
||||
cmake --install . --config Release
|
||||
CD ..
|
||||
71
.github/workflows/linux.yml
vendored
Normal file
71
.github/workflows/linux.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: LibCmo Linux Build
|
||||
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
linux-build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Install Dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y build-essential cmake git
|
||||
- name: Fetch YYCCommonplace
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'yyc12345/YYCCommonplace'
|
||||
ref: 'master'
|
||||
path: 'extern/YYCCommonplace'
|
||||
- name: Build YYCCommonplace
|
||||
shell: bash
|
||||
run: |
|
||||
cd extern/YYCCommonplace
|
||||
source ../../.github/scripts/yycc/linux.sh
|
||||
echo "YYCCommonplace_ROOT=$YYCCommonplace_ROOT" >> "$GITHUB_ENV"
|
||||
cd ../..
|
||||
- name: Fetch ZLIB
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'madler/zlib'
|
||||
ref: 'v1.3.1'
|
||||
path: 'extern/zlib'
|
||||
- name: Build ZLIB
|
||||
shell: bash
|
||||
run: |
|
||||
cd extern/zlib
|
||||
source ../../.github/scripts/zlib/linux.sh
|
||||
echo "ZLIB_ROOT=$ZLIB_ROOT" >> "$GITHUB_ENV"
|
||||
cd ../..
|
||||
- name: Fetch STB
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'nothings/stb'
|
||||
ref: '2e2bef463a5b53ddf8bb788e25da6b8506314c08'
|
||||
path: 'extern/stb'
|
||||
- name: Build STB
|
||||
shell: bash
|
||||
run: |
|
||||
cd extern/stb
|
||||
source ../../.github/scripts/stb/linux.sh
|
||||
echo "STB_ROOT=$STB_ROOT" >> "$GITHUB_ENV"
|
||||
cd ../..
|
||||
- name: Build LibCmo
|
||||
shell: bash
|
||||
run: |
|
||||
source ./.github/scripts/linux.sh
|
||||
- name: Upload Built Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: LibCmo-linux-build
|
||||
path: bin/install/*
|
||||
retention-days: 30
|
||||
- name: Upload Built Dependencies
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: LibCmo-linux-dep
|
||||
path: extern/zlib/install/*
|
||||
retention-days: 30
|
||||
66
.github/workflows/macos.yml
vendored
Normal file
66
.github/workflows/macos.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: LibCmo macOS Build
|
||||
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
macos-build:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Fetch YYCCommonplace
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'yyc12345/YYCCommonplace'
|
||||
ref: 'master'
|
||||
path: 'extern/YYCCommonplace'
|
||||
- name: Build YYCCommonplace
|
||||
shell: bash
|
||||
run: |
|
||||
cd extern/YYCCommonplace
|
||||
source ../../.github/scripts/yycc/macos.sh
|
||||
echo "YYCCommonplace_ROOT=$YYCCommonplace_ROOT" >> "$GITHUB_ENV"
|
||||
cd ../..
|
||||
- name: Fetch ZLIB
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'madler/zlib'
|
||||
ref: 'v1.3.1'
|
||||
path: 'extern/zlib'
|
||||
- name: Build ZLIB
|
||||
shell: bash
|
||||
run: |
|
||||
cd extern/zlib
|
||||
source ../../.github/scripts/zlib/macos.sh
|
||||
echo "ZLIB_ROOT=$ZLIB_ROOT" >> "$GITHUB_ENV"
|
||||
cd ../..
|
||||
- name: Fetch STB
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'nothings/stb'
|
||||
ref: '2e2bef463a5b53ddf8bb788e25da6b8506314c08'
|
||||
path: 'extern/stb'
|
||||
- name: Build STB
|
||||
shell: bash
|
||||
run: |
|
||||
cd extern/stb
|
||||
source ../../.github/scripts/stb/macos.sh
|
||||
echo "STB_ROOT=$STB_ROOT" >> "$GITHUB_ENV"
|
||||
cd ../..
|
||||
- name: Build LibCmo
|
||||
shell: bash
|
||||
run: |
|
||||
source ./.github/scripts/macos.sh
|
||||
- name: Upload Built Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: LibCmo-macos-build
|
||||
path: bin/install/*
|
||||
retention-days: 30
|
||||
- name: Upload Built Dependencies
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: LibCmo-macos-dep
|
||||
path: extern/zlib/install/*
|
||||
retention-days: 30
|
||||
82
.github/workflows/windows.yml
vendored
Normal file
82
.github/workflows/windows.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: LibCmo Windows Build
|
||||
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
windows-build:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- vs: '2022'
|
||||
msvc_arch: 'x64'
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Fetch YYCCommonplace
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'yyc12345/YYCCommonplace'
|
||||
ref: 'master'
|
||||
path: 'extern/YYCCommonplace'
|
||||
- name: Build YYCCommonplace
|
||||
shell: cmd
|
||||
run: |
|
||||
CD extern\YYCCommonplace
|
||||
CALL ..\..\.github\scripts\yycc\windows.bat
|
||||
ECHO SET YYCCommonplace_ROOT=%YYCCommonplace_ROOT% > ..\envs.bat
|
||||
CD ..\..
|
||||
- name: Fetch ZLIB
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'madler/zlib'
|
||||
ref: 'v1.3.1'
|
||||
path: 'extern/zlib'
|
||||
- name: Build ZLIB
|
||||
shell: cmd
|
||||
run: |
|
||||
CD extern\zlib
|
||||
CALL ..\..\.github\scripts\zlib\windows.bat
|
||||
ECHO SET ZLIB_ROOT=%ZLIB_ROOT% >> ..\envs.bat
|
||||
CD ..\..
|
||||
- name: Fetch STB
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'nothings/stb'
|
||||
ref: '2e2bef463a5b53ddf8bb788e25da6b8506314c08'
|
||||
path: 'extern/stb'
|
||||
- name: Build STB
|
||||
shell: cmd
|
||||
run: |
|
||||
CD extern\stb
|
||||
CALL ..\..\.github\scripts\stb\windows.bat
|
||||
ECHO SET STB_ROOT=%STB_ROOT% >> ..\envs.bat
|
||||
CD ..\..
|
||||
- name: Build LibCmo
|
||||
shell: cmd
|
||||
run: |
|
||||
:: Prepare Visual Studio
|
||||
set VS=${{ matrix.vs }}
|
||||
set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
|
||||
call %VCVARS% ${{ matrix.msvc_arch }}
|
||||
:: Extract saved environment variables
|
||||
CALL .\extern\envs.bat
|
||||
:: Build Project
|
||||
CALL .\.github\scripts\windows.bat
|
||||
- name: Upload Built Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: LibCmo-windows-build
|
||||
path: bin/install/*
|
||||
retention-days: 30
|
||||
- name: Upload Built Dependencies
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: LibCmo-windows-dep
|
||||
path: extern/zlib/install/*
|
||||
retention-days: 30
|
||||
|
||||
19
.gitignore
vendored
19
.gitignore
vendored
@@ -1,19 +1,24 @@
|
||||
# -------------------- Personal --------------------
|
||||
## ======== Personal ========
|
||||
# Ignore build resources
|
||||
[Oo]ut/
|
||||
[Bb]uild/
|
||||
[Ii]nstall/
|
||||
[Ee]xtern/
|
||||
[Tt]emp/
|
||||
|
||||
# Ignore all possible test used Virtools files
|
||||
*.nmo
|
||||
*.cmo
|
||||
*.nms
|
||||
*.vmo
|
||||
|
||||
# Ignore temporary Visual Studio files and folders
|
||||
temp/
|
||||
out/
|
||||
# Ignore CMake generated stuff
|
||||
CMakeSettings.json
|
||||
|
||||
# -------------------- VSCode --------------------
|
||||
## ======== VSCode ========
|
||||
.vscode/
|
||||
|
||||
# -------------------- CMake --------------------
|
||||
## ======== CMake ========
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
@@ -26,7 +31,7 @@ compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# -------------------- Visual Studio --------------------
|
||||
## ======== Visual Studio ========
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
|
||||
4
Assets/BMapBindings/BMapSharp/BMapSharp.slnx
Normal file
4
Assets/BMapBindings/BMapSharp/BMapSharp.slnx
Normal file
@@ -0,0 +1,4 @@
|
||||
<Solution>
|
||||
<Project Path="BMapSharp/BMapSharp.csproj" />
|
||||
<Project Path="BMapSharpTestbench/BMapSharpTestbench.csproj" />
|
||||
</Solution>
|
||||
1227
Assets/BMapBindings/BMapSharp/BMapSharp/BMap.cs
Normal file
1227
Assets/BMapBindings/BMapSharp/BMapSharp/BMap.cs
Normal file
File diff suppressed because it is too large
Load Diff
303
Assets/BMapBindings/BMapSharp/BMapSharp/BMapMarshalers.cs
Normal file
303
Assets/BMapBindings/BMapSharp/BMapSharp/BMapMarshalers.cs
Normal file
@@ -0,0 +1,303 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace BMapSharp.BMapMarshalers {
|
||||
|
||||
// References:
|
||||
// https://stackoverflow.com/questions/18498452/how-do-i-write-a-custom-marshaler-which-allows-data-to-flow-from-native-to-manag
|
||||
// https://learn.microsoft.com/en-us/dotnet/fundamentals/runtime-libraries/system-runtime-interopservices-icustommarshaler
|
||||
//
|
||||
// NOTE: I do not create a member to store the object we are marshaling.
|
||||
// Because my binding do not have In, Out parameter. All parameters are In OR Out.
|
||||
// So there is no reason to keep that member.
|
||||
|
||||
// YYC MARK:
|
||||
// When receiving UTF8 string pointer given by BMap as managed string,
|
||||
// I don't know why Microsoft try to call ICustomMarshaler.CleanUpNativeData without calling ICustomMarshaler.MarshalManagedToNative.
|
||||
// It is trying to free the pointer managed by LibCmo self (for example, it will try to free we got string when getting object name)!
|
||||
// So as the compromise, we introduce 2 different marshalers for In / Out string marshaling respectively.
|
||||
// BMStringMarshaler for receiving string from BMap (OUT direction), and BMPOwnedStringMarshaler for passing string to BMap (IN direction).
|
||||
// The name of marshaler for string array marshaling also following this pattern.
|
||||
|
||||
public class BMStringMarshaler : ICustomMarshaler {
|
||||
private static readonly BMStringMarshaler INSTANCE = new BMStringMarshaler();
|
||||
|
||||
public static ICustomMarshaler GetInstance(string pstrCookie) {
|
||||
return BMStringMarshaler.INSTANCE;
|
||||
}
|
||||
|
||||
public IntPtr MarshalManagedToNative(object ManagedObj) {
|
||||
// For OUT direction, we do not convert any managed data into native data.
|
||||
// Return nullptr instead.
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData) {
|
||||
// Check nullptr
|
||||
if (pNativeData == IntPtr.Zero) return null;
|
||||
// Call self
|
||||
return BMStringMarshaler.ToManaged(pNativeData);
|
||||
}
|
||||
|
||||
public void CleanUpNativeData(IntPtr pNativeData) {
|
||||
// For OUT direction, we do not convert any managed data into native data.
|
||||
// Do nothing here.
|
||||
}
|
||||
|
||||
public void CleanUpManagedData(object ManagedObj) {
|
||||
// Managed data will be cleaned by C# GC.
|
||||
// So we do nothing here.
|
||||
}
|
||||
|
||||
public int GetNativeDataSize() {
|
||||
// Return -1 to indicate the size of the native data to be marshaled is variable.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the length in byte of given pointer represented C style string.
|
||||
/// </summary>
|
||||
/// <param name="ptr">The pointer for checking.</param>
|
||||
/// <returns>The length of C style string (NUL exclusive).</returns>
|
||||
internal static int GetCStringLength(IntPtr ptr) {
|
||||
int count = 0, unit = Marshal.SizeOf<byte>();
|
||||
while (Marshal.ReadByte(ptr) != (byte)0) {
|
||||
ptr += unit;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract managed string from given native pointer holding C style string data.
|
||||
/// This function is shared by 2 marshalers.
|
||||
/// </summary>
|
||||
/// <param name="ptr">Native pointer holding string data. Caller must make sure this pointer is not nullptr.</param>
|
||||
/// <returns>The extracted managed string data.</returns>
|
||||
internal static string ToManaged(IntPtr ptr) {
|
||||
// Get the length of given string.
|
||||
int szStringItemCount = BMStringMarshaler.GetCStringLength(ptr);
|
||||
int szStringItemSize = Marshal.SizeOf<byte>();
|
||||
// Prepare cache and copy string data
|
||||
byte[] encString = new byte[szStringItemCount];
|
||||
Marshal.Copy(ptr, encString, 0, szStringItemCount);
|
||||
// Decode string and return
|
||||
return Encoding.UTF8.GetString(encString);
|
||||
}
|
||||
}
|
||||
|
||||
public class BMOwnedStringMarshaler : ICustomMarshaler {
|
||||
private static readonly BMOwnedStringMarshaler INSTANCE = new BMOwnedStringMarshaler();
|
||||
|
||||
public static ICustomMarshaler GetInstance(string pstrCookie) {
|
||||
return BMOwnedStringMarshaler.INSTANCE;
|
||||
}
|
||||
|
||||
public IntPtr MarshalManagedToNative(object ManagedObj) {
|
||||
// Check requirements.
|
||||
if (ManagedObj is null) return IntPtr.Zero;
|
||||
string castManagedObj = ManagedObj as string;
|
||||
if (castManagedObj is null)
|
||||
throw new MarshalDirectiveException("BMStringMarshaler must be used on a string.");
|
||||
// Call self
|
||||
return BMOwnedStringMarshaler.ToNative(castManagedObj);
|
||||
}
|
||||
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData) {
|
||||
// For IN direction, we do not convert any native data into managed data.
|
||||
// Return null instead.
|
||||
return null;
|
||||
}
|
||||
|
||||
public void CleanUpNativeData(IntPtr pNativeData) {
|
||||
// Check nullptr
|
||||
if (pNativeData == IntPtr.Zero) return;
|
||||
// Free native pointer
|
||||
Marshal.FreeHGlobal(pNativeData);
|
||||
}
|
||||
|
||||
public void CleanUpManagedData(object ManagedObj) {
|
||||
// For IN direction, we do not convert any native data into managed data.
|
||||
// Do nothing here.
|
||||
}
|
||||
|
||||
public int GetNativeDataSize() {
|
||||
// Return -1 to indicate the size of the native data to be marshaled is variable.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert given string object to native data.
|
||||
/// This function is shared by 2 marshalers.
|
||||
/// </summary>
|
||||
/// <param name="obj">String object. Caller must make sure this object is not null.</param>
|
||||
/// <returns>The created native data pointer.</returns>
|
||||
internal static IntPtr ToNative(string obj) {
|
||||
// Encode string first
|
||||
byte[] encString = Encoding.UTF8.GetBytes(obj);
|
||||
// Allocate string memory with extra NUL.
|
||||
int szStringItemCount = encString.Length;
|
||||
int szStringItemSize = Marshal.SizeOf<byte>();
|
||||
IntPtr pString = Marshal.AllocHGlobal(szStringItemSize * (szStringItemCount + 1));
|
||||
// Copy encoded string data
|
||||
Marshal.Copy(encString, 0, pString, szStringItemCount);
|
||||
// Setup NUL
|
||||
Marshal.WriteByte(pString + (szStringItemSize * szStringItemCount), (byte)0);
|
||||
// Return value
|
||||
return pString;
|
||||
}
|
||||
}
|
||||
|
||||
// YYC MARK:
|
||||
// For respecting the standard of BMap,
|
||||
// the native memory we created for string array is a simple array and each item is a pointer to a NULL-terminated UTF8 string.
|
||||
// Please note the array self is also NULL-terminated otherwise we don't know its length.
|
||||
|
||||
public class BMStringArrayMarshaler : ICustomMarshaler {
|
||||
private static readonly BMStringArrayMarshaler INSTANCE = new BMStringArrayMarshaler();
|
||||
|
||||
public static ICustomMarshaler GetInstance(string pstrCookie) {
|
||||
return BMStringArrayMarshaler.INSTANCE;
|
||||
}
|
||||
|
||||
public IntPtr MarshalManagedToNative(object ManagedObj) {
|
||||
// For OUT direction, we do not convert any managed data into native data.
|
||||
// Return nullptr instead.
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData) {
|
||||
// Check nullptr
|
||||
if (pNativeData == IntPtr.Zero) return null;
|
||||
|
||||
// Get the length of array
|
||||
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
|
||||
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
|
||||
// Prepare array cache and read it.
|
||||
IntPtr[] apString = new IntPtr[szArrayItemCount];
|
||||
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
|
||||
|
||||
// Iterate the array and process each string one by one.
|
||||
string[] ret = new string[szArrayItemCount];
|
||||
for (int i = 0; i < szArrayItemCount; ++i) {
|
||||
// Get string pointer
|
||||
IntPtr pString = apString[i];
|
||||
if (pString == IntPtr.Zero) {
|
||||
ret[i] = null;
|
||||
continue;
|
||||
}
|
||||
// Extract string
|
||||
ret[i] = BMStringMarshaler.ToManaged(pString);
|
||||
}
|
||||
|
||||
// Return result
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void CleanUpNativeData(IntPtr pNativeData) {
|
||||
// For OUT direction, we do not convert any managed data into native data.
|
||||
// Do nothing here.
|
||||
}
|
||||
|
||||
public void CleanUpManagedData(object ManagedObj) {
|
||||
// Managed data will be cleaned by C# GC.
|
||||
// So we do nothing here.
|
||||
}
|
||||
|
||||
public int GetNativeDataSize() {
|
||||
// Return -1 to indicate the size of the native data to be marshaled is variable.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the length of array created by this marshaler.
|
||||
/// </summary>
|
||||
/// <param name="ptr">The pointer to array for checking.</param>
|
||||
/// <returns>The length of array (NULL terminal exclusive).</returns>
|
||||
internal static int GetArrayLength(IntPtr ptr) {
|
||||
int count = 0, unit = Marshal.SizeOf<IntPtr>();
|
||||
while (Marshal.ReadIntPtr(ptr) != IntPtr.Zero) {
|
||||
ptr += unit;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public class BMOwnedStringArrayMarshaler : ICustomMarshaler {
|
||||
private static readonly BMOwnedStringArrayMarshaler INSTANCE = new BMOwnedStringArrayMarshaler();
|
||||
|
||||
public static ICustomMarshaler GetInstance(string pstrCookie) {
|
||||
return BMOwnedStringArrayMarshaler.INSTANCE;
|
||||
}
|
||||
|
||||
public IntPtr MarshalManagedToNative(object ManagedObj) {
|
||||
// Check nullptr object.
|
||||
if (ManagedObj is null) return IntPtr.Zero;
|
||||
// Check argument type.
|
||||
string[] castManagedObj = ManagedObj as string[];
|
||||
if (castManagedObj is null)
|
||||
throw new MarshalDirectiveException("BMStringArrayMashaler must be used on an string array.");
|
||||
|
||||
// Allocate string items first
|
||||
int szArrayItemCount = castManagedObj.Length;
|
||||
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
|
||||
IntPtr[] apString = new IntPtr[szArrayItemCount];
|
||||
for (int i = 0; i < szArrayItemCount; ++i) {
|
||||
// Check null string
|
||||
string stringObj = castManagedObj[i];
|
||||
if (stringObj is null) apString[i] = IntPtr.Zero;
|
||||
else apString[i] = BMOwnedStringMarshaler.ToNative(stringObj);
|
||||
}
|
||||
|
||||
// Allocate array pointer now.
|
||||
IntPtr pArray = Marshal.AllocHGlobal(szArrayItemSize * (szArrayItemCount + 1));
|
||||
// Copy string pointer data
|
||||
Marshal.Copy(apString, 0, pArray, szArrayItemCount);
|
||||
// Setup NULL ternimal
|
||||
Marshal.WriteIntPtr(pArray + (szArrayItemSize * szArrayItemCount), IntPtr.Zero);
|
||||
|
||||
// Return value
|
||||
return pArray;
|
||||
}
|
||||
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData) {
|
||||
// For IN direction, we do not convert any native data into managed data.
|
||||
// Return null instead.
|
||||
return null;
|
||||
}
|
||||
|
||||
public void CleanUpNativeData(IntPtr pNativeData) {
|
||||
// Check nullptr
|
||||
if (pNativeData == IntPtr.Zero) return;
|
||||
|
||||
// Get the length of array
|
||||
int szArrayItemCount = BMStringArrayMarshaler.GetArrayLength(pNativeData);
|
||||
int szArrayItemSize = Marshal.SizeOf<IntPtr>();
|
||||
// Prepare array cache and read it.
|
||||
IntPtr[] apString = new IntPtr[szArrayItemCount];
|
||||
Marshal.Copy(pNativeData, apString, 0, szArrayItemCount);
|
||||
// Free array self
|
||||
Marshal.FreeHGlobal(pNativeData);
|
||||
|
||||
// Iterate the string pointer array and free them one by one.
|
||||
foreach (IntPtr pString in apString) {
|
||||
// Free string pointer
|
||||
if (pString == IntPtr.Zero) continue;
|
||||
Marshal.FreeHGlobal(pString);
|
||||
}
|
||||
}
|
||||
|
||||
public void CleanUpManagedData(object ManagedObj) {
|
||||
// For IN direction, we do not convert any native data into managed data.
|
||||
// Do nothing here.
|
||||
}
|
||||
|
||||
public int GetNativeDataSize() {
|
||||
// Return -1 to indicate the size of the native data to be marshaled is variable.
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,20 @@ using BMapSharp.VirtoolsTypes;
|
||||
|
||||
namespace BMapSharp.BMapWrapper {
|
||||
|
||||
/// <summary>
|
||||
/// BMapSharp module specific exception.
|
||||
/// </summary>
|
||||
public class BMapException : Exception {
|
||||
public BMapException() { }
|
||||
public BMapException(string message)
|
||||
: base(message) { }
|
||||
public BMapException(string message, Exception inner)
|
||||
: base(message, inner) { }
|
||||
public static void ThrowIfFailed(bool condition) {
|
||||
if (!condition) throw new BMapException("BMap operation failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The guard of native BMap environment.
|
||||
/// This class initialize native BMap environment when constructing and free it when destructing.
|
||||
@@ -375,24 +389,61 @@ namespace BMapSharp.BMapWrapper {
|
||||
|
||||
}
|
||||
|
||||
public class BM3dObject : BMObject {
|
||||
internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||
public class BM3dEntity : BMObject {
|
||||
internal BM3dEntity(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||
|
||||
public VxMatrix GetWorldMatrix() => getGenericValue<VxMatrix>(BMap.BM3dObject_GetWorldMatrix);
|
||||
public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dObject_SetWorldMatrix, mat);
|
||||
public VxMatrix GetWorldMatrix() => getGenericValue<VxMatrix>(BMap.BM3dEntity_GetWorldMatrix);
|
||||
public void SetWorldMatrix(VxMatrix mat) => setGenericValue<VxMatrix>(BMap.BM3dEntity_SetWorldMatrix, mat);
|
||||
|
||||
public BMMesh GetCurrentMesh() {
|
||||
BMapException.ThrowIfFailed(BMap.BM3dObject_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
|
||||
BMapException.ThrowIfFailed(BMap.BM3dEntity_GetCurrentMesh(getPointer(), getCKID(), out uint out_meshid));
|
||||
if (out_meshid == Utils.INVALID_CKID) return null;
|
||||
else return new BMMesh(getPointer(), out_meshid);
|
||||
}
|
||||
public void SetCurrentMesh(BMMesh mesh) {
|
||||
uint meshid = (mesh is null) ? Utils.INVALID_CKID : mesh.getCKID();
|
||||
BMapException.ThrowIfFailed(BMap.BM3dObject_SetCurrentMesh(getPointer(), getCKID(), meshid));
|
||||
BMapException.ThrowIfFailed(BMap.BM3dEntity_SetCurrentMesh(getPointer(), getCKID(), meshid));
|
||||
}
|
||||
|
||||
public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dObject_GetVisibility);
|
||||
public void SetVisibility(bool visb) => setGenericValue<bool>(BMap.BM3dObject_SetVisibility, visb);
|
||||
public bool GetVisibility() => getGenericValue<bool>(BMap.BM3dEntity_GetVisibility);
|
||||
public void SetVisibility(bool visb) => setGenericValue<bool>(BMap.BM3dEntity_SetVisibility, visb);
|
||||
}
|
||||
|
||||
public class BM3dObject : BM3dEntity {
|
||||
internal BM3dObject(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||
}
|
||||
|
||||
public class BMLight : BM3dEntity {
|
||||
internal BMLight(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||
|
||||
// Name `GetType` is conflict with C# base class function name.
|
||||
// So we add a `Light` prefix for it.
|
||||
public VXLIGHT_TYPE GetLightType() => getGenericValue<VXLIGHT_TYPE>(BMap.BMLight_GetType);
|
||||
public void SetLightType(VXLIGHT_TYPE val) => setGenericValue<VXLIGHT_TYPE>(BMap.BMLight_SetType, val);
|
||||
|
||||
public VxColor GetColor() => getGenericValue<VxColor>(BMap.BMLight_GetColor);
|
||||
public void SetColor(VxColor col) => setGenericValue<VxColor>(BMap.BMLight_SetColor, col);
|
||||
|
||||
public float GetConstantAttenuation() => getGenericValue<float>(BMap.BMLight_GetConstantAttenuation);
|
||||
public void SetConstantAttenuation(float val) => setGenericValue<float>(BMap.BMLight_SetConstantAttenuation, val);
|
||||
public float GetLinearAttenuation() => getGenericValue<float>(BMap.BMLight_GetLinearAttenuation);
|
||||
public void SetLinearAttenuation(float val) => setGenericValue<float>(BMap.BMLight_SetLinearAttenuation, val);
|
||||
public float GetQuadraticAttenuation() => getGenericValue<float>(BMap.BMLight_GetQuadraticAttenuation);
|
||||
public void SetQuadraticAttenuation(float val) => setGenericValue<float>(BMap.BMLight_SetQuadraticAttenuation, val);
|
||||
|
||||
public float GetRange() => getGenericValue<float>(BMap.BMLight_GetRange);
|
||||
public void SetRange(float val) => setGenericValue<float>(BMap.BMLight_SetRange, val);
|
||||
|
||||
public float GetHotSpot() => getGenericValue<float>(BMap.BMLight_GetHotSpot);
|
||||
public void SetHotSpot(float val) => setGenericValue<float>(BMap.BMLight_SetHotSpot, val);
|
||||
public float GetFalloff() => getGenericValue<float>(BMap.BMLight_GetFalloff);
|
||||
public void SetFalloff(float val) => setGenericValue<float>(BMap.BMLight_SetFalloff, val);
|
||||
public float GetFalloffShape() => getGenericValue<float>(BMap.BMLight_GetFalloffShape);
|
||||
public void SetFalloffShape(float val) => setGenericValue<float>(BMap.BMLight_SetFalloffShape, val);
|
||||
}
|
||||
|
||||
public class BMTargetLight : BMLight {
|
||||
internal BMTargetLight(IntPtr raw_pointer, uint ckid) : base(raw_pointer, ckid) { }
|
||||
}
|
||||
|
||||
public class BMGroup : BMObject {
|
||||
@@ -463,6 +514,10 @@ namespace BMapSharp.BMapWrapper {
|
||||
getCKObjectCount(BMap.BMFile_GetGroupCount);
|
||||
public IEnumerable<BMGroup> GetGroups() =>
|
||||
getCKObjects<BMGroup>(BMap.BMFile_GetGroupCount, BMap.BMFile_GetGroup, (bmf, id) => new BMGroup(bmf, id));
|
||||
public uint GetTargetLightCount() =>
|
||||
getCKObjectCount(BMap.BMFile_GetTargetLightCount);
|
||||
public IEnumerable<BMTargetLight> GetTargetLights() =>
|
||||
getCKObjects<BMTargetLight>(BMap.BMFile_GetTargetLightCount, BMap.BMFile_GetTargetLight, (bmf, id) => new BMTargetLight(bmf, id));
|
||||
|
||||
}
|
||||
|
||||
@@ -504,6 +559,7 @@ namespace BMapSharp.BMapWrapper {
|
||||
public BMMesh CreateMesh() => createCKObject<BMMesh>(BMap.BMFile_CreateMesh, (bmf, id) => new BMMesh(bmf, id));
|
||||
public BM3dObject Create3dObject() => createCKObject<BM3dObject>(BMap.BMFile_Create3dObject, (bmf, id) => new BM3dObject(bmf, id));
|
||||
public BMGroup CreateGroup() => createCKObject<BMGroup>(BMap.BMFile_CreateGroup, (bmf, id) => new BMGroup(bmf, id));
|
||||
public BMTargetLight CreateTargetLight() => createCKObject<BMTargetLight>(BMap.BMFile_CreateTargetLight, (bmf, id) => new BMTargetLight(bmf, id));
|
||||
}
|
||||
|
||||
public sealed class BMMeshTrans : AbstractPointer {
|
||||
638
Assets/BMapBindings/BMapSharp/BMapSharp/VirtoolsTypes.cs
Normal file
638
Assets/BMapBindings/BMapSharp/BMapSharp/VirtoolsTypes.cs
Normal file
@@ -0,0 +1,638 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Numerics;
|
||||
|
||||
namespace BMapSharp.VirtoolsTypes {
|
||||
|
||||
#region Structures
|
||||
|
||||
// NOTE: Structures defined in there is only served for marshaling.
|
||||
// You should not use them in hash set or anything else,
|
||||
// because they do not have proper hash function and compare function.
|
||||
// You should use the managed type generated by them instead.
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct VxVector2 {
|
||||
[MarshalAs(UnmanagedType.R4)]
|
||||
public float X, Y;
|
||||
|
||||
public VxVector2(float _x = 0.0f, float _y = 0.0f) {
|
||||
X = _x; Y = _y;
|
||||
}
|
||||
public VxVector2(Vector2 vec) {
|
||||
FromManaged(vec);
|
||||
}
|
||||
|
||||
public void FromManaged(Vector2 vec) {
|
||||
X = vec.X; Y = vec.Y;
|
||||
}
|
||||
public Vector2 ToManaged() {
|
||||
return new Vector2(X, Y);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct VxVector3 {
|
||||
[MarshalAs(UnmanagedType.R4)]
|
||||
public float X, Y, Z;
|
||||
|
||||
public VxVector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) {
|
||||
X = _x; Y = _y; Z = _z;
|
||||
}
|
||||
public VxVector3(Vector3 vec) {
|
||||
FromManaged(vec);
|
||||
}
|
||||
|
||||
public void FromManaged(Vector3 vec) {
|
||||
X = vec.X; Y = vec.Y; Z = vec.Z;
|
||||
}
|
||||
public Vector3 ToManaged() {
|
||||
return new Vector3(X, Y, Z);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct VxColor {
|
||||
[MarshalAs(UnmanagedType.R4)]
|
||||
public float R, G, B, A;
|
||||
|
||||
public VxColor(float _r, float _g, float _b, float _a) {
|
||||
A = _a; R = _r; G = _g; B = _b;
|
||||
Regulate();
|
||||
}
|
||||
public VxColor(Vector4 col) {
|
||||
FromManagedRGBA(col);
|
||||
}
|
||||
public VxColor(Vector3 col) {
|
||||
FromManagedRGB(col);
|
||||
}
|
||||
public VxColor(uint val) {
|
||||
FromDword(val);
|
||||
}
|
||||
|
||||
public void FromManagedRGBA(Vector4 col) {
|
||||
R = col.X; G = col.Y; B = col.Z; A = col.W;
|
||||
Regulate();
|
||||
}
|
||||
public Vector4 ToManagedRGBA() {
|
||||
return new Vector4(R, G, B, A);
|
||||
}
|
||||
public void FromManagedRGB(Vector3 col) {
|
||||
R = col.X; G = col.Y; B = col.Z; A = 1.0f;
|
||||
Regulate();
|
||||
}
|
||||
public Vector3 ToManagedRGB() {
|
||||
return new Vector3(R, G, B);
|
||||
}
|
||||
public void FromDword(uint val) {
|
||||
B = (val & 0xFFu) / 255.0f;
|
||||
val >>= 8;
|
||||
G = (val & 0xFFu) / 255.0f;
|
||||
val >>= 8;
|
||||
R = (val & 0xFFu) / 255.0f;
|
||||
val >>= 8;
|
||||
A = (val & 0xFFu) / 255.0f;
|
||||
}
|
||||
public uint ToDword() {
|
||||
// regulate self first
|
||||
Regulate();
|
||||
// build result
|
||||
uint val = 0u;
|
||||
val |= (uint)(A * 255.0f);
|
||||
val <<= 8;
|
||||
val |= (uint)(R * 255.0f);
|
||||
val <<= 8;
|
||||
val |= (uint)(G * 255.0f);
|
||||
val <<= 8;
|
||||
val |= (uint)(B * 255.0f);
|
||||
return val;
|
||||
}
|
||||
|
||||
public static float ClampFactor(float factor) {
|
||||
return System.Math.Clamp(factor, 0.0f, 1.0f);
|
||||
}
|
||||
public void Regulate() {
|
||||
A = ClampFactor(A);
|
||||
R = ClampFactor(R);
|
||||
G = ClampFactor(G);
|
||||
B = ClampFactor(B);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct VxMatrix {
|
||||
[MarshalAs(UnmanagedType.R4)]
|
||||
public float M11, M12, M13, M14;
|
||||
[MarshalAs(UnmanagedType.R4)]
|
||||
public float M21, M22, M23, M24;
|
||||
[MarshalAs(UnmanagedType.R4)]
|
||||
public float M31, M32, M33, M34;
|
||||
[MarshalAs(UnmanagedType.R4)]
|
||||
public float M41, M42, M43, M44;
|
||||
|
||||
public VxMatrix(float m11 = 1.0f, float m12 = 0.0f, float m13 = 0.0f, float m14 = 0.0f,
|
||||
float m21 = 0.0f, float m22 = 1.0f, float m23 = 0.0f, float m24 = 0.0f,
|
||||
float m31 = 0.0f, float m32 = 0.0f, float m33 = 1.0f, float m34 = 0.0f,
|
||||
float m41 = 0.0f, float m42 = 0.0f, float m43 = 0.0f, float m44 = 1.0f) {
|
||||
M11 = m11; M12 = m12; M13 = m13; M14 = m14;
|
||||
M21 = m21; M22 = m22; M23 = m23; M24 = m24;
|
||||
M31 = m31; M32 = m32; M33 = m33; M34 = m34;
|
||||
M41 = m41; M42 = m42; M43 = m43; M44 = m44;
|
||||
}
|
||||
public void Reset() {
|
||||
M11 = 1.0f; M12 = 0.0f; M13 = 0.0f; M14 = 0.0f;
|
||||
M21 = 0.0f; M22 = 1.0f; M23 = 0.0f; M24 = 0.0f;
|
||||
M31 = 0.0f; M32 = 0.0f; M33 = 1.0f; M34 = 0.0f;
|
||||
M41 = 0.0f; M42 = 0.0f; M43 = 0.0f; M44 = 1.0f;
|
||||
}
|
||||
public void FromManaged(Matrix4x4 mat) {
|
||||
M11 = mat.M11; M12 = mat.M12; M13 = mat.M13; M14 = mat.M14;
|
||||
M21 = mat.M21; M22 = mat.M22; M23 = mat.M23; M24 = mat.M24;
|
||||
M31 = mat.M31; M32 = mat.M32; M33 = mat.M33; M34 = mat.M34;
|
||||
M41 = mat.M41; M42 = mat.M42; M43 = mat.M43; M44 = mat.M44;
|
||||
}
|
||||
public Matrix4x4 ToManaged() {
|
||||
return new Matrix4x4(
|
||||
M11, M12, M13, M14,
|
||||
M21, M22, M23, M24,
|
||||
M31, M32, M33, M34,
|
||||
M41, M42, M43, M44
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct CKFaceIndices {
|
||||
[MarshalAs(UnmanagedType.U4)]
|
||||
public uint I1, I2, I3;
|
||||
|
||||
public CKFaceIndices(uint i1 = 0u, uint i2 = 0u, uint i3 = 0u) {
|
||||
I1 = i1;
|
||||
I2 = i2;
|
||||
I3 = i3;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
|
||||
public struct CKShortFaceIndices {
|
||||
[MarshalAs(UnmanagedType.U2)]
|
||||
public ushort I1, I2, I3;
|
||||
|
||||
public CKShortFaceIndices(ushort i1 = 0, ushort i2 = 0, ushort i3 = 0) {
|
||||
I1 = i1;
|
||||
I2 = i2;
|
||||
I3 = i3;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Enums
|
||||
|
||||
/// <summary>
|
||||
/// Specify the way textures or sprites will be saved
|
||||
/// </summary>
|
||||
public enum CK_TEXTURE_SAVEOPTIONS : uint {
|
||||
/// <summary>
|
||||
/// Save raw data inside file. The bitmap is saved in a raw 32 bit per pixel format.
|
||||
/// </summary>
|
||||
CKTEXTURE_RAWDATA = 0,
|
||||
/// <summary>
|
||||
/// Store only the file name for the texture. The bitmap file must be present in the bitmap pathswhen loading the composition.
|
||||
/// </summary>
|
||||
CKTEXTURE_EXTERNAL = 1,
|
||||
/// <summary>
|
||||
/// Save using format specified. The bitmap data will be converted to thespecified format by the correspondant bitmap plugin and saved inside file.
|
||||
/// </summary>
|
||||
CKTEXTURE_IMAGEFORMAT = 2,
|
||||
/// <summary>
|
||||
/// Use Global settings, that is the settings given with CKContext::SetGlobalImagesSaveOptions. (Not valid when using CKContext::SetImagesSaveOptions).
|
||||
/// </summary>
|
||||
CKTEXTURE_USEGLOBAL = 3,
|
||||
/// <summary>
|
||||
/// Insert original image file inside CMO file. The bitmap file thatwas used originally for the texture or sprite will be append tothe composition file and extracted when the file is loaded.
|
||||
/// </summary>
|
||||
CKTEXTURE_INCLUDEORIGINALFILE = 4,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Pixel format types.
|
||||
/// </summary>
|
||||
public enum VX_PIXELFORMAT : uint {
|
||||
/// <summary>
|
||||
/// Unknown pixel format
|
||||
/// </summary>
|
||||
UNKNOWN_PF = 0,
|
||||
/// <summary>
|
||||
/// 32-bit ARGB pixel format with alpha
|
||||
/// </summary>
|
||||
_32_ARGB8888 = 1,
|
||||
/// <summary>
|
||||
/// 32-bit RGB pixel format without alpha
|
||||
/// </summary>
|
||||
_32_RGB888 = 2,
|
||||
/// <summary>
|
||||
/// 24-bit RGB pixel format
|
||||
/// </summary>
|
||||
_24_RGB888 = 3,
|
||||
/// <summary>
|
||||
/// 16-bit RGB pixel format
|
||||
/// </summary>
|
||||
_16_RGB565 = 4,
|
||||
/// <summary>
|
||||
/// 16-bit RGB pixel format (5 bits per color)
|
||||
/// </summary>
|
||||
_16_RGB555 = 5,
|
||||
/// <summary>
|
||||
/// 16-bit ARGB pixel format (5 bits per color + 1 bit for alpha)
|
||||
/// </summary>
|
||||
_16_ARGB1555 = 6,
|
||||
/// <summary>
|
||||
/// 16-bit ARGB pixel format (4 bits per color)
|
||||
/// </summary>
|
||||
_16_ARGB4444 = 7,
|
||||
/// <summary>
|
||||
/// 8-bit RGB pixel format
|
||||
/// </summary>
|
||||
_8_RGB332 = 8,
|
||||
/// <summary>
|
||||
/// 8-bit ARGB pixel format
|
||||
/// </summary>
|
||||
_8_ARGB2222 = 9,
|
||||
/// <summary>
|
||||
/// 32-bit ABGR pixel format
|
||||
/// </summary>
|
||||
_32_ABGR8888 = 10,
|
||||
/// <summary>
|
||||
/// 32-bit RGBA pixel format
|
||||
/// </summary>
|
||||
_32_RGBA8888 = 11,
|
||||
/// <summary>
|
||||
/// 32-bit BGRA pixel format
|
||||
/// </summary>
|
||||
_32_BGRA8888 = 12,
|
||||
/// <summary>
|
||||
/// 32-bit BGR pixel format
|
||||
/// </summary>
|
||||
_32_BGR888 = 13,
|
||||
/// <summary>
|
||||
/// 24-bit BGR pixel format
|
||||
/// </summary>
|
||||
_24_BGR888 = 14,
|
||||
/// <summary>
|
||||
/// 16-bit BGR pixel format
|
||||
/// </summary>
|
||||
_16_BGR565 = 15,
|
||||
/// <summary>
|
||||
/// 16-bit BGR pixel format (5 bits per color)
|
||||
/// </summary>
|
||||
_16_BGR555 = 16,
|
||||
/// <summary>
|
||||
/// 16-bit ABGR pixel format (5 bits per color + 1 bit for alpha)
|
||||
/// </summary>
|
||||
_16_ABGR1555 = 17,
|
||||
/// <summary>
|
||||
/// 16-bit ABGR pixel format (4 bits per color)
|
||||
/// </summary>
|
||||
_16_ABGR4444 = 18,
|
||||
/// <summary>
|
||||
/// S3/DirectX Texture Compression 1
|
||||
/// </summary>
|
||||
_DXT1 = 19,
|
||||
/// <summary>
|
||||
/// S3/DirectX Texture Compression 2
|
||||
/// </summary>
|
||||
_DXT2 = 20,
|
||||
/// <summary>
|
||||
/// S3/DirectX Texture Compression 3
|
||||
/// </summary>
|
||||
_DXT3 = 21,
|
||||
/// <summary>
|
||||
/// S3/DirectX Texture Compression 4
|
||||
/// </summary>
|
||||
_DXT4 = 22,
|
||||
/// <summary>
|
||||
/// S3/DirectX Texture Compression 5
|
||||
/// </summary>
|
||||
_DXT5 = 23,
|
||||
/// <summary>
|
||||
/// 16-bit Bump Map format format (8 bits per color)
|
||||
/// </summary>
|
||||
_16_V8U8 = 24,
|
||||
/// <summary>
|
||||
/// 32-bit Bump Map format format (16 bits per color)
|
||||
/// </summary>
|
||||
_32_V16U16 = 25,
|
||||
/// <summary>
|
||||
/// 16-bit Bump Map format format with luminance
|
||||
/// </summary>
|
||||
_16_L6V5U5 = 26,
|
||||
/// <summary>
|
||||
/// 32-bit Bump Map format format with luminance
|
||||
/// </summary>
|
||||
_32_X8L8V8U8 = 27,
|
||||
/// <summary>
|
||||
/// 8 bits indexed CLUT (ABGR)
|
||||
/// </summary>
|
||||
_8_ABGR8888_CLUT = 28,
|
||||
/// <summary>
|
||||
/// 8 bits indexed CLUT (ARGB)
|
||||
/// </summary>
|
||||
_8_ARGB8888_CLUT = 29,
|
||||
/// <summary>
|
||||
/// 4 bits indexed CLUT (ABGR)
|
||||
/// </summary>
|
||||
_4_ABGR8888_CLUT = 30,
|
||||
/// <summary>
|
||||
/// 4 bits indexed CLUT (ARGB)
|
||||
/// </summary>
|
||||
_4_ARGB8888_CLUT = 31,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Light type.
|
||||
/// </summary>
|
||||
public enum VXLIGHT_TYPE : uint {
|
||||
/// <summary>
|
||||
/// The Light is a point of light
|
||||
/// </summary>
|
||||
VX_LIGHTPOINT = 1U,
|
||||
/// <summary>
|
||||
/// The light is a spotlight
|
||||
/// </summary>
|
||||
VX_LIGHTSPOT = 2U,
|
||||
/// <summary>
|
||||
/// The light is directional light : Lights comes from an infinite point so only direction of light can be given
|
||||
/// </summary>
|
||||
VX_LIGHTDIREC = 3U,
|
||||
// /// <summary>
|
||||
// /// Obsolete, do not use
|
||||
// /// </summary>
|
||||
// VX_LIGHTPARA = 4U,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Blend Mode Flags
|
||||
/// </summary>
|
||||
public enum VXTEXTURE_BLENDMODE : uint {
|
||||
/// <summary>
|
||||
/// Texture replace any material information
|
||||
/// </summary>
|
||||
VXTEXTUREBLEND_DECAL = 1U,
|
||||
/// <summary>
|
||||
/// Texture and material are combine. Alpha information of the texture replace material alpha component.
|
||||
/// </summary>
|
||||
VXTEXTUREBLEND_MODULATE = 2U,
|
||||
/// <summary>
|
||||
/// Alpha information in the texture specify how material and texture are combined. Alpha information of the texture replace material alpha component.
|
||||
/// </summary>
|
||||
VXTEXTUREBLEND_DECALALPHA = 3U,
|
||||
/// <summary>
|
||||
/// Alpha information in the texture specify how material and texture are combined
|
||||
/// </summary>
|
||||
VXTEXTUREBLEND_MODULATEALPHA = 4U,
|
||||
VXTEXTUREBLEND_DECALMASK = 5U,
|
||||
VXTEXTUREBLEND_MODULATEMASK = 6U,
|
||||
/// <summary>
|
||||
/// Equivalent to DECAL
|
||||
/// </summary>
|
||||
VXTEXTUREBLEND_COPY = 7U,
|
||||
VXTEXTUREBLEND_ADD = 8U,
|
||||
/// <summary>
|
||||
/// Perform a Dot Product 3 between texture (normal map)and a referential vector given in VXRENDERSTATE_TEXTUREFACTOR.
|
||||
/// </summary>
|
||||
VXTEXTUREBLEND_DOTPRODUCT3 = 9U,
|
||||
VXTEXTUREBLEND_MAX = 10U,
|
||||
// VXTEXTUREBLEND_MASK = 0xFU,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Filter Mode Options
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum VXTEXTURE_FILTERMODE : uint {
|
||||
/// <summary>
|
||||
/// No Filter
|
||||
/// </summary>
|
||||
VXTEXTUREFILTER_NEAREST = 1U,
|
||||
/// <summary>
|
||||
/// Bilinear Interpolation
|
||||
/// </summary>
|
||||
VXTEXTUREFILTER_LINEAR = 2U,
|
||||
/// <summary>
|
||||
/// Mip mapping
|
||||
/// </summary>
|
||||
VXTEXTUREFILTER_MIPNEAREST = 3U,
|
||||
/// <summary>
|
||||
/// Mip Mapping with Bilinear interpolation
|
||||
/// </summary>
|
||||
VXTEXTUREFILTER_MIPLINEAR = 4U,
|
||||
/// <summary>
|
||||
/// Mip Mapping with Bilinear interpolation between mipmap levels.
|
||||
/// </summary>
|
||||
VXTEXTUREFILTER_LINEARMIPNEAREST = 5U,
|
||||
/// <summary>
|
||||
/// Trilinear Filtering
|
||||
/// </summary>
|
||||
VXTEXTUREFILTER_LINEARMIPLINEAR = 6U,
|
||||
/// <summary>
|
||||
/// Anisotropic filtering
|
||||
/// </summary>
|
||||
VXTEXTUREFILTER_ANISOTROPIC = 7U,
|
||||
// VXTEXTUREFILTER_MASK = 0xFU,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Texture addressing modes.
|
||||
/// </summary>
|
||||
public enum VXTEXTURE_ADDRESSMODE : uint {
|
||||
/// <summary>
|
||||
/// Default mesh wrap mode is used (see CKMesh::SetWrapMode)
|
||||
/// </summary>
|
||||
VXTEXTURE_ADDRESSWRAP = 1U,
|
||||
/// <summary>
|
||||
/// Texture coordinates outside the range [0..1] are flipped evenly.
|
||||
/// </summary>
|
||||
VXTEXTURE_ADDRESSMIRROR = 2U,
|
||||
/// <summary>
|
||||
/// Texture coordinates greater than 1.0 are set to 1.0, and values less than 0.0 are set to 0.0.
|
||||
/// </summary>
|
||||
VXTEXTURE_ADDRESSCLAMP = 3U,
|
||||
/// <summary>
|
||||
/// When texture coordinates are greater than 1.0 or less than 0.0 texture is set to a color defined in CKMaterial::SetTextureBorderColor.
|
||||
/// </summary>
|
||||
VXTEXTURE_ADDRESSBORDER = 4U,
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
VXTEXTURE_ADDRESSMIRRORONCE = 5U,
|
||||
/// <summary>
|
||||
/// mask for all values
|
||||
/// </summary>
|
||||
// VXTEXTURE_ADDRESSMASK = 0x7U,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Blending Mode options
|
||||
/// </summary>
|
||||
public enum VXBLEND_MODE : uint {
|
||||
/// <summary>
|
||||
/// Blend factor is (0, 0, 0, 0).
|
||||
/// </summary>
|
||||
VXBLEND_ZERO = 1U,
|
||||
/// <summary>
|
||||
/// Blend factor is (1, 1, 1, 1).
|
||||
/// </summary>
|
||||
VXBLEND_ONE = 2U,
|
||||
/// <summary>
|
||||
/// Blend factor is (Rs, Gs, Bs, As).
|
||||
/// </summary>
|
||||
VXBLEND_SRCCOLOR = 3U,
|
||||
/// <summary>
|
||||
/// Blend factor is (1-Rs, 1-Gs, 1-Bs, 1-As).
|
||||
/// </summary>
|
||||
VXBLEND_INVSRCCOLOR = 4U,
|
||||
/// <summary>
|
||||
/// Blend factor is (As, As, As, As).
|
||||
/// </summary>
|
||||
VXBLEND_SRCALPHA = 5U,
|
||||
/// <summary>
|
||||
/// Blend factor is (1-As, 1-As, 1-As, 1-As).
|
||||
/// </summary>
|
||||
VXBLEND_INVSRCALPHA = 6U,
|
||||
/// <summary>
|
||||
/// Blend factor is (Ad, Ad, Ad, Ad).
|
||||
/// </summary>
|
||||
VXBLEND_DESTALPHA = 7U,
|
||||
/// <summary>
|
||||
/// Blend factor is (1-Ad, 1-Ad, 1-Ad, 1-Ad).
|
||||
/// </summary>
|
||||
VXBLEND_INVDESTALPHA = 8U,
|
||||
/// <summary>
|
||||
/// Blend factor is (Rd, Gd, Bd, Ad).
|
||||
/// </summary>
|
||||
VXBLEND_DESTCOLOR = 9U,
|
||||
/// <summary>
|
||||
/// Blend factor is (1-Rd, 1-Gd, 1-Bd, 1-Ad).
|
||||
/// </summary>
|
||||
VXBLEND_INVDESTCOLOR = 10U,
|
||||
/// <summary>
|
||||
/// Blend factor is (f, f, f, 1); f = min(As, 1-Ad).
|
||||
/// </summary>
|
||||
VXBLEND_SRCALPHASAT = 11U,
|
||||
// /// <summary>
|
||||
// /// Source blend factor is (As, As, As, As) and destination blend factor is (1-As, 1-As, 1-As, 1-As)
|
||||
// /// </summary>
|
||||
// VXBLEND_BOTHSRCALPHA = 12U,
|
||||
// /// <summary>
|
||||
// /// Source blend factor is (1-As, 1-As, 1-As, 1-As) and destination blend factor is (As, As, As, As)
|
||||
// /// </summary>
|
||||
// VXBLEND_BOTHINVSRCALPHA = 13U,
|
||||
// /// <summary>
|
||||
// /// Source blend factor is (1-As, 1-As, 1-As, 1-As) and destination blend factor is (As, As, As, As)
|
||||
// /// </summary>
|
||||
// VXBLEND_MASK = 0xFU,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fill Mode Options
|
||||
/// </summary>
|
||||
public enum VXFILL_MODE : uint {
|
||||
/// <summary>
|
||||
/// Vertices rendering
|
||||
/// </summary>
|
||||
VXFILL_POINT = 1U,
|
||||
/// <summary>
|
||||
/// Edges rendering
|
||||
/// </summary>
|
||||
VXFILL_WIREFRAME = 2U,
|
||||
/// <summary>
|
||||
/// Face rendering
|
||||
/// </summary>
|
||||
VXFILL_SOLID = 3U,
|
||||
// VXFILL_MASK = 3U,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shade Mode Options
|
||||
/// </summary>
|
||||
public enum VXSHADE_MODE : uint {
|
||||
/// <summary>
|
||||
/// Flat Shading
|
||||
/// </summary>
|
||||
VXSHADE_FLAT = 1U,
|
||||
/// <summary>
|
||||
/// Gouraud Shading
|
||||
/// </summary>
|
||||
VXSHADE_GOURAUD = 2U,
|
||||
/// <summary>
|
||||
/// Phong Shading (Not yet supported by most implementation)
|
||||
/// </summary>
|
||||
VXSHADE_PHONG = 3U,
|
||||
// VXSHADE_MASK = 3U,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Comparison Function
|
||||
/// </summary>
|
||||
public enum VXCMPFUNC : uint {
|
||||
/// <summary>
|
||||
/// Always fail the test.
|
||||
/// </summary>
|
||||
VXCMP_NEVER = 1U,
|
||||
/// <summary>
|
||||
/// Accept if value if less than current value.
|
||||
/// </summary>
|
||||
VXCMP_LESS = 2U,
|
||||
/// <summary>
|
||||
/// Accept if value if equal than current value.
|
||||
/// </summary>
|
||||
VXCMP_EQUAL = 3U,
|
||||
/// <summary>
|
||||
/// Accept if value if less or equal than current value.
|
||||
/// </summary>
|
||||
VXCMP_LESSEQUAL = 4U,
|
||||
/// <summary>
|
||||
/// Accept if value if greater than current value.
|
||||
/// </summary>
|
||||
VXCMP_GREATER = 5U,
|
||||
/// <summary>
|
||||
/// Accept if value if different than current value.
|
||||
/// </summary>
|
||||
VXCMP_NOTEQUAL = 6U,
|
||||
/// <summary>
|
||||
/// Accept if value if greater or equal current value.
|
||||
/// </summary>
|
||||
VXCMP_GREATEREQUAL = 7U,
|
||||
/// <summary>
|
||||
/// Always accept the test.
|
||||
/// </summary>
|
||||
VXCMP_ALWAYS = 8U,
|
||||
// /// <summary>
|
||||
// /// Mask for all possible values.
|
||||
// /// </summary>
|
||||
// VXCMP_MASK = 0xFU,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mesh lighting options
|
||||
/// </summary>
|
||||
public enum VXMESH_LITMODE : uint {
|
||||
/// <summary>
|
||||
/// Lighting use color information store with vertices
|
||||
/// </summary>
|
||||
VX_PRELITMESH = 0,
|
||||
/// <summary>
|
||||
/// Lighting is done by renderer using normals and face material information.
|
||||
/// </summary>
|
||||
VX_LITMESH = 1,
|
||||
}
|
||||
|
||||
public enum CK_CAMERA_PROJECTION : uint {
|
||||
CK_PERSPECTIVEPROJECTION = 1,
|
||||
CK_ORTHOGRAPHICPROJECTION = 2,
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -4,6 +4,10 @@
|
||||
<ProjectReference Include="..\BMapSharp\BMapSharp.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
219
Assets/BMapBindings/BMapSharp/BMapSharpTestbench/Program.cs
Normal file
219
Assets/BMapBindings/BMapSharp/BMapSharpTestbench/Program.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
using BMapSharp.BMapWrapper;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.CommandLine;
|
||||
|
||||
namespace BMapSharpTestbench {
|
||||
internal class Program {
|
||||
|
||||
static void Main(string[] args) {
|
||||
// Parse arguments
|
||||
var resolved_args = ResolveArguments(args);
|
||||
if (resolved_args is null) {
|
||||
// just silent quit
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
// Check environment
|
||||
Console.OutputEncoding = Encoding.UTF8;
|
||||
if (!BMapSharp.BMapWrapper.Utils.IsBMapAvailable()) {
|
||||
Console.WriteLine("Fail to initialize native BMap.");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
// Waiting debugger
|
||||
int pid = System.Diagnostics.Process.GetCurrentProcess().Id;
|
||||
Console.WriteLine($"C# PID is {pid}. Waiting debugger, press any key to continue...");
|
||||
Console.ReadKey(true);
|
||||
|
||||
// Start testbench
|
||||
string file_name = resolved_args.mFileName; // "LightCameraTest.nmo";
|
||||
string temp_folder = resolved_args.mTempFolder; // "Temp";
|
||||
string texture_folder = resolved_args.mTextureFolder; // "F:\\Ballance\\Ballance\\Textures";
|
||||
string[] encodings = resolved_args.mEncodings; // ["cp1252", "gb2312"];
|
||||
|
||||
using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) {
|
||||
TestCommon(reader);
|
||||
TestIEquatable(reader);
|
||||
}
|
||||
|
||||
Console.WriteLine("Press any key to quit...");
|
||||
Console.ReadKey(true);
|
||||
|
||||
}
|
||||
|
||||
class BMapSharpArguments {
|
||||
public string mFileName;
|
||||
public string mTempFolder;
|
||||
public string mTextureFolder;
|
||||
public string[] mEncodings;
|
||||
}
|
||||
|
||||
static BMapSharpArguments ResolveArguments(string[] args) {
|
||||
// define arguments
|
||||
var fileNameOpt = new Option<string>
|
||||
("--file-path", "The path to input Virtools file.");
|
||||
fileNameOpt.IsRequired = true;
|
||||
var tempFolderOpt = new Option<string>
|
||||
("--temp-dir", "The temp folder used by BMap.");
|
||||
tempFolderOpt.IsRequired = true;
|
||||
var textureFolderOpt = new Option<string>
|
||||
("--texture-dir", "The texture folder containing Ballance texture resources.");
|
||||
textureFolderOpt.IsRequired = true;
|
||||
var encodingsOpt = new Option<IEnumerable<string>>
|
||||
("--encodings", "The encodings used to parse the names stroed in input Virtools file.");
|
||||
encodingsOpt.IsRequired = true;
|
||||
encodingsOpt.Arity = ArgumentArity.OneOrMore;
|
||||
encodingsOpt.AllowMultipleArgumentsPerToken = true;
|
||||
|
||||
// init root command
|
||||
var rootCommand = new RootCommand("The testbench of BMapSharp.");
|
||||
rootCommand.Add(fileNameOpt);
|
||||
rootCommand.Add(tempFolderOpt);
|
||||
rootCommand.Add(textureFolderOpt);
|
||||
rootCommand.Add(encodingsOpt);
|
||||
|
||||
// init result container
|
||||
BMapSharpArguments ret = new BMapSharpArguments();
|
||||
// set handler
|
||||
rootCommand.SetHandler((context) => {
|
||||
ret.mFileName = context.ParseResult.GetValueForOption(fileNameOpt);
|
||||
ret.mTempFolder = context.ParseResult.GetValueForOption(tempFolderOpt);
|
||||
ret.mTextureFolder = context.ParseResult.GetValueForOption(textureFolderOpt);
|
||||
ret.mEncodings = context.ParseResult.GetValueForOption(encodingsOpt).ToArray();
|
||||
context.ExitCode = 61;
|
||||
});
|
||||
|
||||
// execute root command and return value.
|
||||
if (rootCommand.Invoke(args) != 61) return null;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void TestCommon(BMapSharp.BMapWrapper.BMFileReader reader) {
|
||||
// Console.WriteLine("===== Groups =====");
|
||||
// foreach (var gp in reader.GetGroups()) {
|
||||
// Console.WriteLine(gp.GetName());
|
||||
// foreach (var gp_item in gp.GetObjects()) {
|
||||
// Console.WriteLine($"\t{gp_item.GetName()}");
|
||||
// }
|
||||
// }
|
||||
|
||||
// Console.WriteLine("===== 3dObjects =====");
|
||||
// foreach (var obj in reader.Get3dObjects()) {
|
||||
// Console.WriteLine(obj.GetName());
|
||||
|
||||
// var current_mesh = obj.GetCurrentMesh();
|
||||
// var mesh_name = current_mesh is null ? "<null>" : current_mesh.GetName();
|
||||
// Console.WriteLine($"\tMesh: {mesh_name}");
|
||||
// Console.WriteLine($"\tVisibility: {obj.GetVisibility()}");
|
||||
// Console.WriteLine($"\tMatrix: {obj.GetWorldMatrix().ToManaged()}");
|
||||
// }
|
||||
|
||||
// Console.WriteLine("===== Meshes =====");
|
||||
// foreach (var mesh in reader.GetMeshes()) {
|
||||
// Console.WriteLine(mesh.GetName());
|
||||
|
||||
// Console.WriteLine($"\tLit Mode: {mesh.GetLitMode()}");
|
||||
// Console.WriteLine($"\tVertex Count: {mesh.GetVertexCount()}");
|
||||
// Console.WriteLine($"\tFace Count: {mesh.GetFaceCount()}");
|
||||
// Console.WriteLine($"\tMaterial Slot Count: {mesh.GetMaterialSlotCount()}");
|
||||
// }
|
||||
|
||||
// Console.WriteLine("===== Materials =====");
|
||||
// foreach (var mtl in reader.GetMaterials()) {
|
||||
// Console.WriteLine(mtl.GetName());
|
||||
|
||||
// Console.WriteLine($"\tDiffuse: {mtl.GetDiffuse().ToManagedRGBA()}");
|
||||
// Console.WriteLine($"\tAmbient: {mtl.GetAmbient().ToManagedRGBA()}");
|
||||
// Console.WriteLine($"\tSpecular: {mtl.GetSpecular().ToManagedRGBA()}");
|
||||
// Console.WriteLine($"\tEmissive: {mtl.GetEmissive().ToManagedRGBA()}");
|
||||
|
||||
// Console.WriteLine($"\tSpecular Power: {mtl.GetSpecularPower()}");
|
||||
|
||||
// Console.WriteLine($"\tTexture Border Color: {mtl.GetTextureBorderColor().ToManagedRGBA()}");
|
||||
|
||||
// Console.WriteLine($"\tTexture Blend Mode: {mtl.GetTextureBlendMode()}");
|
||||
// Console.WriteLine($"\tTexture Min Mode: {mtl.GetTextureMinMode()}");
|
||||
// Console.WriteLine($"\tTexture Mag Mode: {mtl.GetTextureMagMode()}");
|
||||
// Console.WriteLine($"\tSource Blend: {mtl.GetSourceBlend()}");
|
||||
// Console.WriteLine($"\tDest Blend: {mtl.GetDestBlend()}");
|
||||
// Console.WriteLine($"\tFill Mode: {mtl.GetFillMode()}");
|
||||
// Console.WriteLine($"\tShade Mode: {mtl.GetShadeMode()}");
|
||||
|
||||
// Console.WriteLine($"\tAlpha Test Enabled: {mtl.GetAlphaTestEnabled()}");
|
||||
// Console.WriteLine($"\tAlpha Blend Enabled: {mtl.GetAlphaBlendEnabled()}");
|
||||
// Console.WriteLine($"\tPerspective Correction Enabled: {mtl.GetPerspectiveCorrectionEnabled()}");
|
||||
// Console.WriteLine($"\tZ Write Enabled: {mtl.GetZWriteEnabled()}");
|
||||
// Console.WriteLine($"\tTwo Sided Enabled: {mtl.GetTwoSidedEnabled()}");
|
||||
|
||||
// Console.WriteLine($"\tAlpha Ref: {mtl.GetAlphaRef()}");
|
||||
|
||||
// Console.WriteLine($"\tAlpha Func: {mtl.GetAlphaFunc()}");
|
||||
// Console.WriteLine($"\tZ Func: {mtl.GetZFunc()}");
|
||||
// }
|
||||
|
||||
// Console.WriteLine("===== Textures =====");
|
||||
// foreach (var tex in reader.GetTextures()) {
|
||||
// Console.WriteLine(tex.GetName());
|
||||
|
||||
// Console.WriteLine($"\tFile Name: {tex.GetFileName()}");
|
||||
// Console.WriteLine($"\tSave Options: {tex.GetSaveOptions()}");
|
||||
// Console.WriteLine($"\tVideo Format: {tex.GetVideoFormat()}");
|
||||
// }
|
||||
|
||||
Console.WriteLine("===== Target Lights =====");
|
||||
foreach (var lit in reader.GetTargetLights()) {
|
||||
Console.WriteLine(lit.GetName());
|
||||
|
||||
Console.WriteLine($"\tVisibility: {lit.GetVisibility()}");
|
||||
Console.WriteLine($"\tMatrix: {lit.GetWorldMatrix().ToManaged()}");
|
||||
|
||||
Console.WriteLine($"Type: {lit.GetLightType()}");
|
||||
Console.WriteLine($"Color: {lit.GetColor().ToManagedRGBA()}");
|
||||
Console.WriteLine($"Constant Attenuation: {lit.GetConstantAttenuation()}");
|
||||
Console.WriteLine($"Linear Attenuation: {lit.GetLinearAttenuation()}");
|
||||
Console.WriteLine($"Quadratic Attenuation: {lit.GetQuadraticAttenuation()}");
|
||||
Console.WriteLine($"Range: {lit.GetRange()}");
|
||||
Console.WriteLine($"Hot Spot: {lit.GetHotSpot()}");
|
||||
Console.WriteLine($"Falloff: {lit.GetFalloff()}");
|
||||
Console.WriteLine($"Falloff Shape: {lit.GetFalloffShape()}");
|
||||
}
|
||||
|
||||
Console.WriteLine("===== END =====");
|
||||
}
|
||||
|
||||
static void TestIEquatable(BMapSharp.BMapWrapper.BMFileReader reader) {
|
||||
if (reader.Get3dObjectCount() < 2u) {
|
||||
Debug.Fail(
|
||||
"Invalid file for test IEquatable.",
|
||||
"We can not perform IEquatable test because the length of 3dObject is too short (must greater than 2). Please choose another file to perform."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare test variables
|
||||
var all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
|
||||
var first_3dobj = all_3dobjects[0];
|
||||
var second_3dobj = all_3dobjects[1];
|
||||
all_3dobjects = new List<BM3dObject>(reader.Get3dObjects());
|
||||
var first_3dobj_again = all_3dobjects[0];
|
||||
Debug.Assert(!Object.ReferenceEquals(first_3dobj, first_3dobj_again));
|
||||
|
||||
// Hashtable test
|
||||
var test_hashset = new HashSet<BM3dObject>();
|
||||
Debug.Assert(test_hashset.Add(first_3dobj));
|
||||
Debug.Assert(!test_hashset.Add(first_3dobj_again));
|
||||
Debug.Assert(test_hashset.Add(second_3dobj));
|
||||
|
||||
// Dictionary test
|
||||
var test_dictionary = new Dictionary<BM3dObject, string>();
|
||||
Debug.Assert(test_dictionary.TryAdd(first_3dobj, first_3dobj.GetName()));
|
||||
Debug.Assert(!test_dictionary.TryAdd(first_3dobj_again, first_3dobj_again.GetName()));
|
||||
Debug.Assert(test_dictionary.TryAdd(second_3dobj, second_3dobj.GetName()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,3 +5,5 @@ The core of BMapSharp project is placed within `BMapSharp` subdirectory. This di
|
||||
The native BMap library should be placed together with managed `BMapSharp` dynamic library. I use gitignore file to filter all native binary so you need put them manually. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`.
|
||||
|
||||
The most content of `VirtoolsTypes.cs` is generated by EnumsMigration, and the most content of `BMap.cs` is generated by BMapBindings. You should watch these file changes if corresponding C++ code or structures are changed.
|
||||
|
||||
Since BMap 0.3.0, testbench use command line arguments, instead of hardcode variables in code, as the arguments of BMap. It is convenient that debug BMapSharp without any modification of source code. For a brief instruction, you may need to launch BMapSharpTestbench in following command (just an example. you can modify it as you wished): `dotnet run -- --file-path "LightCameraTest.nmo" --temp-dir "Temp" --texture-dir "F:/Ballance/Ballance/Textures" --encodings cp1252 gb2312`.
|
||||
@@ -227,6 +227,22 @@ BMFile_GetTexture = _create_bmap_func('BMFile_GetTexture', [bm_void_p, bm_CKDWOR
|
||||
# @param out_id[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMFile_CreateTexture = _create_bmap_func('BMFile_CreateTexture', [bm_void_p, bm_CKID_p])
|
||||
## BMFile_GetTargetLightCount
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param out_count[out] Type: LibCmo::CKDWORD. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMFile_GetTargetLightCount = _create_bmap_func('BMFile_GetTargetLightCount', [bm_void_p, bm_CKDWORD_p])
|
||||
## BMFile_GetTargetLight
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param idx[in] Type: LibCmo::CKDWORD.
|
||||
# @param out_id[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMFile_GetTargetLight = _create_bmap_func('BMFile_GetTargetLight', [bm_void_p, bm_CKDWORD, bm_CKID_p])
|
||||
## BMFile_CreateTargetLight
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param out_id[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMFile_CreateTargetLight = _create_bmap_func('BMFile_CreateTargetLight', [bm_void_p, bm_CKID_p])
|
||||
## BMMeshTrans_New
|
||||
# @param out_trans[out] Type: BMap::BMMeshTransition*. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
@@ -747,42 +763,150 @@ BMMesh_GetMaterialSlot = _create_bmap_func('BMMesh_GetMaterialSlot', [bm_void_p,
|
||||
# @param mtlid[in] Type: LibCmo::CK2::CK_ID.
|
||||
# @return True if no error, otherwise False.
|
||||
BMMesh_SetMaterialSlot = _create_bmap_func('BMMesh_SetMaterialSlot', [bm_void_p, bm_CKID, bm_CKDWORD, bm_CKID])
|
||||
## BM3dObject_GetWorldMatrix
|
||||
## BM3dEntity_GetWorldMatrix
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_mat[out] Type: LibCmo::VxMath::VxMatrix. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_GetWorldMatrix = _create_bmap_func('BM3dObject_GetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix_p])
|
||||
## BM3dObject_SetWorldMatrix
|
||||
BM3dEntity_GetWorldMatrix = _create_bmap_func('BM3dEntity_GetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix_p])
|
||||
## BM3dEntity_SetWorldMatrix
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param mat[in] Type: LibCmo::VxMath::VxMatrix.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_SetWorldMatrix = _create_bmap_func('BM3dObject_SetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix])
|
||||
## BM3dObject_GetCurrentMesh
|
||||
BM3dEntity_SetWorldMatrix = _create_bmap_func('BM3dEntity_SetWorldMatrix', [bm_void_p, bm_CKID, bm_VxMatrix])
|
||||
## BM3dEntity_GetCurrentMesh
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_meshid[out] Type: LibCmo::CK2::CK_ID. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_GetCurrentMesh = _create_bmap_func('BM3dObject_GetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID_p])
|
||||
## BM3dObject_SetCurrentMesh
|
||||
BM3dEntity_GetCurrentMesh = _create_bmap_func('BM3dEntity_GetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID_p])
|
||||
## BM3dEntity_SetCurrentMesh
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param meshid[in] Type: LibCmo::CK2::CK_ID.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_SetCurrentMesh = _create_bmap_func('BM3dObject_SetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID])
|
||||
## BM3dObject_GetVisibility
|
||||
BM3dEntity_SetCurrentMesh = _create_bmap_func('BM3dEntity_SetCurrentMesh', [bm_void_p, bm_CKID, bm_CKID])
|
||||
## BM3dEntity_GetVisibility
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_isVisible[out] Type: bool. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_GetVisibility = _create_bmap_func('BM3dObject_GetVisibility', [bm_void_p, bm_CKID, bm_bool_p])
|
||||
## BM3dObject_SetVisibility
|
||||
BM3dEntity_GetVisibility = _create_bmap_func('BM3dEntity_GetVisibility', [bm_void_p, bm_CKID, bm_bool_p])
|
||||
## BM3dEntity_SetVisibility
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param is_visible[in] Type: bool.
|
||||
# @return True if no error, otherwise False.
|
||||
BM3dObject_SetVisibility = _create_bmap_func('BM3dObject_SetVisibility', [bm_void_p, bm_CKID, bm_bool])
|
||||
BM3dEntity_SetVisibility = _create_bmap_func('BM3dEntity_SetVisibility', [bm_void_p, bm_CKID, bm_bool])
|
||||
## BMLight_GetType
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::VxMath::VXLIGHT_TYPE. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetType = _create_bmap_func('BMLight_GetType', [bm_void_p, bm_CKID, bm_enum_p])
|
||||
## BMLight_SetType
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::VxMath::VXLIGHT_TYPE.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetType = _create_bmap_func('BMLight_SetType', [bm_void_p, bm_CKID, bm_enum])
|
||||
## BMLight_GetColor
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::VxMath::VxColor. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetColor = _create_bmap_func('BMLight_GetColor', [bm_void_p, bm_CKID, bm_VxColor_p])
|
||||
## BMLight_SetColor
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param col[in] Type: LibCmo::VxMath::VxColor.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetColor = _create_bmap_func('BMLight_SetColor', [bm_void_p, bm_CKID, bm_VxColor])
|
||||
## BMLight_GetConstantAttenuation
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetConstantAttenuation = _create_bmap_func('BMLight_GetConstantAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
|
||||
## BMLight_SetConstantAttenuation
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::CKFLOAT.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetConstantAttenuation = _create_bmap_func('BMLight_SetConstantAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT])
|
||||
## BMLight_GetLinearAttenuation
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetLinearAttenuation = _create_bmap_func('BMLight_GetLinearAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
|
||||
## BMLight_SetLinearAttenuation
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::CKFLOAT.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetLinearAttenuation = _create_bmap_func('BMLight_SetLinearAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT])
|
||||
## BMLight_GetQuadraticAttenuation
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetQuadraticAttenuation = _create_bmap_func('BMLight_GetQuadraticAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
|
||||
## BMLight_SetQuadraticAttenuation
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::CKFLOAT.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetQuadraticAttenuation = _create_bmap_func('BMLight_SetQuadraticAttenuation', [bm_void_p, bm_CKID, bm_CKFLOAT])
|
||||
## BMLight_GetRange
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetRange = _create_bmap_func('BMLight_GetRange', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
|
||||
## BMLight_SetRange
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::CKFLOAT.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetRange = _create_bmap_func('BMLight_SetRange', [bm_void_p, bm_CKID, bm_CKFLOAT])
|
||||
## BMLight_GetHotSpot
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetHotSpot = _create_bmap_func('BMLight_GetHotSpot', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
|
||||
## BMLight_SetHotSpot
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::CKFLOAT.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetHotSpot = _create_bmap_func('BMLight_SetHotSpot', [bm_void_p, bm_CKID, bm_CKFLOAT])
|
||||
## BMLight_GetFalloff
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetFalloff = _create_bmap_func('BMLight_GetFalloff', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
|
||||
## BMLight_SetFalloff
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::CKFLOAT.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetFalloff = _create_bmap_func('BMLight_SetFalloff', [bm_void_p, bm_CKID, bm_CKFLOAT])
|
||||
## BMLight_GetFalloffShape
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param out_val[out] Type: LibCmo::CKFLOAT. Use ctypes.byref(data) pass it.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_GetFalloffShape = _create_bmap_func('BMLight_GetFalloffShape', [bm_void_p, bm_CKID, bm_CKFLOAT_p])
|
||||
## BMLight_SetFalloffShape
|
||||
# @param bmfile[in] Type: BMap::BMFile*. The pointer to corresponding BMFile.
|
||||
# @param objid[in] Type: LibCmo::CK2::CK_ID. The CKID of object you accessing.
|
||||
# @param val[in] Type: LibCmo::CKFLOAT.
|
||||
# @return True if no error, otherwise False.
|
||||
BMLight_SetFalloffShape = _create_bmap_func('BMLight_SetFalloffShape', [bm_void_p, bm_CKID, bm_CKFLOAT])
|
||||
|
||||
##### GENERATED FUNCTIONS END #####
|
||||
|
||||
@@ -476,10 +476,10 @@ class BMMesh(BMObject):
|
||||
except StopIteration:
|
||||
_Utils.raise_out_of_length_exception()
|
||||
|
||||
class BM3dObject(BMObject):
|
||||
class BM3dEntity(BMObject):
|
||||
def get_world_matrix(self) -> virtools_types.VxMatrix:
|
||||
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix()
|
||||
bmap.BM3dObject_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat))
|
||||
bmap.BM3dEntity_GetWorldMatrix(self._get_pointer(), self._get_ckid(), ctypes.byref(mat))
|
||||
# use cast & pointer to get matrix data conveniently
|
||||
flat: bmap.bm_CKFLOAT_p = ctypes.cast(ctypes.byref(mat), bmap.bm_CKFLOAT_p)
|
||||
ret: virtools_types.VxMatrix = virtools_types.VxMatrix()
|
||||
@@ -489,11 +489,11 @@ class BM3dObject(BMObject):
|
||||
def set_world_matrix(self, mat_: virtools_types.VxMatrix) -> None:
|
||||
# star syntax expand the tuple as the argument.
|
||||
mat: bmap.bm_VxMatrix = bmap.bm_VxMatrix(*(mat_.to_const()))
|
||||
bmap.BM3dObject_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat)
|
||||
bmap.BM3dEntity_SetWorldMatrix(self._get_pointer(), self._get_ckid(), mat)
|
||||
|
||||
def get_current_mesh(self) -> BMMesh | None:
|
||||
ckid: bmap.bm_CKID = bmap.bm_CKID()
|
||||
bmap.BM3dObject_GetCurrentMesh(self._get_pointer(), self._get_ckid(), ctypes.byref(ckid))
|
||||
bmap.BM3dEntity_GetCurrentMesh(self._get_pointer(), self._get_ckid(), ctypes.byref(ckid))
|
||||
if ckid.value == g_InvalidCKID:
|
||||
return None
|
||||
else:
|
||||
@@ -503,12 +503,60 @@ class BM3dObject(BMObject):
|
||||
ckid: bmap.bm_CKID = bmap.bm_CKID(g_InvalidCKID)
|
||||
if mesh is not None:
|
||||
ckid = mesh._get_ckid()
|
||||
bmap.BM3dObject_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid)
|
||||
bmap.BM3dEntity_SetCurrentMesh(self._get_pointer(), self._get_ckid(), ckid)
|
||||
|
||||
def get_visibility(self) -> bool:
|
||||
return self._get_bool_value(bmap.BM3dObject_GetVisibility)
|
||||
return self._get_bool_value(bmap.BM3dEntity_GetVisibility)
|
||||
def set_visibility(self, visb_: bool) -> None:
|
||||
self._set_bool_value(bmap.BM3dObject_SetVisibility, visb_)
|
||||
self._set_bool_value(bmap.BM3dEntity_SetVisibility, visb_)
|
||||
|
||||
class BM3dObject(BM3dEntity):
|
||||
pass
|
||||
|
||||
class BMLight(BM3dEntity):
|
||||
def get_type(self) -> virtools_types.VXLIGHT_TYPE:
|
||||
return self._get_enum_value(virtools_types.VXLIGHT_TYPE, bmap.BMLight_GetType)
|
||||
def set_type(self, data_: virtools_types.VXLIGHT_TYPE) -> None:
|
||||
self._set_enum_value(bmap.BMLight_SetType, data_)
|
||||
|
||||
def get_color(self) -> virtools_types.VxColor:
|
||||
return self._get_vxcolor_value(bmap.BMLight_GetColor)
|
||||
def set_color(self, col: virtools_types.VxColor) -> None:
|
||||
self._set_vxcolor_value(bmap.BMLight_SetColor, col)
|
||||
|
||||
def get_constant_attenuation(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetConstantAttenuation)
|
||||
def set_constant_attenuation(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetConstantAttenuation, val_)
|
||||
def get_linear_attenuation(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetLinearAttenuation)
|
||||
def set_linear_attenuation(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetLinearAttenuation, val_)
|
||||
def get_quadratic_attenuation(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetQuadraticAttenuation)
|
||||
def set_quadratic_attenuation(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetQuadraticAttenuation, val_)
|
||||
|
||||
def get_range(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetRange)
|
||||
def set_range(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetRange, val_)
|
||||
|
||||
def get_hot_spot(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetHotSpot)
|
||||
def set_hot_spot(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetHotSpot, val_)
|
||||
def get_falloff(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetFalloff)
|
||||
def set_falloff(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetFalloff, val_)
|
||||
def get_falloff_shape(self) -> float:
|
||||
return self._get_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_GetFalloffShape)
|
||||
def set_falloff_shape(self, val_: float) -> None:
|
||||
self._set_float_point_value(bmap.bm_CKFLOAT, bmap.BMLight_SetFalloffShape, val_)
|
||||
|
||||
class BMTargetLight(BMLight):
|
||||
pass
|
||||
|
||||
class BMGroup(BMObject):
|
||||
def add_object(self, member: BM3dObject) -> None:
|
||||
@@ -603,6 +651,10 @@ class BMFileReader(_AbstractPointer):
|
||||
return self.__get_ckobject_count(bmap.BMFile_GetGroupCount)
|
||||
def get_groups(self) -> typing.Iterator[BMGroup]:
|
||||
return self.__get_ckobjects(BMGroup, bmap.BMFile_GetGroupCount, bmap.BMFile_GetGroup)
|
||||
def get_target_light_count(self) -> int:
|
||||
return self.__get_ckobject_count(bmap.BMFile_GetTargetLightCount)
|
||||
def get_target_lights(self) -> typing.Iterator[BMTargetLight]:
|
||||
return self.__get_ckobjects(BMTargetLight, bmap.BMFile_GetTargetLightCount, bmap.BMFile_GetTargetLight)
|
||||
|
||||
class BMFileWriter(_AbstractPointer):
|
||||
def __init__(self, temp_folder_: str, texture_folder_: str, encodings_: tuple[str]):
|
||||
@@ -663,6 +715,8 @@ class BMFileWriter(_AbstractPointer):
|
||||
return self.__create_ckobject(BM3dObject, bmap.BMFile_Create3dObject)
|
||||
def create_group(self) -> BMGroup:
|
||||
return self.__create_ckobject(BMGroup, bmap.BMFile_CreateGroup)
|
||||
def create_target_light(self) -> BMTargetLight:
|
||||
return self.__create_ckobject(BMTargetLight, bmap.BMFile_CreateTargetLight)
|
||||
|
||||
class BMMeshTrans(_AbstractPointer):
|
||||
def __init__(self):
|
||||
@@ -221,6 +221,15 @@ class VX_PIXELFORMAT(enum.IntEnum):
|
||||
_4_ABGR8888_CLUT = 30 ##< 4 bits indexed CLUT (ABGR)
|
||||
_4_ARGB8888_CLUT = 31 ##< 4 bits indexed CLUT (ARGB)
|
||||
|
||||
class VXLIGHT_TYPE(enum.IntEnum):
|
||||
"""!
|
||||
Light type
|
||||
"""
|
||||
VX_LIGHTPOINT = 1 ##< The Light is a point of light
|
||||
VX_LIGHTSPOT = 2 ##< The light is a spotlight
|
||||
VX_LIGHTDIREC = 3 ##< The light is directional light : Lights comes from an infinite point so only direction of light can be given
|
||||
#VX_LIGHTPARA = 4 ##< Obsolete, do not use
|
||||
|
||||
class VXTEXTURE_BLENDMODE(enum.IntEnum):
|
||||
"""!
|
||||
Blend Mode Flags
|
||||
@@ -5,3 +5,5 @@ The real scripts are placed in sub PyBMap folder. This folder is served for test
|
||||
The native BMap library should be placed in sub PyBMap folder, and I have used gitignore file to filter them. The native BMap library must be named as `BMap.dll` (in Windows), `BMap.so` (in Linux or BSD), or `BMap.dylib` (in macOS). If you still can not load BMap or your system is not listed above, you should name it as `BMap.bin`.
|
||||
|
||||
Please note the most content of `virtools_types.py` are generated by EnumsMigration sub-project. Additionally the most content of `bmap.py` is generated by BMapBindings. So if some structs are updated, do not forget checking these files.
|
||||
|
||||
Since BMap 0.3.0, testbench use command line arguments, instead of hardcode variables in code, as the arguments of BMap. It is convenient that debug BMapSharp without any modification of source code. For a brief instruction, you may need to launch BMapSharpTestbench in following command (just an example. you can modify it as you wished): `py testbench.py --file-path "LightCameraTest.nmo" --temp-dir "Temp" --texture-dir "F:/Ballance/Ballance/Textures" --encodings cp1252 gb2312`.
|
||||
178
Assets/BMapBindings/PyBMap/testbench.py
Normal file
178
Assets/BMapBindings/PyBMap/testbench.py
Normal file
@@ -0,0 +1,178 @@
|
||||
import os
|
||||
import argparse
|
||||
import PyBMap.bmap_wrapper as bmap
|
||||
|
||||
def main(file_name: str, temp_folder: str, texture_folder: str, encodings: tuple[str, ...]) -> None:
|
||||
input(f'Python PID is {os.getpid()}. Waiting for debugger, press any key to continue...')
|
||||
|
||||
# file_name: str = 'LightCameraTest.nmo'
|
||||
# temp_folder: str = 'Temp'
|
||||
# texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
|
||||
# encodings: tuple[str, ...] = ('cp1252', )
|
||||
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
|
||||
test_common(reader)
|
||||
test_equatable(reader)
|
||||
|
||||
def test_common(reader: bmap.BMFileReader):
|
||||
# print('===== Groups =====')
|
||||
# for gp in reader.get_groups():
|
||||
# print(gp.get_name())
|
||||
# for gp_item in gp.get_objects():
|
||||
# print(f'\t{gp_item.get_name()}')
|
||||
|
||||
# print('===== 3dObjects =====')
|
||||
# for obj in reader.get_3dobjects():
|
||||
# print(obj.get_name())
|
||||
|
||||
# current_mesh = obj.get_current_mesh()
|
||||
# mesh_name = '<null>' if current_mesh is None else current_mesh.get_name()
|
||||
# print(f'\tMesh: {mesh_name}')
|
||||
# print(f'\tVisibility: {obj.get_visibility()}')
|
||||
# print(f'\tMatrix: {obj.get_world_matrix().to_const()}')
|
||||
|
||||
# print('===== Meshes =====')
|
||||
# for mesh in reader.get_meshs():
|
||||
# print(mesh.get_name())
|
||||
|
||||
# print(f'\tLit Mode: {mesh.get_lit_mode()}')
|
||||
# print(f'\tVertex Count: {mesh.get_vertex_count()}')
|
||||
# print(f'\tFace Count: {mesh.get_face_count()}')
|
||||
# print(f'\tMaterial Slot Count: {mesh.get_material_slot_count()}')
|
||||
|
||||
# print('===== Materials =====')
|
||||
# for mtl in reader.get_materials():
|
||||
# print(mtl.get_name())
|
||||
|
||||
# print(f'\tDiffuse: {mtl.get_diffuse().to_const_rgba()}')
|
||||
# print(f'\tAmbient: {mtl.get_ambient().to_const_rgba()}')
|
||||
# print(f'\tSpecular: {mtl.get_specular().to_const_rgba()}')
|
||||
# print(f'\tEmissive: {mtl.get_emissive().to_const_rgba()}')
|
||||
|
||||
# print(f'\tSpecular Power: {mtl.get_specular_power()}')
|
||||
|
||||
# print(f'\tTexture Border Color: {mtl.get_texture_border_color().to_const_rgba()}')
|
||||
|
||||
# print(f'\tTexture Blend Mode: {mtl.get_texture_blend_mode()}')
|
||||
# print(f'\tTexture Min Mode: {mtl.get_texture_min_mode()}')
|
||||
# print(f'\tTexture Mag Mode: {mtl.get_texture_mag_mode()}')
|
||||
# print(f'\tSource Blend: {mtl.get_source_blend()}')
|
||||
# print(f'\tDest Blend: {mtl.get_dest_blend()}')
|
||||
# print(f'\tFill Mode: {mtl.get_fill_mode()}')
|
||||
# print(f'\tShade Mode: {mtl.get_shade_mode()}')
|
||||
|
||||
# print(f'\tAlpha Test Enabled: {mtl.get_alpha_test_enabled()}')
|
||||
# print(f'\tAlpha Blend Enabled: {mtl.get_alpha_blend_enabled()}')
|
||||
# print(f'\tPerspective Correction Enabled: {mtl.get_perspective_correction_enabled()}')
|
||||
# print(f'\tZ Write Enabled: {mtl.get_z_write_enabled()}')
|
||||
# print(f'\tTwo Sided Enabled: {mtl.get_two_sided_enabled()}')
|
||||
|
||||
# print(f'\tAlpha Ref: {mtl.get_alpha_ref()}')
|
||||
|
||||
# print(f'\tAlpha Func: {mtl.get_alpha_func()}')
|
||||
# print(f'\tZ Func: {mtl.get_z_func()}')
|
||||
|
||||
# print('===== Textures =====')
|
||||
# for tex in reader.get_textures():
|
||||
# print(tex.get_name())
|
||||
|
||||
# print(f'\tFile Name: {tex.get_file_name()}')
|
||||
# print(f'\tSave Options: {tex.get_save_options()}')
|
||||
# print(f'\tVideo Format: {tex.get_video_format()}')
|
||||
|
||||
print('===== Target Lights =====')
|
||||
for lit in reader.get_target_lights():
|
||||
print(lit.get_name())
|
||||
|
||||
print(f'\tVisibility: {lit.get_visibility()}')
|
||||
print(f'\tMatrix: {lit.get_world_matrix().to_const()}')
|
||||
|
||||
print(f'\tType: {lit.get_type()}')
|
||||
print(f'\tColor: {lit.get_color().to_const_rgba()}')
|
||||
print(f'\tConstant Attenuation: {lit.get_constant_attenuation()}')
|
||||
print(f'\tLinear Attenuation: {lit.get_linear_attenuation()}')
|
||||
print(f'\tQuadratic Attenuation: {lit.get_quadratic_attenuation()}')
|
||||
print(f'\tRange: {lit.get_range()}')
|
||||
print(f'\tHot Spot: {lit.get_hot_spot()}')
|
||||
print(f'\tFalloff: {lit.get_falloff()}')
|
||||
print(f'\tFalloff Shape: {lit.get_falloff_shape()}')
|
||||
|
||||
print('===== END =====')
|
||||
|
||||
def test_equatable(reader: bmap.BMFileReader):
|
||||
# Check requirements
|
||||
assert (reader.get_3dobject_count() >= 2), '''
|
||||
Invalid file for test IEquatable.
|
||||
We can not perform IEquatable test because the length of 3dObject is too short (must greater than 2). Please choose another file to perform.
|
||||
'''
|
||||
|
||||
# Prepare variables
|
||||
all_3dobjects: tuple[bmap.BM3dObject, ...] = tuple(reader.get_3dobjects())
|
||||
first_3dobj: bmap.BM3dObject = all_3dobjects[0]
|
||||
second_3dobj: bmap.BM3dObject = all_3dobjects[1]
|
||||
all_3dobjects = tuple(reader.get_3dobjects())
|
||||
first_3dobj_again: bmap.BM3dObject = all_3dobjects[0]
|
||||
|
||||
# Test set
|
||||
test_set: set[bmap.BM3dObject] = set()
|
||||
|
||||
test_set.add(first_3dobj)
|
||||
assert len(test_set) == 1
|
||||
|
||||
assert first_3dobj in test_set
|
||||
assert first_3dobj_again in test_set
|
||||
assert second_3dobj not in test_set
|
||||
|
||||
test_set.add(first_3dobj_again)
|
||||
assert len(test_set) == 1
|
||||
test_set.add(second_3dobj)
|
||||
assert len(test_set) == 2
|
||||
|
||||
assert second_3dobj in test_set
|
||||
|
||||
# Test dict
|
||||
test_dict: dict[bmap.BM3dObject, str | None] = {}
|
||||
|
||||
test_dict[first_3dobj] = first_3dobj.get_name()
|
||||
assert len(test_dict) == 1
|
||||
|
||||
assert first_3dobj in test_dict
|
||||
assert first_3dobj_again in test_dict
|
||||
assert second_3dobj not in test_dict
|
||||
|
||||
test_dict[first_3dobj_again] = first_3dobj_again.get_name()
|
||||
assert len(test_dict) == 1
|
||||
test_dict[second_3dobj] = second_3dobj.get_name()
|
||||
assert len(test_dict) == 2
|
||||
|
||||
assert second_3dobj in test_dict
|
||||
|
||||
if __name__ == '__main__':
|
||||
# parse argument
|
||||
parser = argparse.ArgumentParser(
|
||||
prog='PyBMap Testbench',
|
||||
description='The testbench of PyBMap.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--file-path',
|
||||
action='store', dest='file_path', required=True,
|
||||
help='The path to input Virtools file.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--temp-dir',
|
||||
action='store', dest='temp_dir', required=True,
|
||||
help='The temp folder used by BMap.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--texture-dir',
|
||||
action='store', dest='texture_dir', required=True,
|
||||
help='The texture folder containing Ballance texture resources.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--encodings',
|
||||
action='extend', nargs='+', dest='encodings', required=True,
|
||||
help='The encodings used to parse the names stroed in input Virtools file.'
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# run main function
|
||||
main(args.file_path, args.temp_dir, args.texture_dir, tuple(args.encodings))
|
||||
1
Assets/BMapBindings/rusty-bmap/.gitignore
vendored
Normal file
1
Assets/BMapBindings/rusty-bmap/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
70
Assets/BMapBindings/rusty-bmap/Cargo.lock
generated
Normal file
70
Assets/BMapBindings/rusty-bmap/Cargo.lock
generated
Normal file
@@ -0,0 +1,70 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "bmap"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"bmap-sys",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bmap-sys"
|
||||
version = "0.4.0"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
6
Assets/BMapBindings/rusty-bmap/Cargo.toml
Normal file
6
Assets/BMapBindings/rusty-bmap/Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["bmap","bmap-sys"]
|
||||
|
||||
[workspace.dependencies]
|
||||
thiserror = "2.0.12"
|
||||
9
Assets/BMapBindings/rusty-bmap/bmap-sys/Cargo.toml
Normal file
9
Assets/BMapBindings/rusty-bmap/bmap-sys/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "bmap-sys"
|
||||
version = "0.4.0"
|
||||
authors = ["yyc12345"]
|
||||
edition = "2024"
|
||||
description = "The Rust binding to BMap."
|
||||
license = "SPDX:MIT"
|
||||
|
||||
[dependencies]
|
||||
13
Assets/BMapBindings/rusty-bmap/bmap-sys/build.rs
Normal file
13
Assets/BMapBindings/rusty-bmap/bmap-sys/build.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
// Fetch user specified install directory of built BMap.
|
||||
let install_dir = env::var("LibCmo_ROOT").expect("You must set LibCmo_ROOT to the install directory of LibCmo built by CMake before building this Rust crate.");
|
||||
let install_path = PathBuf::from(install_dir);
|
||||
|
||||
// Tell Rust compiler where to find linkd dynamic library.
|
||||
println!("cargo:rustc-link-search=native={}", install_path.join("lib").display());
|
||||
// Tell Rust compiler the name of linked dynamic library.
|
||||
println!("cargo:rustc-link-lib=dylib=BMap");
|
||||
}
|
||||
9
Assets/BMapBindings/rusty-bmap/bmap-sys/src/lib.rs
Normal file
9
Assets/BMapBindings/rusty-bmap/bmap-sys/src/lib.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::{c_float, c_void};
|
||||
//use std::ptr;
|
||||
|
||||
#[link(name = "BMap", kind = "dylib")]
|
||||
unsafe extern "C" {
|
||||
pub unsafe fn BMInit() -> bool;
|
||||
pub unsafe fn BMDispose() -> bool;
|
||||
}
|
||||
7
Assets/BMapBindings/rusty-bmap/bmap-sys/tests/basic.rs
Normal file
7
Assets/BMapBindings/rusty-bmap/bmap-sys/tests/basic.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use bmap_sys;
|
||||
|
||||
#[test]
|
||||
fn test_init_and_dispose() {
|
||||
assert!(unsafe { bmap_sys::BMInit() });
|
||||
assert!(unsafe { bmap_sys::BMDispose() });
|
||||
}
|
||||
11
Assets/BMapBindings/rusty-bmap/bmap/Cargo.toml
Normal file
11
Assets/BMapBindings/rusty-bmap/bmap/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "bmap"
|
||||
version = "0.4.0"
|
||||
authors = ["yyc12345"]
|
||||
edition = "2024"
|
||||
description = "The wrapper for Rust binding to BMap."
|
||||
license = "SPDX:MIT"
|
||||
|
||||
[dependencies]
|
||||
thiserror = { workspace = true }
|
||||
bmap-sys = { path="../bmap-sys" }
|
||||
1
Assets/BMapBindings/rusty-bmap/bmap/src/lib.rs
Normal file
1
Assets/BMapBindings/rusty-bmap/bmap/src/lib.rs
Normal file
@@ -0,0 +1 @@
|
||||
use bmap_sys;
|
||||
8
Assets/CKStateChunk/README.md
Normal file
8
Assets/CKStateChunk/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# CKStateChunk Format
|
||||
|
||||
This directory stores the format specification for the CKStateChunk format.
|
||||
CKStateChunk is a core data structure used by Virtools engines.
|
||||
So it is important to know the format of CKStateChunk.
|
||||
|
||||
These concluded formats basically are based on the decompile result.
|
||||
For view them, just use a web browser to open `CKStateChunk.html` in this directory.
|
||||
8
Assets/CodeGen/BMapBinder/.gitignore
vendored
Normal file
8
Assets/CodeGen/BMapBinder/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
## ======== Personal ========
|
||||
# Ignore intermediate stuff and output stuff.
|
||||
Extracted/*
|
||||
!Extracted/*.gitkeep
|
||||
Analyzed/*
|
||||
!Analyzed/*.gitkeep
|
||||
Output/*
|
||||
!Output/*.gitkeep
|
||||
125
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/.gitignore
vendored
Normal file
125
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/.gitignore
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
## ======== Personal ========
|
||||
# Additional remove for JetBrains IDEA
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
## ======== ANTLR Output ========
|
||||
*.interp
|
||||
*.tokens
|
||||
|
||||
ExpFctsLexer*.java
|
||||
ExpFctsParser*.java
|
||||
|
||||
## ======== Java ========
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
## ======== JetBrains ========
|
||||
# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
.idea/sonarlint.xml # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based HTTP Client
|
||||
.idea/httpRequests
|
||||
http-client.private.env.json
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# Apifox Helper cache
|
||||
.idea/.cache/.Apifox_Helper
|
||||
.idea/ApifoxUploaderProjectSetting.xml
|
||||
|
||||
# Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
|
||||
.idea/**/copilot.data.migration.*.xml
|
||||
34
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/CommonHelper.java
Normal file
34
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/CommonHelper.java
Normal file
@@ -0,0 +1,34 @@
|
||||
//import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
//import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class CommonHelper {
|
||||
|
||||
// =========== File Operations ===========
|
||||
|
||||
private static Path getRootDirectoryPath() throws Exception {
|
||||
String rootDir = System.getenv("BMAP_BINDER_ROOT");
|
||||
if (rootDir == null) {
|
||||
throw new RuntimeException("Can not find essential environment variable BMAP_BINDER_ROOT");
|
||||
} else {
|
||||
return Paths.get(rootDir);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getInputFilePath(String filename) throws Exception {
|
||||
Path rootDir = getRootDirectoryPath();
|
||||
Path filePath = rootDir.resolve("Extracted").resolve(filename);
|
||||
return filePath.toString();
|
||||
}
|
||||
|
||||
public static String getOutputFilePath(String filename) throws Exception {
|
||||
Path rootDir = getRootDirectoryPath();
|
||||
Path filePath = rootDir.resolve("Analyzed").resolve(filename);
|
||||
return filePath.toString();
|
||||
}
|
||||
|
||||
}
|
||||
94
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/ExpFctsHelper.java
Normal file
94
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/ExpFctsHelper.java
Normal file
@@ -0,0 +1,94 @@
|
||||
import java.util.Vector;
|
||||
|
||||
public class ExpFctsHelper {
|
||||
|
||||
/**
|
||||
* The class represent a single parameter (argument) of function.
|
||||
*/
|
||||
public static class ExpFctParam {
|
||||
|
||||
/**
|
||||
* The type of this parameter.
|
||||
*/
|
||||
public String mVarType;
|
||||
/**
|
||||
* The name of this parameter.
|
||||
*/
|
||||
public String mVarName;
|
||||
/**
|
||||
* True if this parameter is marked as input parameter, otherwise false.
|
||||
* <p>
|
||||
* Input parameter and output parameter is commonly used in C/C++ code. By using
|
||||
* this feature, each function can receive multiple arguments and return
|
||||
* multiple arguments without defining a struct to hold it.
|
||||
* <p>
|
||||
* The type of input parameter is itself. However, the type of output parameter
|
||||
* is the pointer of itself. So you may need get its pointer type when
|
||||
* processing output parameter, especially for the scenario that the target
|
||||
* language do not support explicit output parameter keyword.
|
||||
*/
|
||||
public boolean mIsInput;
|
||||
/**
|
||||
* The description of this parameter.
|
||||
* <p>
|
||||
* This description is generated by this program. It will indicate the
|
||||
* underlying C++ type to tell end user how to treat this parameter because some
|
||||
* target languages' native calling style can not represent these detail.
|
||||
* <p>
|
||||
* In this program, this field must be written as a annotation of corresponding
|
||||
* function.
|
||||
*/
|
||||
public String mVarDesc;
|
||||
|
||||
public ExpFctParam() {
|
||||
mVarType = "";
|
||||
mVarName = "";
|
||||
mVarDesc = "";
|
||||
mIsInput = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The class represent an export BMap function.
|
||||
*/
|
||||
public static class ExpFct {
|
||||
|
||||
/**
|
||||
* The name of this function.
|
||||
*/
|
||||
public String mFctName;
|
||||
/**
|
||||
* The return value type of this function.
|
||||
*/
|
||||
public String mFctRvType;
|
||||
/**
|
||||
* The parameters (arguments) list of this function. Each item are
|
||||
* {@linkplain ExpFctParam} and represent parameter one by one from left to
|
||||
* right.
|
||||
*/
|
||||
public Vector<ExpFctParam> mFctParams;
|
||||
|
||||
public ExpFct() {
|
||||
mFctName = "";
|
||||
mFctRvType = "";
|
||||
mFctParams = new Vector<ExpFctParam>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The class represent a collection of export BMap functions.
|
||||
*/
|
||||
public static class ExpFctCollection {
|
||||
/**
|
||||
* The collection of exported BMap functions.
|
||||
*/
|
||||
public Vector<ExpFct> mFcts;
|
||||
|
||||
public ExpFctCollection() {
|
||||
mFcts = new Vector<ExpFct>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,34 +1,31 @@
|
||||
import java.util.Collections;
|
||||
import java.util.Vector;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||
|
||||
public ExpFctsWalker() {
|
||||
mFctList = new Vector<ExpFctDecl>();
|
||||
mFctCollection = null;
|
||||
mCurrentFct = null;
|
||||
mCurrentParam = null;
|
||||
}
|
||||
|
||||
public Vector<ExpFctDecl> getResult() {
|
||||
return mFctList;
|
||||
public ExpFctsHelper.ExpFctCollection getResult() {
|
||||
return mFctCollection;
|
||||
}
|
||||
|
||||
private Vector<ExpFctDecl> mFctList;
|
||||
private ExpFctDecl mCurrentFct;
|
||||
private ExpFctParamDecl mCurrentParam;
|
||||
private ExpFctsHelper.ExpFctCollection mFctCollection;
|
||||
private ExpFctsHelper.ExpFct mCurrentFct;
|
||||
private ExpFctsHelper.ExpFctParam mCurrentParam;
|
||||
|
||||
@Override
|
||||
public void enterProgram(ExpFctsParser.ProgramContext ctx) {
|
||||
mFctList.clear();
|
||||
mFctCollection = new ExpFctsHelper.ExpFctCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFctDecl(ExpFctsParser.FctDeclContext ctx) {
|
||||
mCurrentFct = new ExpFctDecl();
|
||||
mCurrentFct = new ExpFctsHelper.ExpFct();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,55 +33,54 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||
// set name
|
||||
mCurrentFct.mFctName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
// check return type
|
||||
if (!mCurrentFct.mFctRetType.isValid() || mCurrentFct.mFctRetType.isPointer()
|
||||
|| !mCurrentFct.mFctRetType.getBaseType().equals("bool"))
|
||||
if (!Objects.equals(mCurrentFct.mFctRvType, "bool"))
|
||||
throw new IllegalArgumentException("invalid interface function return type. must be bool.");
|
||||
|
||||
// add into list
|
||||
mFctList.add(mCurrentFct);
|
||||
mFctCollection.mFcts.add(mCurrentFct);
|
||||
mCurrentFct = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitFctArgFileDecl(ExpFctsParser.FctArgFileDeclContext ctx) {
|
||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
decl.mIsInput = true;
|
||||
decl.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(decl);
|
||||
ExpFctsHelper.ExpFctParam param = new ExpFctsHelper.ExpFctParam();
|
||||
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
param.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
param.mIsInput = true;
|
||||
param.mVarType = "BMap::BMFile*";
|
||||
mCurrentFct.mFctParams.add(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitFctArgMeshTransDecl(ExpFctsParser.FctArgMeshTransDeclContext ctx) {
|
||||
ExpFctParamDecl decl = new ExpFctParamDecl();
|
||||
decl.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
decl.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
||||
decl.mIsInput = true;
|
||||
decl.mVarType.fromCType("BMap::BMMeshTransition*");
|
||||
mCurrentFct.mFctParams.add(decl);
|
||||
ExpFctsHelper.ExpFctParam param = new ExpFctsHelper.ExpFctParam();
|
||||
param.mVarName = ctx.EXPFCTS_IDENTIFIER().getText();
|
||||
param.mVarDesc = "The pointer to corresponding BMMeshTransition.";
|
||||
param.mIsInput = true;
|
||||
param.mVarType = "BMap::BMMeshTransition*";
|
||||
mCurrentFct.mFctParams.add(param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitFctArgObjDecl(ExpFctsParser.FctArgObjDeclContext ctx) {
|
||||
ExpFctParamDecl first_decl = new ExpFctParamDecl();
|
||||
first_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
||||
first_decl.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
first_decl.mIsInput = true;
|
||||
first_decl.mVarType.fromCType("BMap::BMFile*");
|
||||
mCurrentFct.mFctParams.add(first_decl);
|
||||
ExpFctsHelper.ExpFctParam firstParam = new ExpFctsHelper.ExpFctParam();
|
||||
firstParam.mVarName = ctx.EXPFCTS_IDENTIFIER(0).getText();
|
||||
firstParam.mVarDesc = "The pointer to corresponding BMFile.";
|
||||
firstParam.mIsInput = true;
|
||||
firstParam.mVarType = "BMap::BMFile*";
|
||||
mCurrentFct.mFctParams.add(firstParam);
|
||||
|
||||
ExpFctParamDecl second_decl = new ExpFctParamDecl();
|
||||
second_decl.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
||||
second_decl.mVarDesc = "The CKID of object you accessing.";
|
||||
second_decl.mIsInput = true;
|
||||
second_decl.mVarType.fromCType("LibCmo::CK2::CK_ID");
|
||||
mCurrentFct.mFctParams.add(second_decl);
|
||||
ExpFctsHelper.ExpFctParam secondParam = new ExpFctsHelper.ExpFctParam();
|
||||
secondParam.mVarName = ctx.EXPFCTS_IDENTIFIER(1).getText();
|
||||
secondParam.mVarDesc = "The CKID of object you accessing.";
|
||||
secondParam.mIsInput = true;
|
||||
secondParam.mVarType = "LibCmo::CK2::CK_ID";
|
||||
mCurrentFct.mFctParams.add(secondParam);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFctArgParamIn(ExpFctsParser.FctArgParamInContext ctx) {
|
||||
mCurrentParam = new ExpFctParamDecl();
|
||||
mCurrentParam = new ExpFctsHelper.ExpFctParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,7 +94,7 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||
|
||||
@Override
|
||||
public void enterFctArgParamOut(ExpFctsParser.FctArgParamOutContext ctx) {
|
||||
mCurrentParam = new ExpFctParamDecl();
|
||||
mCurrentParam = new ExpFctsHelper.ExpFctParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,12 +118,15 @@ public class ExpFctsWalker extends ExpFctsParserBaseListener {
|
||||
ctype += String.join("", Collections.nCopies(ctx.EXPFCTS_STAR().size(), "*"));
|
||||
}
|
||||
|
||||
if (!mCurrentFct.mFctRetType.isValid()) {
|
||||
// if there is function return value is not filled,
|
||||
// we fill it first because return value type is the first captured type in function statement.
|
||||
// otherwise we fill parameter type.
|
||||
if (mCurrentFct.mFctRvType.isEmpty()) {
|
||||
// fill function ret type first
|
||||
mCurrentFct.mFctRetType.fromCType(ctype);
|
||||
mCurrentFct.mFctRvType = ctype;
|
||||
} else {
|
||||
// otherwise, fill param data
|
||||
mCurrentParam.mVarType.fromCType(ctype);
|
||||
mCurrentParam.mVarType = ctype;
|
||||
}
|
||||
}
|
||||
|
||||
52
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/JsonWriter.java
Normal file
52
Assets/CodeGen/BMapBinder/ExpFctsAnalyzer/JsonWriter.java
Normal file
@@ -0,0 +1,52 @@
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class JsonWriter {
|
||||
|
||||
private static JsonObject writeExpFctParam(ExpFctsHelper.ExpFctParam param) {
|
||||
JsonObject data = new JsonObject();
|
||||
data.addProperty("type", param.mVarType);
|
||||
data.addProperty("name", param.mVarName);
|
||||
data.addProperty("is_input", param.mIsInput);
|
||||
data.addProperty("desc", param.mVarDesc);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static JsonObject writeExpFct(ExpFctsHelper.ExpFct fct) {
|
||||
JsonObject data = new JsonObject();
|
||||
data.addProperty("name", fct.mFctName);
|
||||
data.addProperty("return", fct.mFctRvType);
|
||||
|
||||
JsonArray paramList = new JsonArray();
|
||||
for (ExpFctsHelper.ExpFctParam param : fct.mFctParams) {
|
||||
paramList.add(writeExpFctParam(param));
|
||||
}
|
||||
data.add("params", paramList);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static JsonArray writeExpFctCollection(ExpFctsHelper.ExpFctCollection fctCollection) {
|
||||
JsonArray data = new JsonArray();
|
||||
for (ExpFctsHelper.ExpFct fct : fctCollection.mFcts) {
|
||||
data.add(writeExpFct(fct));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void writeJson(ExpFctsHelper.ExpFctCollection data) throws Exception {
|
||||
FileOutputStream fs = new FileOutputStream(CommonHelper.getOutputFilePath("BMExports.json"));
|
||||
OutputStreamWriter writer = new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
||||
//Gson gsonInstance = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
Gson gsonInstance = new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
|
||||
writer.write(gsonInstance.toJson(writeExpFctCollection(data)));
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,9 @@ public class MainRunner {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// get interface structure
|
||||
FileInputStream fs = new FileInputStream("dest/BMExports.hpp");
|
||||
CharStream antlrfs = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
||||
ExpFctsLexer lexer = new ExpFctsLexer(antlrfs);
|
||||
FileInputStream fs = new FileInputStream(CommonHelper.getInputFilePath("BMExports.hpp"));
|
||||
CharStream antlrStream = CharStreams.fromStream(fs, StandardCharsets.UTF_8);
|
||||
ExpFctsLexer lexer = new ExpFctsLexer(antlrStream);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
ExpFctsParser parser = new ExpFctsParser(tokens);
|
||||
|
||||
@@ -23,12 +23,10 @@ public class MainRunner {
|
||||
fs.close();
|
||||
|
||||
// get data and write them
|
||||
Vector<ExpFctDecl> result = worker.getResult();
|
||||
PythonWriter.writePythonCode(result);
|
||||
CSharpWriter.writeCSharpCode(result);
|
||||
ExpFctsHelper.ExpFctCollection result = worker.getResult();
|
||||
JsonWriter.writeJson(result);
|
||||
|
||||
// print message.
|
||||
System.out.println("DONE!");
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
10
Assets/CodeGen/BMapBinder/ExpFctsExtractor/.gitignore
vendored
Normal file
10
Assets/CodeGen/BMapBinder/ExpFctsExtractor/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
@@ -0,0 +1 @@
|
||||
3.11
|
||||
3
Assets/CodeGen/BMapBinder/ExpFctsExtractor/README.md
Normal file
3
Assets/CodeGen/BMapBinder/ExpFctsExtractor/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# ExpFcts Extractor
|
||||
|
||||
See upper level [README.md](../README.md) for informations.
|
||||
64
Assets/CodeGen/BMapBinder/ExpFctsExtractor/main.py
Normal file
64
Assets/CodeGen/BMapBinder/ExpFctsExtractor/main.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
# region: Path Getter
|
||||
|
||||
|
||||
def _get_libcmo21_repo_directory() -> Path:
|
||||
repo_root = os.environ.get("LIBCMO21_REPO_ROOT", None)
|
||||
if repo_root is None:
|
||||
return Path(__file__).resolve().parent.parent.parent.parent.parent
|
||||
else:
|
||||
return Path(repo_root).resolve()
|
||||
|
||||
|
||||
def get_input_file_path() -> Path:
|
||||
return _get_libcmo21_repo_directory() / "Ballance" / "BMap" / "BMap" / "BMExports.hpp"
|
||||
|
||||
|
||||
def _get_bmap_binder_directory() -> Path:
|
||||
bmap_binder_root = os.environ.get("BMAP_BINDER_ROOT", None)
|
||||
if bmap_binder_root is None:
|
||||
return Path(__file__).resolve().parent.parent
|
||||
else:
|
||||
return Path(bmap_binder_root).resolve()
|
||||
|
||||
|
||||
def get_output_file_path() -> Path:
|
||||
return _get_bmap_binder_directory() / "Extracted" / "BMExports.hpp"
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
# region: Extractor
|
||||
|
||||
# We should not only match BMAP_EXPORT,
|
||||
# because it may match the defination of BMAP_EXPORT.
|
||||
# So we add a bool at head because all BMap functions return bool.
|
||||
EXPFCTS_PATTERN: re.Pattern = re.compile(
|
||||
"^BMAP_EXPORT[ \\t]+bool[ \\t]+[^;]+;", re.MULTILINE
|
||||
)
|
||||
|
||||
|
||||
def extract_expfcts(infile: Path, outfile: Path) -> None:
|
||||
with open(infile, "r", encoding="utf-8") as fin:
|
||||
# read full text
|
||||
fulltext: str = fin.read()
|
||||
# do findall and write into file
|
||||
with open(outfile, "w", encoding="utf-8") as fout:
|
||||
for item in EXPFCTS_PATTERN.findall(fulltext):
|
||||
fout.write(item)
|
||||
fout.write("\n")
|
||||
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
def main():
|
||||
extract_expfcts(get_input_file_path(), get_output_file_path())
|
||||
print("Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,7 @@
|
||||
[project]
|
||||
name = "exp-fcts-extractor"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = []
|
||||
8
Assets/CodeGen/BMapBinder/ExpFctsExtractor/uv.lock
generated
Normal file
8
Assets/CodeGen/BMapBinder/ExpFctsExtractor/uv.lock
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.11"
|
||||
|
||||
[[package]]
|
||||
name = "exp-fcts-extractor"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
10
Assets/CodeGen/BMapBinder/ExpFctsRender/.gitignore
vendored
Normal file
10
Assets/CodeGen/BMapBinder/ExpFctsRender/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
1
Assets/CodeGen/BMapBinder/ExpFctsRender/.python-version
Normal file
1
Assets/CodeGen/BMapBinder/ExpFctsRender/.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.11
|
||||
3
Assets/CodeGen/BMapBinder/ExpFctsRender/README.md
Normal file
3
Assets/CodeGen/BMapBinder/ExpFctsRender/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# ExpFcts Render
|
||||
|
||||
See upper level [README.md](../README.md) for informations.
|
||||
225
Assets/CodeGen/BMapBinder/ExpFctsRender/json_loader.py
Normal file
225
Assets/CodeGen/BMapBinder/ExpFctsRender/json_loader.py
Normal file
@@ -0,0 +1,225 @@
|
||||
import json
|
||||
import typing
|
||||
import utils
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
class VariableType:
|
||||
"""The class represent the type of each parameters and function return value."""
|
||||
|
||||
__base_type_hierarchy: list[str]
|
||||
"""
|
||||
The base type of this variable removing all ending stars (remove all pointer levels).
|
||||
Each item in this list is a part of namespace and the last one must be the type itself
|
||||
(without any namespace constraint).
|
||||
If no namespace constraint for this type, this list will only have one item.
|
||||
|
||||
For end user, it is enough that knowing the last item is type itself.
|
||||
"""
|
||||
__pointer_level: int
|
||||
"""
|
||||
The pointer level of this type.
|
||||
It is equal to the count of trailing star of this field in C style representation.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, base_type_hierarchy: list[str] = [], pointer_level: int = 0
|
||||
) -> None:
|
||||
"""Construct a new varible type."""
|
||||
self.__base_type_hierarchy = base_type_hierarchy
|
||||
self.__pointer_level = pointer_level
|
||||
|
||||
def clone(self) -> "VariableType":
|
||||
"""CLone self into a new instance."""
|
||||
return VariableType(list(self.__base_type_hierarchy), self.__pointer_level)
|
||||
|
||||
@staticmethod
|
||||
def from_c_type(ctype: str) -> "VariableType":
|
||||
"""
|
||||
Set this variable type with a type string in C/C++ style.
|
||||
|
||||
For example, "NSTest::NSTest2::MyType**" will produce 2 pointer level
|
||||
with ('NSTest', 'NSTest2', 'MyType') as its base type hierarchy.
|
||||
|
||||
:param ctype: The type string in C/C++ style.
|
||||
:return: The parsed VariableType instance.
|
||||
"""
|
||||
if len(ctype) == 0:
|
||||
raise RuntimeError("empty string can not be parsed")
|
||||
|
||||
# get pointer part and name part
|
||||
length = len(ctype)
|
||||
star_index = ctype.find("*")
|
||||
name_part: str
|
||||
pointer_level: int
|
||||
if star_index == -1:
|
||||
# No star, no pointer level
|
||||
name_part = ctype
|
||||
pointer_level = 0
|
||||
else:
|
||||
# Has star
|
||||
if star_index == 0:
|
||||
raise RuntimeError("base type not found")
|
||||
name_part = ctype[0:star_index]
|
||||
pointer_level = length - star_index
|
||||
|
||||
# resolve name part
|
||||
base_type_hierarchy = list(name_part.split("::"))
|
||||
|
||||
# return value
|
||||
return VariableType(base_type_hierarchy, pointer_level)
|
||||
|
||||
def to_c_type(self) -> str:
|
||||
"""
|
||||
Build a type string represented by this variable type in C/C++ style.
|
||||
|
||||
:return: The type string in C/C++ style.
|
||||
"""
|
||||
return "::".join(self.__base_type_hierarchy) + ("*" * self.__pointer_level)
|
||||
|
||||
def get_base_type(self) -> str:
|
||||
"""
|
||||
Get the base type of this variable type without any namespace.
|
||||
|
||||
It just simply get the last entry in type hierarchy.
|
||||
|
||||
:return: The base type string without namespace prefix.
|
||||
"""
|
||||
return self.__base_type_hierarchy[-1]
|
||||
|
||||
def is_pointer(self) -> bool:
|
||||
"""
|
||||
Check whether this variable type is a pointer.
|
||||
This function just check whether the pointer level of this variavle type is zero.
|
||||
|
||||
:return: True if it is pointer, otherwise false.
|
||||
"""
|
||||
return self.__pointer_level != 0
|
||||
|
||||
def get_pointer_level(self) -> int:
|
||||
"""
|
||||
Return the pointer level of this variable type.
|
||||
|
||||
You can simply assume the pointer level is equal to the count of trailing star.
|
||||
|
||||
:return: The pointer level integer. Zero means that this type is not a pointer.
|
||||
"""
|
||||
return self.__pointer_level
|
||||
|
||||
def iter_base_type_hierarchy(self) -> typing.Iterator[str]:
|
||||
"""
|
||||
Return the clone of the type hierarchy of this variable type.
|
||||
|
||||
It is rarely used.
|
||||
This only should be used when you need the namespace hierarchy of this variable type.
|
||||
|
||||
:return: The clone of current variable type hierarchy.
|
||||
"""
|
||||
return iter(self.__base_type_hierarchy)
|
||||
|
||||
# def is_valid(self) -> bool:
|
||||
# """
|
||||
# Check whether this type is a valid one.
|
||||
|
||||
# It actually check whether type hierarchy include at least one entry.
|
||||
|
||||
# :return: True if no problem of this type, otherwise false.
|
||||
# """
|
||||
# return len(self.__base_type_hierarchy) != 0
|
||||
|
||||
def get_pointer_of_this(self) -> "VariableType":
|
||||
"""
|
||||
Return a new created variable type which is the pointer of this variable type.
|
||||
|
||||
In internal implementation, it just create a clone of current variable type
|
||||
with the increase of pointer level by 1.
|
||||
|
||||
:return: The new created pointer type of this variable type.
|
||||
"""
|
||||
return VariableType(list(self.__base_type_hierarchy), self.__pointer_level + 1)
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: str) -> "VariableType":
|
||||
return VariableType.from_c_type(data)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ExpFctParam:
|
||||
"""The class represent a single parameter (argument) of function."""
|
||||
|
||||
var_type: VariableType
|
||||
"""The type of this parameter."""
|
||||
var_name: str
|
||||
"""The name of this parameter."""
|
||||
is_input: bool
|
||||
"""
|
||||
True if this parameter is marked as input parameter, otherwise false.
|
||||
|
||||
Input parameter and output parameter is commonly used in C/C++ code.
|
||||
By using this feature, each function can receive multiple arguments
|
||||
and return multiple arguments without defining a struct to hold it.
|
||||
|
||||
The type of input parameter is itself.
|
||||
However, the type of output parameter is the pointer of itself.
|
||||
So you may need get its pointer type when processing output parameter,
|
||||
especially for the scenario that the target language do not support explicit output parameter keyword.
|
||||
"""
|
||||
var_desc: str
|
||||
"""
|
||||
The description of this parameter.
|
||||
|
||||
This description is generated by this program.
|
||||
It will indicate the underlying C++ type to tell end user how to treat this parameter
|
||||
because some target languages' native calling style can not represent these detail.
|
||||
|
||||
In this program, this field must be written as a docstring of corresponding function.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, typing.Any]) -> "ExpFctParam":
|
||||
return ExpFctParam(
|
||||
VariableType.from_c_type(data["type"]),
|
||||
data["name"],
|
||||
data["is_input"],
|
||||
data["desc"],
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ExpFct:
|
||||
"""The class represent an export BMap function."""
|
||||
|
||||
fct_name: str
|
||||
"""The name of this function."""
|
||||
fct_rv_type: VariableType
|
||||
"""The return value type of this function."""
|
||||
fct_params: list[ExpFctParam]
|
||||
"""
|
||||
The parameters (arguments) list of this function.
|
||||
Each item represent parameter accepted by this function one by one from left to right.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, typing.Any]) -> "ExpFct":
|
||||
return ExpFct(
|
||||
data["name"],
|
||||
VariableType.from_json(data["return"]),
|
||||
list(map(lambda i: ExpFctParam.from_json(i), data["params"])),
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ExpFctCollection:
|
||||
"""The class represent a collection of export BMap functions."""
|
||||
|
||||
fcts: list[ExpFct]
|
||||
"""The collection of exported BMap functions."""
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: list[typing.Any]) -> "ExpFctCollection":
|
||||
return ExpFctCollection(list(map(lambda i: ExpFct.from_json(i), data)))
|
||||
|
||||
|
||||
def load_fcts(filename: str) -> ExpFctCollection:
|
||||
with open(utils.get_input_file_path(filename), "r", encoding="utf-8") as f:
|
||||
return ExpFctCollection.from_json(json.load(f))
|
||||
17
Assets/CodeGen/BMapBinder/ExpFctsRender/main.py
Normal file
17
Assets/CodeGen/BMapBinder/ExpFctsRender/main.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import json_loader
|
||||
import template_render
|
||||
import utils
|
||||
|
||||
def main():
|
||||
render = template_render.TemplateRender()
|
||||
fcts = json_loader.load_fcts("BMExports.json")
|
||||
|
||||
render.render_cs_expfcts("BMExports.cs", fcts)
|
||||
render.render_py_expfcts("BMExports.py", fcts)
|
||||
render.render_rs_expfcts("BMExports.rs", fcts)
|
||||
|
||||
print("Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
9
Assets/CodeGen/BMapBinder/ExpFctsRender/pyproject.toml
Normal file
9
Assets/CodeGen/BMapBinder/ExpFctsRender/pyproject.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[project]
|
||||
name = "exp-fcts-render"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"jinja2==3.1.6",
|
||||
]
|
||||
264
Assets/CodeGen/BMapBinder/ExpFctsRender/template_render.py
Normal file
264
Assets/CodeGen/BMapBinder/ExpFctsRender/template_render.py
Normal file
@@ -0,0 +1,264 @@
|
||||
import jinja2
|
||||
import re
|
||||
import typing
|
||||
from dataclasses import dataclass
|
||||
from json_loader import ExpFctCollection, ExpFctParam
|
||||
import utils
|
||||
|
||||
CPP_PY_TYPE_MAP: dict[str, str] = {
|
||||
"CKSTRING": "CKSTRING",
|
||||
"CKDWORD": "CKDWORD",
|
||||
"CKWORD": "CKWORD",
|
||||
"CKINT": "CKINT",
|
||||
"bool": "bool",
|
||||
"CKFLOAT": "CKFLOAT",
|
||||
"CKBYTE": "CKBYTE",
|
||||
"CK_ID": "CKID",
|
||||
"NakedOutputCallback": "callback",
|
||||
"BMFile": "void",
|
||||
"BMMeshTransition": "void",
|
||||
"VxVector3": "VxVector3",
|
||||
"VxVector2": "VxVector2",
|
||||
"VxColor": "VxColor",
|
||||
"VxMatrix": "VxMatrix",
|
||||
"CK_TEXTURE_SAVEOPTIONS": "enum",
|
||||
"VX_PIXELFORMAT": "enum",
|
||||
"VXLIGHT_TYPE": "enum",
|
||||
"VXTEXTURE_BLENDMODE": "enum",
|
||||
"VXTEXTURE_FILTERMODE": "enum",
|
||||
"VXTEXTURE_ADDRESSMODE": "enum",
|
||||
"VXBLEND_MODE": "enum",
|
||||
"VXFILL_MODE": "enum",
|
||||
"VXSHADE_MODE": "enum",
|
||||
"VXCMPFUNC": "enum",
|
||||
"VXMESH_LITMODE": "enum",
|
||||
"CK_CAMERA_PROJECTION": "enum",
|
||||
}
|
||||
|
||||
CS_ENUM_LIKE: set[str] = set((
|
||||
"CK_TEXTURE_SAVEOPTIONS",
|
||||
"VX_PIXELFORMAT",
|
||||
"VXLIGHT_TYPE",
|
||||
"VXTEXTURE_BLENDMODE",
|
||||
"VXTEXTURE_FILTERMODE",
|
||||
"VXTEXTURE_ADDRESSMODE",
|
||||
"VXBLEND_MODE",
|
||||
"VXFILL_MODE",
|
||||
"VXSHADE_MODE",
|
||||
"VXCMPFUNC",
|
||||
"VXMESH_LITMODE",
|
||||
"CK_CAMERA_PROJECTION",
|
||||
))
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CsInteropType:
|
||||
"""The class represent the C# type corresponding to extracted variable type."""
|
||||
|
||||
marshal_as: str
|
||||
"""
|
||||
The argument of MarshalAsAttribute constructor.
|
||||
In generation, this field should be used like this: "[MarshalAs(THIS)]" (for parameter),
|
||||
or "[return: MarshalAs(THIS)]" (for return value).
|
||||
"""
|
||||
cs_type: str
|
||||
"""
|
||||
The C# type used in interop function declaration for corresponding parameter.
|
||||
"""
|
||||
|
||||
|
||||
class RenderUtils:
|
||||
"""Possible used functions for jinja when rendering templates"""
|
||||
|
||||
@staticmethod
|
||||
def get_python_type(param: ExpFctParam) -> str:
|
||||
vt = param.var_type
|
||||
if not param.is_input:
|
||||
vt = vt.get_pointer_of_this()
|
||||
|
||||
# add type prefix
|
||||
sb: str = "bm_"
|
||||
# try getting cpp type from base type and add it
|
||||
cpp_type = CPP_PY_TYPE_MAP.get(vt.get_base_type(), None)
|
||||
if cpp_type is None:
|
||||
raise RuntimeError(f"unexpected type {vt.to_c_type()}")
|
||||
else:
|
||||
sb += cpp_type
|
||||
# add pointer suffix
|
||||
if vt.is_pointer():
|
||||
sb += "_"
|
||||
sb += "p" * vt.get_pointer_level()
|
||||
|
||||
# return built type string.
|
||||
return sb
|
||||
|
||||
@staticmethod
|
||||
def get_cs_interop_type(param: ExpFctParam) -> CsInteropType:
|
||||
# get essential variable type properties first
|
||||
vt = param.var_type
|
||||
vt_base_type = vt.get_base_type()
|
||||
vt_pointer_level = vt.get_pointer_level()
|
||||
|
||||
# declare return value
|
||||
marshal_as: str | None = None
|
||||
cs_type: str | None = None
|
||||
|
||||
# use "match" to check variable type
|
||||
match vt_base_type:
|
||||
case 'CKSTRING':
|
||||
# decide direction cookies
|
||||
direction_cookie = 'In' if param.is_input else 'Out'
|
||||
# only allow 0 and 1 pointer level for string.
|
||||
match vt_pointer_level:
|
||||
case 0:
|
||||
marshaler = 'BMOwnedStringMarshaler' if param.is_input else 'BMStringMarshaler'
|
||||
marshal_as = f'UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof({marshaler})'
|
||||
cs_type = "string"
|
||||
case 1:
|
||||
marshaler = 'BMOwnedStringArrayMarshaler' if param.is_input else 'BMStringArrayMarshaler'
|
||||
marshal_as = f'UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof({marshaler})'
|
||||
cs_type = "string[]"
|
||||
case "CKDWORD":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.U4"
|
||||
cs_type = "uint"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "CKWORD":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.U2"
|
||||
cs_type = "ushort"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "CKINT":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.I4"
|
||||
cs_type = "int"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "bool":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.U1"
|
||||
cs_type = "bool"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "CKFLOAT":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.R4"
|
||||
cs_type = "float"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "CKBYTE":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.U1"
|
||||
cs_type = "byte"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "CK_ID":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.U4"
|
||||
cs_type = "uint"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "NakedOutputCallback":
|
||||
# callback actually is a function pointer
|
||||
# so it only allow base type without any pointer level.
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.FunctionPtr"
|
||||
cs_type = "OutputCallback"
|
||||
case "BMFile":
|
||||
# In any case, BMFile only should be raw pointer
|
||||
if vt_pointer_level != 0:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "BMMeshTransition":
|
||||
# In any case, BMMeshTransition only should be raw pointer
|
||||
if vt_pointer_level != 0:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "VxVector3":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.Struct"
|
||||
cs_type = "VxVector3"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "VxVector2":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.Struct"
|
||||
cs_type = "VxVector2"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "VxColor":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.Struct"
|
||||
cs_type = "VxColor"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case "VxMatrix":
|
||||
if vt_pointer_level == 0:
|
||||
marshal_as = "UnmanagedType.Struct"
|
||||
cs_type = "VxMatrix"
|
||||
else:
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
case enumlike if enumlike in CS_ENUM_LIKE:
|
||||
# all enum type use the same strategy
|
||||
if vt_pointer_level == 0:
|
||||
# all enum type should be marshaled as its underlying type
|
||||
# but we can use its name in C# directly.
|
||||
marshal_as = "UnmanagedType.U4"
|
||||
cs_type = vt_base_type
|
||||
else:
|
||||
# for pointer type, use IntPtr instead.
|
||||
marshal_as = "UnmanagedType.SysInt"
|
||||
cs_type = "IntPtr"
|
||||
|
||||
# check whether we successfully get result
|
||||
if marshal_as is None or cs_type is None:
|
||||
raise RuntimeError(f'unexpected type: {vt.to_c_type()}')
|
||||
|
||||
# return value
|
||||
return CsInteropType(marshal_as, cs_type)
|
||||
|
||||
|
||||
class TemplateRender:
|
||||
"""Render templates to code files"""
|
||||
|
||||
__loader: jinja2.BaseLoader
|
||||
__environment: jinja2.Environment
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.__loader = jinja2.FileSystemLoader(utils.get_template_directory())
|
||||
self.__environment = jinja2.Environment(loader=self.__loader)
|
||||
|
||||
def __render(
|
||||
self, template_name: str, dest_filename: str, payload: ExpFctCollection
|
||||
) -> None:
|
||||
# prepare template argument
|
||||
template_argument: dict[str, typing.Any] = {
|
||||
"payload": payload,
|
||||
"utils": RenderUtils,
|
||||
}
|
||||
# fetch template
|
||||
template = self.__environment.get_template(str(template_name))
|
||||
# render template and save
|
||||
with open(utils.get_output_file_path(dest_filename), "w", encoding="utf-8") as f:
|
||||
f.write(template.render(**template_argument))
|
||||
|
||||
def render_cs_expfcts(self, filename: str, fcts: ExpFctCollection) -> None:
|
||||
self.__render("expfcts.cs.jinja", filename, fcts)
|
||||
|
||||
def render_py_expfcts(self, filename: str, fcts: ExpFctCollection) -> None:
|
||||
self.__render("expfcts.py.jinja", filename, fcts)
|
||||
|
||||
def render_rs_expfcts(self, filename: str, fcts: ExpFctCollection) -> None:
|
||||
self.__render("expfcts.rs.jinja", filename, fcts)
|
||||
@@ -0,0 +1,16 @@
|
||||
{%- for fct in payload.fcts %}
|
||||
/// <summary>{{ fct.fct_name }}</summary>
|
||||
{%- for param in fct.fct_params %}
|
||||
/// <param name="{{ param.var_name }}">Direction: {% if param.is_input -%} input {%- else -%} output {%- endif %}. C++ type: {{ param.var_type.to_c_type() }}. {{ param.var_desc }}</param>
|
||||
{%- endfor %}
|
||||
/// <returns>True if no error, otherwise False.</returns>
|
||||
[DllImport(DLL_NAME, EntryPoint = "{{ fct.fct_name }}", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi, ExactSpelling = true)]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static extern bool {{ fct.fct_name }}(
|
||||
{%- for param in fct.fct_params -%}
|
||||
{%- set param_cs_interop_type = utils.get_cs_interop_type(param) -%}
|
||||
[{% if param.is_input -%} In {%- else -%} Out {%- endif %}, MarshalAs({{ param_cs_interop_type.marshal_as }})] {% if not param.is_input %}out {% endif %} {{- param_cs_interop_type.cs_type }} {{ param.var_name }}
|
||||
{%- if not loop.last %}, {% endif %}
|
||||
{%- endfor -%}
|
||||
);
|
||||
{%- endfor %}
|
||||
@@ -0,0 +1,17 @@
|
||||
{%- for fct in payload.fcts %}
|
||||
{{ fct.fct_name }} = _create_bmap_func('{{ fct.fct_name }}', [
|
||||
{%- for param in fct.fct_params %}
|
||||
{{- utils.get_python_type(param) }}
|
||||
{%- if not loop.last %}, {% endif %}
|
||||
{%- endfor -%}
|
||||
])
|
||||
"""
|
||||
{{ fct.fct_name }}
|
||||
{% for param in fct.fct_params %}
|
||||
:param {{ param.var_name }}: Direction: {% if param.is_input -%} input {%- else -%} output {%- endif %}. {{ param.var_desc }}
|
||||
:type {{ param.var_name }}: {{ utils.get_python_type(param) }} ({{ param.var_type.to_c_type() }} in C++). {% if param.is_input -%} Use ctypes.byref() pass it. {%- endif %}
|
||||
{%- endfor %}
|
||||
:return: True if no error, otherwise False.
|
||||
:rtype: bool
|
||||
"""
|
||||
{%- endfor %}
|
||||
22
Assets/CodeGen/BMapBinder/ExpFctsRender/utils.py
Normal file
22
Assets/CodeGen/BMapBinder/ExpFctsRender/utils.py
Normal file
@@ -0,0 +1,22 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _get_root_directory() -> Path:
|
||||
bmap_binder_root = os.environ.get("BMAP_BINDER_ROOT", None)
|
||||
if bmap_binder_root is None:
|
||||
return Path(__file__).resolve().parent.parent
|
||||
else:
|
||||
return Path(bmap_binder_root).resolve()
|
||||
|
||||
|
||||
def get_input_file_path(filename: str) -> Path:
|
||||
return _get_root_directory() / "Analyzed" / filename
|
||||
|
||||
|
||||
def get_output_file_path(filename: str) -> Path:
|
||||
return _get_root_directory() / "Output" / filename
|
||||
|
||||
|
||||
def get_template_directory() -> Path:
|
||||
return Path(__file__).resolve().parent / "templates"
|
||||
100
Assets/CodeGen/BMapBinder/ExpFctsRender/uv.lock
generated
Normal file
100
Assets/CodeGen/BMapBinder/ExpFctsRender/uv.lock
generated
Normal file
@@ -0,0 +1,100 @@
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.11"
|
||||
|
||||
[[package]]
|
||||
name = "exp-fcts-render"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "jinja2" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "jinja2", specifier = "==3.1.6" }]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "markupsafe" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "3.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
|
||||
]
|
||||
0
Assets/CodeGen/BMapBinder/Output/.gitkeep
Normal file
0
Assets/CodeGen/BMapBinder/Output/.gitkeep
Normal file
65
Assets/CodeGen/BMapBinder/README.md
Normal file
65
Assets/CodeGen/BMapBinder/README.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# BMap Binder
|
||||
|
||||
A helper program to generate BMap binding for Python, C# and Rust.
|
||||
|
||||
## Usage
|
||||
|
||||
This program is consisted by 3 parts: ExpFcts Extractor, ExpFcts Analyzer and ExpFcts Render.
|
||||
|
||||
"ExpFcts" is stand for "Exported Functions".
|
||||
|
||||
### Setup Environment
|
||||
|
||||
First we stay at the root directory of this project (this README file located).
|
||||
And execute `set BMAP_BINDER_ROOT=$(pwd)` on POSIX-like OS, or `set BMAP_BINDER_ROOT=%CD%` on Windows, to set environment variable.
|
||||
This environment variable will be used later by 3 parts conststing this project.
|
||||
|
||||
Then we navigate to the root directory of this repository (where you can find top-level `CMakeLists.txt` file). And execute `set LIBCMO21_REPO_ROOT=$(pwd)` on POSIX-like OS, or `set LIBCMO21_REPO_ROOT=%CD%` on Windows, to set environment variable.
|
||||
This environment variable also will be used later.
|
||||
|
||||
### ExpFcts Extractor
|
||||
|
||||
We should first run ExpFcts Extractor to extract BMap exported function declarations fron header file.
|
||||
BMap header file include various contents, not only the declaration of exported functions, but also many of other utilities.
|
||||
We use regex to extract BMap exported function declarations only to avoid build a complete C lexer and parser in following steps and make our work easier.
|
||||
|
||||
For running this program, please following these steps:
|
||||
|
||||
* Enter `ExpFctsExtractor` directory and setup it with Astral UV.
|
||||
* Execute `uv run main.py` to run program.
|
||||
* Program will process BMap header file `BMExports.hpp` from BMap project located in root directory of this repository, and output extracted text to `Extracted` directory with name `BMExports.hpp`.
|
||||
|
||||
### ExpFcts Analyzer
|
||||
|
||||
Now we can run ExpFcts Analyzer to analyze extracted BMap exported function declarations.
|
||||
|
||||
#### Build
|
||||
|
||||
Enter `ExpFctsAnalyzer` directory, and execute following command to generate Antlr lexer and parser:
|
||||
|
||||
```
|
||||
antlr4 ExpFctsLexer.g4
|
||||
antlr4 ExpFctsParser.g4
|
||||
```
|
||||
|
||||
Keep staying that directory, and execute following command to build Java code.
|
||||
|
||||
```
|
||||
javac *.java
|
||||
```
|
||||
|
||||
#### Run
|
||||
|
||||
Keep staying this directory, and execute following command to run program.
|
||||
|
||||
```
|
||||
java MainRunner
|
||||
```
|
||||
|
||||
After running, program will process input file `BMExports.hpp` located in `Extracted` directory, and output JSON file to `Analyzed` directory with name `BMExports.json`.
|
||||
|
||||
### ExpFcts Render
|
||||
|
||||
* Enter `ExpFctsRender` directory and setup it with Astral UV.
|
||||
* Execute `uv run main.py` to run program.
|
||||
* Program will process JSON file `BMExports.json` located in `Analyzed` directory, and output final artifacts to `Output` directory.
|
||||
6
Assets/CodeGen/EnumsMigration/.gitignore
vendored
Normal file
6
Assets/CodeGen/EnumsMigration/.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
## ======== Personal ========
|
||||
# Ignore intermediate stuff and output stuff.
|
||||
Intermediate/*
|
||||
!Intermediate/*.gitkeep
|
||||
Output/*
|
||||
!Output/*.gitkeep
|
||||
126
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/.gitignore
vendored
Normal file
126
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/.gitignore
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
## ======== Personal ========
|
||||
# Additional remove for JetBrains IDEA
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
## ======== ANTLR Output ========
|
||||
*.interp
|
||||
*.tokens
|
||||
|
||||
CKGenericLexer*.java
|
||||
CKEnumsParser*.java
|
||||
CKDefinesParser*.java
|
||||
|
||||
## ======== Java ========
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
## ======== JetBrains ========
|
||||
# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
.idea/sonarlint.xml # see https://community.sonarsource.com/t/is-the-file-idea-idea-idea-sonarlint-xml-intended-to-be-under-source-control/121119
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based HTTP Client
|
||||
.idea/httpRequests
|
||||
http-client.private.env.json
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
# Apifox Helper cache
|
||||
.idea/.cache/.Apifox_Helper
|
||||
.idea/ApifoxUploaderProjectSetting.xml
|
||||
|
||||
# Github Copilot persisted session migrations, see: https://github.com/microsoft/copilot-intellij-feedback/issues/712#issuecomment-3322062215
|
||||
.idea/**/copilot.data.migration.*.xml
|
||||
@@ -0,0 +1,6 @@
|
||||
parser grammar CKDefinesParser;
|
||||
options { tokenVocab = CKGenericLexer; }
|
||||
|
||||
prog: definePair+ ;
|
||||
|
||||
definePair: CKGENERIC_DEFINE CKGENERIC_ID (CKGENERIC_NUM | CKGENERIC_ID) ;
|
||||
14
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/CKEnumsParser.g4
Normal file
14
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/CKEnumsParser.g4
Normal file
@@ -0,0 +1,14 @@
|
||||
parser grammar CKEnumsParser;
|
||||
options { tokenVocab = CKGenericLexer; }
|
||||
|
||||
prog: enumBody* ;
|
||||
|
||||
enumBody: CKGENERIC_TYPEDEF? CKGENERIC_ENUM CKGENERIC_ID CKGENERIC_LBRACKET
|
||||
entryPair+
|
||||
CKGENERIC_RBRACKET CKGENERIC_ID? CKGENERIC_SEMICOLON ;
|
||||
|
||||
entryPair: CKGENERIC_ID (CKGENERIC_EQUAL entryValue)? CKGENERIC_COMMA? ;
|
||||
|
||||
entryValue: CKGENERIC_NUM (CKGENERIC_LSHIFT CKGENERIC_NUM)? # entryDirectValue
|
||||
| CKGENERIC_ID (CKGENERIC_OR CKGENERIC_ID)* # entryRelativeValue
|
||||
;
|
||||
@@ -0,0 +1,26 @@
|
||||
lexer grammar CKGenericLexer;
|
||||
|
||||
channels { COMMENTS, WHITESPACE }
|
||||
|
||||
// keywords
|
||||
CKGENERIC_TYPEDEF: 'typedef' ;
|
||||
CKGENERIC_DEFINE: '#define' ;
|
||||
CKGENERIC_ENUM: 'enum' ;
|
||||
// symbols
|
||||
CKGENERIC_LBRACKET: '{' ;
|
||||
CKGENERIC_RBRACKET: '}' ;
|
||||
CKGENERIC_EQUAL: '=';
|
||||
CKGENERIC_SEMICOLON: ';' ;
|
||||
CKGENERIC_LSHIFT: '<<' ;
|
||||
CKGENERIC_OR: '|' ;
|
||||
CKGENERIC_COMMA: ',' ;
|
||||
|
||||
// identifider and number
|
||||
CKGENERIC_ID: [_a-zA-Z][_a-zA-Z0-9]* ;
|
||||
CKGENERIC_NUM: (('0'[xX]) | '-')? [0-9a-fA-F]+ [uUlL]* ;
|
||||
|
||||
// comments
|
||||
CKGENERIC_LINE_COMMENT: '//' ~[\r\n]* -> channel(COMMENTS);
|
||||
CKGENERIC_BLOCK_COMMENT: '/*' .*? '*/' -> channel(COMMENTS);
|
||||
// whitespace
|
||||
CKGENERIC_WS: [ \t\r\n]+ -> channel(WHITESPACE);
|
||||
@@ -2,7 +2,6 @@
|
||||
import java.util.Stack;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
/**
|
||||
* The specialized walker for collecting CK_CLASSID and its inherit
|
||||
@@ -19,12 +18,12 @@ public class ClassidWalker extends CKDefinesParserBaseListener {
|
||||
mCurrentEntry = null;
|
||||
}
|
||||
|
||||
public EnumsHelper.Enum_t getEnum() {
|
||||
public EnumsHelper.BEnum getEnum() {
|
||||
return mResult;
|
||||
}
|
||||
|
||||
private int getClassidLevel(Token defineHead) {
|
||||
Token ws = CommonHelper.getPreChannelToken(mTokenStream, defineHead, CKGeneralLexer.WHITESPACE);
|
||||
Token ws = CommonHelper.getPreChannelToken(mTokenStream, defineHead, CKGenericLexer.WHITESPACE);
|
||||
if (ws == null)
|
||||
return 0;
|
||||
|
||||
@@ -54,18 +53,18 @@ public class ClassidWalker extends CKDefinesParserBaseListener {
|
||||
}
|
||||
|
||||
private BufferedTokenStream mTokenStream;
|
||||
private EnumsHelper.Enum_t mResult;
|
||||
private EnumsHelper.BEnum mResult;
|
||||
|
||||
private int mLevel;
|
||||
private Stack<EnumsHelper.EnumEntryWithHierarchy_t> mLevelStack;
|
||||
private EnumsHelper.Enum_t mCurrentEnum;
|
||||
private EnumsHelper.EnumEntryWithHierarchy_t mCurrentEntry;
|
||||
private Stack<EnumsHelper.BHierarchyEnumEntry> mLevelStack;
|
||||
private EnumsHelper.BEnum mCurrentEnum;
|
||||
private EnumsHelper.BHierarchyEnumEntry mCurrentEntry;
|
||||
|
||||
@Override
|
||||
public void enterProg(CKDefinesParser.ProgContext ctx) {
|
||||
mLevel = 0;
|
||||
mLevelStack = new Stack<EnumsHelper.EnumEntryWithHierarchy_t>();
|
||||
mCurrentEnum = new EnumsHelper.Enum_t();
|
||||
mLevelStack = new Stack<EnumsHelper.BHierarchyEnumEntry>();
|
||||
mCurrentEnum = new EnumsHelper.BEnum();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,14 +81,14 @@ public class ClassidWalker extends CKDefinesParserBaseListener {
|
||||
|
||||
@Override
|
||||
public void enterDefinePair(CKDefinesParser.DefinePairContext ctx) {
|
||||
mCurrentEntry = new EnumsHelper.EnumEntryWithHierarchy_t();
|
||||
mCurrentEntry = new EnumsHelper.BHierarchyEnumEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitDefinePair(CKDefinesParser.DefinePairContext ctx) {
|
||||
// fill entry info
|
||||
mCurrentEntry.mEntryName = ctx.CKGENERAL_ID(0).getText();
|
||||
mCurrentEntry.mEntryValue = ctx.CKGENERAL_NUM().getText();
|
||||
mCurrentEntry.mEntryName = ctx.CKGENERIC_ID(0).getText();
|
||||
mCurrentEntry.mEntryValue = ctx.CKGENERIC_NUM().getText();
|
||||
|
||||
// fill entry level info
|
||||
int this_level = getClassidLevel(ctx.getStart());
|
||||
@@ -22,13 +22,13 @@ public class CommentsFinder {
|
||||
// if we don't know where is our token,
|
||||
// we should assume it is from precomment to postcomment
|
||||
// and check it.
|
||||
List<Token> precomment = CommonHelper.getPreChannelTokens(mTokenStream, preToken, CKGeneralLexer.COMMENTS);
|
||||
List<Token> precomment = CommonHelper.getPreChannelTokens(mTokenStream, preToken, CKGenericLexer.COMMENTS);
|
||||
if (precomment != null) {
|
||||
mCommentsPos = CommentsPosition.Precomment;
|
||||
return CommonHelper.cutComments(precomment);
|
||||
}
|
||||
|
||||
List<Token> postcomment = CommonHelper.getPostChannelTokens(mTokenStream, postToken, CKGeneralLexer.COMMENTS);
|
||||
List<Token> postcomment = CommonHelper.getPostChannelTokens(mTokenStream, postToken, CKGenericLexer.COMMENTS);
|
||||
if (postcomment != null) {
|
||||
mCommentsPos = CommentsPosition.Postcomment;
|
||||
return CommonHelper.cutComments(postcomment);
|
||||
@@ -38,10 +38,10 @@ public class CommentsFinder {
|
||||
return null;
|
||||
}
|
||||
case Precomment: {
|
||||
return CommonHelper.cutComments(CommonHelper.getPreChannelTokens(mTokenStream, preToken, CKGeneralLexer.COMMENTS));
|
||||
return CommonHelper.cutComments(CommonHelper.getPreChannelTokens(mTokenStream, preToken, CKGenericLexer.COMMENTS));
|
||||
}
|
||||
case Postcomment: {
|
||||
return CommonHelper.cutComments(CommonHelper.getPostChannelTokens(mTokenStream, postToken, CKGeneralLexer.COMMENTS));
|
||||
return CommonHelper.cutComments(CommonHelper.getPostChannelTokens(mTokenStream, postToken, CKGenericLexer.COMMENTS));
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
@@ -2,6 +2,8 @@ import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -44,12 +46,36 @@ public class CommonHelper {
|
||||
return null;
|
||||
|
||||
switch (comment.getType()) {
|
||||
case CKGeneralLexer.CKGENERAL_LINE_COMMENT: {
|
||||
return removeStars(comment.getText().substring(2));
|
||||
case CKGenericLexer.CKGENERIC_LINE_COMMENT: {
|
||||
// For line comment, we start to remove "//" prefix first
|
||||
String slashRemoved = comment.getText().substring(2);
|
||||
// Then remove successive starts
|
||||
String starsRemoved = removeSeperator(slashRemoved);
|
||||
// Do a strip for it.
|
||||
String stripped = starsRemoved.strip();
|
||||
// Then remove EOL to avoid unexpected line break.
|
||||
String eolRemoved = removeEol(stripped);
|
||||
// Okey
|
||||
return eolRemoved;
|
||||
}
|
||||
case CKGeneralLexer.CKGENERAL_BLOCK_COMMENT: {
|
||||
String cache = comment.getText();
|
||||
return removeStars(cache.substring(2, cache.length() - 4));
|
||||
case CKGenericLexer.CKGENERIC_BLOCK_COMMENT: {
|
||||
// For block comment, we first cut "/*" head and "*/" tail.
|
||||
String blockComment = comment.getText();
|
||||
String slashRemoved = blockComment.substring(2, blockComment.length() - 4);
|
||||
|
||||
// Then we break it at line breaker and process each line one by one.
|
||||
String beautyComment = slashRemoved.lines().map((String line) -> {
|
||||
// Remove successive starts
|
||||
String starsRemoved = removeSeperator(line);
|
||||
// Do a strip for it.
|
||||
String stripped = starsRemoved.strip();
|
||||
// Then remove EOL to avoid unexpected line break.
|
||||
String eolRemoved = removeEol(stripped);
|
||||
// Line process is okey now
|
||||
return eolRemoved;
|
||||
}).collect(Collectors.joining("\n")); // Then re-join with fresh line breaker
|
||||
// Then return
|
||||
return beautyComment;
|
||||
}
|
||||
default:
|
||||
return comment.getText();
|
||||
@@ -70,15 +96,14 @@ public class CommonHelper {
|
||||
return null;
|
||||
|
||||
return tokens.stream().map(value -> {
|
||||
String text = cutComment(value).strip();
|
||||
return text + " ";
|
||||
}).collect(Collectors.joining(""));
|
||||
return cutComment(value);
|
||||
}).collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
// =========== Number Operations ===========
|
||||
|
||||
/**
|
||||
* Check whether Antlr captured CKGENERAL_NUM is a negative number.
|
||||
* Check whether Antlr captured CKGENERIC_NUM is a negative number.
|
||||
*
|
||||
* @param numstr The captured number.
|
||||
* @return true if it is negative number.
|
||||
@@ -88,7 +113,7 @@ public class CommonHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether Altlr captured CKGENERAL_NUM is a hex number.
|
||||
* Check whether Altlr captured CKGENERIC_NUM is a hex number.
|
||||
*
|
||||
* @param numstr The captured number.
|
||||
* @return true if it is hex number.
|
||||
@@ -97,41 +122,17 @@ public class CommonHelper {
|
||||
return numstr.startsWith("0x") || numstr.startsWith("0X");
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert accepted string into Python cupported format.
|
||||
*
|
||||
* It actually just remove trail "UL".
|
||||
*
|
||||
* @param numstr The captured number.
|
||||
* @return The Python style number string.
|
||||
*/
|
||||
public static String convertToPythonNumber(String numstr) {
|
||||
return numstr.replaceFirst("[ulUL]+$", "");
|
||||
}
|
||||
// =========== File Operations ===========
|
||||
|
||||
// =========== Parts ===========
|
||||
|
||||
enum CKParts {
|
||||
CK2, VxMath
|
||||
}
|
||||
|
||||
enum LangType {
|
||||
Cpp, Python, CSharp
|
||||
}
|
||||
|
||||
public static String getCKPartsNamespace(CKParts parts) {
|
||||
switch (parts) {
|
||||
case CK2:
|
||||
return "CK2";
|
||||
case VxMath:
|
||||
return "VxMath";
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected value: " + parts);
|
||||
private static Path getRootDirectoryPath() throws Exception {
|
||||
String rootDir = System.getenv("ENUMS_MIGRATION_ROOT");
|
||||
if (rootDir == null) {
|
||||
throw new RuntimeException("Can not find essential environment variable ENUMS_MIGRATION_ROOT");
|
||||
} else {
|
||||
return Paths.get(rootDir);
|
||||
}
|
||||
}
|
||||
|
||||
// =========== File Operations ===========
|
||||
|
||||
public static class InputFilePair {
|
||||
public CharStream mAntlrStream;
|
||||
public FileInputStream mUnderlyingStream;
|
||||
@@ -144,6 +145,12 @@ public class CommonHelper {
|
||||
return pair;
|
||||
}
|
||||
|
||||
public static String getInputFilePath(String filename) throws Exception {
|
||||
Path rootDir = getRootDirectoryPath();
|
||||
Path filePath = rootDir.resolve("Input").resolve(filename);
|
||||
return filePath.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output file for writing.
|
||||
*
|
||||
@@ -156,82 +163,33 @@ public class CommonHelper {
|
||||
return new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
// =========== String Process ===========
|
||||
|
||||
/**
|
||||
* Escape String
|
||||
*
|
||||
* Escape all characters which are invalid in string quote.
|
||||
*
|
||||
* @param strl The string need to be escaped.
|
||||
* @return The escaped string.
|
||||
* @see removeEol
|
||||
*/
|
||||
public static String escapeString(String strl) {
|
||||
return strl.replace("\\", "\\\\").replace("\t", "\\t").replace("\b", "\\b").replace("\n", "\\n")
|
||||
.replace("\r", "\\r").replace("\f", "\\f").replace("\"", "\\\"");
|
||||
public static String getOutputFilePath(String filename) throws Exception {
|
||||
Path rootDir = getRootDirectoryPath();
|
||||
Path filePath = rootDir.resolve("Intermediate").resolve(filename);
|
||||
return filePath.toString();
|
||||
}
|
||||
|
||||
// =========== String Process ===========
|
||||
|
||||
/**
|
||||
* Remove all EOL (End of Line) characters.
|
||||
*
|
||||
* @param strl The string need to be processed.
|
||||
* @return The string eliminated all EOL.
|
||||
* @see escapeString
|
||||
*/
|
||||
public static String removeEol(String strl) {
|
||||
return strl.replace("\n", "").replace("\r", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove redundent star '*' (at least 5 continuous star chars)
|
||||
* Remove seperator bar consisted by '*' or '-' (at least 5 successive chars)
|
||||
*
|
||||
* @param cmt The string provided.
|
||||
* @return The string processed.
|
||||
*/
|
||||
public static String removeStars(String cmt) {
|
||||
public static String removeSeperator(String cmt) {
|
||||
// only remove at least 5 continuous star chars.
|
||||
return cmt.replaceAll("\\*{5,}", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get indent char by style
|
||||
*
|
||||
* @param use_tab Whether indent use Tab, not Space.
|
||||
* @return The indent chars
|
||||
*/
|
||||
public static String getIndentString(boolean use_tab) {
|
||||
if (use_tab)
|
||||
return "\t";
|
||||
else
|
||||
return " ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-indent a block of string
|
||||
*
|
||||
* This function will first split block string by line. Then remove all indent
|
||||
* (strip Tab and Space). At last, re-indent and join each line
|
||||
*
|
||||
* @param block_str The string provided.
|
||||
* @param use_tab Use Tab, not Space as indent chars.
|
||||
* @param indent_level The level of indent, started by 0.
|
||||
* @return The re-indent string
|
||||
*/
|
||||
public static String reindentBlockString(String block_str, boolean use_tab, int indent_level) {
|
||||
// pre-create indent string
|
||||
String indentChars = getIndentString(use_tab);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < indent_level; ++i) {
|
||||
sb.append(indentChars);
|
||||
}
|
||||
String indents = sb.toString();
|
||||
|
||||
// split line
|
||||
return block_str.lines().map((String line) -> {
|
||||
// strip space and tab, then re-indent it.
|
||||
return indents + line.trim();
|
||||
}).collect(Collectors.joining(System.lineSeparator())); // then join with new line breaker and return.
|
||||
return cmt.replaceAll("[\\*\\-]{5,}", "");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
/**
|
||||
* The generic walker for collecting defines as a enum.
|
||||
@@ -14,19 +13,19 @@ public class DefinesWalker extends CKDefinesParserBaseListener {
|
||||
mCurrentEntry = null;
|
||||
}
|
||||
|
||||
public EnumsHelper.Enum_t getEnum() {
|
||||
public EnumsHelper.BEnum getEnum() {
|
||||
return mResult;
|
||||
}
|
||||
|
||||
private CommentsFinder mCommentsFinder;
|
||||
private EnumsHelper.Enum_t mResult;
|
||||
private EnumsHelper.BEnum mResult;
|
||||
|
||||
private EnumsHelper.Enum_t mCurrentEnum;
|
||||
private EnumsHelper.EnumEntry_t mCurrentEntry;
|
||||
private EnumsHelper.BEnum mCurrentEnum;
|
||||
private EnumsHelper.BEnumEntry mCurrentEntry;
|
||||
|
||||
@Override
|
||||
public void enterProg(CKDefinesParser.ProgContext ctx) {
|
||||
mCurrentEnum = new EnumsHelper.Enum_t();
|
||||
mCurrentEnum = new EnumsHelper.BEnum();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -37,22 +36,22 @@ public class DefinesWalker extends CKDefinesParserBaseListener {
|
||||
|
||||
@Override
|
||||
public void enterDefinePair(CKDefinesParser.DefinePairContext ctx) {
|
||||
mCurrentEntry = new EnumsHelper.EnumEntry_t();
|
||||
mCurrentEntry = new EnumsHelper.BEnumEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitDefinePair(CKDefinesParser.DefinePairContext ctx) {
|
||||
// set values
|
||||
mCurrentEntry.mEntryName = ctx.CKGENERAL_ID(0).getText();
|
||||
mCurrentEntry.mEntryName = ctx.CKGENERIC_ID(0).getText();
|
||||
mCurrentEntry.mEntryComment = mCommentsFinder.getComment(ctx.getStart(), ctx.getStop());
|
||||
|
||||
if (ctx.CKGENERAL_NUM() == null) {
|
||||
if (ctx.CKGENERIC_NUM() == null) {
|
||||
// define with id
|
||||
mCurrentEntry.mEntryValue = ctx.CKGENERAL_ID(1).getText();
|
||||
mCurrentEntry.mEntryValue = ctx.CKGENERIC_ID(1).getText();
|
||||
|
||||
} else {
|
||||
// define with number
|
||||
String num = ctx.CKGENERAL_NUM().getText();
|
||||
String num = ctx.CKGENERIC_NUM().getText();
|
||||
mCurrentEntry.mEntryValue = num;
|
||||
|
||||
// check whether this enum can be unsigned
|
||||
76
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/EnumsHelper.java
Normal file
76
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/EnumsHelper.java
Normal file
@@ -0,0 +1,76 @@
|
||||
import java.util.Vector;
|
||||
|
||||
public class EnumsHelper {
|
||||
/**
|
||||
* The struct to describe the entry of an enum.
|
||||
*/
|
||||
public static class BEnumEntry {
|
||||
public BEnumEntry() {
|
||||
mEntryName = null;
|
||||
mEntryValue = null;
|
||||
mEntryComment = null;
|
||||
}
|
||||
|
||||
/** The name of this entry. Can not be null. */
|
||||
public String mEntryName;
|
||||
/** The value of this entry. null if this entry do not have explicit value. */
|
||||
public String mEntryValue;
|
||||
/** The comment of this entry. null if no comment. */
|
||||
public String mEntryComment;
|
||||
}
|
||||
|
||||
/**
|
||||
* The specialized EnumEntry type which can store extra hierarchy info.
|
||||
* Used in CK_CLASSID parsing.
|
||||
*/
|
||||
public static class BHierarchyEnumEntry extends BEnumEntry {
|
||||
public BHierarchyEnumEntry() {
|
||||
super();
|
||||
mHierarchy = new Vector<BHierarchyEnumEntry>();
|
||||
}
|
||||
|
||||
/**
|
||||
* The list to store this CK_CLASSID inheritance relationship.
|
||||
* The first item is the oldest parent in inheritance.
|
||||
* The last item is self.
|
||||
*/
|
||||
public Vector<BHierarchyEnumEntry> mHierarchy;
|
||||
}
|
||||
|
||||
/**
|
||||
* The struct to describe an enum.
|
||||
*/
|
||||
public static class BEnum {
|
||||
public BEnum() {
|
||||
mEnumName = null;
|
||||
mEnumComment = null;
|
||||
mCanUnsigned = true;
|
||||
mUseFlags = false;
|
||||
mEntries = new Vector<BEnumEntry>();
|
||||
}
|
||||
|
||||
/** The name of this enum. Can not be null. */
|
||||
public String mEnumName;
|
||||
/** The comment of this enum. null if no comment. */
|
||||
public String mEnumComment;
|
||||
/** True if this enum can use unsigned integer as its underlying type. */
|
||||
public boolean mCanUnsigned;
|
||||
/** True if this enum will use flags feature (supporting OR, AND, operators). */
|
||||
public boolean mUseFlags;
|
||||
/** The list to store entries of this enum. */
|
||||
public Vector<BEnumEntry> mEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* The struct to describe a collection of enums.
|
||||
*/
|
||||
public static class BEnumCollection {
|
||||
public BEnumCollection() {
|
||||
mEnums = new Vector<BEnum>();
|
||||
}
|
||||
|
||||
/** The list to store enums. */
|
||||
public Vector<BEnum> mEnums;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,26 +18,26 @@ public class EnumsWalker extends CKEnumsParserBaseListener {
|
||||
mCurrentEntry = null;
|
||||
}
|
||||
|
||||
public EnumsHelper.EnumCollection_t getEnums() {
|
||||
public EnumsHelper.BEnumCollection getEnums() {
|
||||
return mResult;
|
||||
}
|
||||
|
||||
private String getEnumComment(Token enumHead) {
|
||||
return CommonHelper
|
||||
.cutComments(CommonHelper.getPreChannelTokens(mTokenStream, enumHead, CKGeneralLexer.COMMENTS));
|
||||
.cutComments(CommonHelper.getPreChannelTokens(mTokenStream, enumHead, CKGenericLexer.COMMENTS));
|
||||
}
|
||||
|
||||
private BufferedTokenStream mTokenStream;
|
||||
private CommentsFinder mCommentsFinder;
|
||||
private EnumsHelper.EnumCollection_t mResult;
|
||||
private EnumsHelper.BEnumCollection mResult;
|
||||
|
||||
private EnumsHelper.EnumCollection_t mCurrentProg;
|
||||
private EnumsHelper.Enum_t mCurrentEnum;
|
||||
private EnumsHelper.EnumEntry_t mCurrentEntry;
|
||||
private EnumsHelper.BEnumCollection mCurrentProg;
|
||||
private EnumsHelper.BEnum mCurrentEnum;
|
||||
private EnumsHelper.BEnumEntry mCurrentEntry;
|
||||
|
||||
@Override
|
||||
public void enterProg(CKEnumsParser.ProgContext ctx) {
|
||||
mCurrentProg = new EnumsHelper.EnumCollection_t();
|
||||
mCurrentProg = new EnumsHelper.BEnumCollection();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,7 +48,7 @@ public class EnumsWalker extends CKEnumsParserBaseListener {
|
||||
|
||||
@Override
|
||||
public void enterEnumBody(CKEnumsParser.EnumBodyContext ctx) {
|
||||
mCurrentEnum = new EnumsHelper.Enum_t();
|
||||
mCurrentEnum = new EnumsHelper.BEnum();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,7 +56,7 @@ public class EnumsWalker extends CKEnumsParserBaseListener {
|
||||
// get enum comment
|
||||
mCurrentEnum.mEnumComment = getEnumComment(ctx.getStart());
|
||||
// get the last name (for typedef case)
|
||||
List<TerminalNode> allNames = ctx.CKGENERAL_ID();
|
||||
List<TerminalNode> allNames = ctx.CKGENERIC_ID();
|
||||
mCurrentEnum.mEnumName = allNames.get(allNames.size() - 1).getText();
|
||||
|
||||
mCurrentProg.mEnums.add(mCurrentEnum);
|
||||
@@ -65,7 +65,7 @@ public class EnumsWalker extends CKEnumsParserBaseListener {
|
||||
|
||||
@Override
|
||||
public void enterEntryPair(CKEnumsParser.EntryPairContext ctx) {
|
||||
mCurrentEntry = new EnumsHelper.EnumEntry_t();
|
||||
mCurrentEntry = new EnumsHelper.BEnumEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,7 +73,7 @@ public class EnumsWalker extends CKEnumsParserBaseListener {
|
||||
// get entry comment
|
||||
mCurrentEntry.mEntryComment = mCommentsFinder.getComment(ctx.getStart(), ctx.getStop());
|
||||
// get entry name
|
||||
mCurrentEntry.mEntryName = ctx.CKGENERAL_ID().getText();
|
||||
mCurrentEntry.mEntryName = ctx.CKGENERIC_ID().getText();
|
||||
|
||||
mCurrentEnum.mEntries.add(mCurrentEntry);
|
||||
mCurrentEntry = null;
|
||||
@@ -82,7 +82,7 @@ public class EnumsWalker extends CKEnumsParserBaseListener {
|
||||
@Override
|
||||
public void exitEntryDirectValue(CKEnumsParser.EntryDirectValueContext ctx) {
|
||||
// get all numbers
|
||||
List<TerminalNode> nums = ctx.CKGENERAL_NUM();
|
||||
List<TerminalNode> nums = ctx.CKGENERIC_NUM();
|
||||
|
||||
switch (nums.size()) {
|
||||
case 1: {
|
||||
@@ -120,7 +120,7 @@ public class EnumsWalker extends CKEnumsParserBaseListener {
|
||||
@Override
|
||||
public void exitEntryRelativeValue(CKEnumsParser.EntryRelativeValueContext ctx) {
|
||||
// get all identifiers and join them
|
||||
mCurrentEntry.mEntryValue = ctx.CKGENERAL_ID().stream().map(value -> value.getText())
|
||||
mCurrentEntry.mEntryValue = ctx.CKGENERIC_ID().stream().map(value -> value.getText())
|
||||
.collect(Collectors.joining(" | "));
|
||||
|
||||
// | operator appears. this enum must have flags feature
|
||||
73
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/JsonWriter.java
Normal file
73
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/JsonWriter.java
Normal file
@@ -0,0 +1,73 @@
|
||||
import java.io.OutputStreamWriter;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class JsonWriter {
|
||||
|
||||
private static JsonObject writeBEnumEntry(EnumsHelper.BEnumEntry enumEntry) {
|
||||
JsonObject data = new JsonObject();
|
||||
data.addProperty("name", enumEntry.mEntryName);
|
||||
data.addProperty("value", enumEntry.mEntryValue);
|
||||
data.addProperty("comment", enumEntry.mEntryComment);
|
||||
|
||||
// Export hierarchy if possible
|
||||
if (enumEntry instanceof EnumsHelper.BHierarchyEnumEntry hierarchyEnumEntry) {
|
||||
// We only export name in hierarchy.
|
||||
// Otherwise, we may cause recursive calling.
|
||||
JsonArray entries = new JsonArray();
|
||||
for (EnumsHelper.BHierarchyEnumEntry subEntry : hierarchyEnumEntry.mHierarchy) {
|
||||
entries.add(subEntry.mEntryName);
|
||||
}
|
||||
data.add("hierarchy", entries);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static JsonObject writeBEnum(EnumsHelper.BEnum benum) {
|
||||
JsonObject data = new JsonObject();
|
||||
data.addProperty("name", benum.mEnumName);
|
||||
data.addProperty("comment", benum.mEnumComment);
|
||||
data.addProperty("can_unsigned", benum.mCanUnsigned);
|
||||
data.addProperty("use_flags", benum.mUseFlags);
|
||||
data.addProperty("use_flags", benum.mUseFlags);
|
||||
|
||||
JsonArray entries = new JsonArray();
|
||||
for (EnumsHelper.BEnumEntry enumEntry : benum.mEntries) {
|
||||
entries.add(writeBEnumEntry(enumEntry));
|
||||
}
|
||||
data.add("entries", entries);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static JsonArray writeBEnumCollection(EnumsHelper.BEnumCollection enumCollection) {
|
||||
JsonArray data = new JsonArray();
|
||||
for (EnumsHelper.BEnum benum : enumCollection.mEnums) {
|
||||
data.add(writeBEnum(benum));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private static void writeJson(String filename, EnumsHelper.BEnumCollection enumCollection) throws Exception {
|
||||
OutputStreamWriter writer = CommonHelper.openOutputFile(filename);
|
||||
//Gson gsonInstance = new GsonBuilder().serializeNulls().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
Gson gsonInstance = new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
|
||||
writer.write(gsonInstance.toJson(writeBEnumCollection(enumCollection)));
|
||||
writer.close();
|
||||
}
|
||||
|
||||
public static void writeEnums(String filename, EnumsHelper.BEnumCollection enumCollection) throws Exception {
|
||||
writeJson(filename, enumCollection);
|
||||
}
|
||||
|
||||
public static void writeEnum(String filename, EnumsHelper.BEnum benum) throws Exception {
|
||||
// Build collection manually.
|
||||
EnumsHelper.BEnumCollection collection = new EnumsHelper.BEnumCollection();
|
||||
collection.mEnums.add(benum);
|
||||
// Call underlying writer
|
||||
writeEnums(filename, collection);
|
||||
}
|
||||
}
|
||||
142
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/MainRunner.java
Normal file
142
Assets/CodeGen/EnumsMigration/EnumsAnalyzer/MainRunner.java
Normal file
@@ -0,0 +1,142 @@
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
public class MainRunner {
|
||||
|
||||
/**
|
||||
* Extract an enums collection from given file.
|
||||
* <p>
|
||||
* This function is the most commonly used function for extracting enums.
|
||||
* <p>
|
||||
* This function is used for a file which only contain enum declarations. This
|
||||
* is not suit for extracting CKERROR and CK_CLASSID. For these declarations,
|
||||
* please use their specialized extractor as described following.
|
||||
*
|
||||
* @param filename The file name relative to input directory for reading.
|
||||
* @return An {@linkplain EnumsHelper.BEnumCollection} instance.
|
||||
* @throws Exception
|
||||
*/
|
||||
private static EnumsHelper.BEnumCollection getEnumsCollection(String filename) throws Exception {
|
||||
String infile = CommonHelper.getInputFilePath(filename);
|
||||
CommonHelper.InputFilePair pair = CommonHelper.openInputFile(infile);
|
||||
CKGenericLexer lexer = new CKGenericLexer(pair.mAntlrStream);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
CKEnumsParser parser = new CKEnumsParser(tokens);
|
||||
|
||||
ParseTree tree = parser.prog();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
EnumsWalker worker = new EnumsWalker(tokens);
|
||||
walker.walk(worker, tree);
|
||||
|
||||
pair.mUnderlyingStream.close();
|
||||
return worker.getEnums();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a series of "#define" syntax as an enum.
|
||||
* <p>
|
||||
* This function will assume that given file only contain C++ "#define" syntax.
|
||||
* After reading it, it will re-organize it as an enum and return. This only is
|
||||
* used by CKERROR now. But it is suit for more scenarios if there are something
|
||||
* like CKERROR in the future.
|
||||
*
|
||||
* @param filename The file name relative to input directory for reading.
|
||||
* @param assignedEnumName The desired name of organized enum instance.
|
||||
* Contemporary this field should always be "CKERROR"
|
||||
* because no one else is using it.
|
||||
* @return An {@linkplain EnumsHelper.BEnum} instance.
|
||||
* @throws Exception
|
||||
*/
|
||||
private static EnumsHelper.BEnum organiseDefines(String filename, String assignedEnumName) throws Exception {
|
||||
String infile = CommonHelper.getInputFilePath(filename);
|
||||
CommonHelper.InputFilePair pair = CommonHelper.openInputFile(infile);
|
||||
CKGenericLexer lexer = new CKGenericLexer(pair.mAntlrStream);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
CKDefinesParser parser = new CKDefinesParser(tokens);
|
||||
|
||||
ParseTree tree = parser.prog();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
DefinesWalker worker = new DefinesWalker(tokens);
|
||||
walker.walk(worker, tree);
|
||||
|
||||
pair.mUnderlyingStream.close();
|
||||
|
||||
EnumsHelper.BEnum result = worker.getEnum();
|
||||
result.mEnumName = assignedEnumName;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a series of macro define as an enum, considering its indent to build
|
||||
* hierarchy.
|
||||
* <p>
|
||||
* This is specialized enum extractor of CK_CLASSID. The given file should use a
|
||||
* series "#define" syntax to describe enum, and use Tab as the indent before
|
||||
* each "#define" syntax to indicate its hierarchy.
|
||||
*
|
||||
* @param filename The file name relative to input directory for reading.
|
||||
* @return An {@linkplain EnumsHelper.BEnum} instance. Actually it is an
|
||||
* instance to {@linkplain EnumsHelper.BEnum} whose entries is
|
||||
* {@linkplain EnumsHelper.BHierarchyEnumEntry}, the child class of
|
||||
* {@linkplain EnumsHelper.BEnumEntry} (the entry type of common
|
||||
* {@linkplain EnumsHelper.BEnum}) with extra hierarchy infos.
|
||||
* @throws Exception
|
||||
*/
|
||||
private static EnumsHelper.BEnum organiseClassid(String filename) throws Exception {
|
||||
String infile = CommonHelper.getInputFilePath(filename);
|
||||
CommonHelper.InputFilePair pair = CommonHelper.openInputFile(infile);
|
||||
CKGenericLexer lexer = new CKGenericLexer(pair.mAntlrStream);
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
CKDefinesParser parser = new CKDefinesParser(tokens);
|
||||
|
||||
ParseTree tree = parser.prog();
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
ClassidWalker worker = new ClassidWalker(tokens);
|
||||
walker.walk(worker, tree);
|
||||
|
||||
pair.mUnderlyingStream.close();
|
||||
|
||||
EnumsHelper.BEnum result = worker.getEnum();
|
||||
result.mEnumName = "CK_CLASSID";
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// =========== CKERROR ===========
|
||||
EnumsHelper.BEnum ckerror = organiseDefines("CKERROR.txt", "CKERROR");
|
||||
JsonWriter.writeEnum(CommonHelper.getOutputFilePath("CKERROR.json"), ckerror);
|
||||
|
||||
// =========== CK_CLASSID ===========
|
||||
EnumsHelper.BEnum classid = organiseClassid("CK_CLASSID.txt");
|
||||
JsonWriter.writeEnum(CommonHelper.getOutputFilePath("CK_CLASSID.json"), classid);
|
||||
|
||||
// =========== Define2 ===========
|
||||
EnumsHelper.BEnumCollection def2 = getEnumsCollection("Defines2.txt");
|
||||
JsonWriter.writeEnums(CommonHelper.getOutputFilePath("Defines2.json"), def2);
|
||||
|
||||
// =========== Combined enums ===========
|
||||
EnumsHelper.BEnumCollection ck2Enums = getEnumsCollection("CKEnums.txt"),
|
||||
vxEnums = getEnumsCollection("VxEnums.txt");
|
||||
JsonWriter.writeEnums(CommonHelper.getOutputFilePath("CKEnums.json"), ck2Enums);
|
||||
JsonWriter.writeEnums(CommonHelper.getOutputFilePath("VxEnums.json"), vxEnums);
|
||||
|
||||
// =========== Single enums ===========
|
||||
EnumsHelper.BEnum single;
|
||||
|
||||
single = organiseDefines("CK_STATECHUNK_CHUNKVERSION.txt", "CK_STATECHUNK_CHUNKVERSION");
|
||||
JsonWriter.writeEnum(CommonHelper.getOutputFilePath("CK_STATECHUNK_CHUNKVERSION.json"), single);
|
||||
|
||||
single = organiseDefines("CK_STATECHUNK_DATAVERSION.txt", "CK_STATECHUNK_DATAVERSION");
|
||||
JsonWriter.writeEnum(CommonHelper.getOutputFilePath("CK_STATECHUNK_DATAVERSION.json"), single);
|
||||
|
||||
single = organiseDefines("CK_BITMAPDATA_FLAGS.txt", "CK_BITMAPDATA_FLAGS");
|
||||
JsonWriter.writeEnum(CommonHelper.getOutputFilePath("CK_BITMAPDATA_FLAGS.json"), single);
|
||||
|
||||
single = organiseDefines("CK_CAMERA_PROJECTION.txt", "CK_CAMERA_PROJECTION");
|
||||
JsonWriter.writeEnum(CommonHelper.getOutputFilePath("CK_CAMERA_PROJECTION.json"), single);
|
||||
|
||||
// print message.
|
||||
System.out.println("Done");
|
||||
}
|
||||
}
|
||||
10
Assets/CodeGen/EnumsMigration/EnumsRender/.gitignore
vendored
Normal file
10
Assets/CodeGen/EnumsMigration/EnumsRender/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
@@ -0,0 +1 @@
|
||||
3.11
|
||||
3
Assets/CodeGen/EnumsMigration/EnumsRender/README.md
Normal file
3
Assets/CodeGen/EnumsMigration/EnumsRender/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Enums Render
|
||||
|
||||
See upper level [README.md](../README.md) for informations.
|
||||
190
Assets/CodeGen/EnumsMigration/EnumsRender/json_loader.py
Normal file
190
Assets/CodeGen/EnumsMigration/EnumsRender/json_loader.py
Normal file
@@ -0,0 +1,190 @@
|
||||
import json
|
||||
import typing
|
||||
import utils
|
||||
|
||||
|
||||
class BEnumEntry:
|
||||
"""The struct to describe the entry of an enum."""
|
||||
|
||||
__entry_name: str
|
||||
"""The name of this entry."""
|
||||
__entry_value: str | None
|
||||
"""The value of this entry. None if this entry do not have explicit value."""
|
||||
__entry_comment: str | None
|
||||
"""The comment of this entry. None if no comment."""
|
||||
|
||||
def __init__(
|
||||
self, entry_name: str, entry_value: str | None, entry_comment: str | None
|
||||
):
|
||||
self.__entry_name = entry_name
|
||||
self.__entry_value = entry_value
|
||||
self.__entry_comment = entry_comment
|
||||
|
||||
def get_entry_name(self) -> str:
|
||||
"""Get the name of this entry."""
|
||||
return self.__entry_name
|
||||
|
||||
def get_entry_value(self) -> str | None:
|
||||
"""Get the value of this entry. None if this entry do not have explicit value."""
|
||||
return self.__entry_value
|
||||
|
||||
def get_entry_comment(self) -> str | None:
|
||||
"""Get the comment of this entry. None if no comment."""
|
||||
return self.__entry_comment
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, typing.Any]) -> "BEnumEntry":
|
||||
return BEnumEntry(
|
||||
data["name"],
|
||||
data.get("value", None),
|
||||
data.get("comment", None),
|
||||
)
|
||||
|
||||
|
||||
class BHierarchyEnumEntry(BEnumEntry):
|
||||
"""
|
||||
The specialized EnumEntry type which can store extra hierarchy info.
|
||||
Used in CK_CLASSID parsing.
|
||||
"""
|
||||
|
||||
__hierarchy: list[str]
|
||||
"""
|
||||
The list to store this CK_CLASSID inheritance relationship.
|
||||
The first item is the oldest parent in inheritance.
|
||||
The last item is self.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
entry_name: str,
|
||||
entry_value: str | None,
|
||||
entry_comment: str | None,
|
||||
hierarchy: list[str],
|
||||
):
|
||||
super().__init__(entry_name, entry_value, entry_comment)
|
||||
self.__hierarchy = hierarchy
|
||||
|
||||
def iter_hierarchy(self, benum: "BEnum") -> typing.Iterator["BHierarchyEnumEntry"]:
|
||||
return map(
|
||||
lambda e: typing.cast(BHierarchyEnumEntry, benum.get_entry_by_name(e)),
|
||||
self.__hierarchy,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, typing.Any]) -> "BHierarchyEnumEntry":
|
||||
return BHierarchyEnumEntry(
|
||||
data["name"],
|
||||
data.get("value", None),
|
||||
data.get("comment", None),
|
||||
data["hierarchy"],
|
||||
)
|
||||
|
||||
|
||||
class BEnum:
|
||||
"""The struct to describe an enum."""
|
||||
|
||||
__enum_name: str
|
||||
"""The name of this enum."""
|
||||
__enum_comment: str | None
|
||||
"""The comment of this enum. None if no comment."""
|
||||
__can_unsigned: bool
|
||||
"""True if this enum can use unsigned integer as its underlying type."""
|
||||
__use_flags: bool
|
||||
"""True if this enum will use flags feature (supporting OR, AND, operators)."""
|
||||
__entries: list[BEnumEntry]
|
||||
"""The list to store entries of this enum."""
|
||||
|
||||
__entries_map: dict[str, BEnumEntry]
|
||||
"""The name map for `entries`."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
enum_name: str,
|
||||
enum_comment: str | None,
|
||||
can_unsigned: bool,
|
||||
use_flags: bool,
|
||||
entries: list[BEnumEntry],
|
||||
):
|
||||
self.__enum_name = enum_name
|
||||
self.__enum_comment = enum_comment
|
||||
self.__can_unsigned = can_unsigned
|
||||
self.__use_flags = use_flags
|
||||
self.__entries = entries
|
||||
self.__entries_map = {e.get_entry_name(): e for e in entries}
|
||||
|
||||
def get_enum_name(self) -> str:
|
||||
"""Get the name of this enum."""
|
||||
return self.__enum_name
|
||||
|
||||
def get_enum_comment(self) -> str | None:
|
||||
"""Get the comment of this enum. None if no comment."""
|
||||
return self.__enum_comment
|
||||
|
||||
def get_can_unsigned(self) -> bool:
|
||||
"""True if this enum can use unsigned integer as its underlying type."""
|
||||
return self.__can_unsigned
|
||||
|
||||
def get_use_flags(self) -> bool:
|
||||
"""True if this enum will use flags feature (supporting OR, AND, operators)."""
|
||||
return self.__use_flags
|
||||
|
||||
def iter_entries(self) -> typing.Iterator[BEnumEntry]:
|
||||
"""Get the iterator of entries of this enum."""
|
||||
return iter(self.__entries)
|
||||
|
||||
def get_entry_by_name(self, name: str) -> BEnumEntry:
|
||||
return self.__entries_map[name]
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: dict[str, typing.Any]) -> "BEnum":
|
||||
return BEnum(
|
||||
data["name"],
|
||||
data.get("comment", None),
|
||||
data["can_unsigned"],
|
||||
data["use_flags"],
|
||||
list(map(lambda i: BEnum.__create_entry_by_content(i), data["entries"])),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def __create_entry_by_content(data: dict[str, typing.Any]) -> "BEnumEntry":
|
||||
if "hierarchy" in data:
|
||||
return BHierarchyEnumEntry.from_json(data)
|
||||
else:
|
||||
return BEnumEntry.from_json(data)
|
||||
|
||||
|
||||
class BEnumCollection:
|
||||
"""The struct to describe a collection of enums."""
|
||||
|
||||
__enums: list[BEnum]
|
||||
"""The list to store enums."""
|
||||
|
||||
def __init__(self, enums: list[BEnum]):
|
||||
self.__enums = enums
|
||||
|
||||
def iter_enums(self) -> typing.Iterator[BEnum]:
|
||||
"""Get the iterator of enums."""
|
||||
return iter(self.__enums)
|
||||
|
||||
def get_enums_count(self) -> int:
|
||||
"""Get the count of enums."""
|
||||
return len(self.__enums)
|
||||
|
||||
def get_enum_by_index(self, index: int) -> BEnum:
|
||||
"""Get the enum by index."""
|
||||
return self.__enums[index]
|
||||
|
||||
@staticmethod
|
||||
def from_json(data: list[typing.Any]) -> "BEnumCollection":
|
||||
return BEnumCollection(list(map(lambda i: BEnum.from_json(i), data)))
|
||||
|
||||
|
||||
def load_enums(filename: str) -> BEnumCollection:
|
||||
with open(utils.get_input_file_path(filename), "r", encoding="utf-8") as f:
|
||||
return BEnumCollection.from_json(json.load(f))
|
||||
|
||||
|
||||
def load_enum(filename: str) -> BEnum:
|
||||
collection = load_enums(filename)
|
||||
assert collection.get_enums_count() == 1
|
||||
return collection.get_enum_by_index(0)
|
||||
106
Assets/CodeGen/EnumsMigration/EnumsRender/main.py
Normal file
106
Assets/CodeGen/EnumsMigration/EnumsRender/main.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import json_loader
|
||||
import template_render
|
||||
import utils
|
||||
from utils import CKParts
|
||||
|
||||
def main():
|
||||
render = template_render.TemplateRender()
|
||||
|
||||
# CKERROR
|
||||
ckerror = json_loader.load_enum("CKERROR.json")
|
||||
render.render_cpp_enum("CKERROR.hpp", ckerror)
|
||||
render.render_py_enum("CKERROR.py", ckerror)
|
||||
render.render_cs_enum("CKERROR.cs", ckerror)
|
||||
render.render_cpp_ckerror_docstring("CKERROR.docstring.hpp", "CKERROR.docstring.cpp", ckerror)
|
||||
render.render_py_enum_docstring("CKERROR.docstring.py", ckerror)
|
||||
render.render_cs_enum_docstring("CKERROR.docstring.cs", ckerror)
|
||||
render.render_rs_enum_docstring("CKERROR.docstring.rs", ckerror)
|
||||
|
||||
# CK_CLASSID
|
||||
classid = json_loader.load_enum("CK_CLASSID.json")
|
||||
render.render_cpp_enum("CK_CLASSID.hpp", classid)
|
||||
render.render_py_enum("CK_CLASSID.py", classid)
|
||||
render.render_cs_enum("CK_CLASSID.cs", classid)
|
||||
render.render_rs_enum("CK_CLASSID.rs", classid)
|
||||
render.render_cpp_ckclassid_docstring("CK_CLASSID.docstring.hpp", "CK_CLASSID.docstring.cpp", classid)
|
||||
render.render_py_enum_docstring("CK_CLASSID.docstring.py", classid)
|
||||
render.render_cs_enum_docstring("CK_CLASSID.docstring.cs", classid)
|
||||
render.render_rs_enum_docstring("CK_CLASSID.docstring.rs", classid)
|
||||
|
||||
# Define2
|
||||
def2 = json_loader.load_enums("Defines2.json")
|
||||
render.render_cpp_enums("Defines2.hpp", def2)
|
||||
render.render_py_enums("Defines2.py", def2)
|
||||
render.render_cs_enums("Defines2.cs", def2)
|
||||
render.render_rs_enums("Defines2.rs", def2)
|
||||
# Define2 do not need annotation output.
|
||||
# Because they are CKStateChunk used value which are not exposed to outside.
|
||||
|
||||
# Combined Enums
|
||||
ck2Enums = json_loader.load_enums("CKEnums.json")
|
||||
vxEnums = json_loader.load_enums("VxEnums.json")
|
||||
|
||||
render.render_cpp_enums("CKEnums.hpp", ck2Enums)
|
||||
render.render_py_enums("CKEnums.py", ck2Enums)
|
||||
render.render_cs_enums("CKEnums.cs", ck2Enums)
|
||||
render.render_rs_enums("CKEnums.rs", ck2Enums)
|
||||
render.render_cpp_enum_docstrings("CKEnums.docstring.hpp", "CKEnums.docstring.cpp", ck2Enums, CKParts.CK2)
|
||||
render.render_py_enum_docstrings("CKEnums.docstring.py", ck2Enums)
|
||||
render.render_cs_enum_docstrings("CKEnums.docstring.cs", ck2Enums)
|
||||
render.render_rs_enum_docstrings("CKEnums.docstring.rs", ck2Enums)
|
||||
|
||||
render.render_cpp_enums("VxEnums.hpp", vxEnums)
|
||||
render.render_py_enums("VxEnums.py", vxEnums)
|
||||
render.render_cs_enums("VxEnums.cs", vxEnums)
|
||||
render.render_rs_enums("VxEnums.rs", vxEnums)
|
||||
render.render_cpp_enum_docstrings("VxEnums.docstring.hpp", "VxEnums.docstring.cpp", vxEnums, CKParts.VxMath)
|
||||
render.render_py_enum_docstrings("VxEnums.docstring.py", vxEnums)
|
||||
render.render_cs_enum_docstrings("VxEnums.docstring.cs", vxEnums)
|
||||
render.render_rs_enum_docstrings("VxEnums.docstring.rs", vxEnums)
|
||||
|
||||
# Single enums
|
||||
single = json_loader.load_enum("CK_STATECHUNK_CHUNKVERSION.json")
|
||||
render.render_cpp_enum("CK_STATECHUNK_CHUNKVERSION.hpp", single)
|
||||
render.render_py_enum("CK_STATECHUNK_CHUNKVERSION.py", single)
|
||||
render.render_cs_enum("CK_STATECHUNK_CHUNKVERSION.cs", single)
|
||||
render.render_rs_enum("CK_STATECHUNK_CHUNKVERSION.rs", single)
|
||||
render.render_cpp_enum_docstring("CK_STATECHUNK_CHUNKVERSION.docstring.hpp", "CK_STATECHUNK_CHUNKVERSION.docstring.cpp", single, CKParts.CK2)
|
||||
render.render_py_enum_docstring("CK_STATECHUNK_CHUNKVERSION.docstring.py", single)
|
||||
render.render_cs_enum_docstring("CK_STATECHUNK_CHUNKVERSION.docstring.cs", single)
|
||||
render.render_rs_enum_docstring("CK_STATECHUNK_CHUNKVERSION.docstring.rs", single)
|
||||
|
||||
single = json_loader.load_enum("CK_STATECHUNK_DATAVERSION.json")
|
||||
render.render_cpp_enum("CK_STATECHUNK_DATAVERSION.hpp", single)
|
||||
render.render_py_enum("CK_STATECHUNK_DATAVERSION.py", single)
|
||||
render.render_cs_enum("CK_STATECHUNK_DATAVERSION.cs", single)
|
||||
render.render_rs_enum("CK_STATECHUNK_DATAVERSION.rs", single)
|
||||
render.render_cpp_enum_docstring("CK_STATECHUNK_DATAVERSION.docstring.hpp", "CK_STATECHUNK_DATAVERSION.docstring.cpp", single, CKParts.CK2)
|
||||
render.render_py_enum_docstring("CK_STATECHUNK_DATAVERSION.docstring.py", single)
|
||||
render.render_cs_enum_docstring("CK_STATECHUNK_DATAVERSION.docstring.cs", single)
|
||||
render.render_rs_enum_docstring("CK_STATECHUNK_DATAVERSION.docstring.rs", single)
|
||||
|
||||
single = json_loader.load_enum("CK_BITMAPDATA_FLAGS.json")
|
||||
render.render_cpp_enum("CK_BITMAPDATA_FLAGS.hpp", single)
|
||||
render.render_py_enum("CK_BITMAPDATA_FLAGS.py", single)
|
||||
render.render_cs_enum("CK_BITMAPDATA_FLAGS.cs", single)
|
||||
render.render_rs_enum("CK_BITMAPDATA_FLAGS.rs", single)
|
||||
render.render_cpp_enum_docstring("CK_BITMAPDATA_FLAGS.docstring.hpp", "CK_BITMAPDATA_FLAGS.docstring.cpp", single, CKParts.CK2)
|
||||
render.render_py_enum_docstring("CK_BITMAPDATA_FLAGS.docstring.py", single)
|
||||
render.render_cs_enum_docstring("CK_BITMAPDATA_FLAGS.docstring.cs", single)
|
||||
render.render_rs_enum_docstring("CK_BITMAPDATA_FLAGS.docstring.rs", single)
|
||||
|
||||
single = json_loader.load_enum("CK_CAMERA_PROJECTION.json")
|
||||
render.render_cpp_enum("CK_CAMERA_PROJECTION.hpp", single)
|
||||
render.render_py_enum("CK_CAMERA_PROJECTION.py", single)
|
||||
render.render_cs_enum("CK_CAMERA_PROJECTION.cs", single)
|
||||
render.render_rs_enum("CK_CAMERA_PROJECTION.rs", single)
|
||||
render.render_cpp_enum_docstring("CK_CAMERA_PROJECTION.docstring.hpp", "CK_CAMERA_PROJECTION.docstring.cpp", single, CKParts.CK2)
|
||||
render.render_py_enum_docstring("CK_CAMERA_PROJECTION.docstring.py", single)
|
||||
render.render_cs_enum_docstring("CK_CAMERA_PROJECTION.docstring.cs", single)
|
||||
render.render_rs_enum_docstring("CK_CAMERA_PROJECTION.docstring.rs", single)
|
||||
|
||||
print("Done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user