24#include "BasicDialog.hpp"
27#include "components/ErrorUtils.hpp"
30std::filesystem::path getSelfPath() {
33 if (GetModuleFileNameA(NULL, path, MAX_PATH) == 0)
return "";
34 return std::filesystem::path(path);
37 ssize_t count = readlink(
"/proc/self/exe", path, PATH_MAX);
38 if (count == -1)
return "";
39 return std::filesystem::path(std::string(path, count));
43void restartApplication(
int argc,
char* argv[]) {
44 vex::log(
">> Restarting Application...");
45 std::filesystem::path exePath = getSelfPath();
46 if (exePath.empty()) exit(1);
49 std::string params =
"";
50 for (
int i = 1; i < argc; i++) params +=
"\"" + std::string(argv[i]) +
"\" ";
51 ShellExecuteA(NULL,
"open", exePath.string().c_str(), params.c_str(), NULL, SW_SHOWDEFAULT);
54 execv(exePath.c_str(), argv);
59void checkHashAndExit(
const std::string& path) {
60 std::string hash =
"0";
62 HMODULE lib = LoadLibraryExA(path.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
64 typedef const char* (*FuncType)();
65 FuncType func = (FuncType)GetProcAddress(lib,
"VexModule_GetExpectedHash");
69 std::cerr <<
">> [Warning] GameModule is missing hash export (VexModule_GetExpectedHash).\n"
70 <<
" This usually means it was built with an older Engine version.\n";
75 void* lib = dlopen(path.c_str(), RTLD_LAZY | RTLD_LOCAL);
77 typedef const char* (*FuncType)();
78 FuncType func = (FuncType)dlsym(lib,
"VexModule_GetExpectedHash");
82 std::cerr <<
">> [Warning] GameModule is missing hash export (VexModule_GetExpectedHash).\n"
83 <<
" This usually means it was built with an older Engine version.\n";
87 std::cout << hash << std::flush;
91std::string getModuleHash(
const std::string& libPath) {
92 std::filesystem::path exe = getSelfPath();
93 if (exe.empty())
return "0";
96 std::string cmd =
"\"\"" + exe.string() +
"\" --check-hash \"" + libPath +
"\"\"";
98 std::string cmd =
"\"" + exe.string() +
"\" --check-hash \"" + libPath +
"\"";
100 std::string result =
"0";
103 FILE* pipe = _popen(cmd.c_str(),
"r");
105 FILE* pipe = popen(cmd.c_str(),
"r");
109 vex::log(
"Failed to spawn hash checker process.");
114 if (fgets(buffer,
sizeof(buffer), pipe) !=
nullptr) {
116 result.erase(std::remove(result.begin(), result.end(),
'\n'), result.end());
117 result.erase(std::remove(result.begin(), result.end(),
'\r'), result.end());
129void rebuildProject(
const std::filesystem::path& projectPath,
vex::GameInfo& info,
bool clean) {
130 vex::DialogWindow dialogWindow(clean ?
"Engine Updated - Clean Rebuilding..." :
"Building Project...", info);
133 std::string cleanFlag = clean ?
" -clean" :
"";
136 command =
"..\\..\\BuildTools\\build\\ProjectBuilder.exe \"" + projectPath.string() +
"\" -d" + cleanFlag;
138 command =
"../../BuildTools/build/ProjectBuilder \"" + projectPath.string() +
"\" -d" + cleanFlag;
141 std::thread buildThread([&]() {
142 std::string outputLog;
143 executeCommandRealTime(command, [&](
const std::string& line) {
146 dialogWindow.setDialogContent(outputLog);
156int main(
int argc,
char* argv[]) {
157 if (argc == 3 && std::string(argv[1]) ==
"--check-hash") {
158 checkHashAndExit(argv[2]);
163 std::cerr <<
"Error: Missing argument.\n";
164 std::cout <<
"Usage: " << argv[0] <<
" <path_to_project>\n";
172 std::filesystem::path projectPath = argv[1];
173 std::filesystem::path modulePath = projectPath /
"Build" /
"Debug";
176 std::string libPath = (modulePath /
"libGameModule.so").
string();
178 std::string libPath = (modulePath /
"GameModule.dll").
string();
181 if (!std::filesystem::exists(projectPath /
"VexProject.json")) {
182 createBasicDialog(
"Error",
"No valid vex project file in path:\n" + projectPath.string(), dialogGameInfo);
183 vex::log(vex::LogLevel::ERROR,
"No valid vex project file in path: %s", projectPath.string().c_str());
187 if (!std::filesystem::exists(libPath)) {
188 vex::log(
"Game Module missing. Building...");
189 rebuildProject(projectPath, dialogGameInfo,
false);
193 std::string moduleHash = getModuleHash(libPath);
195 if (moduleHash.empty() || moduleHash ==
"0" || moduleHash != engineHash) {
196 vex::log(
">> ABI Mismatch Detected!");
197 vex::log(
" Engine Hash: %s", engineHash.c_str());
198 vex::log(
" Module Hash: %s", moduleHash.c_str());
200 rebuildProject(projectPath, dialogGameInfo,
true);
201 restartApplication(argc, argv);
207 vex::log(
"Attempting to load game module from: %s", libPath.c_str());
209 if (!cr_plugin_open(ctx, libPath.c_str())) {
210 createBasicDialog(
"Critical Error",
"Failed to load Game Module! Check path and file permissions.\nAlternativly try clean building you project manually.", dialogGameInfo);
211 vex::log(vex::LogLevel::CRITICAL,
"Failed to load Game Module! Check path and file permissions.");
222 vex::Editor engine(
"VEX Editor", 1280, 720, gInfo, projectPath.string());
223 ctx.userdata = &engine;
227 vex::log(
"Starting Engine Loop with Hot Reload...");
231 unsigned int oldVersion = ctx.version;
232 int result = cr_plugin_update(ctx);
238 if (ctx.version != oldVersion) {
239 engine.OnHotReload();
241 }
catch (
const std::exception& e) {
A specialized Engine class for creating and managing modal dialog windows.
The main Editor class, inheriting from Engine and providing editor-specific functionality and UI.
Contains main Engine class.
This file defines struct GameInfo.
A specialized Engine class for creating and managing modal dialog windows.
The main Editor class, inheriting from Engine and providing editor-specific functionality and UI.
static int GetVersionMinor()
Returns the minor version of the engine.
static const char * GetVersionString()
Returns the version string of the engine.
static const char * GetBuildHash()
returns engine hash generated during build process.
static int GetVersionPatch()
Returns the patch version of the engine.
static int GetVersionMajor()
Returns the major version of the engine.
void VEX_EXPORT InitCrashHandler()
Initializes the low-level crash handler.
void VEX_EXPORT throw_error(const std::string &msg)
Throws an error or terminates the application.
void VEX_EXPORT log(const char *fmt,...)
Logs a formatted message.
void VEX_EXPORT handle_critical_exception(const std::exception &e)
Handles a critical exception, forcing termination.
this struct contains information about the game. like project name and version.