Compare commits
3 Commits
fe4a58e864
...
v0.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
| af6a50c2f9 | |||
| 0bf0519c4c | |||
| c18ff8f2e3 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,6 +5,9 @@
|
|||||||
*.nms
|
*.nms
|
||||||
*.vmo
|
*.vmo
|
||||||
|
|
||||||
|
# Ignore CMake generated version header
|
||||||
|
LibCmo/VTVersion.hpp
|
||||||
|
|
||||||
# Ignore temporary Visual Studio files and folders
|
# Ignore temporary Visual Studio files and folders
|
||||||
temp/
|
temp/
|
||||||
out/
|
out/
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
<ProjectReference Include="..\BMapSharp\BMapSharp.csproj" />
|
<ProjectReference Include="..\BMapSharp\BMapSharp.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
|||||||
@@ -3,11 +3,19 @@ using System;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.CommandLine;
|
||||||
|
|
||||||
namespace BMapSharpTestbench {
|
namespace BMapSharpTestbench {
|
||||||
internal class Program {
|
internal class Program {
|
||||||
|
|
||||||
static void Main(string[] args) {
|
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
|
// Check environment
|
||||||
Console.OutputEncoding = Encoding.UTF8;
|
Console.OutputEncoding = Encoding.UTF8;
|
||||||
if (!BMapSharp.BMapWrapper.Utils.IsBMapAvailable()) {
|
if (!BMapSharp.BMapWrapper.Utils.IsBMapAvailable()) {
|
||||||
@@ -21,10 +29,10 @@ namespace BMapSharpTestbench {
|
|||||||
Console.ReadKey(true);
|
Console.ReadKey(true);
|
||||||
|
|
||||||
// Start testbench
|
// Start testbench
|
||||||
string file_name = "LightCameraTest.nmo";
|
string file_name = resolved_args.mFileName; // "LightCameraTest.nmo";
|
||||||
string temp_folder = "Temp";
|
string temp_folder = resolved_args.mTempFolder; // "Temp";
|
||||||
string texture_folder = "F:\\Ballance\\Ballance\\Textures";
|
string texture_folder = resolved_args.mTextureFolder; // "F:\\Ballance\\Ballance\\Textures";
|
||||||
string[] encodings = ["cp1252", "gb2312"];
|
string[] encodings = resolved_args.mEncodings; // ["cp1252", "gb2312"];
|
||||||
|
|
||||||
using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) {
|
using (var reader = new BMapSharp.BMapWrapper.BMFileReader(file_name, temp_folder, texture_folder, encodings)) {
|
||||||
TestCommon(reader);
|
TestCommon(reader);
|
||||||
@@ -36,6 +44,53 @@ namespace BMapSharpTestbench {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
static void TestCommon(BMapSharp.BMapWrapper.BMFileReader reader) {
|
||||||
// Console.WriteLine("===== Groups =====");
|
// Console.WriteLine("===== Groups =====");
|
||||||
// foreach (var gp in reader.GetGroups()) {
|
// foreach (var gp in reader.GetGroups()) {
|
||||||
|
|||||||
@@ -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 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.
|
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`.
|
||||||
|
|||||||
@@ -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`.
|
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.
|
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`.
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import os
|
import os
|
||||||
|
import argparse
|
||||||
import PyBMap.bmap_wrapper as bmap
|
import PyBMap.bmap_wrapper as bmap
|
||||||
|
|
||||||
def main() -> None:
|
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...')
|
input(f'Python PID is {os.getpid()}. Waiting for debugger, press any key to continue...')
|
||||||
|
|
||||||
file_name: str = 'LightCameraTest.nmo'
|
# file_name: str = 'LightCameraTest.nmo'
|
||||||
temp_folder: str = 'Temp'
|
# temp_folder: str = 'Temp'
|
||||||
texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
|
# texture_folder: str = 'F:\\Ballance\\Ballance\\Textures'
|
||||||
encodings: tuple[str, ...] = ('cp1252', )
|
# encodings: tuple[str, ...] = ('cp1252', )
|
||||||
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
|
with bmap.BMFileReader(file_name, temp_folder, texture_folder, encodings) as reader:
|
||||||
test_common(reader)
|
test_common(reader)
|
||||||
test_equatable(reader)
|
test_equatable(reader)
|
||||||
@@ -146,4 +147,32 @@ def test_equatable(reader: bmap.BMFileReader):
|
|||||||
assert second_3dobj in test_dict
|
assert second_3dobj in test_dict
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
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))
|
||||||
|
|||||||
6
CMake/VTVersion.hpp.in
Normal file
6
CMake/VTVersion.hpp.in
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define LIBCMO_VER_MAJOR @PROJECT_VERSION_MAJOR@
|
||||||
|
#define LIBCMO_VER_MINOR @PROJECT_VERSION_MINOR@
|
||||||
|
#define LIBCMO_VER_PATCH @PROJECT_VERSION_PATCH@
|
||||||
|
#define LIBCMO_VER_STR "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.23)
|
cmake_minimum_required(VERSION 3.23)
|
||||||
project(NeMo
|
project(NeMo
|
||||||
VERSION 0.2.0
|
VERSION 0.3.0
|
||||||
LANGUAGES CXX
|
LANGUAGES CXX
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -102,24 +102,27 @@ namespace LibCmo::CK2 {
|
|||||||
// This is a patch for Dassault stupid programmer.
|
// This is a patch for Dassault stupid programmer.
|
||||||
//
|
//
|
||||||
// After Virtools 4.0, Dassault use a new way to compute the CRC of file.
|
// After Virtools 4.0, Dassault use a new way to compute the CRC of file.
|
||||||
// Dassault introduce a new class called CKMemoryBufferWriter which use file and memory map to handle big file properly.
|
// Dassault introduces a new class called CKMemoryBufferWriter which use file and memory map to handle big file properly.
|
||||||
|
// This algorithm splits the whole data body into 8 MB chunks and calculate them one by one to avoid instantaneous memory occupation.
|
||||||
// However, there is a bug in virtual function CKMemoryBufferWriter::ComputeCRC.
|
// However, there is a bug in virtual function CKMemoryBufferWriter::ComputeCRC.
|
||||||
// It takes `PreviousCRC` as argument but never use it in function. In this function, the start value of CRC compution is hardcoded 0.
|
// It takes `PreviousCRC` as argument but never use it in function.
|
||||||
|
// In this function, the start value of CRC compution is hardcoded 0.
|
||||||
// So, although Dassault programmer try to compute CRC for file header, header part and daat part in code, it actually only compute CRC for data part!
|
// So, although Dassault programmer try to compute CRC for file header, header part and daat part in code, it actually only compute CRC for data part!
|
||||||
// I 100% sure this is the mistake of Dassault stupid programmer and this bug cause horrible result.
|
// I 100% sure this is the mistake of Dassault stupid programmer and this bug cause more horrible result.
|
||||||
//
|
//
|
||||||
// In Virtools 2.1, engine will check CRC of file first. If no matched CRC, engine will reject loading file.
|
// In Virtools 2.1, engine will check CRC of file first. If no matched CRC, engine will reject loading file.
|
||||||
// So the obvious result is that we can not load file saved by Virtools 4.0 in Virtools 2.1.
|
// So the obvious result is that we can not load file saved by Virtools 4.0 in Virtools 2.1.
|
||||||
// But this is not the point which makes me indignant.
|
// But this is not the point which makes me indignant.
|
||||||
// The real weird point is that we can use Virtools 3.5 to open file saved by Virtools 4.0 but why?
|
// The real weird point is that we can use Virtools 3.5 to open file saved by Virtools 4.0, but why?
|
||||||
// After some research, I found that the programmer of Dassault totally removed CRC check when loading file since some version which I don't know!
|
// After some researches, I found that the programmer of Dassault totally removed CRC check when loading file, since some version which I don't know, to suppress this bug!
|
||||||
// This is totally cheat and commercial-oriented behavior!
|
// This is totally cheat and commercial-oriented behavior!
|
||||||
// I guess Dassault programmer also find that they can not load new created file in old Virtools.
|
// I guess Dassault programmer also found that they can not load new created file in old Virtools.
|
||||||
// But they entirely don't know how to resolve it. So they just directly remove the whole of CRC checker!
|
// But they didn't find out what cause this bug, and just directly remove the whole of CRC checker to resolve this bug!
|
||||||
// That's the point which makes me indignant.
|
// I can't believe that this thing happens on such official software.
|
||||||
|
// This is the point which makes me indignant.
|
||||||
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, 0u);
|
gotten_crc = CKComputeDataCRC(parser->GetPtr(), this->m_FileInfo.DataPackSize, 0u);
|
||||||
|
|
||||||
// Both CRC compute methods are failed, this file may be really broken.
|
// Both CRC compute methods are failed. This file may be really broken.
|
||||||
// Report exception directly.
|
// Report exception directly.
|
||||||
if (gotten_crc != this->m_FileInfo.Crc) {
|
if (gotten_crc != this->m_FileInfo.Crc) {
|
||||||
this->m_Ctx->OutputToConsole(u8"Virtools file CRC error.");
|
this->m_Ctx->OutputToConsole(u8"Virtools file CRC error.");
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ SetObjectFlags(obj_flags); \
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CKCamera::ComputeProjectionMatrix(VxMath::VxMatrix& mat) const {
|
void CKCamera::ComputeProjectionMatrix(VxMath::VxMatrix& mat) const {
|
||||||
CKFLOAT aspect = m_Width / m_Height;
|
CKFLOAT aspect = static_cast<CKFLOAT>(m_Width) / m_Height;
|
||||||
if (m_ProjectType == CK_CAMERA_PROJECTION::CK_PERSPECTIVEPROJECTION) {
|
if (m_ProjectType == CK_CAMERA_PROJECTION::CK_PERSPECTIVEPROJECTION) {
|
||||||
mat.Perspective(m_Fov, aspect, m_FrontPlane, m_BackPlane);
|
mat.Perspective(m_Fov, aspect, m_FrontPlane, m_BackPlane);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "CKLight.hpp"
|
#include "CKLight.hpp"
|
||||||
#include "../CKStateChunk.hpp"
|
#include "../CKStateChunk.hpp"
|
||||||
|
#include <numbers>
|
||||||
|
|
||||||
namespace LibCmo::CK2::ObjImpls {
|
namespace LibCmo::CK2::ObjImpls {
|
||||||
|
|
||||||
@@ -16,8 +17,8 @@ namespace LibCmo::CK2::ObjImpls {
|
|||||||
m_LightData.m_Attenuation0 = 1.0f;
|
m_LightData.m_Attenuation0 = 1.0f;
|
||||||
m_LightData.m_Attenuation1 = 0.0f;
|
m_LightData.m_Attenuation1 = 0.0f;
|
||||||
m_LightData.m_Attenuation2 = 0.0f;
|
m_LightData.m_Attenuation2 = 0.0f;
|
||||||
m_LightData.m_InnerSpotCone = 0.69813174f; // MARK: Perhaps 40 deg in rad.
|
m_LightData.m_InnerSpotCone = 40.0f / 180.0f * std::numbers::pi_v<float>; // MARK: Original value is 0.69813174f. Perhaps 40 deg in rad.
|
||||||
m_LightData.m_OuterSpotCone = 0.78539819f; // MARK: Perhaps 45 deg in rad.
|
m_LightData.m_OuterSpotCone = 45.0f / 180.0f * std::numbers::pi_v<float>; // MARK: Original value is 0.78539819f. Perhaps 45 deg in rad.
|
||||||
}
|
}
|
||||||
|
|
||||||
CKLight::~CKLight() {}
|
CKLight::~CKLight() {}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
# Configure version file
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../CMake/VTVersion.hpp.in
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/VTVersion.hpp
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
# Create static library
|
# Create static library
|
||||||
add_library(LibCmo STATIC "")
|
add_library(LibCmo STATIC "")
|
||||||
# Setup static library sources
|
# Setup static library sources
|
||||||
@@ -47,6 +54,7 @@ PUBLIC
|
|||||||
FILE_SET HEADERS
|
FILE_SET HEADERS
|
||||||
FILES
|
FILES
|
||||||
# Asststant header files
|
# Asststant header files
|
||||||
|
VTVersion.hpp
|
||||||
VTInternal.hpp
|
VTInternal.hpp
|
||||||
VTEncoding.hpp
|
VTEncoding.hpp
|
||||||
VTUtils.hpp
|
VTUtils.hpp
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
* They should use Virtools type anywhere, except that Virtools type can not fulfill their requirements.
|
* They should use Virtools type anywhere, except that Virtools type can not fulfill their requirements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// The version info header of LibCmo
|
||||||
|
#include "VTVersion.hpp"
|
||||||
// The base header of LibCmo.
|
// The base header of LibCmo.
|
||||||
// It provides various convenient stuff, for example:
|
// It provides various convenient stuff, for example:
|
||||||
// - General LibCmo specific custom exception.
|
// - General LibCmo specific custom exception.
|
||||||
|
|||||||
@@ -444,7 +444,7 @@ namespace LibCmo::VxMath {
|
|||||||
}
|
}
|
||||||
void VxMatrix::Perspective(CKFLOAT Fov, CKFLOAT Aspect, CKFLOAT Near_plane, CKFLOAT Far_plane) {
|
void VxMatrix::Perspective(CKFLOAT Fov, CKFLOAT Aspect, CKFLOAT Near_plane, CKFLOAT Far_plane) {
|
||||||
Clear();
|
Clear();
|
||||||
m_Data[0][0] = std::cosf(Fov * 0.5f) / std::sinf(Fov * 0.5f);
|
m_Data[0][0] = std::cos(Fov * 0.5f) / std::sin(Fov * 0.5f);
|
||||||
m_Data[1][1] = m_Data[0][0] * Aspect;
|
m_Data[1][1] = m_Data[0][0] * Aspect;
|
||||||
m_Data[2][2] = Far_plane / (Far_plane - Near_plane);
|
m_Data[2][2] = Far_plane / (Far_plane - Near_plane);
|
||||||
m_Data[3][2] = -m_Data[2][2] * Near_plane;
|
m_Data[3][2] = -m_Data[2][2] * Near_plane;
|
||||||
|
|||||||
@@ -362,8 +362,8 @@ namespace Unvirt::CmdHelper {
|
|||||||
throw std::invalid_argument("root node should not be inserted as child node.");
|
throw std::invalid_argument("root node should not be inserted as child node.");
|
||||||
// check conflict
|
// check conflict
|
||||||
const auto& new_node_set = new_node_ptr->GetConflictSet();
|
const auto& new_node_set = new_node_ptr->GetConflictSet();
|
||||||
for (auto& node : m_Nodes) {
|
for (auto& child_node : m_Nodes) {
|
||||||
const auto& node_set = node->GetConflictSet();
|
const auto& node_set = child_node->GetConflictSet();
|
||||||
if (new_node_set.IsConflictWith(node_set))
|
if (new_node_set.IsConflictWith(node_set))
|
||||||
throw std::invalid_argument("try to add a conflict node. please check your code.");
|
throw std::invalid_argument("try to add a conflict node. please check your code.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ namespace Unvirt::Context {
|
|||||||
YYCC::ConsoleHelper::EnableColorfulConsole();
|
YYCC::ConsoleHelper::EnableColorfulConsole();
|
||||||
|
|
||||||
// Show banner
|
// Show banner
|
||||||
YYCC::ConsoleHelper::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"Unvirt 0.2.0") " built at " __DATE__ " " __TIME__);
|
YYCC::ConsoleHelper::WriteLine(YYCC_COLOR_LIGHT_YELLOW(u8"Unvirt") " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__);
|
||||||
YYCC::ConsoleHelper::WriteLine(u8"Type 'help' for more infomation. Type 'exit' to quit.");
|
YYCC::ConsoleHelper::WriteLine(u8"Type 'help' for more infomation. Type 'exit' to quit.");
|
||||||
|
|
||||||
// start process loop
|
// start process loop
|
||||||
|
|||||||
Reference in New Issue
Block a user