From 4fae59c826897b0660188dd5ddbd397c709de403 Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Mon, 15 Jan 2007 22:19:50 +0000 Subject: [PATCH] Started implementation of Auto3 compatibility engine Originally committed to SVN as r803. --- aegisub/auto4_auto3.cpp | 251 ++++++++++++++++++++++++++++++++++++++++ aegisub/auto4_auto3.h | 122 +++++++++++++++++++ aegisub/auto4_base.cpp | 11 +- aegisub/auto4_lua.cpp | 12 +- aegisub/auto4_lua.h | 2 - 5 files changed, 391 insertions(+), 7 deletions(-) create mode 100644 aegisub/auto4_auto3.cpp create mode 100644 aegisub/auto4_auto3.h diff --git a/aegisub/auto4_auto3.cpp b/aegisub/auto4_auto3.cpp new file mode 100644 index 000000000..54f1577c9 --- /dev/null +++ b/aegisub/auto4_auto3.cpp @@ -0,0 +1,251 @@ +// Copyright (c) 2005, 2006, 2007, Niels Martin Hansen +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the Aegisub Group nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------------- +// +// AEGISUB +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:jiifurusu@gmail.com +// + +#include "auto4_auto3.h" +#include "auto4_lua.h" + +namespace Automation4 { + + + // Auto3ProgressSink + + int Auto3ProgressSink::LuaSetStatus(lua_State *L) + { + Auto3ProgressSink *ps = GetObjPointer(L, lua_upvalueindex(1)); + wxString task(lua_tostring(L, 1), wxConvUTF8); + ps->SetTask(task); + return 0; + } + + int Auto3ProgressSink::LuaOutputDebug(lua_State *L) + { + Auto3ProgressSink *ps = GetObjPointer(L, lua_upvalueindex(1)); + wxString msg(lua_tostring(L, 1), wxConvUTF8); + ps->AddDebugOutput(msg); + return 0; + } + + int Auto3ProgressSink::LuaReportProgress(lua_State *L) + { + Auto3ProgressSink *ps = GetObjPointer(L, lua_upvalueindex(1)); + float progress = lua_tonumber(L, 1); + ps->SetProgress(progress); + return 0; + } + + Auto3ProgressSink::Auto3ProgressSink(lua_State *_L, wxWindow *parent) + : ProgressSink(parent) + , L(_L) + { + Auto3ProgressSink **ud = (Auto3ProgressSink**)lua_newuserdata(L, sizeof(Auto3ProgressSink*)); + *ud = this; + + // register progress reporting stuff + lua_getglobal(L, "aegisub"); + + lua_pushvalue(L, -2); + lua_pushcclosure(L, LuaReportProgress, 1); + lua_setfield(L, -2, "report_progress"); + + lua_pushvalue(L, -2); + lua_pushcclosure(L, LuaOutputDebug, 1); + lua_setfield(L, -2, "output_debug"); + + lua_pushvalue(L, -2); + lua_pushcclosure(L, LuaSetStatus, 1); + lua_setfield(L, -2, "set_status"); + + // reference so other objects can also find the progress sink + lua_pushvalue(L, -2); + lua_setfield(L, LUA_REGISTRYINDEX, "progress_sink"); + + // Remove aegisub table and userdata object from stack + lua_pop(L, 2); + } + + Auto3ProgressSink::~Auto3ProgressSink() + { + // remove progress reporting stuff + lua_getglobal(L, "aegisub"); + lua_pushnil(L); + lua_setfield(L, -2, "report_progress"); + lua_pushnil(L); + lua_setfield(L, -2, "output_debug"); + lua_pushnil(L); + lua_setfield(L, -2, "set_status"); + lua_pop(L, 1); + lua_pushnil(L); + lua_setfield(L, LUA_REGISTRYINDEX, "progress_sink"); + } + + Auto3ProgressSink* Auto3ProgressSink::GetObjPointer(lua_State *L, int idx) + { + assert(lua_type(L, idx) == LUA_TUSERDATA); + void *ud = lua_touserdata(L, idx); + return *((Auto3ProgressSink**)ud); + } + + + // Auto3ConfigDialog + + wxWindow* Auto3ConfigDialog::CreateWindow(wxWindow *parent) + { + // TODO + return 0; + } + + Auto3ConfigDialog::Auto3ConfigDialog(lua_State *_L, bool include_buttons) + { + // TODO + } + + Auto3ConfigDialog::~Auto3ConfigDialog() + { + // TODO + } + + int Auto3ConfigDialog::LuaReadBack(lua_State *L) + { + // TODO + return 0; + } + + void Auto3ConfigDialog::ReadBack() + { + // TODO + } + + + // Auto3Filter + + Auto3Filter::Auto3Filter(const wxString &_name, const wxString &_description, lua_State *_L) + : Feature(SCRIPTFEATURE_FILTER, _name) + , FeatureFilter(_name, _description, 0) + { + // TODO + } + + ScriptConfigDialog* Auto3Filter::GenerateConfigDialog(wxWindow *parent) + { + // TODO + return 0; + } + + void Auto3Filter::Init() + { + // Nothing to do here + } + + void Auto3Filter::ProcessSubs(AssFile *subs, wxWindow *export_dialog) + { + // TODO + } + + + // Auto3ThreadedCall + + Auto3ThreadedCall::Auto3ThreadedCall(lua_State *_L, int _nargs, int _nresults) + { + // TODO + } + + wxThread::ExitCode Auto3ThreadedCall::Entry() + { + // TODO + return (wxThread::ExitCode)0; + } + + + // Auto3Script + + Auto3Script::Auto3Script(const wxString &filename) + : Script(filename) + , L(0) + { + try { + Create(); + } + catch (wxChar *e) { + description = e; + loaded = false; + } + } + + Auto3Script::~Auto3Script() + { + if (L) Destroy(); + } + + void Auto3Script::Create() + { + // TODO + } + + void Auto3Script::Destroy() + { + // TODO + } + + void Auto3Script::Reload() + { + // TODO + } + + + // Auto3ScriptFactory + + class Auto3ScriptFactory : public ScriptFactory { + public: + Auto3ScriptFactory() + { + engine_name = _T("Legacy Automation 3"); + filename_pattern = _T("*.auto3"); + Register(this); + } + + ~Auto3ScriptFactory() { } + + virtual Script* Produce(const wxString &filename) const + { + if (filename.Right(4).Lower() == _T(".auto3")) { + return new Auto3Script(filename); + } else { + return 0; + } + } + }; + Auto3ScriptFactory _script_factory; + +}; diff --git a/aegisub/auto4_auto3.h b/aegisub/auto4_auto3.h new file mode 100644 index 000000000..1524f06a0 --- /dev/null +++ b/aegisub/auto4_auto3.h @@ -0,0 +1,122 @@ +// Copyright (c) 2007, Niels Martin Hansen +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of the Aegisub Group nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// ----------------------------------------------------------------------------- +// +// AEGISUB +// +// Website: http://aegisub.cellosoft.com +// Contact: mailto:jiifurusu@gmail.com +// + +// Scripting engine for legacy Automation 3 compatibility + +#pragma once + +#ifndef _AUTO4_AUTO3_H +#define _AUTO4_AUTO3_H + +#include "auto4_base.h" +#include +#include +#include "../lua51/src/lua.h" +#include "../lua51/src/lauxlib.h" + +namespace Automation4 { + + class Auto3ProgressSink : public ProgressSink { + private: + lua_State *L; + + static int LuaSetStatus(lua_State *L); + static int LuaOutputDebug(lua_State *L); + static int LuaReportProgress(lua_State *L); + + public: + Auto3ProgressSink(lua_State *_L, wxWindow *parent); + virtual ~Auto3ProgressSink(); + + static Auto3ProgressSink* GetObjPointer(lua_State *L, int idx); + }; + + + class Auto3ConfigDialog : public ScriptConfigDialog { + // copypasta + protected: + wxWindow* CreateWindow(wxWindow *parent); + + public: + Auto3ConfigDialog(lua_State *_L, bool include_buttons); + virtual ~Auto3ConfigDialog(); + int LuaReadBack(lua_State *L); // read back internal structure to lua structures + + void ReadBack(); // from auto4 base + }; + + + class Auto3Filter : public FeatureFilter { + protected: + Auto3Filter(const wxString &_name, const wxString &_description, lua_State *_L); + + ScriptConfigDialog* GenerateConfigDialog(wxWindow *parent); + + void Init(); + public: + void ProcessSubs(AssFile *subs, wxWindow *export_dialog); + }; + + + class Auto3ThreadedCall : public wxThread { + // This is pretty much copy-paste from the non-legacy version + private: + lua_State *L; + int nargs; + int nresults; + public: + Auto3ThreadedCall(lua_State *_L, int _nargs, int _nresults); + virtual ExitCode Entry(); + }; + + + class Auto3Script : public Script { + private: + Auto3Filter *filter; + lua_State *L; + + void Create(); + void Destroy(); + + public: + Auto3Script(const wxString &filename); + virtual ~Auto3Script(); + + virtual void Reload(); + }; + +}; + +#endif diff --git a/aegisub/auto4_base.cpp b/aegisub/auto4_base.cpp index c5f37b6a4..59ce88e5a 100644 --- a/aegisub/auto4_base.cpp +++ b/aegisub/auto4_base.cpp @@ -697,8 +697,15 @@ namespace Automation4 { factories = new std::vector(); for (std::vector::iterator i = factories->begin(); i != factories->end(); ++i) { - Script *s = (*i)->Produce(filename); - if (s) return s; + try { + Script *s = (*i)->Produce(filename); + if (s) return s; + } + catch (Script *e) { + // This was the wrong script factory, but it throwing a Script object means it did know what to do about the file + // Use this script object + return e; + } } return new UnknownScript(filename); } diff --git a/aegisub/auto4_lua.cpp b/aegisub/auto4_lua.cpp index 094cf0af0..918afb9cb 100644 --- a/aegisub/auto4_lua.cpp +++ b/aegisub/auto4_lua.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2006, Niels Martin Hansen +// Copyright (c) 2006, 2007, Niels Martin Hansen // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -34,6 +34,7 @@ // #include "auto4_lua.h" +#include "auto4_auto3.h" #include "ass_dialogue.h" #include "ass_style.h" #include "ass_file.h" @@ -177,6 +178,7 @@ namespace Automation4 { } catch (wxChar *e) { description = e; + loaded = false; } } @@ -264,7 +266,9 @@ namespace Automation4 { if (lua_isnumber(L, -1)) { if (lua_tointeger(L, -1) == 3) { lua_pop(L, 1); // just to avoid tripping the stackcheck in debug - throw _T("This script looks like an Automation 3 Lua script. Automation 3 is not supported in this version of Aegisub, please use Aegisub 1.10 or earlier to use this script."); + // So this is an auto3 script... + // Throw it as an exception, the script factory manager will catch this and use the auto3 script instead of this script object + throw new Auto3Script(GetFilename()); } } lua_getglobal(L, "script_name"); @@ -395,7 +399,9 @@ namespace Automation4 { lua_error(L); } - if (luaL_loadfile(L, fname.GetFullPath().mb_str(wxConvUTF8))) { + LuaScriptReader script_reader(fname.GetFullPath()); + if (lua_load(L, script_reader.reader_func, &script_reader, s->GetFilename().mb_str(wxConvUTF8))) { + //if (luaL_loadfile(L, fname.GetFullPath().mb_str(wxConvUTF8))) { lua_pushfstring(L, "An error occurred loading the Lua script file \"%s\":\n\n%s", fname.GetFullPath().mb_str(wxConvUTF8).data(), lua_tostring(L, -1)); lua_error(L); return 0; diff --git a/aegisub/auto4_lua.h b/aegisub/auto4_lua.h index ed884d474..20a960930 100644 --- a/aegisub/auto4_lua.h +++ b/aegisub/auto4_lua.h @@ -88,8 +88,6 @@ namespace Automation4 { }; - class LuaConfigDialog; - // Provides progress UI and control functions for a Lua script class LuaProgressSink : public ProgressSink { private: