latest code update
- app icon - starting with map view - code cleanup Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
@@ -9,6 +9,7 @@ extern "C" {
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <cstdio>
|
||||
|
||||
namespace wherigo {
|
||||
|
||||
@@ -82,10 +83,42 @@ void LuaPersistence::serializeValue(lua_State* L, int index, std::string& output
|
||||
case LUA_TSTRING: {
|
||||
const char* str = lua_tostring(L, index);
|
||||
output += "\"";
|
||||
// Escape special characters
|
||||
// Properly escape all special characters for Lua strings
|
||||
for (const char* p = str; *p; ++p) {
|
||||
if (*p == '"' || *p == '\\') output += '\\';
|
||||
output += *p;
|
||||
unsigned char c = (unsigned char)*p;
|
||||
switch (c) {
|
||||
case '"':
|
||||
output += "\\\"";
|
||||
break;
|
||||
case '\\':
|
||||
output += "\\\\";
|
||||
break;
|
||||
case '\n':
|
||||
output += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
output += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
output += "\\t";
|
||||
break;
|
||||
case '\b':
|
||||
output += "\\b";
|
||||
break;
|
||||
case '\f':
|
||||
output += "\\f";
|
||||
break;
|
||||
default:
|
||||
// For control characters and high bytes, use decimal escape
|
||||
if (c < 32 || c >= 127) {
|
||||
char hex[6];
|
||||
snprintf(hex, sizeof(hex), "\\%d", c);
|
||||
output += hex;
|
||||
} else {
|
||||
output += c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
output += "\"";
|
||||
break;
|
||||
@@ -199,23 +232,120 @@ bool LuaPersistence::loadGlobals(lua_State* L, const std::string& filePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Restore globals
|
||||
// Restore globals - but for tables (Wherigo objects), merge instead of replace
|
||||
// Strategy: For each saved object, find the matching existing object and merge
|
||||
int count = 0;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
if (lua_isstring(L, -2)) {
|
||||
const char* key = lua_tostring(L, -2);
|
||||
if (lua_isstring(L, -2) && lua_istable(L, -1)) {
|
||||
const char* savedKey = lua_tostring(L, -2);
|
||||
wxLogDebug("Restoring global: %s", savedKey);
|
||||
int stackBefore = lua_gettop(L);
|
||||
|
||||
// Set the global
|
||||
lua_pushvalue(L, -1); // duplicate value
|
||||
lua_setglobal(L, key);
|
||||
// Get the Name field of the saved object (if it exists)
|
||||
lua_getfield(L, -1, "Name");
|
||||
std::string savedName;
|
||||
if (lua_isstring(L, -1)) {
|
||||
savedName = lua_tostring(L, -1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
// Try to find matching existing object
|
||||
bool merged = false;
|
||||
|
||||
if (!savedName.empty()) {
|
||||
// Search for existing object with same Name
|
||||
lua_getglobal(L, "_G");
|
||||
lua_pushnil(L);
|
||||
|
||||
while (lua_next(L, -2) != 0) {
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_getfield(L, -1, "Name");
|
||||
if (lua_isstring(L, -1)) {
|
||||
if (savedName == lua_tostring(L, -1)) {
|
||||
lua_pop(L, 1); // pop Name
|
||||
// Found matching object! Merge data
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -3) != 0) {
|
||||
if (lua_isstring(L, -2)) {
|
||||
const char* field = lua_tostring(L, -2);
|
||||
if (!lua_isfunction(L, -1)) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -4, field);
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
merged = true;
|
||||
lua_pop(L, 2); // pop iterator and object
|
||||
break;
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1); // pop _G
|
||||
}
|
||||
|
||||
if (!merged) {
|
||||
// No match found or no Name field - use key matching
|
||||
lua_getglobal(L, savedKey);
|
||||
if (lua_istable(L, -1)) {
|
||||
// Object exists by key - merge it
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -3) != 0) {
|
||||
if (lua_isstring(L, -2)) {
|
||||
const char* field = lua_tostring(L, -2);
|
||||
if (!lua_isfunction(L, -1)) {
|
||||
lua_getfield(L, -3, field); // get existing value
|
||||
if (lua_istable(L, -1) && lua_istable(L, -2)) {
|
||||
// Both are tables: merge recursively
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -3) != 0) {
|
||||
if (lua_isstring(L, -2)) {
|
||||
const char* subfield = lua_tostring(L, -2);
|
||||
if (!lua_isfunction(L, -1)) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -5, subfield); // merge into existing table
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1); // pop existing value
|
||||
} else {
|
||||
lua_pop(L, 1); // pop existing value
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -3, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1); // pop existing object
|
||||
merged = true;
|
||||
} else {
|
||||
lua_pop(L, 1); // pop nil
|
||||
}
|
||||
}
|
||||
if (!merged) {
|
||||
// No existing object found - create new global
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, savedKey);
|
||||
}
|
||||
int stackAfter = lua_gettop(L);
|
||||
if (stackBefore != stackAfter) {
|
||||
wxLogError("Stack imbalance detected for global %s: before=%d after=%d", savedKey, stackBefore, stackAfter);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
lua_pop(L, 1); // pop value
|
||||
lua_pop(L, 1); // pop value from lua_next
|
||||
}
|
||||
|
||||
lua_pop(L, 1); // pop table
|
||||
|
||||
lua_pop(L, 1); // pop table
|
||||
|
||||
wxLogDebug("Restored %d globals from %s", count, filePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user