fix: fix standalone code but not finished

This commit is contained in:
2024-08-11 00:25:08 +08:00
parent 7d9b7f14e8
commit 0e08e518c4
6 changed files with 240 additions and 106 deletions

View File

@@ -1,46 +1,11 @@
#if defined(MATERIALIZER_PLUGIN)
#include "ExportDialog.hpp"
#include "PluginMain.hpp"
#include <stdexcept>
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 {
#define RADIOBTN_GETCHECK(instance) (instance.GetCheck() == BST_CHECKED)
@@ -118,7 +83,7 @@ namespace VSW::Materializer {
CDialogEx::OnInitDialog();
// 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();
if (!u8_last_path.empty()) {
auto last_path = YYCC::FsPathPatch::FromUTF8Path(u8_last_path.c_str());
@@ -158,7 +123,7 @@ namespace VSW::Materializer {
}
// 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_Encoding.Set(m_EncodingResult);

View File

@@ -6,6 +6,35 @@ namespace VSW::Materializer::PluginMain {
#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::FsPathPatch::FromUTF8Path(u8_virtools_path.c_str()));
return YYCC::FsPathPatch::ToUTF8Path(virtools_path.parent_path() / YYCC::FsPathPatch::FromUTF8Path(YYCC_U8("vsw_materializer.cfg")));
}
#pragma endregion
PluginInterface* g_Plugininterface = nullptr;
PluginInfo g_PluginInfo;
CMenu* g_MainMenu = nullptr;

View File

@@ -4,9 +4,25 @@
namespace VSW::Materializer::PluginMain {
#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();
PluginInfo* GetPluginInfo();
PluginInterface* GetPluginInterface();
#endif
}

View File

@@ -1,86 +1,190 @@
#include "StandaloneMain.hpp"
#include "ExportCore.hpp"
#include "GenericHelper.hpp"
namespace VSW::Materializer::StandaloneMain {
#ifdef MATERIALIZER_STANDALONE
void PlayerMain(int argc, char* argv[]) {
printf("Super Script Materializer\n");
printf("Homepage: https://github.com/yyc12345/SuperScriptMaterializer\n");
printf("Report bug: https://github.com/yyc12345/SuperScriptMaterializer/issues\n");
#pragma region Program Command Line Parser
// ====================== Init ck2 engine
#if defined(VIRTOOLS_21)
CommonAssert(LoadLibrary("CK2.dll") != NULL, "Error loading CK2.dll");
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_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
CommonAssert(!CKStartUp(), "CKStartUp Error");
CKPluginManager* pluginManager = CKGetPluginManager();
CommonAssert(pluginManager != NULL, "PluginManager = null");
CommonAssert(pluginManager->ParsePlugins("RenderEngines") > 0, "Error loading RenderEngines");
CommonAssert(pluginManager->ParsePlugins("Managers") > 0, "Error loading Managers");
CommonAssert(pluginManager->ParsePlugins("BuildingBlocks") > 0, "Error loading BuildingBlocks");
CommonAssert(pluginManager->ParsePlugins("Plugins") > 0, "Error loading Plugins");
// 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;
}
// ====================== create context and load file
CKContext* context = NULL;
CommonAssert(!CKCreateContext(&context, NULL), "CKCreateContext Error");
// 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
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[]) {
// ========== Check Passed Arguments ==========
CmdArguments captured;
if (!ParseCmd(argc, argv, captured)) {
return;
}
// ========== 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 and Load File ==========
CKContext* ctx = nullptr;
#if defined(VIRTOOLS_21)
CUSTOM_ASSERT(CKCreateContext(&ctx, NULL, 0, 0) == CK_OK, "CKCreateContext Error");
#else
CUSTOM_ASSERT(CKCreateContext(&ctx, NULL) == CK_OK, "CKCreateContext Error");
#endif
CKObjectArray* array = CreateCKObjectArray();
CommonAssert(!context->Load((char*)virtools_composition, array), "CKContext->Load() Error");
CUSTOM_ASSERT(!ctx->Load((char*)virtools_composition, array), "CKContext::Load() Error");
printf("Parsing %s...\n", virtools_composition);
// ====================== 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!");
// ========== Export Data ==========
if (!captured.m_ScriptDbPath.empty()) {
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);
}
// ====================== free resources and shutdown engine
DeleteCKObjectArray(array);
context->Reset();
context->ClearAll();
ctx->Reset();
ctx->ClearAll();
// todo: Virtools 4.0 standalone version throw exception in there, but i don't knwo why
// ========== Destroy CKContext ==========
// todo: Virtools 4.0 standalone version throw exception in there, but i don't know why
// but it doesn't affect SSMaterializerDatabase export, perhaps
CKCloseContext(context);
CUSTOM_ASSERT(CKCloseContext(ctx) == CK_OK, "CKCloseContext Error.");
CKShutdown();
// ========== Shutdown CK2 Engine ==========
CUSTOM_ASSERT(CKShutdown() == CK_OK, "CKShutdown() Error.");
// 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
}

View File

@@ -14,7 +14,8 @@ namespace VSW::Materializer::Utilities {
void EnhancedReporter::DisableBeep() { m_OrderBeep = false; }
void EnhancedReporter::PrePrint(const YYCC::yycc_char8_t* strl) const {
if (m_Ctx != nullptr)
// 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);
}

View File

@@ -25,12 +25,19 @@ public:
YYCC::ExceptionHelper::Register(vtobjplugin::VirtoolsMenu::UnhandledExceptionCallback);
#endif
// load config from file
auto& config_manager = VSW::Materializer::PluginMain::ConfigManager::GetSingleton();
config_manager.m_Mgr.Load();
// init plugin info
VSW::Materializer::PluginMain::InitializePluginInfo();
return CWinApp::InitInstance();
}
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
#ifdef MATERIALIZER_RELEASE
@@ -45,7 +52,19 @@ CMaterializer theApp;
#else
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);
// unregister unhandler exception handler
#ifdef MATERIALIZER_RELEASE
YYCC::ExceptionHelper::Unregister();
#endif
return 0;
}