Compare commits
10 Commits
78d5e74c6f
...
v2
| Author | SHA1 | Date | |
|---|---|---|---|
| d3fd3c2b0d | |||
| 5c18e2ccbc | |||
| 1dba1e0674 | |||
| 0e08e518c4 | |||
| 7d9b7f14e8 | |||
| 6943088df1 | |||
| 7ffc191f66 | |||
| 46a6222959 | |||
| 7c5bc44724 | |||
| c1abf2cdcd |
@@ -1,15 +1,23 @@
|
|||||||
if (WIN32)
|
if (WIN32)
|
||||||
# In Windows, we use custom way to import SQLite
|
# In Windows, we use custom way to import SQLite.
|
||||||
|
# Before using this CMake file in Windows, you should do following steps first.
|
||||||
|
# 1. Get SQLite SDK (amalgamation) and binaries (sqlite-dll) from http://www.sqlite.org/
|
||||||
|
# 2. Extract SQLite SDK and binaries to your preferred directory.
|
||||||
|
# 3. Open Developer Command Prompt for Visual Studio (embedded with Visual Studio installation)
|
||||||
|
# 4. Use `cd` command to switch work directory to the directory where you extract binaries.
|
||||||
|
# 5. Execute `lib /DEF:sqlite3.def /OUT:sqlite3.lib /MACHINE:x86` (`x86` is the architecture of your SQLite3, you may change it according to your requirement).
|
||||||
|
# 6. Now you have a generated LIB file for MSVC linking.
|
||||||
|
|
||||||
# Check variables# Check YYCC path variable
|
# Check SQLite path variable
|
||||||
if (NOT DEFINED SQLITE_AMALGAMATION_PATH)
|
if (NOT DEFINED SQLITE_AMALGAMATION_PATH)
|
||||||
message(FATAL_ERROR "You must set SQLITE_AMALGAMATION_PATH variable to the header of SQLite library.")
|
message(FATAL_ERROR "You must set SQLITE_AMALGAMATION_PATH to the directory where the SQLite3 header file locate.")
|
||||||
endif()
|
endif()
|
||||||
if (NOT DEFINED SQLITE_DLL_PATH)
|
if (NOT DEFINED SQLITE_DLL_PATH)
|
||||||
message(FATAL_ERROR "You must set SQLITE_DLL_PATH variable the directory containing generated linking LIB file.")
|
message(FATAL_ERROR "You must set SQLITE_DLL_PATH to the directory where the generated SQLite3 LIB file locate for linking.")
|
||||||
endif()
|
endif()
|
||||||
# Add imported library
|
# Add imported library
|
||||||
add_library(SQLite3 INTERFACE IMPORTED)
|
add_library(SQLite3 INTERFACE IMPORTED)
|
||||||
|
# Add alias for it to let it has the same behavior with CMake imported SQLite3.
|
||||||
add_library(SQLite3::SQLite3 ALIAS SQLite3)
|
add_library(SQLite3::SQLite3 ALIAS SQLite3)
|
||||||
# Setup header files
|
# Setup header files
|
||||||
set_target_properties(SQLite3 PROPERTIES
|
set_target_properties(SQLite3 PROPERTIES
|
||||||
@@ -22,6 +30,6 @@ if (WIN32)
|
|||||||
"${SQLITE_DLL_PATH}/sqlite3.lib"
|
"${SQLITE_DLL_PATH}/sqlite3.lib"
|
||||||
)
|
)
|
||||||
else ()
|
else ()
|
||||||
# In non-Windows, we import SQLite from CMake
|
# In non-Windows, we simply import SQLite3 from CMake preset.
|
||||||
find_package(SQLite3 REQUIRED)
|
find_package(SQLite3 REQUIRED)
|
||||||
endif ()
|
endif ()
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
# Check YYCC path variable
|
|
||||||
|
# Check YYCC path environment variable
|
||||||
if (NOT DEFINED YYCC_PATH)
|
if (NOT DEFINED YYCC_PATH)
|
||||||
message(FATAL_ERROR "You must set YYCC_PATH variable to one of CMake distribution of YYCC installation path.")
|
message(FATAL_ERROR "You must set YYCC_PATH variable to one of YYCC CMake distribution installation path.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Find YYCC library
|
# Find YYCC library
|
||||||
find_package(YYCCommonplace REQUIRED
|
# It will produce YYCC::YYCCommonplace target for including and linking.
|
||||||
HINTS ${YYCC_PATH} NO_DEFAULT_PATH
|
#
|
||||||
)
|
# Please note we MUST set CMake variable YYCCommonplace_ROOT to make sure CMake can found YYCC in out given path.
|
||||||
|
# The cache status of YYCCommonplace_ROOT is doesn't matter.
|
||||||
|
# CMake will throw error if we use HINTS feature in find_package to find YYCC.
|
||||||
|
set(YYCCommonplace_ROOT ${YYCC_PATH} CACHE PATH
|
||||||
|
"The path to YYCC CMake distribution installation path.")
|
||||||
|
find_package(YYCCommonplace REQUIRED)
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ FILES
|
|||||||
target_include_directories(VSWDecorator
|
target_include_directories(VSWDecorator
|
||||||
PUBLIC
|
PUBLIC
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
YYCC::YYCCommonplace
|
|
||||||
SQLite3::SQLite3
|
|
||||||
VSWShared
|
|
||||||
)
|
)
|
||||||
# Setup linked library
|
# Setup linked library
|
||||||
target_link_libraries(VSWDecorator
|
target_link_libraries(VSWDecorator
|
||||||
|
|||||||
@@ -54,10 +54,6 @@ FILES
|
|||||||
target_include_directories(VSWMaterializer
|
target_include_directories(VSWMaterializer
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
YYCC::YYCCommonplace
|
|
||||||
SQLite3::SQLite3
|
|
||||||
VirtoolsSDK
|
|
||||||
VSWShared
|
|
||||||
)
|
)
|
||||||
# Setup linked library
|
# Setup linked library
|
||||||
target_link_libraries(VSWMaterializer
|
target_link_libraries(VSWMaterializer
|
||||||
|
|||||||
@@ -4,33 +4,41 @@
|
|||||||
|
|
||||||
namespace VSW::Materializer::DataTypes {
|
namespace VSW::Materializer::DataTypes {
|
||||||
|
|
||||||
|
struct BlobDescriptor {
|
||||||
|
const void* ptr;
|
||||||
|
int length;
|
||||||
|
};
|
||||||
|
|
||||||
namespace Script {
|
namespace Script {
|
||||||
|
|
||||||
struct Table_script {
|
struct Table_script {
|
||||||
CK_ID thisobj;
|
CK_ID beobj;
|
||||||
std::string host_name;
|
YYCC::yycc_u8string beobj_name;
|
||||||
int index;
|
int behavior_index;
|
||||||
CK_ID behavior;
|
CK_ID behavior;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_behavior {
|
struct Table_behavior {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
CK_BEHAVIOR_TYPE type;
|
CK_BEHAVIOR_TYPE type;
|
||||||
std::string proto_name;
|
YYCC::yycc_u8string proto_name;
|
||||||
std::string proto_guid;
|
int64_t proto_guid;
|
||||||
CK_BEHAVIOR_FLAGS flags;
|
CK_BEHAVIOR_FLAGS flags;
|
||||||
int priority;
|
int priority;
|
||||||
CKDWORD version;
|
CKDWORD version;
|
||||||
//pTarget, pIn, pOut, bIn, bOut
|
int pin_count_ptarget;
|
||||||
std::string pin_count;
|
int pin_count_pin;
|
||||||
|
int pin_count_pout;
|
||||||
|
int pin_count_bin;
|
||||||
|
int pin_count_bout;
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_bIO {
|
struct Table_bIO {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
int index;
|
int index;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
};
|
};
|
||||||
struct Table_bIn : public Table_bIO {};
|
struct Table_bIn : public Table_bIO {};
|
||||||
@@ -38,9 +46,8 @@ namespace VSW::Materializer::DataTypes {
|
|||||||
|
|
||||||
struct Table_pTarget {
|
struct Table_pTarget {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
std::string type;
|
int64_t type;
|
||||||
std::string type_guid;
|
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
CK_ID direct_source;
|
CK_ID direct_source;
|
||||||
CK_ID shared_source;
|
CK_ID shared_source;
|
||||||
@@ -49,9 +56,8 @@ namespace VSW::Materializer::DataTypes {
|
|||||||
struct Table_pIn {
|
struct Table_pIn {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
int index;
|
int index;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
std::string type;
|
int64_t type;
|
||||||
std::string type_guid;
|
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
CK_ID direct_source;
|
CK_ID direct_source;
|
||||||
CK_ID shared_source;
|
CK_ID shared_source;
|
||||||
@@ -60,9 +66,8 @@ namespace VSW::Materializer::DataTypes {
|
|||||||
struct Table_pOut {
|
struct Table_pOut {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
int index;
|
int index;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
std::string type;
|
int64_t type;
|
||||||
std::string type_guid;
|
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,54 +88,53 @@ namespace VSW::Materializer::DataTypes {
|
|||||||
|
|
||||||
struct Table_pLocal {
|
struct Table_pLocal {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
std::string type;
|
int64_t type;
|
||||||
std::string type_guid;
|
bool is_setting;
|
||||||
BOOL is_setting;
|
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_pAttr {
|
struct Table_pAttr {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
std::string type;
|
int64_t type;
|
||||||
std::string type_guid;
|
CK_ID owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_pLink {
|
struct Table_pLink {
|
||||||
CK_ID input;
|
// Basic infos
|
||||||
CK_ID output;
|
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
|
// Input infos
|
||||||
//additional field
|
CK_ID input;
|
||||||
CK_ID input_obj;
|
CK_ID input_obj;
|
||||||
VSW::DataTypes::ParameterLinkIOType input_type;
|
VSW::DataTypes::ParameterLinkIOType input_type;
|
||||||
BOOL input_is_bb;
|
bool input_is_bb;
|
||||||
int input_index;
|
int input_index;
|
||||||
|
// Output infos
|
||||||
|
CK_ID output;
|
||||||
CK_ID output_obj;
|
CK_ID output_obj;
|
||||||
VSW::DataTypes::ParameterLinkIOType output_type;
|
VSW::DataTypes::ParameterLinkIOType output_type;
|
||||||
BOOL output_is_bb;
|
bool output_is_bb;
|
||||||
int output_index;
|
int output_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_pOper {
|
struct Table_pOper {
|
||||||
CK_ID thisobj;
|
CK_ID thisobj;
|
||||||
std::string op;
|
int64_t op;
|
||||||
std::string op_guid;
|
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_eLink {
|
struct Table_eLink {
|
||||||
CK_ID export_obj;
|
CK_ID export_obj;
|
||||||
CK_ID internal_obj;
|
CK_ID internal_obj;
|
||||||
BOOL is_in;
|
bool is_in;
|
||||||
int index;
|
int index;
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_data {
|
struct Table_data {
|
||||||
std::string field;
|
YYCC::yycc_u8string field;
|
||||||
std::string data;
|
BlobDescriptor data;
|
||||||
CK_ID parent;
|
CK_ID parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -168,14 +172,14 @@ namespace VSW::Materializer::DataTypes {
|
|||||||
|
|
||||||
struct Table_msg {
|
struct Table_msg {
|
||||||
CKMessageType index;
|
CKMessageType index;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_obj {
|
struct Table_obj {
|
||||||
CK_ID id;
|
CK_ID id;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
CK_CLASSID classid;
|
CK_CLASSID classid;
|
||||||
std::string classtype;
|
YYCC::yycc_u8string classid_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DataCache {
|
class DataCache {
|
||||||
@@ -193,72 +197,80 @@ namespace VSW::Materializer::DataTypes {
|
|||||||
namespace Environment {
|
namespace Environment {
|
||||||
|
|
||||||
struct Table_op {
|
struct Table_op {
|
||||||
std::string func_ptr;
|
YYCC::yycc_u8string func_ptr;
|
||||||
int64_t in1_guid;
|
int64_t in1_guid;
|
||||||
int64_t in2_guid;
|
int64_t in2_guid;
|
||||||
int64_t out_guid;
|
int64_t out_guid;
|
||||||
int64_t op_guid;
|
int64_t op_guid;
|
||||||
std::string op_name;
|
YYCC::yycc_u8string op_name;
|
||||||
CKOperationType op_code;
|
CKOperationType op_code;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_param {
|
struct Table_param {
|
||||||
|
// Parameter infos
|
||||||
CKParameterType index;
|
CKParameterType index;
|
||||||
int64_t guid;
|
int64_t guid;
|
||||||
int64_t derived_from;
|
int64_t derived_from;
|
||||||
std::string type_name;
|
YYCC::yycc_u8string name;
|
||||||
int default_size;
|
int default_size;
|
||||||
std::string func_CreateDefault;
|
YYCC::yycc_u8string func_CreateDefault;
|
||||||
std::string func_Delete;
|
YYCC::yycc_u8string func_Delete;
|
||||||
std::string func_SaveLoad;
|
YYCC::yycc_u8string func_SaveLoad;
|
||||||
std::string func_Check;
|
YYCC::yycc_u8string func_Check;
|
||||||
std::string func_Copy;
|
YYCC::yycc_u8string func_Copy;
|
||||||
std::string func_String;
|
YYCC::yycc_u8string func_String;
|
||||||
std::string func_UICreator;
|
YYCC::yycc_u8string func_UICreator;
|
||||||
int creator_dll_index;
|
// Dll infos
|
||||||
int creator_plugin_index;
|
YYCC::yycc_u8string dll_name;
|
||||||
|
int dll_index;
|
||||||
|
int position_in_dll;
|
||||||
|
// Misc
|
||||||
|
CKDWORD flags;
|
||||||
CKDWORD dw_param;
|
CKDWORD dw_param;
|
||||||
CKDWORD dw_flags;
|
|
||||||
CKDWORD cid;
|
CKDWORD cid;
|
||||||
int64_t saver_manager;
|
int64_t saver_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_attr {
|
struct Table_attr {
|
||||||
CKAttributeType index;
|
CKAttributeType index;
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
CKAttributeCategory category_index;
|
CKAttributeCategory category_index;
|
||||||
std::string category_name;
|
YYCC::yycc_u8string category_name;
|
||||||
CK_ATTRIBUT_FLAGS flags;
|
CK_ATTRIBUT_FLAGS flags;
|
||||||
CKParameterType param_index;
|
CKParameterType param_index;
|
||||||
|
int64_t param_guid;
|
||||||
CK_CLASSID compatible_classid;
|
CK_CLASSID compatible_classid;
|
||||||
std::string default_value;
|
YYCC::yycc_u8string default_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Table_plugin {
|
struct Table_plugin {
|
||||||
// Category
|
// Category
|
||||||
std::string category;
|
YYCC::yycc_u8string category_name;
|
||||||
|
int category_index;
|
||||||
// Dll infos
|
// Dll infos
|
||||||
std::string dll_name;
|
YYCC::yycc_u8string dll_name;
|
||||||
|
int dll_index;
|
||||||
int position_in_dll;
|
int position_in_dll;
|
||||||
// Plugin infos
|
// Plugin infos
|
||||||
|
int index;
|
||||||
int64_t guid;
|
int64_t guid;
|
||||||
std::string desc;
|
YYCC::yycc_u8string desc;
|
||||||
std::string author;
|
YYCC::yycc_u8string author;
|
||||||
std::string summary;
|
YYCC::yycc_u8string summary;
|
||||||
DWORD version;
|
DWORD version;
|
||||||
CK_PLUGIN_TYPE type;
|
CK_PLUGIN_TYPE type;
|
||||||
std::string func_init;
|
YYCC::yycc_u8string func_init;
|
||||||
std::string func_exit;
|
YYCC::yycc_u8string func_exit;
|
||||||
// Reader specific
|
// Reader specific
|
||||||
std::string reader_fct;
|
YYCC::yycc_u8string reader_fct;
|
||||||
int reader_opt_count;
|
int reader_opt_count;
|
||||||
CK_DATAREADER_FLAGS reader_flags;
|
CK_DATAREADER_FLAGS reader_flags;
|
||||||
int64_t reader_setting_param_guid;
|
int64_t reader_setting_param_guid;
|
||||||
std::string reader_file_ext;
|
YYCC::yycc_u8string reader_file_ext;
|
||||||
// Manager and Render Engine specific
|
// Manager and Render Engine specific
|
||||||
CKBOOL manager_active;
|
bool manager_active;
|
||||||
// Behavior specific
|
// Behavior specific
|
||||||
std::string behavior_guids;
|
YYCC::yycc_u8string behavior_guids;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(VIRTOOLS_21)
|
#if defined(VIRTOOLS_21)
|
||||||
@@ -269,12 +281,12 @@ namespace VSW::Materializer::DataTypes {
|
|||||||
using GenericVarType_t = CKVariableManager::Variable::Type;
|
using GenericVarType_t = CKVariableManager::Variable::Type;
|
||||||
#endif
|
#endif
|
||||||
struct Table_variable {
|
struct Table_variable {
|
||||||
std::string name;
|
YYCC::yycc_u8string name;
|
||||||
std::string desciption;
|
YYCC::yycc_u8string desciption;
|
||||||
XWORD flags;
|
XWORD flags;
|
||||||
GenericVarType_t type;
|
GenericVarType_t type;
|
||||||
std::string representation;
|
YYCC::yycc_u8string representation;
|
||||||
std::string data;
|
YYCC::yycc_u8string data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DataCache {
|
class DataCache {
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ sqlite3_reset(stmt);
|
|||||||
failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
||||||
|
|
||||||
#define REVEAL_ENUM(enum_val) static_cast<std::underlying_type_t<decltype(enum_val)>>(enum_val)
|
#define REVEAL_ENUM(enum_val) static_cast<std::underlying_type_t<decltype(enum_val)>>(enum_val)
|
||||||
|
#define REVEAL_U8STR(u8_str) YYCC::EncodingHelper::ToOrdinary((u8_str).c_str()), -1, SQLITE_TRANSIENT
|
||||||
|
#define REVEAL_BLOB(blob_val) (blob_val).ptr, (blob_val).length, SQLITE_TRANSIENT
|
||||||
|
#define REVEAL_BOOL(bool_val) ((bool_val) ? 1 : 0)
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
@@ -47,7 +50,7 @@ failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
|||||||
// connect to database (the argument of sqlite3 open function is UTF8)
|
// connect to database (the argument of sqlite3 open function is UTF8)
|
||||||
int errcode;
|
int errcode;
|
||||||
if (file.empty()) goto failed;
|
if (file.empty()) goto failed;
|
||||||
errcode = sqlite3_open(YYCC::EncodingHelper::ToOrdinary(file.data()), &m_Db);
|
errcode = sqlite3_open_v2(YYCC::EncodingHelper::ToOrdinary(file.data()), &m_Db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
|
||||||
if (errcode != SQLITE_OK) goto failed;
|
if (errcode != SQLITE_OK) goto failed;
|
||||||
|
|
||||||
// disable synchronous to accelerate speed.
|
// disable synchronous to accelerate speed.
|
||||||
@@ -121,27 +124,40 @@ failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
|||||||
AbstractDatabase(file) {
|
AbstractDatabase(file) {
|
||||||
// initialize table
|
// initialize table
|
||||||
BEGIN_CTOR;
|
BEGIN_CTOR;
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [script] ([thisobj] INTEGER, [name] TEXT, [index] INTEGER, [behavior] INTEGER);");
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [script];");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [behavior] ([thisobj] INTEGER, [name] TEXT, [type] INTEGER, [proto_name] TEXT, [proto_guid] TEXT, [flags] INTEGER, [priority] INTEGER, [version] INTEGER, [pin_count] TEXT, [parent] INTEGER);");
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [behavior];");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [pTarget] ([thisobj] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [parent] INTEGER, [direct_source] INTEGER, [shard_source] INTEGER);");
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [bIO];");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [pIn] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [parent] INTEGER, [direct_source] INTEGER, [shared_source] INTEGER);");
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [pTarget];");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [pOut] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [parent] INTEGER);");
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [pIn];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [pOut];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [bLink];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [pLocal];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [pAttr];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [pLink];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [pOper];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [eLink];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [data];");
|
||||||
|
|
||||||
|
CTOR_SQL_EXEC("CREATE TABLE [script] ([beobj] INTEGER, [beobj_name] TEXT, [behavior_index] INTEGER, [behavior] INTEGER);");
|
||||||
|
CTOR_SQL_EXEC("CREATE TABLE [behavior] ([thisobj] INTEGER, [name] TEXT, [type] INTEGER, [proto_name] TEXT, [proto_guid] INTEGER, [flags] INTEGER, [priority] INTEGER, [version] INTEGER, [pin_count_ptarget] INTEGER, [pin_count_pin] INTEGER, [pin_count_pout] INTEGER, [pin_count_bin] INTEGER, [pin_count_bout] INTEGER, [parent] INTEGER);");
|
||||||
|
CTOR_SQL_EXEC("CREATE TABLE [pTarget] ([thisobj] INTEGER, [name] TEXT, [type] INTEGER, [parent] INTEGER, [direct_source] INTEGER, [shared_source] INTEGER);");
|
||||||
|
CTOR_SQL_EXEC("CREATE TABLE [pIn] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [type] INTEGER, [parent] INTEGER, [direct_source] INTEGER, [shared_source] INTEGER);");
|
||||||
|
CTOR_SQL_EXEC("CREATE TABLE [pOut] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [type] INTEGER, [parent] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [bIn] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [bIn] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [parent] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [bOut] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [bOut] ([thisobj] INTEGER, [index] INTEGER, [name] TEXT, [parent] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [bLink] ([input] INTEGER, [output] INTEGER, [delay] INTEGER, [input_obj] INTEGER, [input_type] INTEGER, [input_index] INETEGR, [output_obj] INTEGER, [output_type] INTEGER, [output_index] INETEGR, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [bLink] ([input] INTEGER, [output] INTEGER, [delay] INTEGER, [parent] INTEGER, [input_obj] INTEGER, [input_type] INTEGER, [input_index] INTEGER, [output_obj] INTEGER, [output_type] INTEGER, [output_index] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [pLocal] ([thisobj] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT, [is_setting] INTEGER, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [pLocal] ([thisobj] INTEGER, [name] TEXT, [type] INTEGER, [is_setting] INTEGER, [parent] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [pLink] ([input] INTEGER, [output] INTEGER, [input_obj] INTEGER, [input_type] INTEGER, [input_is_bb] INTEGER, [input_index] INETEGR, [output_obj] INTEGER, [output_type] INTEGER, [output_is_bb] INTEGER, [output_index] INETEGR, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [pLink] ([parent] INTEGER, [input] INTEGER, [input_obj] INTEGER, [input_type] INTEGER, [input_is_bb] INTEGER, [input_index] INTEGER, [output] INTEGER, [output_obj] INTEGER, [output_type] INTEGER, [output_is_bb] INTEGER, [output_index] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [pOper] ([thisobj] INTEGER, [op] TEXT, [op_guid] TEXT, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [pOper] ([thisobj] INTEGER, [op] INTEGER, [parent] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [eLink] ([export_obj] INTEGER, [internal_obj] INTEGER, [is_in] INTEGER, [index] INTEGER, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [eLink] ([export_obj] INTEGER, [internal_obj] INTEGER, [is_in] INTEGER, [index] INTEGER, [parent] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [pAttr] ([thisobj] INTEGER, [name] TEXT, [type] TEXT, [type_guid] TEXT);");
|
CTOR_SQL_EXEC("CREATE TABLE [pAttr] ([thisobj] INTEGER, [name] TEXT, [type] INTEGER, [owner] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [data] ([field] TEXT, [data] TEXT, [parent] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [data] ([field] TEXT, [data] BLOB, [parent] INTEGER);");
|
||||||
END_CTOR;
|
END_CTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptDatabase::~ScriptDatabase() {
|
ScriptDatabase::~ScriptDatabase() {
|
||||||
// create index for quick select in following process
|
// create index for quick select in following process
|
||||||
BEGIN_DTOR;
|
BEGIN_DTOR;
|
||||||
DTOR_SQL_EXEC("begin;");
|
|
||||||
DTOR_SQL_EXEC("CREATE INDEX [quick_where1] ON [behavior] ([parent])");
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where1] ON [behavior] ([parent])");
|
||||||
DTOR_SQL_EXEC("CREATE INDEX [quick_where2] ON [pOper] ([parent], [thisobj])");
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where2] ON [pOper] ([parent], [thisobj])");
|
||||||
DTOR_SQL_EXEC("CREATE INDEX [quick_where3] ON [pTarget] ([parent])");
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where3] ON [pTarget] ([parent])");
|
||||||
@@ -155,140 +171,138 @@ failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
|||||||
DTOR_SQL_EXEC("CREATE INDEX [quick_where11] ON [elink] ([parent])");
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where11] ON [elink] ([parent])");
|
||||||
DTOR_SQL_EXEC("CREATE INDEX [quick_where12] ON [pAttr] ([thisobj])");
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where12] ON [pAttr] ([thisobj])");
|
||||||
DTOR_SQL_EXEC("CREATE INDEX [quick_where13] ON [data] ([parent])");
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where13] ON [data] ([parent])");
|
||||||
DTOR_SQL_EXEC("commit;");
|
|
||||||
END_DTOR;
|
END_DTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_script& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_script& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script] VALUES (?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [script] VALUES (?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.beobj));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.host_name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.beobj_name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.behavior_index));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.behavior));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.behavior));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_behavior& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_behavior& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_behavior] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [behavior] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.type));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.proto_name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.proto_name)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.proto_guid.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.proto_guid));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.flags));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.flags));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.priority));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.priority));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.version));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.version));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.pin_count.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.pin_count_ptarget));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.pin_count_pin));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.pin_count_pout));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.pin_count_bin));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.pin_count_bout));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_bIn& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_bIn& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_bIn] VALUES (?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [bIn] VALUES (?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_bOut& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_bOut& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_bOut] VALUES (?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [bOut] VALUES (?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_pIn& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_pIn& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_pIn] VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [pIn] VALUES (?, ?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type_guid.c_str(), -1, SQLITE_TRANSIENT));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.direct_source));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.direct_source));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.shared_source));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.shared_source));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_pOut& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_pOut& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_pOut] VALUES (?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [pOut] VALUES (?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type_guid.c_str(), -1, SQLITE_TRANSIENT));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_bLink& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_bLink& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_bLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [bLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.delay));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.delay));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_obj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_obj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.input_type)));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.input_type)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_index));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_obj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_obj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.output_type)));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.output_type)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_index));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_pLocal& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_pLocal& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_pLocal] VALUES (?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [pLocal] VALUES (?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type_guid.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_BOOL(data.is_setting)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.is_setting));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_pAttr& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_pAttr& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_pAttr] VALUES (?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [pAttr] VALUES (?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type_guid.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.owner));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_pLink& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_pLink& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_pLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [pLink] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_obj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_obj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.input_type)));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.input_type)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_is_bb));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_BOOL(data.input_is_bb)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.input_index));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_obj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_obj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.output_type)));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.output_type)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_is_bb));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_BOOL(data.output_is_bb)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.output_index));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_pOper& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_pOper& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_pOper] VALUES (?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [pOper] VALUES (?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.op.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.op));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.op_guid.c_str(), -1, SQLITE_TRANSIENT));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_eLink& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_eLink& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_eLink] VALUES (?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [eLink] VALUES (?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.export_obj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.export_obj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.internal_obj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.internal_obj));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.is_in));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_BOOL(data.is_in)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_pTarget& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_pTarget& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [script_pTarget] VALUES (?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [pTarget] VALUES (?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.thisobj));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type_guid.c_str(), -1, SQLITE_TRANSIENT));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.direct_source));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.direct_source));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.shared_source));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.shared_source));
|
||||||
@@ -296,8 +310,8 @@ failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
|||||||
}
|
}
|
||||||
void ScriptDatabase::Write(const DataTypes::Script::Table_data& data) {
|
void ScriptDatabase::Write(const DataTypes::Script::Table_data& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [data] VALUES (?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [data] VALUES (?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.field.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.field)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.data.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_blob(WRITER_STMT, WRITER_INDEX, REVEAL_BLOB(data.data)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.parent));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
@@ -310,27 +324,34 @@ failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
|||||||
AbstractDatabase(file) {
|
AbstractDatabase(file) {
|
||||||
// initialize table
|
// initialize table
|
||||||
BEGIN_CTOR;
|
BEGIN_CTOR;
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [msg];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [obj];");
|
||||||
|
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [msg] ([index] INTEGER, [name] TEXT);");
|
CTOR_SQL_EXEC("CREATE TABLE [msg] ([index] INTEGER, [name] TEXT);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [obj] ([id] INTEGER, [name] TEXT, [classid] INTEGER, [classtype] TEXT);");
|
CTOR_SQL_EXEC("CREATE TABLE [obj] ([id] INTEGER, [name] TEXT, [classid] INTEGER, [classid_name] TEXT);");
|
||||||
END_CTOR;
|
END_CTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentDatabase::~DocumentDatabase() {
|
DocumentDatabase::~DocumentDatabase() {
|
||||||
// do nothing
|
// create index for quick select in following process
|
||||||
|
BEGIN_DTOR;
|
||||||
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where1] ON [msg] ([index])");
|
||||||
|
DTOR_SQL_EXEC("CREATE INDEX [quick_where2] ON [obj] ([id])");
|
||||||
|
END_DTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentDatabase::Write(const DataTypes::Document::Table_msg& data) {
|
void DocumentDatabase::Write(const DataTypes::Document::Table_msg& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [msg] VALUES (?, ?);");
|
BEGIN_WRITER("INSERT INTO [msg] VALUES (?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void DocumentDatabase::Write(const DataTypes::Document::Table_obj& data) {
|
void DocumentDatabase::Write(const DataTypes::Document::Table_obj& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [obj] VALUES (?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [obj] VALUES (?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.id));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.id));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.classid));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.classid));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.classtype.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.classid_name)));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,87 +363,106 @@ failed: throw std::runtime_error("fail to bind value for prepared statement.");
|
|||||||
AbstractDatabase(file) {
|
AbstractDatabase(file) {
|
||||||
// initialize table
|
// initialize table
|
||||||
BEGIN_CTOR;
|
BEGIN_CTOR;
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [op];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [param];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [attr];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [plugin];");
|
||||||
|
CTOR_SQL_EXEC("DROP TABLE IF EXISTS [variable];");
|
||||||
|
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [op] ([func_ptr] TEXT, [in1_guid] INTEGER, [in2_guid] INTEGER, [out_guid] INTEGER, [op_guid] INTEGER, [op_name] TEXT, [op_code] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [op] ([func_ptr] TEXT, [in1_guid] INTEGER, [in2_guid] INTEGER, [out_guid] INTEGER, [op_guid] INTEGER, [op_name] TEXT, [op_code] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [param] ([index] INTEGER, [guid] INTEGER, [derived_from] INTEGER, [type_name] TEXT, [default_size] INTEGER, [func_CreateDefault] TEXT, [func_Delete] TEXT, [func_SaveLoad] TEXT, [func_Check] TEXT, [func_Copy] TEXT, [func_String] TEXT, [func_UICreator] TEXT, [creator_dll_index] INTEGER, [creator_plugin_index] INTEGER, [dw_param] INTEGER, [dw_flags] INTEGER, [cid] INTEGER, [saver_manager] INTEGER);");
|
CTOR_SQL_EXEC("CREATE TABLE [param] ([index] INTEGER, [guid] INTEGER, [derived_from] INTEGER, [name] TEXT, [default_size] INTEGER, [func_CreateDefault] TEXT, [func_Delete] TEXT, [func_SaveLoad] TEXT, [func_Check] TEXT, [func_Copy] TEXT, [func_String] TEXT, [func_UICreator] TEXT, [dll_name] TEXT, [dll_index] INTEGER, [position_in_dll] INTEGER, [flags] INTEGER, [dw_param] INTEGER, [cid] INTEGER, [saver_manager] INTEGER);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [attr] ([index] INTEGER, [name] TEXT, [category_index] INTEGER, [category_name] TEXT, [flags] INTEGER, [param_index] INTEGER, [compatible_classid] INTEGER, [default_value] TEXT);");
|
CTOR_SQL_EXEC("CREATE TABLE [attr] ([index] INTEGER, [name] TEXT, [category_index] INTEGER, [category_name] TEXT, [flags] INTEGER, [param_index] INTEGER, [param_guid] INTEGER, [compatible_classid] INTEGER, [default_value] TEXT);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [plugin] ([dll_index] INTEGER, [dll_name] TEXT, [plugin_index] INTEGER, [category] TEXT, [active] INTEGER, [guid] INTEGER, [desc] TEXT, [author] TEXT, [summary] TEXT, [version] INTEGER, [func_init] TEXT, [func_exit] TEXT);");
|
CTOR_SQL_EXEC("CREATE TABLE [plugin] ([category_name] TEXT, [category_index] INTEGER, [dll_name] TEXT, [dll_index] INTEGER, [position_in_dll] INTEGER, [index] INTEGER, [guid] INTEGER, [desc] TEXT, [author] TEXT, [summary] TEXT, [version] INTEGER, [type] INTEGER, [func_init] TEXT, [func_exit] TEXT, [reader_fct] TEXT, [reader_opt_count] INTEGER, [reader_flags] INTEGER, [reader_setting_param_guid] INTEGER, [reader_file_ext] TEXT, [manager_active] INTEGER, [behavior_guids] TEXT);");
|
||||||
CTOR_SQL_EXEC("CREATE TABLE [variable] ([name] TEXT, [description] TEXT, [flags] INTEGER, [type] INTEGER, [representation] TEXT, [data] TEXT);");
|
CTOR_SQL_EXEC("CREATE TABLE [variable] ([name] TEXT, [desciption] TEXT, [flags] INTEGER, [type] INTEGER, [representation] TEXT, [data] TEXT);");
|
||||||
END_CTOR;
|
END_CTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
EnvironmentDatabase::~EnvironmentDatabase() {
|
EnvironmentDatabase::~EnvironmentDatabase() {
|
||||||
// do nothing
|
// create index for quick select in following process
|
||||||
|
BEGIN_DTOR;
|
||||||
|
END_DTOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_op& data) {
|
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_op& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [op] VALUES (?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [op] VALUES (?, ?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_ptr.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_ptr)));
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.in1_guid));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.in1_guid));
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.in2_guid));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.in2_guid));
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.out_guid));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.out_guid));
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.op_guid));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.op_guid));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.op_name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.op_name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.op_code));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.op_code));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_param& data) {
|
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_param& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [param] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [param] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.guid));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.guid));
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.derived_from));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.derived_from));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.type_name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.default_size));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.default_size));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_CreateDefault.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_CreateDefault)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_Delete.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_Delete)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_SaveLoad.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_SaveLoad)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_Check.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_Check)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_Copy.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_Copy)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_String.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_String)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_UICreator.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_UICreator)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.creator_dll_index));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.dll_name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.creator_plugin_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.dll_index));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.position_in_dll));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.flags));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.dw_param));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.dw_param));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.dw_flags));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.cid));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.cid));
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.saver_manager));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.saver_manager));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_attr& data) {
|
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_attr& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [attr] VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [attr] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.category_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.category_index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.category_name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.category_name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.flags));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.flags));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.param_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.param_index));
|
||||||
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.param_guid));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.compatible_classid));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.compatible_classid));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.default_value.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.default_value)));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_plugin& data) {
|
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_plugin& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [plugin] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [plugin] VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
|
||||||
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.category_name)));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.category_index));
|
||||||
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.dll_name)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.dll_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.dll_index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.dll_name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.position_in_dll));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.plugin_index));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.category.c_str(), -1, SQLITE_TRANSIENT));
|
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.active));
|
|
||||||
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.guid));
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.guid));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.desc.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.desc)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.author.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.author)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.summary.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.summary)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.version));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.version));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_init.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.func_exit.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_init)));
|
||||||
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.func_exit)));
|
||||||
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.reader_fct)));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.reader_opt_count));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.reader_flags));
|
||||||
|
WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.reader_setting_param_guid));
|
||||||
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.reader_file_ext)));
|
||||||
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_BOOL(data.manager_active)));
|
||||||
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.behavior_guids)));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_variable& data) {
|
void EnvironmentDatabase::Write(const DataTypes::Environment::Table_variable& data) {
|
||||||
BEGIN_WRITER("INSERT INTO [variable] VALUES (?, ?, ?, ?, ?, ?);");
|
BEGIN_WRITER("INSERT INTO [variable] VALUES (?, ?, ?, ?, ?, ?);");
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.desciption.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.desciption)));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.flags));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.flags));
|
||||||
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.type));
|
WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.type));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.representation.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.representation)));
|
||||||
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.data.c_str(), -1, SQLITE_TRANSIENT));
|
WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.data)));
|
||||||
END_WRITER;
|
END_WRITER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +1,16 @@
|
|||||||
#if defined(MATERIALIZER_PLUGIN)
|
#if defined(MATERIALIZER_PLUGIN)
|
||||||
|
|
||||||
#include "ExportDialog.hpp"
|
#include "ExportDialog.hpp"
|
||||||
|
#include "PluginMain.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace VSW::Materializer {
|
namespace VSW::Materializer {
|
||||||
|
|
||||||
class ExportDialogSetting {
|
|
||||||
public:
|
|
||||||
static ExportDialogSetting& GetSingleton();
|
|
||||||
private:
|
|
||||||
static YYCC::yycc_u8string GetConfigFilePath();
|
|
||||||
ExportDialogSetting() :
|
|
||||||
m_LastFilePath(YYCC_U8("last-file-path"), YYCC_U8("")),
|
|
||||||
m_Encoding(YYCC_U8("encoding"), CP_ACP),
|
|
||||||
m_Mgr(ExportDialogSetting::GetConfigFilePath(), UINT64_C(0), {
|
|
||||||
&m_LastFilePath, &m_Encoding
|
|
||||||
}) {
|
|
||||||
m_Mgr.Load();
|
|
||||||
}
|
|
||||||
~ExportDialogSetting() {
|
|
||||||
m_Mgr.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
YYCC::ConfigManager::StringSetting m_LastFilePath;
|
|
||||||
YYCC::ConfigManager::NumberSetting<UINT> m_Encoding;
|
|
||||||
YYCC::ConfigManager::CoreManager m_Mgr;
|
|
||||||
};
|
|
||||||
ExportDialogSetting& ExportDialogSetting::GetSingleton() {
|
|
||||||
static ExportDialogSetting g_Singleton;
|
|
||||||
return g_Singleton;
|
|
||||||
}
|
|
||||||
YYCC::yycc_u8string ExportDialogSetting::GetConfigFilePath() {
|
|
||||||
// get path to executable virtools
|
|
||||||
YYCC::yycc_u8string u8_virtools_path;
|
|
||||||
if (!YYCC::WinFctHelper::GetModuleFileName(NULL, u8_virtools_path))
|
|
||||||
u8_virtools_path.clear();
|
|
||||||
// get its parent folder and append with cfg file name
|
|
||||||
std::filesystem::path virtools_path(YYCC::FsPathPatch::FromUTF8Path(u8_virtools_path.c_str()));
|
|
||||||
return YYCC::FsPathPatch::ToUTF8Path(virtools_path.parent_path() / YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("vsw_materializer.cfg")));
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ExportDialogHelper {
|
namespace ExportDialogHelper {
|
||||||
|
|
||||||
#define RADIOBTN_GETCHECK(instance) (instance.GetCheck() == BST_CHECKED)
|
#define RADIOBTN_GETCHECK(instance) (instance.GetCheck() == BST_CHECKED)
|
||||||
#define RADIOBTN_SETCHECK(instance, stmt) (instance.SetCheck((stmt) ? BST_CHECKED : BST_UNCHECKED))
|
#define RADIOBTN_SETCHECK(instance, stmt) (instance.SetCheck((stmt) ? BST_CHECKED : BST_UNCHECKED))
|
||||||
|
|
||||||
static bool ValidateCodePage(UINT code_page) {
|
|
||||||
CPINFOEXW cpinfo;
|
|
||||||
return GetCPInfoExW(code_page, 0, &cpinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetCWndText(CWnd* ctl, const YYCC::yycc_u8string_view& val) {
|
static void SetCWndText(CWnd* ctl, const YYCC::yycc_u8string_view& val) {
|
||||||
ctl->SetWindowTextA(YYCC::EncodingHelper::UTF8ToChar(val, CP_ACP).c_str());
|
ctl->SetWindowTextA(YYCC::EncodingHelper::UTF8ToChar(val, CP_ACP).c_str());
|
||||||
}
|
}
|
||||||
@@ -123,24 +83,24 @@ namespace VSW::Materializer {
|
|||||||
CDialogEx::OnInitDialog();
|
CDialogEx::OnInitDialog();
|
||||||
|
|
||||||
// Read settings from config manager
|
// Read settings from config manager
|
||||||
auto& config_manager = ExportDialogSetting::GetSingleton();
|
auto& config_manager = PluginMain::ConfigManager::GetSingleton();
|
||||||
auto u8_last_path = config_manager.m_LastFilePath.Get();
|
auto u8_last_path = config_manager.m_LastFilePath.Get();
|
||||||
if (!u8_last_path.empty()) {
|
if (!u8_last_path.empty()) {
|
||||||
auto last_path = YYCC::FsPathPatch::FromUTF8Path(u8_last_path.c_str());
|
auto last_path = YYCC::StdPatch::ToStdPath(u8_last_path);
|
||||||
switch (m_InitialDatabaseType) {
|
switch (m_InitialDatabaseType) {
|
||||||
case InitialDatabaseType::Script:
|
case InitialDatabaseType::Script:
|
||||||
last_path.replace_filename(YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("script.db")));
|
last_path.replace_filename(YYCC::StdPatch::ToStdPath(YYCC_U8("script.db")));
|
||||||
break;
|
break;
|
||||||
case InitialDatabaseType::Document:
|
case InitialDatabaseType::Document:
|
||||||
last_path.replace_filename(YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("doc.db")));
|
last_path.replace_filename(YYCC::StdPatch::ToStdPath(YYCC_U8("doc.db")));
|
||||||
break;
|
break;
|
||||||
case InitialDatabaseType::Environment:
|
case InitialDatabaseType::Environment:
|
||||||
last_path.replace_filename(YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("env.db")));
|
last_path.replace_filename(YYCC::StdPatch::ToStdPath(YYCC_U8("env.db")));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("invalid initial database type");
|
throw std::runtime_error("invalid initial database type");
|
||||||
}
|
}
|
||||||
u8_last_path = YYCC::FsPathPatch::ToUTF8Path(last_path);
|
u8_last_path = YYCC::StdPatch::ToUTF8Path(last_path);
|
||||||
}
|
}
|
||||||
PushDatabaseFile(u8_last_path);
|
PushDatabaseFile(u8_last_path);
|
||||||
PushEncoding(config_manager.m_Encoding.Get());
|
PushEncoding(config_manager.m_Encoding.Get());
|
||||||
@@ -157,13 +117,13 @@ namespace VSW::Materializer {
|
|||||||
MessageBoxW(m_hWnd, L"Exported database file should not be empty!", L"Setting Error", MB_OK + MB_ICONERROR);
|
MessageBoxW(m_hWnd, L"Exported database file should not be empty!", L"Setting Error", MB_OK + MB_ICONERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ExportDialogHelper::ValidateCodePage(m_EncodingResult)) {
|
if (!YYCC::WinFctHelper::IsValidCodePage(m_EncodingResult)) {
|
||||||
MessageBoxW(m_hWnd, L"Invalid encoding!", L"Setting Error", MB_OK + MB_ICONERROR);
|
MessageBoxW(m_hWnd, L"Invalid encoding!", L"Setting Error", MB_OK + MB_ICONERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check done. sync settings to config manager
|
// check done. sync settings to config manager
|
||||||
auto& config_manager = ExportDialogSetting::GetSingleton();
|
auto& config_manager = PluginMain::ConfigManager::GetSingleton();
|
||||||
config_manager.m_LastFilePath.Set(m_DatabaseFileResult);
|
config_manager.m_LastFilePath.Set(m_DatabaseFileResult);
|
||||||
config_manager.m_Encoding.Set(m_EncodingResult);
|
config_manager.m_Encoding.Set(m_EncodingResult);
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,79 @@
|
|||||||
#include "ExportCore.hpp"
|
#include "ExportCore.hpp"
|
||||||
|
#include "Database.hpp"
|
||||||
|
#include "DataTypes.hpp"
|
||||||
|
#include "Utilities.hpp"
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace VSW::Materializer::ExportDocument {
|
namespace VSW::Materializer::ExportDocument {
|
||||||
|
|
||||||
|
struct ExportContext {
|
||||||
|
ExportContext(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) :
|
||||||
|
db(db_path), cache(), reporter(ctx), cp(code_page) {}
|
||||||
|
Database::DocumentDatabase db;
|
||||||
|
DataTypes::Document::DataCache cache;
|
||||||
|
Utilities::EnhancedReporter reporter;
|
||||||
|
UINT cp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void IterateMessage(ExportContext& expctx, CKMessageManager* msg_mgr) {
|
||||||
|
int count = msg_mgr->GetMessageTypeCount();
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
expctx.cache.msg.index = i;
|
||||||
|
CP_CKSTR(expctx.cache.msg.name, msg_mgr->GetMessageTypeName(i));
|
||||||
|
|
||||||
void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) {
|
expctx.db.Write(expctx.cache.msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief The common parents list which exported objects belong to.
|
||||||
|
static const std::vector<CK_CLASSID> g_CommonClassIds {
|
||||||
|
// Export CKSceneObject will export almost objects in scene
|
||||||
|
// That's enough
|
||||||
|
CKCID_SCENEOBJECT
|
||||||
|
};
|
||||||
|
static void IterateObject(ExportContext& expctx, CKContext* ctx) {
|
||||||
|
// Get CKParameterManager to resolve Class ID name
|
||||||
|
CKParameterManager* param_mgr = ctx->GetParameterManager();
|
||||||
|
// prepare variables
|
||||||
|
CK_CLASSID classid_cache;
|
||||||
|
|
||||||
|
for (const auto& cid : g_CommonClassIds) {
|
||||||
|
XObjectPointerArray obj_array = ctx->GetObjectListByType(cid, TRUE);
|
||||||
|
int obj_count = obj_array.Size();
|
||||||
|
for (int i = 0; i < obj_count; i++) {
|
||||||
|
CKSceneObject* scene_obj = static_cast<CKSceneObject*>(obj_array.GetObjectA(i));
|
||||||
|
|
||||||
|
// basic infos
|
||||||
|
expctx.cache.obj.id = scene_obj->GetID();
|
||||||
|
CP_CKSTR(expctx.cache.obj.name, scene_obj->GetName());
|
||||||
|
classid_cache = scene_obj->GetClassID();
|
||||||
|
expctx.cache.obj.classid = classid_cache;
|
||||||
|
// resolve class id name
|
||||||
|
CP_CKSTR(expctx.cache.obj.classid_name, param_mgr->ParameterGuidToName(param_mgr->ClassIDToGuid(classid_cache)));
|
||||||
|
|
||||||
|
expctx.db.Write(expctx.cache.obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) {
|
||||||
|
// create export context
|
||||||
|
ExportContext expctx(ctx, db_path, code_page);
|
||||||
|
if (!expctx.db.IsValid()) {
|
||||||
|
expctx.reporter.Err(YYCC_U8("Fail to open database. Export process aborted."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// export document
|
||||||
|
IterateMessage(expctx, ctx->GetMessageManager());
|
||||||
|
IterateObject(expctx, ctx);
|
||||||
|
|
||||||
|
// report success
|
||||||
|
expctx.reporter.EnableBeep();
|
||||||
|
expctx.reporter.Info(YYCC_U8("Exporting document database done."));
|
||||||
|
expctx.reporter.DisableBeep();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,17 @@
|
|||||||
namespace VSW::Materializer::ExportEnvironment {
|
namespace VSW::Materializer::ExportEnvironment {
|
||||||
|
|
||||||
struct ExportContext {
|
struct ExportContext {
|
||||||
ExportContext(CKContext* ctx, const YYCC::yycc_u8string_view& db_path) :
|
ExportContext(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) :
|
||||||
db(db_path), cache(), reporter(ctx) {}
|
db(db_path), cache(), reporter(ctx), cp(code_page), ctx(ctx), plugin_mgr(CKGetPluginManager()) {}
|
||||||
Database::EnvironmentDatabase db;
|
Database::EnvironmentDatabase db;
|
||||||
DataTypes::Environment::DataCache cache;
|
DataTypes::Environment::DataCache cache;
|
||||||
Utilities::EnhancedReporter reporter;
|
Utilities::EnhancedReporter reporter;
|
||||||
|
UINT cp;
|
||||||
|
|
||||||
|
/// @brief Virtools context.
|
||||||
|
CKContext* ctx;
|
||||||
|
/// @brief Virtools Plugin Manager
|
||||||
|
CKPluginManager* plugin_mgr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void IterateParameterOperation(ExportContext& expctx, CKParameterManager* param_mgr) {
|
static void IterateParameterOperation(ExportContext& expctx, CKParameterManager* param_mgr) {
|
||||||
@@ -26,8 +32,8 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
// fill the shared data part.
|
// fill the shared data part.
|
||||||
expctx.cache.op.op_code = i;
|
expctx.cache.op.op_code = i;
|
||||||
guid = param_mgr->OperationCodeToGuid(i);
|
guid = param_mgr->OperationCodeToGuid(i);
|
||||||
Utilities::CopyGuid(expctx.cache.op.op_guid, guid);
|
CP_GUID(expctx.cache.op.op_guid, guid);
|
||||||
expctx.cache.op.op_name = param_mgr->OperationCodeToName(i);
|
CP_CKSTR(expctx.cache.op.op_name, param_mgr->OperationCodeToName(i));
|
||||||
|
|
||||||
// get all sub-operation of this parameter operation.
|
// get all sub-operation of this parameter operation.
|
||||||
// each sub-operation can have different in out parameter type
|
// each sub-operation can have different in out parameter type
|
||||||
@@ -36,10 +42,10 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
op_list.resize(static_cast<size_t>(op_list_count));
|
op_list.resize(static_cast<size_t>(op_list_count));
|
||||||
param_mgr->GetAvailableOperationsDesc(guid, nullptr, nullptr, nullptr, op_list.data());
|
param_mgr->GetAvailableOperationsDesc(guid, nullptr, nullptr, nullptr, op_list.data());
|
||||||
for (const auto& op : op_list) {
|
for (const auto& op : op_list) {
|
||||||
Utilities::CopyGuid(expctx.cache.op.in1_guid, op.P1Guid);
|
CP_GUID(expctx.cache.op.in1_guid, op.P1Guid);
|
||||||
Utilities::CopyGuid(expctx.cache.op.in2_guid, op.P2Guid);
|
CP_GUID(expctx.cache.op.in2_guid, op.P2Guid);
|
||||||
Utilities::CopyGuid(expctx.cache.op.out_guid, op.ResGuid);
|
CP_GUID(expctx.cache.op.out_guid, op.ResGuid);
|
||||||
expctx.cache.op.func_ptr = Utilities::RelativeAddress(op.Fct);
|
CP_ADDR(expctx.cache.op.func_ptr, op.Fct);
|
||||||
|
|
||||||
expctx.db.Write(expctx.cache.op);
|
expctx.db.Write(expctx.cache.op);
|
||||||
}
|
}
|
||||||
@@ -55,30 +61,40 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
desc = param_mgr->GetParameterTypeDescription(i);
|
desc = param_mgr->GetParameterTypeDescription(i);
|
||||||
|
|
||||||
|
// Parameter basic infos
|
||||||
expctx.cache.param.index = desc->Index;
|
expctx.cache.param.index = desc->Index;
|
||||||
Utilities::CopyGuid(expctx.cache.param.guid, desc->Guid);
|
CP_GUID(expctx.cache.param.guid, desc->Guid);
|
||||||
Utilities::CopyGuid(expctx.cache.param.derived_from, desc->DerivedFrom);
|
CP_GUID(expctx.cache.param.derived_from, desc->DerivedFrom);
|
||||||
expctx.cache.param.type_name = desc->TypeName.CStr();
|
CP_CKSTR(expctx.cache.param.name, desc->TypeName.CStr());
|
||||||
expctx.cache.param.default_size = desc->DefaultSize;
|
expctx.cache.param.default_size = desc->DefaultSize;
|
||||||
expctx.cache.param.func_CreateDefault = Utilities::RelativeAddress(desc->CreateDefaultFunction);
|
CP_ADDR(expctx.cache.param.func_CreateDefault, desc->CreateDefaultFunction);
|
||||||
expctx.cache.param.func_Delete = Utilities::RelativeAddress(desc->DeleteFunction);
|
CP_ADDR(expctx.cache.param.func_Delete, desc->DeleteFunction);
|
||||||
expctx.cache.param.func_SaveLoad = Utilities::RelativeAddress(desc->SaveLoadFunction);
|
CP_ADDR(expctx.cache.param.func_SaveLoad, desc->SaveLoadFunction);
|
||||||
expctx.cache.param.func_Check = Utilities::RelativeAddress(desc->CheckFunction);
|
CP_ADDR(expctx.cache.param.func_Check, desc->CheckFunction);
|
||||||
expctx.cache.param.func_Copy = Utilities::RelativeAddress(desc->CopyFunction);
|
CP_ADDR(expctx.cache.param.func_Copy, desc->CopyFunction);
|
||||||
expctx.cache.param.func_String = Utilities::RelativeAddress(desc->StringFunction);
|
CP_ADDR(expctx.cache.param.func_String, desc->StringFunction);
|
||||||
expctx.cache.param.func_UICreator = Utilities::RelativeAddress(desc->UICreatorFunction);
|
CP_ADDR(expctx.cache.param.func_UICreator, desc->UICreatorFunction);
|
||||||
|
|
||||||
|
// Creator dll infos
|
||||||
|
// This is different with plugin.
|
||||||
|
// Because some parameters are provided by Virtools self.
|
||||||
CKPluginEntry* plugin_entry = desc->CreatorDll;
|
CKPluginEntry* plugin_entry = desc->CreatorDll;
|
||||||
if (plugin_entry != nullptr) {
|
if (plugin_entry != nullptr) {
|
||||||
expctx.cache.param.creator_dll_index = plugin_entry->m_PluginDllIndex;
|
CKPluginDll* plugin_dll = expctx.plugin_mgr->GetPluginDllInfo(plugin_entry->m_PluginDllIndex);
|
||||||
expctx.cache.param.creator_plugin_index = plugin_entry->m_PositionInDll;
|
CP_CKSTR(expctx.cache.param.dll_name, plugin_dll->m_DllFileName.CStr());
|
||||||
|
expctx.cache.param.dll_index = plugin_entry->m_PluginDllIndex;
|
||||||
|
expctx.cache.param.position_in_dll = plugin_entry->m_PositionInDll;
|
||||||
} else {
|
} else {
|
||||||
expctx.cache.param.creator_dll_index = -1;
|
expctx.cache.param.dll_name = YYCC_U8("<embedded>");
|
||||||
expctx.cache.param.creator_plugin_index = -1;
|
expctx.cache.param.dll_index = -1;
|
||||||
|
expctx.cache.param.position_in_dll = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Misc
|
||||||
|
expctx.cache.param.flags = desc->dwFlags;
|
||||||
expctx.cache.param.dw_param = desc->dwParam;
|
expctx.cache.param.dw_param = desc->dwParam;
|
||||||
expctx.cache.param.dw_flags = desc->dwFlags;
|
|
||||||
expctx.cache.param.cid = desc->Cid;
|
expctx.cache.param.cid = desc->Cid;
|
||||||
Utilities::CopyGuid(expctx.cache.param.saver_manager, desc->Saver_Manager);
|
CP_GUID(expctx.cache.param.saver_manager, desc->Saver_Manager);
|
||||||
|
|
||||||
expctx.db.Write(expctx.cache.param);
|
expctx.db.Write(expctx.cache.param);
|
||||||
}
|
}
|
||||||
@@ -89,13 +105,14 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
int count = attr_mgr->GetAttributeCount();
|
int count = attr_mgr->GetAttributeCount();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
expctx.cache.attr.index = i;
|
expctx.cache.attr.index = i;
|
||||||
expctx.cache.attr.name = attr_mgr->GetAttributeNameByType(i);
|
CP_CKSTR(expctx.cache.attr.name, attr_mgr->GetAttributeNameByType(i));
|
||||||
expctx.cache.attr.category_index = attr_mgr->GetAttributeCategoryIndex(i);
|
expctx.cache.attr.category_index = attr_mgr->GetAttributeCategoryIndex(i);
|
||||||
Utilities::CopyCKString(expctx.cache.attr.category_name, attr_mgr->GetAttributeCategory(i));
|
CP_CKSTR(expctx.cache.attr.category_name, attr_mgr->GetAttributeCategory(i));
|
||||||
expctx.cache.attr.flags = attr_mgr->GetAttributeFlags(i);
|
expctx.cache.attr.flags = attr_mgr->GetAttributeFlags(i);
|
||||||
expctx.cache.attr.param_index = attr_mgr->GetAttributeParameterType(i);
|
expctx.cache.attr.param_index = attr_mgr->GetAttributeParameterType(i);
|
||||||
|
CP_GUID(expctx.cache.attr.param_guid, attr_mgr->GetAttributeParameterGUID(i));
|
||||||
expctx.cache.attr.compatible_classid = attr_mgr->GetAttributeCompatibleClassId(i);
|
expctx.cache.attr.compatible_classid = attr_mgr->GetAttributeCompatibleClassId(i);
|
||||||
Utilities::CopyCKString(expctx.cache.attr.default_value, attr_mgr->GetAttributeDefaultValue(i));
|
CP_CKSTR(expctx.cache.attr.default_value, attr_mgr->GetAttributeDefaultValue(i));
|
||||||
|
|
||||||
expctx.db.Write(expctx.cache.attr);
|
expctx.db.Write(expctx.cache.attr);
|
||||||
}
|
}
|
||||||
@@ -108,8 +125,9 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
// get category count and iterate them
|
// get category count and iterate them
|
||||||
int category_count = plugin_mgr->GetCategoryCount();
|
int category_count = plugin_mgr->GetCategoryCount();
|
||||||
for (int i = 0; i < category_count; ++i) {
|
for (int i = 0; i < category_count; ++i) {
|
||||||
// get category name and set it
|
// category name and its index
|
||||||
expctx.cache.plugin.category = plugin_mgr->GetCategoryName(i);
|
CP_CKSTR(expctx.cache.plugin.category_name, plugin_mgr->GetCategoryName(i));
|
||||||
|
expctx.cache.plugin.category_index = i;
|
||||||
|
|
||||||
// iterate plugin within this category
|
// iterate plugin within this category
|
||||||
int plugin_count = plugin_mgr->GetPluginCount(i);
|
int plugin_count = plugin_mgr->GetPluginCount(i);
|
||||||
@@ -118,25 +136,32 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
CKPluginInfo* plugin_info = &(plugin_entry->m_PluginInfo);
|
CKPluginInfo* plugin_info = &(plugin_entry->m_PluginInfo);
|
||||||
CKPluginDll* plugin_dll = plugin_mgr->GetPluginDllInfo(plugin_entry->m_PluginDllIndex);
|
CKPluginDll* plugin_dll = plugin_mgr->GetPluginDllInfo(plugin_entry->m_PluginDllIndex);
|
||||||
|
|
||||||
// dll infomation (name + position in dll)
|
// dll infomation (name + index + position in dll)
|
||||||
expctx.cache.plugin.dll_name = plugin_dll->m_DllFileName.CStr();
|
CP_CKSTR(expctx.cache.plugin.dll_name, plugin_dll->m_DllFileName.CStr());
|
||||||
|
expctx.cache.plugin.dll_index = plugin_entry->m_PluginDllIndex;
|
||||||
expctx.cache.plugin.position_in_dll = plugin_entry->m_PositionInDll;
|
expctx.cache.plugin.position_in_dll = plugin_entry->m_PositionInDll;
|
||||||
|
|
||||||
// plugin info
|
// plugin info
|
||||||
Utilities::CopyGuid(expctx.cache.plugin.guid, plugin_info->m_GUID);
|
expctx.cache.plugin.index = j;
|
||||||
expctx.cache.plugin.desc = plugin_info->m_Description.CStr();
|
CP_GUID(expctx.cache.plugin.guid, plugin_info->m_GUID);
|
||||||
expctx.cache.plugin.author = plugin_info->m_Author.CStr();
|
CP_CKSTR(expctx.cache.plugin.desc, plugin_info->m_Description.CStr());
|
||||||
expctx.cache.plugin.summary = plugin_info->m_Summary.CStr();
|
CP_CKSTR(expctx.cache.plugin.author, plugin_info->m_Author.CStr());
|
||||||
|
CP_CKSTR(expctx.cache.plugin.summary, plugin_info->m_Summary.CStr());
|
||||||
expctx.cache.plugin.version = plugin_info->m_Version;
|
expctx.cache.plugin.version = plugin_info->m_Version;
|
||||||
plugin_type = plugin_info->m_Type;
|
plugin_type = plugin_info->m_Type;
|
||||||
expctx.cache.plugin.type = plugin_type;
|
expctx.cache.plugin.type = plugin_type;
|
||||||
expctx.cache.plugin.func_init = Utilities::RelativeAddress(plugin_info->m_InitInstanceFct);
|
CP_ADDR(expctx.cache.plugin.func_init, plugin_info->m_InitInstanceFct);
|
||||||
expctx.cache.plugin.func_exit = Utilities::RelativeAddress(plugin_info->m_ExitInstanceFct);
|
CP_ADDR(expctx.cache.plugin.func_exit, plugin_info->m_ExitInstanceFct);
|
||||||
|
|
||||||
// extra fields according to plugin type
|
// extra fields according to plugin type
|
||||||
// first reset these specific fields
|
// first reset these specific fields
|
||||||
expctx.cache.plugin.reader_fct.clear();
|
expctx.cache.plugin.reader_fct.clear();
|
||||||
|
expctx.cache.plugin.reader_opt_count = 0;
|
||||||
|
expctx.cache.plugin.reader_flags = static_cast<CK_DATAREADER_FLAGS>(0);
|
||||||
|
expctx.cache.plugin.reader_setting_param_guid = INT64_C(0);
|
||||||
|
expctx.cache.plugin.reader_file_ext.clear();
|
||||||
|
expctx.cache.plugin.behavior_guids.clear();
|
||||||
|
expctx.cache.plugin.manager_active = false;
|
||||||
// then try to fetch these specific fields
|
// then try to fetch these specific fields
|
||||||
switch (plugin_type) {
|
switch (plugin_type) {
|
||||||
case CKPLUGIN_BITMAP_READER:
|
case CKPLUGIN_BITMAP_READER:
|
||||||
@@ -145,25 +170,23 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
case CKPLUGIN_MOVIE_READER:
|
case CKPLUGIN_MOVIE_READER:
|
||||||
{
|
{
|
||||||
// Reader specific
|
// Reader specific
|
||||||
expctx.cache.plugin.reader_fct = Utilities::RelativeAddress(plugin_entry->m_ReadersInfo->m_GetReaderFct);
|
CP_ADDR(expctx.cache.plugin.reader_fct, plugin_entry->m_ReadersInfo->m_GetReaderFct);
|
||||||
expctx.cache.plugin.reader_opt_count = plugin_entry->m_ReadersInfo->m_OptionCount;
|
expctx.cache.plugin.reader_opt_count = plugin_entry->m_ReadersInfo->m_OptionCount;
|
||||||
expctx.cache.plugin.reader_flags = plugin_entry->m_ReadersInfo->m_ReaderFlags;
|
expctx.cache.plugin.reader_flags = plugin_entry->m_ReadersInfo->m_ReaderFlags;
|
||||||
Utilities::CopyGuid(expctx.cache.plugin.reader_setting_param_guid, plugin_entry->m_ReadersInfo->m_SettingsParameterGuid);
|
CP_GUID(expctx.cache.plugin.reader_setting_param_guid, plugin_entry->m_ReadersInfo->m_SettingsParameterGuid);
|
||||||
expctx.cache.plugin.reader_file_ext = static_cast<const char*>(plugin_info->m_Extension);
|
CP_CKSTR(expctx.cache.plugin.reader_file_ext, static_cast<const char*>(plugin_info->m_Extension), YYCC_U8(""));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CKPLUGIN_BEHAVIOR_DLL:
|
case CKPLUGIN_BEHAVIOR_DLL:
|
||||||
{
|
{
|
||||||
// Behavior specific
|
// Behavior specific
|
||||||
std::vector<YYCC::yycc_u8string> guids;
|
std::vector<YYCC::yycc_u8string> guids;
|
||||||
|
YYCC::yycc_u8string guid_cache;
|
||||||
for (int i = 0; i < plugin_entry->m_BehaviorsInfo->m_BehaviorsGUID.Size(); ++i) {
|
for (int i = 0; i < plugin_entry->m_BehaviorsInfo->m_BehaviorsGUID.Size(); ++i) {
|
||||||
int64_t guid_cache;
|
CP_STR_GUID(guid_cache, plugin_entry->m_BehaviorsInfo->m_BehaviorsGUID[i]);
|
||||||
Utilities::CopyGuid(guid_cache, plugin_entry->m_BehaviorsInfo->m_BehaviorsGUID[i]);
|
guids.emplace_back(guid_cache);
|
||||||
guids.emplace_back(YYCC::ParserHelper::ToString(guid_cache));
|
|
||||||
}
|
}
|
||||||
expctx.cache.plugin.behavior_guids = YYCC::EncodingHelper::ToOrdinaryView(
|
expctx.cache.plugin.behavior_guids = YYCC::StringHelper::Join(guids, YYCC_U8(", "));
|
||||||
YYCC::StringHelper::Join(guids, YYCC_U8(", "))
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CKPLUGIN_MANAGER_DLL:
|
case CKPLUGIN_MANAGER_DLL:
|
||||||
@@ -176,7 +199,6 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
expctx.db.Write(expctx.cache.plugin);
|
expctx.db.Write(expctx.cache.plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,9 +220,9 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
varobj = it.GetVariable();
|
varobj = it.GetVariable();
|
||||||
// variable name
|
// variable name
|
||||||
var_name = it.GetName();
|
var_name = it.GetName();
|
||||||
expctx.cache.variable.name = var_name;
|
CP_CKSTR(expctx.cache.variable.name, var_name);
|
||||||
// variable description
|
// variable description
|
||||||
Utilities::CopyCKString(expctx.cache.variable.desciption, varobj->GetDescription());
|
CP_CKSTR(expctx.cache.variable.desciption, varobj->GetDescription());
|
||||||
// variable flags
|
// variable flags
|
||||||
expctx.cache.variable.flags = varobj->GetFlags();
|
expctx.cache.variable.flags = varobj->GetFlags();
|
||||||
// variable type
|
// variable type
|
||||||
@@ -211,21 +233,21 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
// Because it is not a name.
|
// Because it is not a name.
|
||||||
// So we should record it as empty string if it is nullptr, instead of default <unamed>
|
// So we should record it as empty string if it is nullptr, instead of default <unamed>
|
||||||
var_representation = varobj->GetRepresentation();
|
var_representation = varobj->GetRepresentation();
|
||||||
Utilities::CopyCKString(expctx.cache.variable.representation, var_representation, "");
|
CP_CKSTR(expctx.cache.variable.representation, var_representation, YYCC_U8(""));
|
||||||
// We output variable stored value in different way
|
// We output variable stored value in different way
|
||||||
// according to its type.
|
// according to its type.
|
||||||
switch (var_type) {
|
switch (var_type) {
|
||||||
case CKVariableManager::Variable::Type::INT:
|
case CKVariableManager::Variable::Type::INT:
|
||||||
var_mgr->GetValue(var_name, &int_cache);
|
var_mgr->GetValue(var_name, &int_cache);
|
||||||
expctx.cache.variable.data = YYCC::EncodingHelper::ToOrdinaryView(YYCC::ParserHelper::ToString(int_cache));
|
expctx.cache.variable.data = YYCC::ParserHelper::ToString(int_cache);
|
||||||
break;
|
break;
|
||||||
case CKVariableManager::Variable::Type::FLOAT:
|
case CKVariableManager::Variable::Type::FLOAT:
|
||||||
var_mgr->GetValue(var_name, &float_cache);
|
var_mgr->GetValue(var_name, &float_cache);
|
||||||
expctx.cache.variable.data = YYCC::EncodingHelper::ToOrdinaryView(YYCC::ParserHelper::ToString(float_cache));
|
expctx.cache.variable.data = YYCC::ParserHelper::ToString(float_cache);
|
||||||
break;
|
break;
|
||||||
case CKVariableManager::Variable::Type::STRING:
|
case CKVariableManager::Variable::Type::STRING:
|
||||||
var_mgr->GetValue(var_name, xstring_cache);
|
var_mgr->GetValue(var_name, xstring_cache);
|
||||||
expctx.cache.variable.data = xstring_cache.CStr();
|
CP_CKSTR(expctx.cache.variable.data, xstring_cache.CStr());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("invalid variable type!");
|
throw std::runtime_error("invalid variable type!");
|
||||||
@@ -238,7 +260,11 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
|
|
||||||
void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) {
|
void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) {
|
||||||
// create database and data cache in context
|
// create database and data cache in context
|
||||||
ExportContext expctx(ctx, db_path);
|
ExportContext expctx(ctx, db_path, code_page);
|
||||||
|
if (!expctx.db.IsValid()) {
|
||||||
|
expctx.reporter.Err(YYCC_U8("Fail to open database. Export process aborted."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// export environment one by one
|
// export environment one by one
|
||||||
IterateParameterOperation(expctx, ctx->GetParameterManager());
|
IterateParameterOperation(expctx, ctx->GetParameterManager());
|
||||||
@@ -248,6 +274,11 @@ namespace VSW::Materializer::ExportEnvironment {
|
|||||||
#if !defined(VIRTOOLS_21)
|
#if !defined(VIRTOOLS_21)
|
||||||
IterateVariable(expctx, ctx->GetVariableManager());
|
IterateVariable(expctx, ctx->GetVariableManager());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// report success
|
||||||
|
expctx.reporter.EnableBeep();
|
||||||
|
expctx.reporter.Info(YYCC_U8("Exporting environment database done."));
|
||||||
|
expctx.reporter.DisableBeep();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,648 @@
|
|||||||
#include "ExportCore.hpp"
|
#include "ExportCore.hpp"
|
||||||
|
#include "Database.hpp"
|
||||||
|
#include "DataTypes.hpp"
|
||||||
|
#include "Utilities.hpp"
|
||||||
|
#include <numeric>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The namespace contain functions exporting scripts
|
||||||
|
* @details
|
||||||
|
* \c Generate mean that this function will analyse something to generate some objects which are not existed in original Virtools document.
|
||||||
|
* \c Proc meath that this function only just export something which is already existed in original Virtools document, or with slight modifications.
|
||||||
|
*/
|
||||||
namespace VSW::Materializer::ExportScript {
|
namespace VSW::Materializer::ExportScript {
|
||||||
|
|
||||||
|
struct ExportContext {
|
||||||
|
ExportContext(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) :
|
||||||
|
db(db_path), cache(), reporter(ctx), cp(code_page), attr_set(), ctx(ctx), param_mgr(ctx->GetParameterManager()) {}
|
||||||
|
Database::ScriptDatabase db;
|
||||||
|
DataTypes::Script::DataCache cache;
|
||||||
|
Utilities::EnhancedReporter reporter;
|
||||||
|
UINT cp;
|
||||||
|
|
||||||
|
/// @brief Variable for removing duplicated exported attributes.
|
||||||
|
std::set<CK_ID> attr_set;
|
||||||
|
/// @brief Virtools context.
|
||||||
|
CKContext* ctx;
|
||||||
|
/// @brief Virtools Parameter Manager
|
||||||
|
CKParameterManager* param_mgr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma region Assist Functions
|
||||||
|
|
||||||
void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) {
|
static void DataDictWriter(ExportContext& expctx, const YYCC::yycc_u8string_view& field, const void* data, size_t data_length, CK_ID parent) {
|
||||||
|
// check given data length
|
||||||
|
using db_size_t = decltype(expctx.cache.data.data.length);
|
||||||
|
if (data_length > static_cast<size_t>(std::numeric_limits<db_size_t>::max()))
|
||||||
|
throw std::runtime_error("Too long data length when exporting to data dictionary.");
|
||||||
|
// if length is zero, reset ptr to nullptr
|
||||||
|
if (data_length == 0u) data = nullptr;
|
||||||
|
// write data
|
||||||
|
expctx.cache.data.field = field;
|
||||||
|
expctx.cache.data.data.ptr = data;
|
||||||
|
expctx.cache.data.data.length = static_cast<db_size_t>(data_length);
|
||||||
|
expctx.cache.data.parent = parent;
|
||||||
|
expctx.db.Write(expctx.cache.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DataDictWriter(ExportContext& expctx, const YYCC::yycc_u8string_view& field, const YYCC::yycc_u8string& data, CK_ID parent) {
|
||||||
|
DataDictWriter(expctx, field, data.c_str(), data.length(), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class _Ty, std::enable_if_t<!std::is_same_v<_Ty, YYCC::yycc_u8string>, int> = 0>
|
||||||
|
static void DataDictWriter(ExportContext& expctx, const YYCC::yycc_u8string_view& field, const _Ty& data, CK_ID parent) {
|
||||||
|
DataDictWriter(expctx, field, &data, sizeof(_Ty), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REC_RAW_DATA(field, data, len) DataDictWriter(expctx, YYCC_U8(field), data, len, parent)
|
||||||
|
#define REC_DATA(field, data) DataDictWriter(expctx, YYCC_U8(field), data, parent)
|
||||||
|
|
||||||
|
void DigParameterData(ExportContext& expctx, CKParameter* p, CK_ID parent) {
|
||||||
|
// According to our algorithm, CKParameter passed in this function can not be duplicated.
|
||||||
|
// So we don't need check it anymore.
|
||||||
|
// Get CKGUID and Parameter Type first
|
||||||
|
CKGUID t = p->GetGUID();
|
||||||
|
CKParameterType pt = p->GetType();
|
||||||
|
|
||||||
|
// Record GUID
|
||||||
|
int64_t exported_t;
|
||||||
|
CP_GUID(exported_t, t);
|
||||||
|
REC_DATA("dumper.guid", exported_t);
|
||||||
|
// Record Parameter Type name
|
||||||
|
YYCC::yycc_u8string exported_pt;
|
||||||
|
CP_CKSTR(exported_pt, expctx.param_mgr->ParameterTypeToName(pt));
|
||||||
|
REC_DATA("dumper.type-name", exported_pt);
|
||||||
|
|
||||||
|
// Detect value object scenario (associated with an existing CKObject)
|
||||||
|
if (p->GetParameterClassID() && p->GetValueObject(false)) {
|
||||||
|
// Record CK_ID of associated object
|
||||||
|
CKObject* assoc_obj = p->GetValueObject(false);
|
||||||
|
REC_DATA("dumper.assoc-ckobj", assoc_obj->GetID());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing
|
||||||
|
if (t == CKPGUID_NONE) return;
|
||||||
|
|
||||||
|
// Float value
|
||||||
|
if (t == CKPGUID_FLOAT || t == CKPGUID_ANGLE || t == CKPGUID_PERCENTAGE || t == CKPGUID_TIME
|
||||||
|
#if defined(VIRTOOLS_50) || defined(VIRTOOLS_40) || defined(VIRTOOLS_35)
|
||||||
|
|| t == CKPGUID_FLOATSLIDER
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
REC_DATA("dumper.float", *static_cast<float*>(p->GetReadDataPtr(false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Integral value
|
||||||
|
if (t == CKPGUID_INT || t == CKPGUID_KEY || t == CKPGUID_BOOL || t == CKPGUID_ID || t == CKPGUID_POINTER
|
||||||
|
|| t == CKPGUID_MESSAGE || t == CKPGUID_ATTRIBUTE || t == CKPGUID_BLENDMODE || t == CKPGUID_FILTERMODE
|
||||||
|
|| t == CKPGUID_BLENDFACTOR || t == CKPGUID_FILLMODE || t == CKPGUID_LITMODE || t == CKPGUID_SHADEMODE
|
||||||
|
|| t == CKPGUID_ADDRESSMODE || t == CKPGUID_WRAPMODE || t == CKPGUID_3DSPRITEMODE || t == CKPGUID_FOGMODE
|
||||||
|
|| t == CKPGUID_LIGHTTYPE || t == CKPGUID_SPRITEALIGN || t == CKPGUID_DIRECTION || t == CKPGUID_LAYERTYPE
|
||||||
|
|| t == CKPGUID_COMPOPERATOR || t == CKPGUID_BINARYOPERATOR || t == CKPGUID_SETOPERATOR
|
||||||
|
|| t == CKPGUID_OBSTACLEPRECISION || t == CKPGUID_OBSTACLEPRECISIONBEH) {
|
||||||
|
REC_DATA("dumper.int", *static_cast<int*>(p->GetReadDataPtr(false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Vector value
|
||||||
|
if (t == CKPGUID_VECTOR) {
|
||||||
|
REC_DATA("dumper.vector", *static_cast<VxVector*>(p->GetReadDataPtr(false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (t == CKPGUID_2DVECTOR) {
|
||||||
|
REC_DATA("dumper.2dvector", *static_cast<Vx2DVector*>(p->GetReadDataPtr(false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (t == CKPGUID_MATRIX) {
|
||||||
|
REC_DATA("dumper.matrix", *static_cast<VxMatrix*>(p->GetReadDataPtr(false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (t == CKPGUID_COLOR) {
|
||||||
|
REC_DATA("dumper.color", *static_cast<VxColor*>(p->GetReadDataPtr(false)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 2D Curve value
|
||||||
|
if (t == CKPGUID_2DCURVE) {
|
||||||
|
// Get instance
|
||||||
|
CK2dCurve* c = static_cast<CK2dCurve*>(p->GetReadDataPtr(false));
|
||||||
|
// We build our unique binary 2d curve data.
|
||||||
|
Utilities::Curve2DBuilder builder(c);
|
||||||
|
REC_RAW_DATA("dumper.2d-curve", builder.GetDataPtr(), builder.GetDataLength());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// String value
|
||||||
|
if (t == CKPGUID_STRING) {
|
||||||
|
// Virtools internal data may not have null terminal,
|
||||||
|
// so we use need copy it into container first.
|
||||||
|
std::string native_string(
|
||||||
|
static_cast<char*>(p->GetReadDataPtr(false)),
|
||||||
|
static_cast<size_t>(p->GetDataSize())
|
||||||
|
);
|
||||||
|
// Then do encoding convertion
|
||||||
|
YYCC::yycc_u8string utf8_string;
|
||||||
|
if (!YYCC::EncodingHelper::CharToUTF8(native_string, utf8_string, expctx.cp)) {
|
||||||
|
// If failed, report error
|
||||||
|
expctx.reporter.Err(YYCC_U8("Fail to convert string encoding for data of CKParameter. Some value may be empty!"));
|
||||||
|
// reset to blank string
|
||||||
|
utf8_string.clear();
|
||||||
|
}
|
||||||
|
REC_DATA("dumper.string", utf8_string);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If it gets here, we have no idea what it really is. so simply dump it.
|
||||||
|
// Buffer-like
|
||||||
|
if (t == CKPGUID_VOIDBUF
|
||||||
|
#if defined(VIRTOOLS_50) || defined(VIRTOOLS_40) || defined(VIRTOOLS_35)
|
||||||
|
|| t == CKPGUID_SHADER || t == CKPGUID_TECHNIQUE || t == CKPGUID_PASS
|
||||||
|
#endif
|
||||||
|
|| true // All unknown type goes here.
|
||||||
|
) {
|
||||||
|
// Raw data is similar with string,
|
||||||
|
// but we don't need do encoding convertion.
|
||||||
|
const void* data_ptr = p->GetReadDataPtr(false);
|
||||||
|
size_t data_len = static_cast<size_t>(p->GetDataSize());
|
||||||
|
REC_RAW_DATA("dumper.raw", data_ptr, data_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process Attribute Parameter
|
||||||
|
* @details
|
||||||
|
* pAttr do not have any explicit interface to get them, so they only can be find via pLink analyse.
|
||||||
|
* 2 pLink analyse funcstions will call this function to record each pAttr.
|
||||||
|
* Due to this mechanism, it might cause a duplication issues,
|
||||||
|
* so we need check possible duplication in here.
|
||||||
|
* @param[in] expctx Reference to export context.
|
||||||
|
* @param[in] ckobj Pointer to CKParameter (actually is attribute parameter) for processing.
|
||||||
|
*/
|
||||||
|
static void Proc_pAttr(ExportContext& expctx, CKParameter* ckobj) {
|
||||||
|
// Check duplication.
|
||||||
|
// We should not export duplicated pAttr
|
||||||
|
auto insert_result = expctx.attr_set.emplace(ckobj->GetID());
|
||||||
|
if (!insert_result.second) return;
|
||||||
|
|
||||||
|
// Write self first
|
||||||
|
expctx.cache.pAttr.thisobj = ckobj->GetID();
|
||||||
|
CP_CKSTR(expctx.cache.pAttr.name, ckobj->GetName());
|
||||||
|
CP_GUID(expctx.cache.pAttr.type, ckobj->GetGUID());
|
||||||
|
expctx.cache.pAttr.owner = ckobj->GetOwner()->GetID();
|
||||||
|
expctx.db.Write(expctx.cache.pAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate pLink and eLink from pIn
|
||||||
|
* @param[in] expctx Reference to export context.
|
||||||
|
* @param[in] analysed Pointer to CKParameterIn for analysing.
|
||||||
|
* @param[in] parent
|
||||||
|
* @param[in] grandparent
|
||||||
|
* @param[in] pin_index
|
||||||
|
* @param[in] executed_from_bb True if given CKParameterIn is belong to a CKBehavior, otherwise false (CKParamterOperation).
|
||||||
|
* @param[in] is_target True if this function is called from pTarget processor.
|
||||||
|
*/
|
||||||
|
static void Generate_pLink(ExportContext& expctx, CKParameterIn* analysed, CK_ID parent, CK_ID grandparent, int pin_index, bool executed_from_bb, bool is_target) {
|
||||||
|
// First, we analyse eLink.
|
||||||
|
// Check whether this is export parameter and write to database.
|
||||||
|
// If the behavior graph where this pIn's parent locate, also include this pIn,
|
||||||
|
// we can simply assume there is an eLink between them
|
||||||
|
CKBehavior* ckobj_grandparent = static_cast<CKBehavior*>(expctx.ctx->GetObjectA(grandparent));
|
||||||
|
if (ckobj_grandparent->GetInputParameterPosition(analysed) != -1) {
|
||||||
|
expctx.cache.eLink.export_obj = analysed->GetID();
|
||||||
|
expctx.cache.eLink.internal_obj = parent;
|
||||||
|
expctx.cache.eLink.is_in = true;
|
||||||
|
expctx.cache.eLink.index = pin_index;
|
||||||
|
expctx.cache.eLink.parent = grandparent;
|
||||||
|
expctx.db.Write(expctx.cache.eLink);
|
||||||
|
|
||||||
|
// if a eLink has been detected successfully, we returned immediately
|
||||||
|
// and do not analyse any pLink any more.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start to analyse pLink
|
||||||
|
// first, analyse \c direct_source
|
||||||
|
CKParameter* direct_source = analysed->GetDirectSource();
|
||||||
|
if (direct_source != nullptr) {
|
||||||
|
expctx.cache.pLink.input = direct_source->GetID();
|
||||||
|
|
||||||
|
// For almost pIn, they are connected to a pLocal, so we use \c if statement to test it first
|
||||||
|
CK_CLASSID direct_source_cid = direct_source->GetClassID();
|
||||||
|
if (direct_source_cid == CKCID_PARAMETERLOCAL || direct_source_cid == CKCID_PARAMETERVARIABLE) {
|
||||||
|
// pLocal
|
||||||
|
expctx.cache.pLink.input_obj = direct_source->GetID(); // the owner of pLocal is itself.
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::PLOCAL;
|
||||||
|
expctx.cache.pLink.input_is_bb = false;
|
||||||
|
expctx.cache.pLink.input_index = Utilities::INVALID_INDEX;
|
||||||
|
} else {
|
||||||
|
// According to Virtools SDK document, there are 4 possible value gotten by us:
|
||||||
|
// bb pOut / pOper pOut / CKObject Attribute / CKDataArray.
|
||||||
|
// However, the last 2 returned values have NOT been tested perfectly.
|
||||||
|
CKObject* ds_owner = direct_source->GetOwner();
|
||||||
|
switch (ds_owner->GetClassID()) {
|
||||||
|
case CKCID_BEHAVIOR:
|
||||||
|
{;
|
||||||
|
CKBehavior* ds_owner_cast = static_cast<CKBehavior*>(ds_owner);
|
||||||
|
CKParameterOut* direct_source_cast = static_cast<CKParameterOut*>(direct_source);
|
||||||
|
expctx.cache.pLink.input_obj = ds_owner->GetID();
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::POUT;
|
||||||
|
expctx.cache.pLink.input_is_bb = true;
|
||||||
|
expctx.cache.pLink.input_index = ds_owner_cast->GetOutputParameterPosition(direct_source_cast);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CKCID_PARAMETEROPERATION:
|
||||||
|
{
|
||||||
|
expctx.cache.pLink.input_obj = ds_owner->GetID();
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::POUT;
|
||||||
|
expctx.cache.pLink.input_is_bb = false;
|
||||||
|
expctx.cache.pLink.input_index = 0; // pOper only have 1 pOut
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CKCID_DATAARRAY:
|
||||||
|
{
|
||||||
|
// CKDataArray, see as virtual bb pLocal shortcut
|
||||||
|
expctx.cache.pLink.input_obj = direct_source->GetID();
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::PATTR;
|
||||||
|
expctx.cache.pLink.input_is_bb = false; // discard
|
||||||
|
expctx.cache.pLink.input_index = Utilities::INVALID_INDEX; // discard
|
||||||
|
Proc_pAttr(expctx, direct_source);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// CKObject, because CKDataArray also a CKObject, so we test it first.
|
||||||
|
// see as virtual bb pLocal shortcut
|
||||||
|
expctx.cache.pLink.input_obj = direct_source->GetID();
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::PATTR;
|
||||||
|
expctx.cache.pLink.input_is_bb = false; // discard
|
||||||
|
expctx.cache.pLink.input_index = Utilities::INVALID_INDEX; // discard
|
||||||
|
Proc_pAttr(expctx, direct_source);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// \c direct_source reflect the real source of current analysed pIn,
|
||||||
|
// however \c direct_source can not reflect export link.
|
||||||
|
// So we need to analyse \c shared_source now for export link.
|
||||||
|
//
|
||||||
|
// If this pIn has established some export relation, its \c shared_source must be filled, so we can detect this in here.
|
||||||
|
// Once its \c shared_source is not nullptr, we should consider export link in here.
|
||||||
|
//
|
||||||
|
// We do not need to analyse any export link here,
|
||||||
|
// we just need to export some infos to tell that there is an export link.
|
||||||
|
CKParameterIn* shared_source = analysed->GetSharedSource();
|
||||||
|
if (shared_source != nullptr) {
|
||||||
|
// pIn from BB
|
||||||
|
// Get the owner of shared_source
|
||||||
|
CKObject* ss_owner = shared_source->GetOwner();
|
||||||
|
// Setup fields
|
||||||
|
expctx.cache.pLink.input = shared_source->GetID();
|
||||||
|
expctx.cache.pLink.input_obj = ss_owner->GetID();
|
||||||
|
|
||||||
|
switch (ss_owner->GetClassID()) {
|
||||||
|
case CKCID_BEHAVIOR: // CKBehavior
|
||||||
|
{
|
||||||
|
CKBehavior* ss_owner_cast = static_cast<CKBehavior*>(ss_owner);
|
||||||
|
if (ss_owner_cast->IsUsingTarget() && (ss_owner_cast->GetTargetParameter() == shared_source)) {
|
||||||
|
// pTarget
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::PTARGET;
|
||||||
|
expctx.cache.pLink.input_is_bb = true;
|
||||||
|
expctx.cache.pLink.input_index = Utilities::INVALID_INDEX; // discard
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// pIn
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::PIN;
|
||||||
|
expctx.cache.pLink.input_is_bb = true;
|
||||||
|
expctx.cache.pLink.input_index = ((CKBehavior*)ss_owner)->GetInputParameterPosition(shared_source);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CKCID_PARAMETEROPERATION: // CKParameterOperation
|
||||||
|
{
|
||||||
|
// pOper only can have pIn (there is no possibility to have pTarget).
|
||||||
|
CKParameterOperation* ss_owner_cast = static_cast<CKParameterOperation*>(ss_owner);
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::PIN;
|
||||||
|
expctx.cache.pLink.input_is_bb = false;
|
||||||
|
expctx.cache.pLink.input_index = ss_owner_cast->GetInParameter1() == shared_source ? 0 : 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// The unexpected value.
|
||||||
|
// According to SDK manual, there are only 2 possible types.
|
||||||
|
throw std::runtime_error("unexpected shared_source owner class id!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the head of pLink has been analysed successfully,
|
||||||
|
// we can add tail info and push into database
|
||||||
|
if (shared_source != nullptr || direct_source != nullptr) {
|
||||||
|
expctx.cache.pLink.output = analysed->GetID();
|
||||||
|
expctx.cache.pLink.output_obj = parent;
|
||||||
|
expctx.cache.pLink.output_type = is_target ? VSW::DataTypes::ParameterLinkIOType::PTARGET : VSW::DataTypes::ParameterLinkIOType::PIN;
|
||||||
|
expctx.cache.pLink.output_is_bb = executed_from_bb;
|
||||||
|
expctx.cache.pLink.output_index = pin_index;
|
||||||
|
expctx.cache.pLink.parent = grandparent;
|
||||||
|
|
||||||
|
expctx.db.Write(expctx.cache.pLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate pLink and eLink from pOut
|
||||||
|
* @param[in] expctx Reference to export context.
|
||||||
|
* @param[in] analysed Pointer to CKParameterIn for analysing.
|
||||||
|
* @param[in] parent
|
||||||
|
* @param[in] grandparent
|
||||||
|
* @param[in] pout_index
|
||||||
|
* @param[in] executed_from_bb True if given CKParameterIn is belong to a CKBehavior, otherwise false (CKParamterOperation).
|
||||||
|
*/
|
||||||
|
static void Generate_pLink(ExportContext& expctx, CKParameterOut* analysed, CK_ID parent, CK_ID grandparent, int pout_index, bool executed_from_bb) {
|
||||||
|
// Check eLink first
|
||||||
|
// Check whether there is an export parameter and write to database
|
||||||
|
// Same check method as another overload
|
||||||
|
CKBehavior* ckobj_grandparent = static_cast<CKBehavior*>(expctx.ctx->GetObjectA(grandparent));
|
||||||
|
if (ckobj_grandparent->GetOutputParameterPosition(analysed) != -1) {
|
||||||
|
expctx.cache.eLink.export_obj = analysed->GetID();
|
||||||
|
expctx.cache.eLink.internal_obj = parent;
|
||||||
|
expctx.cache.eLink.is_in = false;
|
||||||
|
expctx.cache.eLink.index = pout_index;
|
||||||
|
expctx.cache.eLink.parent = grandparent;
|
||||||
|
|
||||||
|
expctx.db.Write(expctx.cache.eLink);
|
||||||
|
// if an eLink has been generated, skip following pLink generation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to generate pLink
|
||||||
|
for (int j = 0, j_count = analysed->GetDestinationCount(); j < j_count; j++) {
|
||||||
|
CKParameter* dest = analysed->GetDestination(j);
|
||||||
|
|
||||||
|
expctx.cache.pLink.input = analysed->GetID();
|
||||||
|
expctx.cache.pLink.input_obj = parent;
|
||||||
|
expctx.cache.pLink.input_type = VSW::DataTypes::ParameterLinkIOType::POUT;
|
||||||
|
expctx.cache.pLink.input_is_bb = executed_from_bb;
|
||||||
|
expctx.cache.pLink.input_index = pout_index;
|
||||||
|
|
||||||
|
expctx.cache.pLink.output = dest->GetID();
|
||||||
|
if (dest->GetClassID() == CKCID_PARAMETERLOCAL) {
|
||||||
|
// pLocal
|
||||||
|
expctx.cache.pLink.output_obj = dest->GetID();
|
||||||
|
expctx.cache.pLink.output_type = VSW::DataTypes::ParameterLinkIOType::PLOCAL;
|
||||||
|
expctx.cache.pLink.output_is_bb = false; // discard
|
||||||
|
expctx.cache.pLink.output_index = Utilities::INVALID_INDEX; // discard
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// pOut. It must belong to a graph BB
|
||||||
|
// (pOut can not be shared, and prototype bb or pOper do not have linkable pOut).
|
||||||
|
CKObject* dest_owner = dest->GetOwner();
|
||||||
|
switch (dest_owner->GetClassID()) {
|
||||||
|
case CKCID_BEHAVIOR:
|
||||||
|
{
|
||||||
|
CKBehavior* dest_owner_cast = static_cast<CKBehavior*>(dest_owner);
|
||||||
|
CKParameterOut* dest_cast = static_cast<CKParameterOut*>(dest);
|
||||||
|
expctx.cache.pLink.output_obj = dest_owner->GetID();
|
||||||
|
expctx.cache.pLink.output_type = VSW::DataTypes::ParameterLinkIOType::POUT;
|
||||||
|
expctx.cache.pLink.output_is_bb = true;
|
||||||
|
expctx.cache.pLink.output_index = dest_owner_cast->GetOutputParameterPosition(dest_cast);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CKCID_DATAARRAY:
|
||||||
|
{
|
||||||
|
// CKDataArray, see as virtual BB pLocal shortcut
|
||||||
|
expctx.cache.pLink.output_obj = dest->GetID();
|
||||||
|
expctx.cache.pLink.output_type = VSW::DataTypes::ParameterLinkIOType::PATTR;
|
||||||
|
expctx.cache.pLink.input_is_bb = false; // discard
|
||||||
|
expctx.cache.pLink.input_index = Utilities::INVALID_INDEX; // discard
|
||||||
|
Proc_pAttr(expctx, dest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// CKObject. Because CKDataArray also a CKObject, so we test it above this case statement.
|
||||||
|
// See this as virtual BB pLocal shortcut
|
||||||
|
expctx.cache.pLink.output_obj = dest->GetID();
|
||||||
|
expctx.cache.pLink.output_type = VSW::DataTypes::ParameterLinkIOType::PATTR;
|
||||||
|
expctx.cache.pLink.input_is_bb = false; // discard
|
||||||
|
expctx.cache.pLink.input_index = Utilities::INVALID_INDEX; // discard
|
||||||
|
Proc_pAttr(expctx, dest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup parent and write into database
|
||||||
|
expctx.cache.pLink.parent = grandparent;
|
||||||
|
expctx.db.Write(expctx.cache.pLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_pTarget(ExportContext& expctx, CKParameterIn* ckobj, CK_ID parent, CK_ID grandparent) {
|
||||||
|
expctx.cache.pTarget.thisobj = ckobj->GetID();
|
||||||
|
CP_CKSTR(expctx.cache.pTarget.name, ckobj->GetName());
|
||||||
|
CP_GUID(expctx.cache.pTarget.type, ckobj->GetGUID());
|
||||||
|
expctx.cache.pTarget.parent = parent;
|
||||||
|
expctx.cache.pTarget.direct_source = ckobj->GetDirectSource() ? ckobj->GetDirectSource()->GetID() : Utilities::INVALID_CK_ID;
|
||||||
|
expctx.cache.pTarget.shared_source = ckobj->GetSharedSource() ? ckobj->GetSharedSource()->GetID() : Utilities::INVALID_CK_ID;
|
||||||
|
expctx.db.Write(expctx.cache.pTarget);
|
||||||
|
|
||||||
|
// try to generate pLink and eLink
|
||||||
|
Generate_pLink(expctx, ckobj, parent, grandparent, Utilities::INVALID_INDEX, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_pIn(ExportContext& expctx, CKParameterIn* ckobj, CK_ID parent, CK_ID grandparent, int index, bool executed_from_bb) {
|
||||||
|
expctx.cache.pIn.thisobj = ckobj->GetID();
|
||||||
|
expctx.cache.pIn.index = index;
|
||||||
|
CP_CKSTR(expctx.cache.pIn.name, ckobj->GetName());
|
||||||
|
CP_GUID(expctx.cache.pIn.type, ckobj->GetGUID());
|
||||||
|
expctx.cache.pIn.parent = parent;
|
||||||
|
expctx.cache.pIn.direct_source = ckobj->GetDirectSource() ? ckobj->GetDirectSource()->GetID() : Utilities::INVALID_CK_ID;
|
||||||
|
expctx.cache.pIn.shared_source = ckobj->GetSharedSource() ? ckobj->GetSharedSource()->GetID() : Utilities::INVALID_CK_ID;
|
||||||
|
expctx.db.Write(expctx.cache.pIn);
|
||||||
|
|
||||||
|
// try to generate pLink and eLink
|
||||||
|
Generate_pLink(expctx, ckobj, parent, grandparent, index, executed_from_bb, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_pOut(ExportContext& expctx, CKParameterOut* ckobj, CK_ID parent, CK_ID grandparent, int index, bool executed_from_bb) {
|
||||||
|
expctx.cache.pOut.thisobj = ckobj->GetID();
|
||||||
|
expctx.cache.pOut.index = index;
|
||||||
|
CP_CKSTR(expctx.cache.pOut.name, ckobj->GetName());
|
||||||
|
CP_GUID(expctx.cache.pOut.type, ckobj->GetGUID());
|
||||||
|
expctx.cache.pOut.parent = parent;
|
||||||
|
expctx.db.Write(expctx.cache.pOut);
|
||||||
|
|
||||||
|
// try to generate pLink and eLink
|
||||||
|
Generate_pLink(expctx, ckobj, parent, grandparent, index, executed_from_bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_bIn(ExportContext& expctx, CKBehaviorIO* ckobj, CK_ID parent, int index) {
|
||||||
|
expctx.cache.bIn.thisobj = ckobj->GetID();
|
||||||
|
expctx.cache.bIn.index = index;
|
||||||
|
CP_CKSTR(expctx.cache.bIn.name, ckobj->GetName());
|
||||||
|
expctx.cache.bIn.parent = parent;
|
||||||
|
expctx.db.Write(expctx.cache.bIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_bOut(ExportContext& expctx, CKBehaviorIO* ckobj, CK_ID parent, int index) {
|
||||||
|
expctx.cache.bOut.thisobj = ckobj->GetID();
|
||||||
|
expctx.cache.bOut.index = index;
|
||||||
|
CP_CKSTR(expctx.cache.bOut.name, ckobj->GetName());
|
||||||
|
expctx.cache.bOut.parent = parent;
|
||||||
|
expctx.db.Write(expctx.cache.bOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_bLink(ExportContext& expctx, CKBehaviorLink* ckobj, CK_ID parent) {
|
||||||
|
// setup start terminal
|
||||||
|
CKBehaviorIO* io = ckobj->GetInBehaviorIO();
|
||||||
|
CKBehavior* beh = io->GetOwner();
|
||||||
|
expctx.cache.bLink.input = io->GetID();
|
||||||
|
expctx.cache.bLink.input_obj = beh->GetID();
|
||||||
|
expctx.cache.bLink.input_type = (io->GetType() == CK_BEHAVIORIO_IN ? VSW::DataTypes::BehaviorLinkIOType::INPUT : VSW::DataTypes::BehaviorLinkIOType::OUTPUT);
|
||||||
|
expctx.cache.bLink.input_index = (io->GetType() == CK_BEHAVIORIO_IN ? io->GetOwner()->GetInputPosition(io) : io->GetOwner()->GetOutputPosition(io));
|
||||||
|
// setup end terminal
|
||||||
|
io = ckobj->GetOutBehaviorIO();
|
||||||
|
beh = io->GetOwner();
|
||||||
|
expctx.cache.bLink.output = io->GetID();
|
||||||
|
expctx.cache.bLink.output_obj = beh->GetID();
|
||||||
|
expctx.cache.bLink.output_type = (io->GetType() == CK_BEHAVIORIO_IN ? VSW::DataTypes::BehaviorLinkIOType::INPUT : VSW::DataTypes::BehaviorLinkIOType::OUTPUT);
|
||||||
|
expctx.cache.bLink.output_index = (io->GetType() == CK_BEHAVIORIO_IN ? io->GetOwner()->GetInputPosition(io) : io->GetOwner()->GetOutputPosition(io));
|
||||||
|
// other properties
|
||||||
|
expctx.cache.bLink.delay = ckobj->GetActivationDelay();
|
||||||
|
expctx.cache.bLink.parent = parent;
|
||||||
|
// write to database
|
||||||
|
expctx.db.Write(expctx.cache.bLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_pLocal(ExportContext& expctx, CKParameterLocal* ckobj, CK_ID parent, bool is_setting) {
|
||||||
|
expctx.cache.pLocal.thisobj = ckobj->GetID();
|
||||||
|
CP_CKSTR(expctx.cache.pLocal.name, ckobj->GetName());
|
||||||
|
CP_GUID(expctx.cache.pLocal.type, ckobj->GetGUID());
|
||||||
|
expctx.cache.pLocal.is_setting = is_setting;
|
||||||
|
expctx.cache.pLocal.parent = parent;
|
||||||
|
expctx.db.Write(expctx.cache.pLocal);
|
||||||
|
|
||||||
|
// Export pLocal internal data
|
||||||
|
DigParameterData(expctx, ckobj, ckobj->GetID());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Proc_pOper(ExportContext& expctx, CKParameterOperation* ckobj, CK_ID parent) {
|
||||||
|
expctx.cache.pOper.thisobj = ckobj->GetID();
|
||||||
|
CP_GUID(expctx.cache.pOper.op, ckobj->GetOperationGuid());
|
||||||
|
expctx.cache.pOper.parent = parent;
|
||||||
|
expctx.db.Write(expctx.cache.pOper);
|
||||||
|
|
||||||
|
// Process associated 2 pIn and 1 pOut
|
||||||
|
Proc_pIn(expctx, ckobj->GetInParameter1(), ckobj->GetID(), parent, 0, false);
|
||||||
|
Proc_pIn(expctx, ckobj->GetInParameter2(), ckobj->GetID(), parent, 1, false);
|
||||||
|
Proc_pOut(expctx, ckobj->GetOutParameter(), ckobj->GetID(), parent, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process CKBehavior
|
||||||
|
* @param[in] expctx Reference to export context.
|
||||||
|
* @param[in] behavior Pointer to CKBehavior for processing.
|
||||||
|
* @param[in] parent The parent of this CKBehavior. Set to \c INVALID_CK_ID if it was called from script iterator.
|
||||||
|
*/
|
||||||
|
static void Proc_Behavior(ExportContext& expctx, CKBehavior* behavior, CK_ID parent) {
|
||||||
|
// Write basic behavior infomation
|
||||||
|
expctx.cache.behavior.thisobj = behavior->GetID();
|
||||||
|
CP_CKSTR(expctx.cache.behavior.name, behavior->GetName());
|
||||||
|
expctx.cache.behavior.type = behavior->GetType();
|
||||||
|
CP_CKSTR(expctx.cache.behavior.proto_name, behavior->GetPrototypeName());
|
||||||
|
CP_GUID(expctx.cache.behavior.proto_guid, behavior->GetPrototypeGuid());
|
||||||
|
expctx.cache.behavior.flags = behavior->GetFlags();
|
||||||
|
expctx.cache.behavior.priority = behavior->GetPriority();
|
||||||
|
expctx.cache.behavior.version = behavior->GetVersion();
|
||||||
|
expctx.cache.behavior.pin_count_ptarget = (behavior->IsUsingTarget() ? 1 : 0);
|
||||||
|
expctx.cache.behavior.pin_count_pin = behavior->GetInputParameterCount();
|
||||||
|
expctx.cache.behavior.pin_count_pout = behavior->GetOutputParameterCount();
|
||||||
|
expctx.cache.behavior.pin_count_bin = behavior->GetInputCount();
|
||||||
|
expctx.cache.behavior.pin_count_bout = behavior->GetOutputCount();
|
||||||
|
expctx.cache.behavior.parent = parent;
|
||||||
|
expctx.db.Write(expctx.cache.behavior);
|
||||||
|
|
||||||
|
// pTarget
|
||||||
|
if (behavior->IsUsingTarget())
|
||||||
|
Proc_pTarget(expctx, behavior->GetTargetParameter(), behavior->GetID(), parent);
|
||||||
|
|
||||||
|
// pIn
|
||||||
|
for (int i = 0, count = behavior->GetInputParameterCount(); i < count; ++i)
|
||||||
|
Proc_pIn(expctx, behavior->GetInputParameter(i), behavior->GetID(), parent, i, true);
|
||||||
|
// pOut
|
||||||
|
for (int i = 0, count = behavior->GetOutputParameterCount(); i < count; ++i)
|
||||||
|
Proc_pOut(expctx, behavior->GetOutputParameter(i), behavior->GetID(), parent, i, true);
|
||||||
|
// bIn
|
||||||
|
for (int i = 0, count = behavior->GetInputCount(); i < count; ++i)
|
||||||
|
Proc_bIn(expctx, behavior->GetInput(i), behavior->GetID(), i);
|
||||||
|
// bOut
|
||||||
|
for (int i = 0, count = behavior->GetOutputCount(); i < count; ++i)
|
||||||
|
Proc_bOut(expctx, behavior->GetOutput(i), behavior->GetID(), i);
|
||||||
|
// bLink
|
||||||
|
for (int i = 0, count = behavior->GetSubBehaviorLinkCount(); i < count; ++i)
|
||||||
|
Proc_bLink(expctx, behavior->GetSubBehaviorLink(i), behavior->GetID());
|
||||||
|
// pLocal
|
||||||
|
for (int i = 0, count = behavior->GetLocalParameterCount(); i < count; ++i)
|
||||||
|
Proc_pLocal(expctx, behavior->GetLocalParameter(i), behavior->GetID(), behavior->IsLocalParameterSetting(i));
|
||||||
|
// pOper
|
||||||
|
for (int i = 0, count = behavior->GetParameterOperationCount(); i < count; ++i)
|
||||||
|
Proc_pOper(expctx, behavior->GetParameterOperation(i), behavior->GetID());
|
||||||
|
|
||||||
|
// Iterate sub behavior
|
||||||
|
for (int i = 0, count = behavior->GetSubBehaviorCount(); i < count; ++i)
|
||||||
|
Proc_Behavior(expctx, behavior->GetSubBehavior(i), behavior->GetID());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IterateScript(ExportContext& expctx) {
|
||||||
|
// Get all CKBeObjects to try to get all scripts,
|
||||||
|
// because only CKBeObject can own script.
|
||||||
|
XObjectPointerArray obj_array = expctx.ctx->GetObjectListByType(CKCID_BEOBJECT, TRUE);
|
||||||
|
int obj_count = obj_array.Size();
|
||||||
|
for (int i = 0; i < obj_count; ++i) {
|
||||||
|
// Get CKBeObject
|
||||||
|
CKBeObject* beobj = static_cast<CKBeObject*>(obj_array.GetObjectA(i));
|
||||||
|
|
||||||
|
// Get script count. If no script, skip this object.
|
||||||
|
int script_count = beobj->GetScriptCount();
|
||||||
|
if (script_count == 0) continue;
|
||||||
|
|
||||||
|
// Iterate binding scripts
|
||||||
|
for (int j = 0; j < script_count; ++j) {
|
||||||
|
// Get associated behavior
|
||||||
|
CKBehavior* behavior = beobj->GetScript(j);
|
||||||
|
// Write to database
|
||||||
|
expctx.cache.script.beobj = beobj->GetID();
|
||||||
|
CP_CKSTR(expctx.cache.script.beobj_name, beobj->GetName());
|
||||||
|
expctx.cache.script.behavior_index = j;
|
||||||
|
expctx.cache.script.behavior = behavior->GetID();
|
||||||
|
expctx.db.Write(expctx.cache.script);
|
||||||
|
|
||||||
|
// Process this script
|
||||||
|
Proc_Behavior(expctx, behavior, Utilities::INVALID_CK_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) {
|
||||||
|
// create export context
|
||||||
|
ExportContext expctx(ctx, db_path, code_page);
|
||||||
|
if (!expctx.db.IsValid()) {
|
||||||
|
expctx.reporter.Err(YYCC_U8("Fail to open database. Export process aborted."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// export script
|
||||||
|
IterateScript(expctx);
|
||||||
|
|
||||||
|
// report success
|
||||||
|
expctx.reporter.EnableBeep();
|
||||||
|
expctx.reporter.Info(YYCC_U8("Exporting script database done."));
|
||||||
|
expctx.reporter.DisableBeep();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,38 @@
|
|||||||
#include "ExportDialog.hpp"
|
#include "ExportDialog.hpp"
|
||||||
|
|
||||||
namespace VSW::Materializer::PluginMain {
|
namespace VSW::Materializer::PluginMain {
|
||||||
|
|
||||||
#ifdef MATERIALIZER_PLUGIN
|
#ifdef MATERIALIZER_PLUGIN
|
||||||
|
|
||||||
|
#pragma region Export Dialog Setting
|
||||||
|
|
||||||
|
ConfigManager::ConfigManager() :
|
||||||
|
m_LastFilePath(YYCC_U8("last-file-path"), YYCC_U8("")),
|
||||||
|
m_Encoding(YYCC_U8("encoding"), CP_ACP),
|
||||||
|
m_Mgr(ConfigManager::GetConfigFilePath(), UINT64_C(0), {
|
||||||
|
&m_LastFilePath, &m_Encoding
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
ConfigManager::~ConfigManager() {}
|
||||||
|
|
||||||
|
ConfigManager& ConfigManager::GetSingleton() {
|
||||||
|
static ConfigManager g_Singleton;
|
||||||
|
return g_Singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
YYCC::yycc_u8string ConfigManager::GetConfigFilePath() {
|
||||||
|
// get path to executable virtools
|
||||||
|
YYCC::yycc_u8string u8_virtools_path;
|
||||||
|
if (!YYCC::WinFctHelper::GetModuleFileName(NULL, u8_virtools_path))
|
||||||
|
u8_virtools_path.clear();
|
||||||
|
// get its parent folder and append with cfg file name
|
||||||
|
std::filesystem::path virtools_path(YYCC::StdPatch::ToStdPath(u8_virtools_path));
|
||||||
|
return YYCC::StdPatch::ToUTF8Path(virtools_path.parent_path() / YYCC::StdPatch::ToStdPath(YYCC_U8("vsw_materializer.cfg")));
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
PluginInterface* g_Plugininterface = nullptr;
|
PluginInterface* g_Plugininterface = nullptr;
|
||||||
PluginInfo g_PluginInfo;
|
PluginInfo g_PluginInfo;
|
||||||
CMenu* g_MainMenu = nullptr;
|
CMenu* g_MainMenu = nullptr;
|
||||||
@@ -49,7 +78,7 @@ namespace VSW::Materializer::PluginMain {
|
|||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
const wchar_t* body =
|
const wchar_t* body =
|
||||||
L"VSW Materializer v2.0.0 - Virtools Schematic Weaver Materializer.\n"
|
L"VSW Materializer v2.0.0 - Virtools Schematic Weaver Materializer.\n"
|
||||||
L"The exporter of universal Virtools scripts analyser.\n"
|
L"The exporter of universal Virtools scripts analyser.\n"
|
||||||
L"Under GPL v3 License.\n"
|
L"Under GPL v3 License.\n"
|
||||||
|
|||||||
@@ -4,9 +4,25 @@
|
|||||||
namespace VSW::Materializer::PluginMain {
|
namespace VSW::Materializer::PluginMain {
|
||||||
|
|
||||||
#ifdef MATERIALIZER_PLUGIN
|
#ifdef MATERIALIZER_PLUGIN
|
||||||
|
|
||||||
|
class ConfigManager {
|
||||||
|
public:
|
||||||
|
static ConfigManager& GetSingleton();
|
||||||
|
private:
|
||||||
|
static YYCC::yycc_u8string GetConfigFilePath();
|
||||||
|
ConfigManager();
|
||||||
|
~ConfigManager();
|
||||||
|
|
||||||
|
public:
|
||||||
|
YYCC::ConfigManager::StringSetting m_LastFilePath;
|
||||||
|
YYCC::ConfigManager::NumberSetting<UINT> m_Encoding;
|
||||||
|
YYCC::ConfigManager::CoreManager m_Mgr;
|
||||||
|
};
|
||||||
|
|
||||||
void InitializePluginInfo();
|
void InitializePluginInfo();
|
||||||
PluginInfo* GetPluginInfo();
|
PluginInfo* GetPluginInfo();
|
||||||
PluginInterface* GetPluginInterface();
|
PluginInterface* GetPluginInterface();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,86 +1,260 @@
|
|||||||
#include "StandaloneMain.hpp"
|
#include "StandaloneMain.hpp"
|
||||||
|
#include "ExportCore.hpp"
|
||||||
|
#include "GenericHelper.hpp"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace VSW::Materializer::StandaloneMain {
|
namespace VSW::Materializer::StandaloneMain {
|
||||||
|
|
||||||
#ifdef MATERIALIZER_STANDALONE
|
#ifdef MATERIALIZER_STANDALONE
|
||||||
|
|
||||||
|
#pragma region Program Command Line Parser
|
||||||
|
|
||||||
|
struct CmdArguments {
|
||||||
|
CmdArguments() :
|
||||||
|
m_InputFilePath(),
|
||||||
|
m_ScriptDbPath(), m_DocumentDbPath(), m_EnvironmentDbPath(),
|
||||||
|
m_CodePage(CP_ACP) {}
|
||||||
|
YYCC::yycc_u8string m_InputFilePath;
|
||||||
|
YYCC::yycc_u8string m_ScriptDbPath, m_DocumentDbPath, m_EnvironmentDbPath;
|
||||||
|
UINT m_CodePage;
|
||||||
|
};
|
||||||
|
static YYCC::Constraints::Constraint<UINT> GetCodePageConstraint() {
|
||||||
|
return YYCC::Constraints::Constraint<UINT> {
|
||||||
|
[](const UINT& val) -> bool {
|
||||||
|
return YYCC::WinFctHelper::IsValidCodePage(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
class CmdParser {
|
||||||
|
public:
|
||||||
|
CmdParser() :
|
||||||
|
m_InputFilePath(YYCC_U8("input"), YYCC_U8_CHAR('i'), YYCC_U8("The path to Virtools file for exporting."), YYCC_U8("example.cmo"), true),
|
||||||
|
m_ScriptDbPath(YYCC_U8("script"), YYCC_U8_CHAR('s'), YYCC_U8("The path to exported script database. Input file is required."), YYCC_U8("script.db"), true),
|
||||||
|
m_DocumentDbPath(YYCC_U8("document"), YYCC_U8_CHAR('d'), YYCC_U8("The path to exported document database. Input file is required."), YYCC_U8("doc.db"), true),
|
||||||
|
m_EnvironmentDbPath(YYCC_U8("environment"), YYCC_U8_CHAR('e'), YYCC_U8("The path to exported environment database. Input file is not required."), YYCC_U8("env.db"), true),
|
||||||
|
m_CodePage(YYCC_U8("code-page"), YYCC_U8_CHAR('c'), YYCC_U8("The code page used when reading Virtools document."), YYCC_U8("1252"), true, GetCodePageConstraint()),
|
||||||
|
m_Version(YYCC_U8("version"), YYCC_U8_CHAR('v'), YYCC_U8("Print version infomation about this program and exit.")),
|
||||||
|
m_Help(YYCC_U8("help"), YYCC_U8_CHAR('h'), YYCC_U8("Print this help page and exit.")),
|
||||||
|
m_OptionContext(YYCC_U8("Virtools Schematic Weaver - Materializer"), YYCC_U8("The exporter of Virtools Schematic Weaver"), {
|
||||||
|
&m_InputFilePath,
|
||||||
|
&m_ScriptDbPath, &m_DocumentDbPath, &m_EnvironmentDbPath, &m_CodePage,
|
||||||
|
&m_Version, &m_Help
|
||||||
|
}) {}
|
||||||
|
~CmdParser() {}
|
||||||
|
YYCC_DEL_CLS_COPY_MOVE(CmdParser);
|
||||||
|
|
||||||
|
public:
|
||||||
|
YYCC::ArgParser::StringArgument m_InputFilePath;
|
||||||
|
YYCC::ArgParser::StringArgument m_ScriptDbPath;
|
||||||
|
YYCC::ArgParser::StringArgument m_DocumentDbPath;
|
||||||
|
YYCC::ArgParser::StringArgument m_EnvironmentDbPath;
|
||||||
|
YYCC::ArgParser::NumberArgument<UINT> m_CodePage;
|
||||||
|
|
||||||
|
YYCC::ArgParser::SwitchArgument m_Version;
|
||||||
|
YYCC::ArgParser::SwitchArgument m_Help;
|
||||||
|
|
||||||
|
YYCC::ArgParser::OptionContext m_OptionContext;
|
||||||
|
};
|
||||||
|
static bool ParseCmd(int argc, char* argv[], CmdArguments& captured) {
|
||||||
|
// fetch argument list
|
||||||
|
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||||
|
auto al = YYCC::ArgParser::ArgumentList::CreateFromWin32();
|
||||||
|
#else
|
||||||
|
auto al = YYCC::ArgParser::ArgumentList::CreateFromStd(argc, argv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// do parse
|
||||||
|
CmdParser parser;
|
||||||
|
if (!parser.m_OptionContext.Parse(al)) {
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8(YYCC_COLOR_LIGHT_RED("Invalid command line.")));
|
||||||
|
parser.m_OptionContext.Help();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check help command
|
||||||
|
if (parser.m_Help.IsCaptured()) {
|
||||||
|
parser.m_OptionContext.Help();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// check version command
|
||||||
|
if (parser.m_Version.IsCaptured()) {
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8("Virtools Schematic Weaver - Materializer v2.0.0"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check command relation
|
||||||
|
// if specify script or document export, user must provide input file
|
||||||
|
if (parser.m_ScriptDbPath.IsCaptured() || parser.m_DocumentDbPath.IsCaptured()) {
|
||||||
|
if (!parser.m_InputFilePath.IsCaptured()) {
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8(YYCC_COLOR_LIGHT_RED("You must specify one input file if you want to export script or document.")));
|
||||||
|
parser.m_OptionContext.Help();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup argument
|
||||||
|
if (parser.m_InputFilePath.IsCaptured()) captured.m_InputFilePath = parser.m_InputFilePath.Get();
|
||||||
|
else captured.m_InputFilePath.clear();
|
||||||
|
if (parser.m_ScriptDbPath.IsCaptured()) captured.m_ScriptDbPath = parser.m_ScriptDbPath.Get();
|
||||||
|
else captured.m_ScriptDbPath.clear();
|
||||||
|
if (parser.m_DocumentDbPath.IsCaptured()) captured.m_DocumentDbPath = parser.m_DocumentDbPath.Get();
|
||||||
|
else captured.m_DocumentDbPath.clear();
|
||||||
|
if (parser.m_EnvironmentDbPath.IsCaptured()) captured.m_EnvironmentDbPath = parser.m_EnvironmentDbPath.Get();
|
||||||
|
else captured.m_EnvironmentDbPath.clear();
|
||||||
|
if (parser.m_CodePage.IsCaptured()) captured.m_CodePage = parser.m_CodePage.Get();
|
||||||
|
else captured.m_CodePage = CP_ACP;
|
||||||
|
// okey, return
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Assistant Functions
|
||||||
|
|
||||||
|
class TemporaryFile {
|
||||||
|
public:
|
||||||
|
TemporaryFile(CKContext* ctx, const YYCC::yycc_u8string_view& u8_vt_file) :
|
||||||
|
m_IsSuccess(false), m_TempFile() {
|
||||||
|
if (ctx == nullptr) throw std::invalid_argument("Invalid CKContext");
|
||||||
|
if (u8_vt_file.empty()) throw std::invalid_argument("Invalid Virtools file path");
|
||||||
|
|
||||||
|
// build source virtools file
|
||||||
|
auto vt_file = YYCC::StdPatch::ToStdPath(u8_vt_file);
|
||||||
|
|
||||||
|
// build cache path located in Windows temp path and keep its extension
|
||||||
|
YYCC::yycc_u8string u8_temp_dir;
|
||||||
|
if (!YYCC::WinFctHelper::GetTempDirectory(u8_temp_dir))
|
||||||
|
throw std::runtime_error("Fail to fetch Windows Temp directory");
|
||||||
|
auto temp_dir = YYCC::StdPatch::ToStdPath(u8_temp_dir);
|
||||||
|
temp_dir /= YYCC::StdPatch::ToStdPath(YYCC_U8("07159749-81e5-4ec2-b649-87b8eb9c1f5a"));
|
||||||
|
temp_dir.replace_extension(vt_file.extension());
|
||||||
|
m_TempFile = YYCC::StdPatch::ToUTF8Path(temp_dir);
|
||||||
|
|
||||||
|
// copy it to temp directory
|
||||||
|
if (!YYCC::WinFctHelper::CopyFile(u8_vt_file, m_TempFile, FALSE))
|
||||||
|
throw std::runtime_error("Fail to copy file.");
|
||||||
|
|
||||||
|
// okey
|
||||||
|
m_IsSuccess = true;
|
||||||
|
}
|
||||||
|
~TemporaryFile() {
|
||||||
|
if (m_IsSuccess) {
|
||||||
|
std::wstring w_temp_file;
|
||||||
|
if (!YYCC::EncodingHelper::UTF8ToWchar(m_TempFile, w_temp_file)) return;
|
||||||
|
::DeleteFileW(w_temp_file.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TemporaryFile(TemporaryFile&& rhs) :
|
||||||
|
m_IsSuccess(rhs.m_IsSuccess), m_TempFile(rhs.m_TempFile) {
|
||||||
|
rhs.m_IsSuccess = false;
|
||||||
|
rhs.m_TempFile.clear();
|
||||||
|
}
|
||||||
|
TemporaryFile& operator=(TemporaryFile&& rhs) {
|
||||||
|
this->m_IsSuccess = rhs.m_IsSuccess;
|
||||||
|
this->m_TempFile = rhs.m_TempFile;
|
||||||
|
rhs.m_IsSuccess = false;
|
||||||
|
rhs.m_TempFile.clear();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
YYCC_DEL_CLS_COPY(TemporaryFile);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool IsSuccess() const { return m_IsSuccess; }
|
||||||
|
const YYCC::yycc_u8string& GetPath() const { return m_TempFile; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_IsSuccess;
|
||||||
|
YYCC::yycc_u8string m_TempFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void CustomAssert(VSW::Reporter& reporter, bool condition, const YYCC::yycc_char8_t* msg) {
|
||||||
|
if (!condition) {
|
||||||
|
if (msg != nullptr)
|
||||||
|
reporter.Err(msg);
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#define CUSTOM_ASSERT(condition, msg) CustomAssert(reporter, (condition), YYCC_U8(msg))
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
void PlayerMain(int argc, char* argv[]) {
|
void PlayerMain(int argc, char* argv[]) {
|
||||||
printf("Super Script Materializer\n");
|
// ========== Check Passed Arguments ==========
|
||||||
printf("Homepage: https://github.com/yyc12345/SuperScriptMaterializer\n");
|
CmdArguments captured;
|
||||||
printf("Report bug: https://github.com/yyc12345/SuperScriptMaterializer/issues\n");
|
if (!ParseCmd(argc, argv, captured)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// ====================== Init ck2 engine
|
// ========== Print Header ==========
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8("Virtools Schematic Weaver - Materializer"));
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8("Homepage: https://github.com/yyc12345/SuperScriptMaterializer"));
|
||||||
|
YYCC::ConsoleHelper::WriteLine(YYCC_U8("Report bug: https://github.com/yyc12345/SuperScriptMaterializer/issues"));
|
||||||
|
|
||||||
|
// ========== Init CK2 Engine ==========
|
||||||
|
// Prepare reporter
|
||||||
|
VSW::Reporter reporter;
|
||||||
|
|
||||||
|
CUSTOM_ASSERT(CKStartUp() == CK_OK, "CKStartUp() Error");
|
||||||
|
CKPluginManager* plugin_mgr = CKGetPluginManager();
|
||||||
|
CUSTOM_ASSERT(plugin_mgr != nullptr, "CKPluginManager is nullptr");
|
||||||
|
CUSTOM_ASSERT(plugin_mgr->ParsePlugins("RenderEngines") > 0, "Error loading RenderEngines");
|
||||||
|
CUSTOM_ASSERT(plugin_mgr->ParsePlugins("Managers") > 0, "Error loading Managers");
|
||||||
|
CUSTOM_ASSERT(plugin_mgr->ParsePlugins("BuildingBlocks") > 0, "Error loading BuildingBlocks");
|
||||||
|
CUSTOM_ASSERT(plugin_mgr->ParsePlugins("Plugins") > 0, "Error loading Plugins");
|
||||||
|
|
||||||
|
// ========== Create CKContext ==========
|
||||||
|
CKContext* ctx = nullptr;
|
||||||
#if defined(VIRTOOLS_21)
|
#if defined(VIRTOOLS_21)
|
||||||
CommonAssert(LoadLibrary("CK2.dll") != NULL, "Error loading CK2.dll");
|
CUSTOM_ASSERT(CKCreateContext(&ctx, NULL, 0, 0) == CK_OK, "CKCreateContext Error");
|
||||||
|
#else
|
||||||
|
CUSTOM_ASSERT(CKCreateContext(&ctx, NULL) == CK_OK, "CKCreateContext Error");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CommonAssert(!CKStartUp(), "CKStartUp Error");
|
// ========== Load File ==========
|
||||||
CKPluginManager* pluginManager = CKGetPluginManager();
|
std::optional<TemporaryFile> loaded_file;
|
||||||
CommonAssert(pluginManager != NULL, "PluginManager = null");
|
CKObjectArray* loaded_file_objs = CreateCKObjectArray();
|
||||||
CommonAssert(pluginManager->ParsePlugins("RenderEngines") > 0, "Error loading RenderEngines");
|
if (!captured.m_InputFilePath.empty()) {
|
||||||
CommonAssert(pluginManager->ParsePlugins("Managers") > 0, "Error loading Managers");
|
TemporaryFile cache(ctx, captured.m_InputFilePath);
|
||||||
CommonAssert(pluginManager->ParsePlugins("BuildingBlocks") > 0, "Error loading BuildingBlocks");
|
if (cache.IsSuccess()) {
|
||||||
CommonAssert(pluginManager->ParsePlugins("Plugins") > 0, "Error loading Plugins");
|
std::string temp_file;
|
||||||
|
if (YYCC::EncodingHelper::UTF8ToChar(cache.GetPath(), temp_file, CP_ACP)) {
|
||||||
|
if (ctx->Load(const_cast<CKSTRING>(temp_file.c_str()), loaded_file_objs) == CK_OK) {
|
||||||
|
loaded_file = std::move(cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CUSTOM_ASSERT(loaded_file.has_value(), "Fail to open specified file.");
|
||||||
|
}
|
||||||
|
|
||||||
// ====================== create context and load file
|
// ========== Export Data ==========
|
||||||
CKContext* context = NULL;
|
if (!captured.m_ScriptDbPath.empty()) {
|
||||||
CommonAssert(!CKCreateContext(&context, NULL), "CKCreateContext Error");
|
reporter.Info(YYCC_U8("Exporting script database..."));
|
||||||
|
ExportScript::Export(ctx, captured.m_ScriptDbPath, captured.m_CodePage);
|
||||||
|
}
|
||||||
|
if (!captured.m_DocumentDbPath.empty()) {
|
||||||
|
reporter.Info(YYCC_U8("Exporting document database..."));
|
||||||
|
ExportDocument::Export(ctx, captured.m_DocumentDbPath, captured.m_CodePage);
|
||||||
|
}
|
||||||
|
if (!captured.m_EnvironmentDbPath.empty()) {
|
||||||
|
reporter.Info(YYCC_U8("Exporting environment database..."));
|
||||||
|
ExportEnvironment::Export(ctx, captured.m_EnvironmentDbPath, captured.m_CodePage);
|
||||||
|
}
|
||||||
|
|
||||||
CKObjectArray* array = CreateCKObjectArray();
|
// ========== Unload File and Clear CKContext ==========
|
||||||
CommonAssert(!context->Load((char*)virtools_composition, array), "CKContext->Load() Error");
|
DeleteCKObjectArray(loaded_file_objs);
|
||||||
|
loaded_file.reset();
|
||||||
|
ctx->Reset();
|
||||||
|
ctx->ClearAll();
|
||||||
|
|
||||||
printf("Parsing %s...\n", virtools_composition);
|
// ========== Destroy CKContext ==========
|
||||||
|
// todo: Virtools 4.0 standalone version throw exception in there, but i don't know why
|
||||||
// ====================== do SSMaterializerDatabase export
|
|
||||||
// define and Init
|
|
||||||
scriptDatabase* _script_db = new scriptDatabase();
|
|
||||||
dbScriptDataStructHelper* _script_helper = new dbScriptDataStructHelper();
|
|
||||||
envDatabase* _env_db = new envDatabase();
|
|
||||||
dbEnvDataStructHelper* _env_helper = new dbEnvDataStructHelper();
|
|
||||||
|
|
||||||
DeleteFile(script_db_path);
|
|
||||||
DeleteFile(env_db_path);
|
|
||||||
_script_db->open(script_db_path);
|
|
||||||
_script_helper->init(context->GetParameterManager());
|
|
||||||
_env_db->open(env_db_path);
|
|
||||||
_env_helper->init();
|
|
||||||
|
|
||||||
// export
|
|
||||||
IterateScript(context, _script_db, _script_helper);
|
|
||||||
|
|
||||||
IterateParameterOperation(context->GetParameterManager(), _env_db, _env_helper);
|
|
||||||
IterateParameter(context->GetParameterManager(), _env_db, _env_helper);
|
|
||||||
IterateMessage(context->GetMessageManager(), _env_db, _env_helper);
|
|
||||||
IterateAttribute(context->GetAttributeManager(), _env_db, _env_helper);
|
|
||||||
IteratePlugin(CKGetPluginManager(), _env_db, _env_helper);
|
|
||||||
#if !defined(VIRTOOLS_21)
|
|
||||||
IterateVariable(context->GetVariableManager(), _env_db, _env_helper);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// free
|
|
||||||
_script_helper->dispose();
|
|
||||||
_script_db->close();
|
|
||||||
_env_helper->dispose();
|
|
||||||
_env_db->close();
|
|
||||||
delete _script_helper;
|
|
||||||
delete _script_db;
|
|
||||||
delete _env_helper;
|
|
||||||
delete _env_db;
|
|
||||||
|
|
||||||
printf("Done!");
|
|
||||||
|
|
||||||
// ====================== free resources and shutdown engine
|
|
||||||
DeleteCKObjectArray(array);
|
|
||||||
context->Reset();
|
|
||||||
context->ClearAll();
|
|
||||||
|
|
||||||
// todo: Virtools 4.0 standalone version throw exception in there, but i don't knwo why
|
|
||||||
// but it doesn't affect SSMaterializerDatabase export, perhaps
|
// but it doesn't affect SSMaterializerDatabase export, perhaps
|
||||||
CKCloseContext(context);
|
CKCloseContext(ctx);
|
||||||
|
|
||||||
|
// ========== Shutdown CK2 Engine ==========
|
||||||
CKShutdown();
|
CKShutdown();
|
||||||
|
|
||||||
// todo: Virtools 2.5 standalone version throw exception in there, but i don't knwo why
|
// todo: Virtools 2.5 standalone version throw exception in there, but i don't know why
|
||||||
// but it doesn't affect SSMaterializerDatabase export, perhaps
|
// but it doesn't affect SSMaterializerDatabase export, perhaps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,103 @@
|
|||||||
|
|
||||||
namespace VSW::Materializer::Utilities {
|
namespace VSW::Materializer::Utilities {
|
||||||
|
|
||||||
std::string RelativeAddress(const void* absolute_addr) {
|
#pragma region Enhanced Reporter
|
||||||
// prepare return value
|
|
||||||
std::string ret("<error>");
|
|
||||||
|
|
||||||
|
EnhancedReporter::EnhancedReporter(CKContext* ctx) :
|
||||||
|
m_Ctx(ctx), m_OrderBeep(false) {}
|
||||||
|
|
||||||
|
EnhancedReporter::~EnhancedReporter() {}
|
||||||
|
|
||||||
|
void EnhancedReporter::EnableBeep() { m_OrderBeep = true; }
|
||||||
|
|
||||||
|
void EnhancedReporter::DisableBeep() { m_OrderBeep = false; }
|
||||||
|
|
||||||
|
void EnhancedReporter::PrePrint(const YYCC::yycc_char8_t* strl) const {
|
||||||
|
// only write when CKContext is not nullptr and we are in Interface Mode (Dev mode).
|
||||||
|
if (m_Ctx != nullptr && m_Ctx->IsInInterfaceMode())
|
||||||
|
m_Ctx->OutputToConsole(const_cast<CKSTRING>(YYCC::EncodingHelper::UTF8ToChar(strl, CP_ACP).c_str()), m_OrderBeep);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Curve 2D Builder
|
||||||
|
|
||||||
|
Curve2DBuilder::Curve2DBuilder(CK2dCurve* curve_2d) : m_Cache() {
|
||||||
|
BuildCurve(curve_2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
Curve2DBuilder::~Curve2DBuilder() {}
|
||||||
|
|
||||||
|
const void* Curve2DBuilder::GetDataPtr() const { return m_Cache.c_str(); }
|
||||||
|
size_t Curve2DBuilder::GetDataLength() const { return m_Cache.size(); }
|
||||||
|
|
||||||
|
void Curve2DBuilder::BuildCurve(CK2dCurve* c) {
|
||||||
|
// check curve
|
||||||
|
if (c == nullptr) return;
|
||||||
|
// get curve control point count
|
||||||
|
int cp_count = c->GetControlPointCount();
|
||||||
|
// reserve enough space
|
||||||
|
// count * (x + y + is_linear + is_tcb + (io_tangent_tuple / tcb_tuple))
|
||||||
|
m_Cache.reserve(static_cast<size_t>(cp_count) * (sizeof(float) * 2u + sizeof(float) * 4u + sizeof(uint32_t) + sizeof(uint32_t)));
|
||||||
|
|
||||||
|
// iterate control point
|
||||||
|
for (int i = 0; i < cp_count; ++i) {
|
||||||
|
BuildCurvePoint(c->GetControlPoint(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Curve2DBuilder::BuildCurvePoint(CK2dCurvePoint* cp) {
|
||||||
|
// check control point
|
||||||
|
if (cp == nullptr) return;
|
||||||
|
// prepare variable
|
||||||
|
uint32_t int_cache;
|
||||||
|
Vx2DVector vector_cache;
|
||||||
|
float float_cache;
|
||||||
|
|
||||||
|
#define APPEND_DATA(data) m_Cache.append(reinterpret_cast<decltype(m_Cache)::value_type*>(&data), sizeof(data))
|
||||||
|
|
||||||
|
// x y value
|
||||||
|
vector_cache = cp->GetPosition();
|
||||||
|
APPEND_DATA(vector_cache);
|
||||||
|
|
||||||
|
// is linear
|
||||||
|
int_cache = static_cast<uint32_t>(cp->IsLinear());
|
||||||
|
APPEND_DATA(int_cache);
|
||||||
|
// is tcb
|
||||||
|
int_cache = static_cast<uint32_t>(cp->IsTCB());
|
||||||
|
APPEND_DATA(int_cache);
|
||||||
|
|
||||||
|
if (cp->IsTCB()) {
|
||||||
|
// TCB control point
|
||||||
|
float_cache = cp->GetTension();
|
||||||
|
APPEND_DATA(float_cache);
|
||||||
|
float_cache = cp->GetContinuity();
|
||||||
|
APPEND_DATA(float_cache);
|
||||||
|
float_cache = cp->GetBias();
|
||||||
|
APPEND_DATA(float_cache);
|
||||||
|
// To keep balance with non-TCB control point,
|
||||||
|
// We add a blank 0.0f in there
|
||||||
|
float_cache = 0.0f;
|
||||||
|
APPEND_DATA(float_cache);
|
||||||
|
} else {
|
||||||
|
// non-TCB control point
|
||||||
|
vector_cache = cp->GetInTangent();
|
||||||
|
APPEND_DATA(vector_cache);
|
||||||
|
vector_cache = cp->GetOutTangent();
|
||||||
|
APPEND_DATA(vector_cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef APPEND_DATA
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
void RelativeAddress(const EnhancedReporter& reporter, YYCC::yycc_u8string& relative_addr_str, const void* absolute_addr) {
|
||||||
// If address is nullptr, return directly
|
// If address is nullptr, return directly
|
||||||
if (absolute_addr == nullptr) {
|
if (absolute_addr == nullptr) {
|
||||||
ret = "<nullptr>";
|
relative_addr_str = YYCC_U8("<nullptr>");
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the module handle which given function address belongs to
|
// Get the module handle which given function address belongs to
|
||||||
@@ -19,16 +108,22 @@ namespace VSW::Materializer::Utilities {
|
|||||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, // get address and do not inc ref counter.
|
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, // get address and do not inc ref counter.
|
||||||
(LPCWSTR)absolute_addr,
|
(LPCWSTR)absolute_addr,
|
||||||
&hModule);
|
&hModule);
|
||||||
if (hModule == NULL)
|
if (hModule == NULL) {
|
||||||
return ret;
|
reporter.ErrF(YYCC_U8("Fail to get module of given absolute address 0x%" PRI_XPTR_LEFT_PADDING PRIXPTR ". Some relative address may be empty."), absolute_addr);
|
||||||
|
relative_addr_str.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get full path to module
|
// Get full path to module
|
||||||
YYCC::yycc_u8string u8_module_path;
|
YYCC::yycc_u8string u8_module_path;
|
||||||
if (!YYCC::WinFctHelper::GetModuleFileName(hModule, u8_module_path))
|
if (!YYCC::WinFctHelper::GetModuleFileName(hModule, u8_module_path)) {
|
||||||
return ret;
|
reporter.ErrF(YYCC_U8("Fail to get file name of given module 0x%" PRI_XPTR_LEFT_PADDING PRIXPTR ". Some relative address may be empty."), hModule);
|
||||||
|
relative_addr_str.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Then get its file name part
|
// Then get its file name part
|
||||||
auto module_path = YYCC::FsPathPatch::FromUTF8Path(u8_module_path.c_str());
|
auto module_path = YYCC::StdPatch::ToStdPath(u8_module_path);
|
||||||
auto u8_module_name = YYCC::FsPathPatch::ToUTF8Path(module_path.filename());
|
auto u8_module_name = YYCC::StdPatch::ToUTF8Path(module_path.filename());
|
||||||
|
|
||||||
// Get the base address of current module
|
// Get the base address of current module
|
||||||
// HMODULE is the base address of loaded module
|
// HMODULE is the base address of loaded module
|
||||||
@@ -36,42 +131,74 @@ namespace VSW::Materializer::Utilities {
|
|||||||
uintptr_t relative_addr = reinterpret_cast<uintptr_t>(absolute_addr) - reinterpret_cast<uintptr_t>(hModule);
|
uintptr_t relative_addr = reinterpret_cast<uintptr_t>(absolute_addr) - reinterpret_cast<uintptr_t>(hModule);
|
||||||
|
|
||||||
// get final result
|
// get final result
|
||||||
auto u8_ret = YYCC::StringHelper::Printf(YYCC_U8("%s+0x%" PRI_XPTR_LEFT_PADDING PRIXPTR), u8_module_name.c_str(), relative_addr);
|
if (!YYCC::StringHelper::Printf(relative_addr_str, YYCC_U8("%s+0x%" PRI_XPTR_LEFT_PADDING PRIXPTR), u8_module_name.c_str(), relative_addr)) {
|
||||||
ret = YYCC::EncodingHelper::ToOrdinaryView(u8_ret);
|
reporter.Err(YYCC_U8("Fail to format relative address. Some relative address may be empty."));
|
||||||
return ret;
|
relative_addr_str.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//void CopyStrGuid(std::string& dst, const CKGUID& src) {
|
//void GetBase64(YYCC::yycc_u8string& dst, const char* data, size_t data_len) {
|
||||||
// auto ret = YYCC::StringHelper::Printf(YYCC_U8("<0x%08" PRIX32 ", 0x%08" PRIX32 ">"), src.d1, src.d2);
|
// // Reference: https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
|
||||||
// dst = YYCC::EncodingHelper::ToOrdinaryView(ret);
|
// static const YYCC::yycc_char8_t* BASE64_TABLE = YYCC_U8("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
|
||||||
|
// static const int MOD_TABLE[] = { 0, 2, 1 };
|
||||||
|
|
||||||
|
// // compute size
|
||||||
|
// size_t output_length = 4u * ((data_len + 2u) / 3u);
|
||||||
|
// dst.resize(output_length);
|
||||||
|
|
||||||
|
// // compute
|
||||||
|
// for (size_t i = 0, j = 0; i < data_len;) {
|
||||||
|
|
||||||
|
// uint32_t octet_a = i < data_len ? (unsigned char)data[i++] : 0;
|
||||||
|
// uint32_t octet_b = i < data_len ? (unsigned char)data[i++] : 0;
|
||||||
|
// uint32_t octet_c = i < data_len ? (unsigned char)data[i++] : 0;
|
||||||
|
|
||||||
|
// uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
|
||||||
|
|
||||||
|
// dst[j++] = BASE64_TABLE[(triple >> 3 * 6) & 0x3F];
|
||||||
|
// dst[j++] = BASE64_TABLE[(triple >> 2 * 6) & 0x3F];
|
||||||
|
// dst[j++] = BASE64_TABLE[(triple >> 1 * 6) & 0x3F];
|
||||||
|
// dst[j++] = BASE64_TABLE[(triple >> 0 * 6) & 0x3F];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // fill blank
|
||||||
|
// for (int i = 0; i < MOD_TABLE[data_len % 3]; i++)
|
||||||
|
// dst[output_length - 1 - i] = '=';
|
||||||
//}
|
//}
|
||||||
|
|
||||||
void CopyGuid(int64_t& dst, const CKGUID& src) {
|
void CopyStrGuid(const EnhancedReporter& reporter, YYCC::yycc_u8string& dst, const CKGUID& src) {
|
||||||
// todo: use template argument to implement this to improve performance
|
if (!YYCC::StringHelper::Printf(dst, YYCC_U8("<0x%08" PRIX32 ", 0x%08" PRIX32 ">"), src.d1, src.d2)) {
|
||||||
if (sizeof(dst) != sizeof(src))
|
reporter.Err(YYCC_U8("Fail to format CKGUID. Some stringified GUID may be empty."));
|
||||||
throw std::invalid_argument("CKGUID size error");
|
dst.clear();
|
||||||
std::memcpy(&dst, &src, sizeof(int64_t));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyCKString(std::string& storage, const char* str, const char* fallback) {
|
void CopyGuid(int64_t& dst, const CKGUID& src) {
|
||||||
|
// reset dst to zero
|
||||||
|
uint64_t* pdst = reinterpret_cast<uint64_t*>(&dst);
|
||||||
|
// CKGUID.d1 to high 32 bits
|
||||||
|
*pdst = static_cast<uint64_t>(src.d1);
|
||||||
|
*pdst <<= 32u;
|
||||||
|
// CKGUID.d2 to low 32 bits
|
||||||
|
*pdst = (*pdst) | static_cast<uint64_t>(src.d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyCKString(const EnhancedReporter& reporter, YYCC::yycc_u8string& storage, const char* str, UINT code_page, const YYCC::yycc_char8_t* fallback) {
|
||||||
|
// check whether callback is nullptr.
|
||||||
if (fallback == nullptr)
|
if (fallback == nullptr)
|
||||||
throw std::invalid_argument("fallback string should not be nullptr!");
|
throw std::invalid_argument("fallback string should not be nullptr!");
|
||||||
if (str == nullptr) storage = fallback;
|
|
||||||
else storage = str;
|
// if given string is nullptr, use fallback instead
|
||||||
|
if (str == nullptr) {
|
||||||
|
storage = fallback;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise do encoding convertion of original string.
|
||||||
|
if (!YYCC::EncodingHelper::CharToUTF8(str, storage, code_page)) {
|
||||||
|
reporter.Err(YYCC_U8("Fail to convert encoding. Some string may use fallback string accidently."));
|
||||||
|
storage = fallback;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma region Enhanced Reporter
|
|
||||||
|
|
||||||
EnhancedReporter::EnhancedReporter(CKContext* ctx) :
|
|
||||||
m_Ctx(ctx) {}
|
|
||||||
|
|
||||||
EnhancedReporter::~EnhancedReporter() {}
|
|
||||||
|
|
||||||
void EnhancedReporter::PrePrint(const YYCC::yycc_char8_t* strl) {
|
|
||||||
if (m_Ctx != nullptr)
|
|
||||||
m_Ctx->OutputToConsole(const_cast<CKSTRING>(YYCC::EncodingHelper::UTF8ToChar(strl, CP_ACP).c_str()), FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,28 +6,68 @@ namespace VSW::Materializer::Utilities {
|
|||||||
|
|
||||||
/// @brief The value representing a invalid CK_ID.
|
/// @brief The value representing a invalid CK_ID.
|
||||||
constexpr CK_ID INVALID_CK_ID = static_cast<CK_ID>(-1);
|
constexpr CK_ID INVALID_CK_ID = static_cast<CK_ID>(-1);
|
||||||
|
constexpr int INVALID_INDEX = static_cast<int>(-1);
|
||||||
|
constexpr char NULLPTR_CKSTRING[] = "<null>";
|
||||||
|
|
||||||
class EnhancedReporter : public VSW::Reporter {
|
class EnhancedReporter : public VSW::Reporter {
|
||||||
public:
|
public:
|
||||||
EnhancedReporter(CKContext* ctx);
|
EnhancedReporter(CKContext* ctx);
|
||||||
~EnhancedReporter();
|
~EnhancedReporter();
|
||||||
|
|
||||||
|
public:
|
||||||
|
void EnableBeep();
|
||||||
|
void DisableBeep();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void PrePrint(const YYCC::yycc_char8_t* strl) override;
|
virtual void PrePrint(const YYCC::yycc_char8_t* strl) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CKContext* m_Ctx;
|
CKContext* m_Ctx;
|
||||||
|
bool m_OrderBeep;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Curve2DBuilder {
|
||||||
|
public:
|
||||||
|
Curve2DBuilder(CK2dCurve* curve_2d);
|
||||||
|
~Curve2DBuilder();
|
||||||
|
|
||||||
|
public:
|
||||||
|
const void* GetDataPtr() const;
|
||||||
|
size_t GetDataLength() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void BuildCurve(CK2dCurve* c);
|
||||||
|
void BuildCurvePoint(CK2dCurvePoint* cp);
|
||||||
|
std::basic_string<uint8_t> m_Cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get relative address from given absolute address
|
* @brief Get relative address from given absolute address
|
||||||
* @details This function is used when exporting function pointer into database.
|
* @details This function is used when exporting function pointer into database.
|
||||||
|
* @param[out] relative_addr_str
|
||||||
|
* The variable holding relative address result.
|
||||||
|
* The result is module based relative address like \c xxx.dll+0x00000000.
|
||||||
* @param[in] absolute_addr The absolute address
|
* @param[in] absolute_addr The absolute address
|
||||||
* @return Module based relative address like \c xxx.dll+0x00000000.
|
|
||||||
*/
|
*/
|
||||||
std::string RelativeAddress(const void* absolute_addr);
|
void RelativeAddress(const EnhancedReporter& reporter, YYCC::yycc_u8string& relative_addr_str, const void* absolute_addr);
|
||||||
//void CopyStrGuid(std::string& dst, const CKGUID& src);
|
void CopyStrGuid(const EnhancedReporter& reporter, YYCC::yycc_u8string& dst, const CKGUID& src);
|
||||||
void CopyGuid(int64_t& dst, const CKGUID& src);
|
void CopyGuid(int64_t& dst, const CKGUID& src);
|
||||||
void CopyCKString(std::string& storage, const char* str, const char* fallback = "<unamed>");
|
void CopyCKString(
|
||||||
|
const EnhancedReporter& reporter,
|
||||||
|
YYCC::yycc_u8string& storage,
|
||||||
|
const char* str,
|
||||||
|
UINT code_page,
|
||||||
|
const YYCC::yycc_char8_t* fallback = YYCC::EncodingHelper::ToUTF8(NULLPTR_CKSTRING)
|
||||||
|
);
|
||||||
|
|
||||||
|
#pragma region Convenient Macros
|
||||||
|
|
||||||
|
#define CP_ADDR(dst, src) ::VSW::Materializer::Utilities::RelativeAddress(expctx.reporter, (dst), (src))
|
||||||
|
#define CP_STR_GUID(dst, src) ::VSW::Materializer::Utilities::CopyStrGuid(expctx.reporter, (dst), (src))
|
||||||
|
#define CP_GUID(dst, src) ::VSW::Materializer::Utilities::CopyGuid((dst), (src))
|
||||||
|
#define CP_CKSTR(dst, src, ...) ::VSW::Materializer::Utilities::CopyCKString(expctx.reporter, (dst), (src), expctx.cp, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,12 +25,19 @@ public:
|
|||||||
YYCC::ExceptionHelper::Register(vtobjplugin::VirtoolsMenu::UnhandledExceptionCallback);
|
YYCC::ExceptionHelper::Register(vtobjplugin::VirtoolsMenu::UnhandledExceptionCallback);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// load config from file
|
||||||
|
auto& config_manager = VSW::Materializer::PluginMain::ConfigManager::GetSingleton();
|
||||||
|
config_manager.m_Mgr.Load();
|
||||||
|
|
||||||
// init plugin info
|
// init plugin info
|
||||||
VSW::Materializer::PluginMain::InitializePluginInfo();
|
VSW::Materializer::PluginMain::InitializePluginInfo();
|
||||||
|
|
||||||
return CWinApp::InitInstance();
|
return CWinApp::InitInstance();
|
||||||
}
|
}
|
||||||
virtual int ExitInstance() override {
|
virtual int ExitInstance() override {
|
||||||
|
// save config to file
|
||||||
|
auto& config_manager = VSW::Materializer::PluginMain::ConfigManager::GetSingleton();
|
||||||
|
config_manager.m_Mgr.Save();
|
||||||
|
|
||||||
// unregister unhandler exception handler
|
// unregister unhandler exception handler
|
||||||
#ifdef MATERIALIZER_RELEASE
|
#ifdef MATERIALIZER_RELEASE
|
||||||
@@ -45,7 +52,19 @@ CMaterializer theApp;
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
|
// register unhandler exception handler
|
||||||
|
#ifdef MATERIALIZER_RELEASE
|
||||||
|
YYCC::ExceptionHelper::Register(vtobjplugin::VirtoolsMenu::UnhandledExceptionCallback);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Run core code.
|
||||||
VSW::Materializer::StandaloneMain::PlayerMain(argc, argv);
|
VSW::Materializer::StandaloneMain::PlayerMain(argc, argv);
|
||||||
|
|
||||||
|
// unregister unhandler exception handler
|
||||||
|
#ifdef MATERIALIZER_RELEASE
|
||||||
|
YYCC::ExceptionHelper::Unregister();
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
153
script/sqlite_helper.py
Normal file
153
script/sqlite_helper.py
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
import typing
|
||||||
|
import re
|
||||||
|
|
||||||
|
class FieldDecl():
|
||||||
|
c_EnumTuple: typing.ClassVar[tuple[str, ...]] = (
|
||||||
|
'VSW::DataTypes::ParameterLinkIOType',
|
||||||
|
'VSW::DataTypes::BehaviorLinkIOType'
|
||||||
|
)
|
||||||
|
|
||||||
|
m_DeclType: str
|
||||||
|
m_DeclName: str
|
||||||
|
|
||||||
|
def __init__(self, decl_type: str, decl_name: str):
|
||||||
|
self.m_DeclType = decl_type
|
||||||
|
self.m_DeclName = decl_name
|
||||||
|
|
||||||
|
def is_bool(self):
|
||||||
|
return self.m_DeclType == 'bool'
|
||||||
|
|
||||||
|
def is_string(self):
|
||||||
|
return self.m_DeclType == 'YYCC::yycc_u8string'
|
||||||
|
|
||||||
|
def is_blob(self):
|
||||||
|
return self.m_DeclType == 'BlobDescriptor'
|
||||||
|
|
||||||
|
def is_int64(self):
|
||||||
|
return self.m_DeclType == 'int64_t'
|
||||||
|
|
||||||
|
def is_enum(self):
|
||||||
|
return self.m_DeclType in FieldDecl.c_EnumTuple
|
||||||
|
|
||||||
|
class StructDecl():
|
||||||
|
m_StructName: str
|
||||||
|
m_StructFields: tuple[FieldDecl, ...]
|
||||||
|
|
||||||
|
def __init__(self, name: str, fields: tuple[FieldDecl, ...]):
|
||||||
|
self.m_StructName = name
|
||||||
|
self.m_StructFields = fields
|
||||||
|
|
||||||
|
def accept_input() -> str:
|
||||||
|
cache: list[str] = list()
|
||||||
|
blank_line: bool = False
|
||||||
|
|
||||||
|
while True:
|
||||||
|
recv: str = input("> ")
|
||||||
|
if len(recv) == 0:
|
||||||
|
# If double blank line, exit
|
||||||
|
# Otherwise set blank line flag
|
||||||
|
if blank_line: break
|
||||||
|
else: blank_line = True
|
||||||
|
else:
|
||||||
|
# Reset blank line flag
|
||||||
|
blank_line = False
|
||||||
|
cache.append(recv)
|
||||||
|
|
||||||
|
return '\n'.join(cache)
|
||||||
|
|
||||||
|
def analyse_input(val: str) -> tuple[StructDecl, ...]:
|
||||||
|
# result container
|
||||||
|
ret: list[StructDecl] = list()
|
||||||
|
# regex for capturing struct declarations
|
||||||
|
struct_matcher: re.Pattern = re.compile('struct[ \t]+([a-zA-Z0-9_]+)[ \t]+{([^}]*)};')
|
||||||
|
# regex for capturing struct field declarations
|
||||||
|
field_matcher: re.Pattern = re.compile('([a-zA-Z0-9_:]+)[ \t]+([a-zA-Z0-9_]+)[ \t]*;')
|
||||||
|
|
||||||
|
# capture struct declaration part
|
||||||
|
found_match: re.Match
|
||||||
|
for found_match in struct_matcher.finditer(val):
|
||||||
|
# get struct name
|
||||||
|
struct_name: str = found_match.group(1)
|
||||||
|
# analyse struct body
|
||||||
|
struct_body: str = found_match.group(2)
|
||||||
|
struct_fields: list[FieldDecl] = []
|
||||||
|
for ln in struct_body.split('\n'):
|
||||||
|
# Skip annotation
|
||||||
|
ln = ln.strip()
|
||||||
|
if ln.startswith('//'): continue
|
||||||
|
# Check whether it is declaration
|
||||||
|
found_field_match: re.Match = field_matcher.match(ln)
|
||||||
|
if found_field_match is not None:
|
||||||
|
field_decl_type: str = found_field_match.group(1)
|
||||||
|
field_decl_name: str = found_field_match.group(2)
|
||||||
|
struct_fields.append(FieldDecl(field_decl_type, field_decl_name))
|
||||||
|
# add into result
|
||||||
|
ret.append(StructDecl(struct_name, tuple(struct_fields)))
|
||||||
|
|
||||||
|
return tuple(ret)
|
||||||
|
|
||||||
|
def output_result(decls: tuple[StructDecl, ...]) -> None:
|
||||||
|
# assistant function for sql create table statement
|
||||||
|
def conv_sql_create_table(decl_pair: FieldDecl) -> str:
|
||||||
|
if decl_pair.is_string(): return f'[{decl_pair.m_DeclName}] TEXT'
|
||||||
|
elif decl_pair.is_blob(): return f'[{decl_pair.m_DeclName}] BLOB'
|
||||||
|
else: return f'[{decl_pair.m_DeclName}] INTEGER'
|
||||||
|
# assistant function for sql insert statement
|
||||||
|
def conv_sql_insert(decl_pair: FieldDecl) -> str:
|
||||||
|
return '?'
|
||||||
|
# assistant function for c++ bind statement
|
||||||
|
def conv_cpp(decl_pair: FieldDecl) -> str:
|
||||||
|
if decl_pair.is_string():
|
||||||
|
return f'WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.{decl_pair.m_DeclName})));'
|
||||||
|
elif decl_pair.is_int64():
|
||||||
|
return f'WRITER_BIND(sqlite3_bind_int64(WRITER_STMT, WRITER_INDEX, data.{decl_pair.m_DeclName}));'
|
||||||
|
elif decl_pair.is_blob():
|
||||||
|
return f'WRITER_BIND(sqlite3_bind_blob(WRITER_STMT, WRITER_INDEX, REVEAL_BLOB(data.{decl_pair.m_DeclName})));'
|
||||||
|
elif decl_pair.is_enum():
|
||||||
|
return f'WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_ENUM(data.{decl_pair.m_DeclName})));'
|
||||||
|
elif decl_pair.is_bool():
|
||||||
|
return f'WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, REVEAL_BOOL(data.{decl_pair.m_DeclName})));'
|
||||||
|
else:
|
||||||
|
return f'WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.{decl_pair.m_DeclName}));'
|
||||||
|
|
||||||
|
ret_sql_drop_table: list[str] = []
|
||||||
|
ret_sql_create_table: list[str] = []
|
||||||
|
ret_sql_insert: list[str] = []
|
||||||
|
ret_cpp_bind: list[tuple[str, str]] = []
|
||||||
|
for struct_decl in decls:
|
||||||
|
# generate drop table statement
|
||||||
|
gen_statement: str = f'DROP TABLE IF EXISTS [{struct_decl.m_StructName}];'
|
||||||
|
ret_sql_drop_table.append(gen_statement)
|
||||||
|
|
||||||
|
# generate sql create table statement
|
||||||
|
table_string: str = ', '.join(map(conv_sql_create_table, struct_decl.m_StructFields))
|
||||||
|
gen_statement = f'CREATE TABLE [{struct_decl.m_StructName}] ({table_string});'
|
||||||
|
ret_sql_create_table.append(gen_statement)
|
||||||
|
|
||||||
|
# generate sql insert statement
|
||||||
|
table_string = ', '.join(map(conv_sql_insert, struct_decl.m_StructFields))
|
||||||
|
gen_statement = f'INSERT INTO [{struct_decl.m_StructName}] VALUES ({table_string});'
|
||||||
|
ret_sql_insert.append(gen_statement)
|
||||||
|
|
||||||
|
# generate c++ bind statement
|
||||||
|
bind_string: str = '\n'.join(map(conv_cpp, struct_decl.m_StructFields))
|
||||||
|
ret_cpp_bind.append((struct_decl.m_StructName, bind_string))
|
||||||
|
|
||||||
|
print('========== SQL Drop Table ==========')
|
||||||
|
for item in ret_sql_drop_table:
|
||||||
|
print(item)
|
||||||
|
print('========== SQL Create Table ==========')
|
||||||
|
for item in ret_sql_create_table:
|
||||||
|
print(item)
|
||||||
|
print('========== SQL Insert ==========')
|
||||||
|
for item in ret_sql_insert:
|
||||||
|
print(item)
|
||||||
|
print('========== C++ Bind ==========')
|
||||||
|
for name, item in ret_cpp_bind:
|
||||||
|
print(f'===== {name} =====')
|
||||||
|
print(item)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
input_str: str = accept_input()
|
||||||
|
decls: tuple[StructDecl, ...] = analyse_input(input_str)
|
||||||
|
output_result(decls)
|
||||||
@@ -18,7 +18,6 @@ FILES
|
|||||||
target_include_directories(VSWShared
|
target_include_directories(VSWShared
|
||||||
PUBLIC
|
PUBLIC
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
YYCC::YYCCommonplace
|
|
||||||
)
|
)
|
||||||
# Setup linked library
|
# Setup linked library
|
||||||
target_link_libraries(VSWShared
|
target_link_libraries(VSWShared
|
||||||
|
|||||||
@@ -6,32 +6,36 @@ namespace VSW {
|
|||||||
Reporter::Reporter() {}
|
Reporter::Reporter() {}
|
||||||
Reporter::~Reporter() {}
|
Reporter::~Reporter() {}
|
||||||
|
|
||||||
void Reporter::PrePrint(const YYCC::yycc_char8_t* strl) {}
|
void Reporter::PrePrint(const YYCC::yycc_char8_t* strl) const {}
|
||||||
|
|
||||||
#define GENERIC_REPORTER_WRITE(ty, data) YYCC::ConsoleHelper::Write(YYCC_U8("[" #ty "] ")); \
|
#define GENERIC_REPORTER_WRITE(ty, data) YYCC::yycc_u8string cache(YYCC_U8("[" #ty "] ")); \
|
||||||
YYCC::ConsoleHelper::WriteLine(data);
|
cache += data; \
|
||||||
#define GENERIC_REPORTER_FORMAT(ty, data) YYCC::ConsoleHelper::Write(YYCC_U8("[" #ty "] ")); \
|
this->PrePrint(cache.c_str()); \
|
||||||
va_list argptr; \
|
YYCC::ConsoleHelper::WriteLine(cache.c_str());
|
||||||
|
#define GENERIC_REPORTER_FORMAT(ty, data) va_list argptr; \
|
||||||
va_start(argptr, data); \
|
va_start(argptr, data); \
|
||||||
YYCC::ConsoleHelper::WriteLine(YYCC::StringHelper::VPrintf(data, argptr).c_str()); \
|
YYCC::yycc_u8string cache(YYCC::StringHelper::VPrintf(data, argptr)); \
|
||||||
|
cache.insert(0u, YYCC_U8("[" #ty "] ")); \
|
||||||
|
this->PrePrint(cache.c_str()); \
|
||||||
|
YYCC::ConsoleHelper::WriteLine(cache.c_str()); \
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
void Reporter::Err(const YYCC::yycc_char8_t* strl) {
|
void Reporter::Err(const YYCC::yycc_char8_t* strl) const {
|
||||||
GENERIC_REPORTER_WRITE(Error, strl);
|
GENERIC_REPORTER_WRITE(Error, strl);
|
||||||
}
|
}
|
||||||
void Reporter::ErrF(const YYCC::yycc_char8_t* fmt, ...) {
|
void Reporter::ErrF(const YYCC::yycc_char8_t* fmt, ...) const {
|
||||||
GENERIC_REPORTER_FORMAT(Error ,fmt);
|
GENERIC_REPORTER_FORMAT(Error ,fmt);
|
||||||
}
|
}
|
||||||
void Reporter::Warn(const YYCC::yycc_char8_t* strl) {
|
void Reporter::Warn(const YYCC::yycc_char8_t* strl) const {
|
||||||
GENERIC_REPORTER_WRITE(Warning, strl);
|
GENERIC_REPORTER_WRITE(Warning, strl);
|
||||||
}
|
}
|
||||||
void Reporter::WarnF(const YYCC::yycc_char8_t* fmt, ...) {
|
void Reporter::WarnF(const YYCC::yycc_char8_t* fmt, ...) const {
|
||||||
GENERIC_REPORTER_FORMAT(Warning ,fmt);
|
GENERIC_REPORTER_FORMAT(Warning ,fmt);
|
||||||
}
|
}
|
||||||
void Reporter::Info(const YYCC::yycc_char8_t* strl) {
|
void Reporter::Info(const YYCC::yycc_char8_t* strl) const {
|
||||||
GENERIC_REPORTER_WRITE(Info, strl);
|
GENERIC_REPORTER_WRITE(Info, strl);
|
||||||
}
|
}
|
||||||
void Reporter::InfoF(const YYCC::yycc_char8_t* fmt, ...) {
|
void Reporter::InfoF(const YYCC::yycc_char8_t* fmt, ...) const {
|
||||||
GENERIC_REPORTER_FORMAT(Info ,fmt);
|
GENERIC_REPORTER_FORMAT(Info ,fmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,33 +10,32 @@ namespace VSW {
|
|||||||
~Reporter();
|
~Reporter();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void PrePrint(const YYCC::yycc_char8_t* strl);
|
virtual void PrePrint(const YYCC::yycc_char8_t* strl) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Err(const YYCC::yycc_char8_t* strl);
|
void Err(const YYCC::yycc_char8_t* strl) const;
|
||||||
void ErrF(const YYCC::yycc_char8_t* fmt, ...);
|
void ErrF(const YYCC::yycc_char8_t* fmt, ...) const;
|
||||||
void Warn(const YYCC::yycc_char8_t* strl);
|
void Warn(const YYCC::yycc_char8_t* strl) const;
|
||||||
void WarnF(const YYCC::yycc_char8_t* fmt, ...);
|
void WarnF(const YYCC::yycc_char8_t* fmt, ...) const;
|
||||||
void Info(const YYCC::yycc_char8_t* strl);
|
void Info(const YYCC::yycc_char8_t* strl) const;
|
||||||
void InfoF(const YYCC::yycc_char8_t* fmt, ...);
|
void InfoF(const YYCC::yycc_char8_t* fmt, ...) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace DataTypes {
|
namespace DataTypes {
|
||||||
|
|
||||||
enum class BehaviorLinkIOType : int {
|
enum class BehaviorLinkIOType : int {
|
||||||
Input,
|
INPUT, OUTPUT
|
||||||
Output
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ParameterLinkIOType : int {
|
enum class ParameterLinkIOType : int {
|
||||||
ParameterIn,
|
PIN,
|
||||||
ParameterOut,
|
POUT,
|
||||||
/// @brief When using this, ignore [index] and [input_is_bb], set [input_index] to -1
|
/// @brief When using this, ignore [index] and [input_is_bb], set [input_index] to -1
|
||||||
ParameterLocal,
|
PLOCAL,
|
||||||
/// @brief When using this, ignore [index] and [input_is_bb], set [input_index] to -1
|
/// @brief When using this, ignore [index] and [input_is_bb], set [input_index] to -1
|
||||||
ParameterTarget,
|
PTARGET,
|
||||||
/// @brief When using this, ignore [index], and [input_is_bb] will become [input_is_dataarray]
|
/// @brief When using this, ignore [index], and [input_is_bb] will become [input_is_dataarray]
|
||||||
pParameterAttribute
|
PATTR
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user