From 159dfcde3931a885127310af8c64c1e6179d119a Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Wed, 23 Apr 2014 21:50:26 +0200 Subject: [PATCH] Add extradata reading/writing to Auto4 Lua --- src/auto4_lua.cpp | 12 ++++++++++++ src/auto4_lua.h | 2 +- src/auto4_lua_assfile.cpp | 32 +++++++++++++++++++++++++++----- src/auto4_lua_utils.h | 5 +++-- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/auto4_lua.cpp b/src/auto4_lua.cpp index 194c110dc..26d2768f2 100644 --- a/src/auto4_lua.cpp +++ b/src/auto4_lua.cpp @@ -56,6 +56,7 @@ #include #include +#include #include #include #include @@ -274,6 +275,17 @@ namespace { luaL_argcheck(L, lua_istable(L, 1), 1, ""); luaL_argcheck(L, lua_isstring(L, 2), 2, ""); + // have to check that it looks like a style table before actually converting + // if it's a dialogue table then an active AssFile object is required + { + lua_getfield(L, 1, "class"); + std::string actual_class{lua_tostring(L, -1)}; + boost::to_lower(actual_class); + if (actual_class != "style") + return luaL_error(L, "Not a style entry"); + lua_pop(L, 1); + } + lua_pushvalue(L, 1); std::unique_ptr et(Automation4::LuaAssFile::LuaToAssEntry(L)); auto st = dynamic_cast(et.get()); diff --git a/src/auto4_lua.h b/src/auto4_lua.h index 9695c3ad9..e2b2a7369 100644 --- a/src/auto4_lua.h +++ b/src/auto4_lua.h @@ -124,7 +124,7 @@ namespace Automation4 { /// makes a Lua representation of AssEntry and places on the top of the stack void AssEntryToLua(lua_State *L, size_t idx); /// assumes a Lua representation of AssEntry on the top of the stack, and creates an AssEntry object of it - static std::unique_ptr LuaToAssEntry(lua_State *L); + static std::unique_ptr LuaToAssEntry(lua_State *L, AssFile *ass=0); /// @brief Signal that the script using this file is now done running /// @param set_undo If there's any uncommitted changes to the file, diff --git a/src/auto4_lua_assfile.cpp b/src/auto4_lua_assfile.cpp index b21bbcfdf..f397568b6 100644 --- a/src/auto4_lua_assfile.cpp +++ b/src/auto4_lua_assfile.cpp @@ -173,6 +173,15 @@ namespace Automation4 { set_field(L, "text", dia->Text); + // create extradata table + lua_newtable(L); + for (auto const& ed : ass->GetExtradata(dia->ExtradataIds)) { + push_value(L, ed.first); + push_value(L, ed.second); + lua_settable(L, -3); + } + lua_setfield(L, -2, "extra"); + set_field(L, "class", "dialogue"); } else if (auto sty = dynamic_cast(e)) { @@ -221,7 +230,7 @@ namespace Automation4 { } } - std::unique_ptr LuaAssFile::LuaToAssEntry(lua_State *L) + std::unique_ptr LuaAssFile::LuaToAssEntry(lua_State *L, AssFile *ass) { // assume an assentry table is on the top of the stack // convert it to a real AssEntry object, and pop the table from the stack @@ -271,6 +280,7 @@ namespace Automation4 { sty->UpdateData(); } else if (lclass == "dialogue") { + assert(ass != 0); // since we need AssFile::AddExtradata auto dia = new AssDialogue; result.reset(dia); @@ -285,6 +295,18 @@ namespace Automation4 { dia->Margin[2] = get_int_field(L, "margin_t", "dialogue"); dia->Effect = get_string_field(L, "effect", "dialogue"); dia->Text = get_string_field(L, "text", "dialogue"); + + lua_getfield(L, -1, "extra"); + std::vector new_ids; + lua_pushnil(L); + while (lua_next(L, -2)) { + auto key = get_string_or_default(L, -2); + auto value = get_string_or_default(L, -1); + new_ids.push_back(ass->AddExtradata(key, value)); + lua_pop(L, 1); + } + lua_pop(L, 1); + dia->ExtradataIds = new_ids; } else { luaL_error(L, "Found line with unknown class: %s", lclass.c_str()); @@ -422,7 +444,7 @@ namespace Automation4 { // insert CheckBounds(n); - auto e = LuaToAssEntry(L); + auto e = LuaToAssEntry(L, ass); modification_type |= modification_mask(e.get()); QueueLineForDeletion(n - 1); AssignLine(n - 1, std::move(e)); @@ -511,7 +533,7 @@ namespace Automation4 { for (int i = 1; i <= n; i++) { lua_pushvalue(L, i); - auto e = LuaToAssEntry(L); + auto e = LuaToAssEntry(L, ass); modification_type |= modification_mask(e.get()); if (lines.empty()) { @@ -555,7 +577,7 @@ namespace Automation4 { new_entries.reserve(n - 1); for (int i = 2; i <= n; i++) { lua_pushvalue(L, i); - auto e = LuaToAssEntry(L); + auto e = LuaToAssEntry(L, ass); modification_type |= modification_mask(e.get()); InsertLine(new_entries, i - 2, std::move(e)); lua_pop(L, 1); @@ -594,7 +616,7 @@ namespace Automation4 { int LuaAssFile::LuaParseKaraokeData(lua_State *L) { - auto e = LuaToAssEntry(L); + auto e = LuaToAssEntry(L, ass); auto dia = dynamic_cast(e.get()); luaL_argcheck(L, dia, 1, "Subtitle line must be a dialogue line"); diff --git a/src/auto4_lua_utils.h b/src/auto4_lua_utils.h index a9e9c9a92..9639121c6 100644 --- a/src/auto4_lua_utils.h +++ b/src/auto4_lua_utils.h @@ -71,10 +71,11 @@ inline wxString check_wxstring(lua_State *L, int idx) { } inline std::string get_string_or_default(lua_State *L, int idx) { - const char *str = lua_tostring(L, idx); + size_t len = 0; + const char *str = lua_tolstring(L, idx, &len); if (!str) str = ""; - return str; + return std::string(str, len); } inline std::string get_global_string(lua_State *L, const char *name) {