mirror of https://github.com/odrling/Aegisub
Make Automation4::Script mostly pure abstract and clean up the implementation of LuaScript
Originally committed to SVN as r5640.
This commit is contained in:
parent
c09259c93d
commit
492a0d3046
|
@ -36,6 +36,8 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "auto4_base.h"
|
||||||
|
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
@ -60,7 +62,6 @@
|
||||||
|
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "ass_style.h"
|
#include "ass_style.h"
|
||||||
#include "auto4_base.h"
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "dialog_progress.h"
|
#include "dialog_progress.h"
|
||||||
#include "include/aegisub/context.h"
|
#include "include/aegisub/context.h"
|
||||||
|
@ -497,20 +498,9 @@ namespace Automation4 {
|
||||||
impl->Run(bind(progress_sink_wrapper, task, std::tr1::placeholders::_1, this), prio);
|
impl->Run(bind(progress_sink_wrapper, task, std::tr1::placeholders::_1, this), prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Script
|
// Script
|
||||||
|
Script::Script(wxString const& filename)
|
||||||
|
: filename(filename)
|
||||||
/// @brief DOCME
|
|
||||||
/// @param _filename
|
|
||||||
///
|
|
||||||
Script::Script(const wxString &_filename)
|
|
||||||
: filename(_filename)
|
|
||||||
, name("")
|
|
||||||
, description("")
|
|
||||||
, author("")
|
|
||||||
, version("")
|
|
||||||
, loaded(false)
|
|
||||||
{
|
{
|
||||||
// copied from auto3
|
// copied from auto3
|
||||||
include_path.clear();
|
include_path.clear();
|
||||||
|
@ -526,90 +516,6 @@ namespace Automation4 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
Script::~Script()
|
|
||||||
{
|
|
||||||
for (std::vector<Feature*>::iterator f = features.begin(); f != features.end(); ++f) {
|
|
||||||
delete *f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
wxString Script::GetPrettyFilename() const
|
|
||||||
{
|
|
||||||
wxFileName fn(filename);
|
|
||||||
return fn.GetFullName();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const wxString& Script::GetFilename() const
|
|
||||||
{
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const wxString& Script::GetName() const
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const wxString& Script::GetDescription() const
|
|
||||||
{
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const wxString& Script::GetAuthor() const
|
|
||||||
{
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
const wxString& Script::GetVersion() const
|
|
||||||
{
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
bool Script::GetLoadedState() const
|
|
||||||
{
|
|
||||||
return loaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
std::vector<Feature*>& Script::GetFeatures()
|
|
||||||
{
|
|
||||||
return features;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ScriptManager
|
// ScriptManager
|
||||||
|
|
||||||
|
|
||||||
|
@ -923,18 +829,8 @@ namespace Automation4 {
|
||||||
|
|
||||||
|
|
||||||
// UnknownScript
|
// UnknownScript
|
||||||
|
UnknownScript::UnknownScript(wxString const& filename)
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param filename
|
|
||||||
///
|
|
||||||
UnknownScript::UnknownScript(const wxString &filename)
|
|
||||||
: Script(filename)
|
: Script(filename)
|
||||||
{
|
{
|
||||||
wxFileName fn(filename);
|
|
||||||
name = fn.GetName();
|
|
||||||
description = _("File was not recognized as a script");
|
|
||||||
loaded = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
|
#include <wx/filename.h>
|
||||||
#include <wx/gauge.h>
|
#include <wx/gauge.h>
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/stattext.h>
|
#include <wx/stattext.h>
|
||||||
|
@ -312,64 +313,40 @@ namespace Automation4 {
|
||||||
ProgressSink(agi::ProgressSink *impl, BackgroundScriptRunner *bsr);
|
ProgressSink(agi::ProgressSink *impl, BackgroundScriptRunner *bsr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
/// @class Script
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
/// DOCME
|
|
||||||
class Script {
|
class Script {
|
||||||
private:
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
wxString filename;
|
wxString filename;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/// The automation include path, consisting of the user-specified paths
|
||||||
/// DOCME
|
/// along with the script's path
|
||||||
wxString name;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
wxString description;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
wxString author;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
wxString version;
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
bool loaded; // is the script properly loaded?
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
wxPathList include_path;
|
wxPathList include_path;
|
||||||
|
Script(wxString const& filename);
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
std::vector<Feature*> features;
|
|
||||||
|
|
||||||
Script(const wxString &_filename);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Script();
|
virtual ~Script() { }
|
||||||
|
|
||||||
|
/// Reload this script
|
||||||
virtual void Reload() = 0;
|
virtual void Reload() = 0;
|
||||||
|
|
||||||
const wxString& GetFilename() const;
|
/// The script's file name with path
|
||||||
wxString GetPrettyFilename() const;
|
wxString GetFilename() const { return filename; }
|
||||||
const wxString& GetName() const;
|
/// The script's file name without path
|
||||||
const wxString& GetDescription() const;
|
wxString GetPrettyFilename() const { return wxFileName(filename).GetFullName(); }
|
||||||
const wxString& GetAuthor() const;
|
/// The script's name. Not required to be unique.
|
||||||
const wxString& GetVersion() const;
|
virtual wxString GetName() const=0;
|
||||||
bool GetLoadedState() const;
|
/// A short description of the script
|
||||||
|
virtual wxString GetDescription() const=0;
|
||||||
|
/// The author of the script
|
||||||
|
virtual wxString GetAuthor() const=0;
|
||||||
|
/// A version string that should not be used for anything but display
|
||||||
|
virtual wxString GetVersion() const=0;
|
||||||
|
/// Did the script load correctly?
|
||||||
|
virtual bool GetLoadedState() const=0;
|
||||||
|
|
||||||
std::vector<Feature*>& GetFeatures();
|
/// Get a list of features provided by this script
|
||||||
|
virtual std::vector<Feature*> GetFeatures() const=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class ScriptManager
|
/// @class ScriptManager
|
||||||
/// @brief DOCME
|
/// @brief DOCME
|
||||||
|
@ -477,11 +454,16 @@ namespace Automation4 {
|
||||||
/// automation engines
|
/// automation engines
|
||||||
class UnknownScript : public Script {
|
class UnknownScript : public Script {
|
||||||
public:
|
public:
|
||||||
UnknownScript(const wxString &filename);
|
UnknownScript(wxString const& filename);
|
||||||
|
|
||||||
/// @brief DOCME
|
void Reload() { }
|
||||||
///
|
|
||||||
void Reload() { };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
wxString GetName() const { return wxFileName(GetFilename()).GetName(); }
|
||||||
|
wxString GetDescription() const { return _("File was not recognized as a script"); }
|
||||||
|
wxString GetAuthor() const { return ""; }
|
||||||
|
wxString GetVersion() const { return ""; }
|
||||||
|
bool GetLoadedState() const { return false; }
|
||||||
|
|
||||||
|
std::vector<Feature*> GetFeatures() const { return std::vector<Feature*>(); }
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,8 +38,10 @@
|
||||||
|
|
||||||
#ifdef WITH_AUTO4_LUA
|
#ifdef WITH_AUTO4_LUA
|
||||||
|
|
||||||
|
#include "auto4_lua.h"
|
||||||
|
|
||||||
#ifndef AGI_PRE
|
#ifndef AGI_PRE
|
||||||
#include <assert.h>
|
#include <cassert>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -52,17 +54,18 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
|
#include <libaegisub/scoped_ptr.h>
|
||||||
|
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
#include "ass_file.h"
|
#include "ass_file.h"
|
||||||
#include "ass_override.h"
|
#include "ass_override.h"
|
||||||
#include "ass_style.h"
|
#include "ass_style.h"
|
||||||
#include "auto4_lua.h"
|
|
||||||
#include "auto4_lua_factory.h"
|
#include "auto4_lua_factory.h"
|
||||||
#include "auto4_lua_scriptreader.h"
|
#include "auto4_lua_scriptreader.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "standard_paths.h"
|
#include "standard_paths.h"
|
||||||
#include "text_file_reader.h"
|
#include "text_file_reader.h"
|
||||||
|
#include "utils.h"
|
||||||
#include "video_context.h"
|
#include "video_context.h"
|
||||||
|
|
||||||
// This must be below the headers above.
|
// This must be below the headers above.
|
||||||
|
@ -74,13 +77,38 @@
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void push_value(lua_State *L, lua_CFunction fn) {
|
||||||
|
lua_pushcfunction(L, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_value(lua_State *L, int n) {
|
||||||
|
lua_pushinteger(L, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_value(lua_State *L, double n) {
|
||||||
|
lua_pushnumber(L, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void set_field(lua_State *L, const char *name, T value) {
|
||||||
|
push_value(L, value);
|
||||||
|
lua_setfield(L, -2, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString get_global_string(lua_State *L, const char *name) {
|
||||||
|
lua_getglobal(L, name);
|
||||||
|
wxString ret;
|
||||||
|
if (lua_isstring(L, -1))
|
||||||
|
ret = wxString(lua_tostring(L, -1), wxConvUTF8);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
namespace Automation4 {
|
namespace Automation4 {
|
||||||
|
|
||||||
// LuaStackcheck
|
// LuaStackcheck
|
||||||
|
|
||||||
//#ifdef _DEBUG
|
|
||||||
#if 0
|
#if 0
|
||||||
struct LuaStackcheck {
|
struct LuaStackcheck {
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
@ -140,35 +168,22 @@ namespace Automation4 {
|
||||||
|
|
||||||
|
|
||||||
// LuaScript
|
// LuaScript
|
||||||
|
LuaScript::LuaScript(wxString const& filename)
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param filename
|
|
||||||
///
|
|
||||||
LuaScript::LuaScript(const wxString &filename)
|
|
||||||
: Script(filename)
|
: Script(filename)
|
||||||
, L(0)
|
, L(0)
|
||||||
{
|
{
|
||||||
Create();
|
Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
LuaScript::~LuaScript()
|
LuaScript::~LuaScript()
|
||||||
{
|
{
|
||||||
if (L) Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
void LuaScript::Create()
|
void LuaScript::Create()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
loaded = true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// create lua environment
|
// create lua environment
|
||||||
L = lua_open();
|
L = lua_open();
|
||||||
|
@ -209,7 +224,7 @@ namespace Automation4 {
|
||||||
|
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
|
||||||
// Replace the default lua module loader with our utf-8 compatible one
|
// Replace the default lua module loader with our unicode compatible one
|
||||||
lua_getfield(L, -1, "loaders");
|
lua_getfield(L, -1, "loaders");
|
||||||
lua_pushcfunction(L, LuaModuleLoader);
|
lua_pushcfunction(L, LuaModuleLoader);
|
||||||
lua_rawseti(L, -2, 2);
|
lua_rawseti(L, -2, 2);
|
||||||
|
@ -229,37 +244,28 @@ namespace Automation4 {
|
||||||
// make "aegisub" table
|
// make "aegisub" table
|
||||||
lua_pushstring(L, "aegisub");
|
lua_pushstring(L, "aegisub");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
// aegisub.register_macro
|
|
||||||
lua_pushcfunction(L, LuaFeatureMacro::LuaRegister);
|
set_field(L, "register_macro", LuaFeatureMacro::LuaRegister);
|
||||||
lua_setfield(L, -2, "register_macro");
|
set_field(L, "register_filter", LuaFeatureFilter::LuaRegister);
|
||||||
// aegisub.register_filter
|
set_field(L, "text_extents", LuaTextExtents);
|
||||||
lua_pushcfunction(L, LuaFeatureFilter::LuaRegister);
|
set_field(L, "frame_from_ms", LuaFrameFromMs);
|
||||||
lua_setfield(L, -2, "register_filter");
|
set_field(L, "ms_from_frame", LuaMsFromFrame);
|
||||||
// aegisub.text_extents
|
set_field(L, "video_size", LuaVideoSize);
|
||||||
lua_pushcfunction(L, LuaTextExtents);
|
set_field(L, "lua_automation_version", 4);
|
||||||
lua_setfield(L, -2, "text_extents");
|
|
||||||
// VFR handling
|
|
||||||
lua_pushcfunction(L, LuaFrameFromMs);
|
|
||||||
lua_setfield(L, -2, "frame_from_ms");
|
|
||||||
lua_pushcfunction(L, LuaMsFromFrame);
|
|
||||||
lua_setfield(L, -2, "ms_from_frame");
|
|
||||||
lua_pushcfunction(L, LuaVideoSize);
|
|
||||||
lua_setfield(L, -2, "video_size");
|
|
||||||
// aegisub.lua_automation_version
|
|
||||||
lua_pushinteger(L, 4);
|
|
||||||
lua_setfield(L, -2, "lua_automation_version");
|
|
||||||
// store aegisub table to globals
|
// store aegisub table to globals
|
||||||
lua_settable(L, LUA_GLOBALSINDEX);
|
lua_settable(L, LUA_GLOBALSINDEX);
|
||||||
_stackcheck.check_stack(0);
|
_stackcheck.check_stack(0);
|
||||||
|
|
||||||
// load user script
|
// load user script
|
||||||
LuaScriptReader script_reader(GetFilename());
|
LuaScriptReader script_reader(GetFilename());
|
||||||
if (lua_load(L, script_reader.reader_func, &script_reader, GetPrettyFilename().mb_str(wxConvUTF8))) {
|
if (lua_load(L, script_reader.reader_func, &script_reader, GetPrettyFilename().utf8_str())) {
|
||||||
wxString err(lua_tostring(L, -1), wxConvUTF8);
|
wxString err(lua_tostring(L, -1), wxConvUTF8);
|
||||||
err.Prepend("Error loading Lua script \"" + GetPrettyFilename() + "\":\n\n");
|
err.Prepend("Error loading Lua script \"" + GetPrettyFilename() + "\":\n\n");
|
||||||
throw ScriptLoadError(STD_STR(err));
|
throw ScriptLoadError(STD_STR(err));
|
||||||
}
|
}
|
||||||
_stackcheck.check_stack(1);
|
_stackcheck.check_stack(1);
|
||||||
|
|
||||||
// and execute it
|
// and execute it
|
||||||
// this is where features are registered
|
// this is where features are registered
|
||||||
// don't thread this, as there's no point in it and it seems to break on wx 2.8.3, for some reason
|
// don't thread this, as there's no point in it and it seems to break on wx 2.8.3, for some reason
|
||||||
|
@ -270,80 +276,49 @@ namespace Automation4 {
|
||||||
throw ScriptLoadError(STD_STR(err));
|
throw ScriptLoadError(STD_STR(err));
|
||||||
}
|
}
|
||||||
_stackcheck.check_stack(0);
|
_stackcheck.check_stack(0);
|
||||||
|
|
||||||
lua_getglobal(L, "version");
|
lua_getglobal(L, "version");
|
||||||
if (lua_isnumber(L, -1)) {
|
if (lua_isnumber(L, -1) && lua_tointeger(L, -1) == 3) {
|
||||||
if (lua_tointeger(L, -1) == 3) {
|
|
||||||
lua_pop(L, 1); // just to avoid tripping the stackcheck in debug
|
lua_pop(L, 1); // just to avoid tripping the stackcheck in debug
|
||||||
throw ScriptLoadError("Attempted to load an Automation 3 script as an Automation 4 Lua script. Automation 3 is no longer supported.");
|
throw ScriptLoadError("Attempted to load an Automation 3 script as an Automation 4 Lua script. Automation 3 is no longer supported.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
lua_getglobal(L, "script_name");
|
name = get_global_string(L, "script_name");
|
||||||
if (lua_isstring(L, -1)) {
|
description = get_global_string(L, "script_description");
|
||||||
name = wxString(lua_tostring(L, -1), wxConvUTF8);
|
author = get_global_string(L, "script_author");
|
||||||
} else {
|
version = get_global_string(L, "script_version");
|
||||||
|
|
||||||
|
if (name.empty())
|
||||||
name = GetPrettyFilename();
|
name = GetPrettyFilename();
|
||||||
}
|
|
||||||
lua_getglobal(L, "script_description");
|
lua_pop(L, 1);
|
||||||
if (lua_isstring(L, -1)) {
|
|
||||||
description = wxString(lua_tostring(L, -1), wxConvUTF8);
|
|
||||||
}
|
|
||||||
lua_getglobal(L, "script_author");
|
|
||||||
if (lua_isstring(L, -1)) {
|
|
||||||
author = wxString(lua_tostring(L, -1), wxConvUTF8);
|
|
||||||
}
|
|
||||||
lua_getglobal(L, "script_version");
|
|
||||||
if (lua_isstring(L, -1)) {
|
|
||||||
version = wxString(lua_tostring(L, -1), wxConvUTF8);
|
|
||||||
}
|
|
||||||
lua_pop(L, 5);
|
|
||||||
// if we got this far, the script should be ready
|
// if we got this far, the script should be ready
|
||||||
_stackcheck.check_stack(0);
|
_stackcheck.check_stack(0);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (agi::Exception const& e) {
|
catch (agi::Exception const& e) {
|
||||||
Destroy();
|
Destroy();
|
||||||
loaded = false;
|
|
||||||
name = GetPrettyFilename();
|
name = GetPrettyFilename();
|
||||||
description = e.GetChainedMessage();
|
description = e.GetChainedMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
void LuaScript::Destroy()
|
void LuaScript::Destroy()
|
||||||
{
|
{
|
||||||
// Assume the script object is clean if there's no Lua state
|
// Assume the script object is clean if there's no Lua state
|
||||||
if (!L) return;
|
if (!L) return;
|
||||||
|
|
||||||
// remove features
|
delete_clear(features);
|
||||||
for (int i = 0; i < (int)features.size(); i++) {
|
|
||||||
Feature *f = features[i];
|
|
||||||
delete f;
|
|
||||||
}
|
|
||||||
features.clear();
|
|
||||||
|
|
||||||
// delete environment
|
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
L = 0;
|
L = 0;
|
||||||
|
|
||||||
loaded = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
void LuaScript::Reload()
|
void LuaScript::Reload()
|
||||||
{
|
{
|
||||||
Destroy();
|
|
||||||
Create();
|
Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param L
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
LuaScript* LuaScript::GetScriptObject(lua_State *L)
|
LuaScript* LuaScript::GetScriptObject(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, "aegisub");
|
lua_getfield(L, LUA_REGISTRYINDEX, "aegisub");
|
||||||
|
@ -352,41 +327,31 @@ namespace Automation4 {
|
||||||
return (LuaScript*)ptr;
|
return (LuaScript*)ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LuaScript::RegisterFeature(Feature *feature) {
|
||||||
|
features.push_back(feature);
|
||||||
|
return features.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param L
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
int LuaScript::LuaTextExtents(lua_State *L)
|
int LuaScript::LuaTextExtents(lua_State *L)
|
||||||
{
|
{
|
||||||
if (!lua_istable(L, 1)) {
|
if (!lua_istable(L, 1))
|
||||||
lua_pushstring(L, "First argument to text_extents must be a table");
|
return luaL_error(L, "First argument to text_extents must be a table");
|
||||||
lua_error(L);
|
|
||||||
}
|
if (!lua_isstring(L, 2))
|
||||||
if (!lua_isstring(L, 2)) {
|
return luaL_error(L, "Second argument to text_extents must be a string");
|
||||||
lua_pushstring(L, "Second argument to text_extents must be a string");
|
|
||||||
lua_error(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_pushvalue(L, 1);
|
lua_pushvalue(L, 1);
|
||||||
AssEntry *et = LuaAssFile::LuaToAssEntry(L);
|
agi::scoped_ptr<AssEntry> et(LuaAssFile::LuaToAssEntry(L));
|
||||||
AssStyle *st = dynamic_cast<AssStyle*>(et);
|
AssStyle *st = dynamic_cast<AssStyle*>(et.get());
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (!st) {
|
if (!st)
|
||||||
delete et; // Make sure to delete the "live" pointer
|
return luaL_error(L, "Not a style entry");
|
||||||
lua_pushstring(L, "Not a style entry");
|
|
||||||
lua_error(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString text(lua_tostring(L, 2), wxConvUTF8);
|
wxString text(lua_tostring(L, 2), wxConvUTF8);
|
||||||
|
|
||||||
double width, height, descent, extlead;
|
double width, height, descent, extlead;
|
||||||
if (!CalculateTextExtents(st, text, width, height, descent, extlead)) {
|
if (!CalculateTextExtents(st, text, width, height, descent, extlead))
|
||||||
delete st;
|
return luaL_error(L, "Some internal error occurred calculating text_extents");
|
||||||
lua_pushstring(L, "Some internal error occurred calculating text_extents");
|
|
||||||
lua_error(L);
|
|
||||||
}
|
|
||||||
delete st;
|
|
||||||
|
|
||||||
lua_pushnumber(L, width);
|
lua_pushnumber(L, width);
|
||||||
lua_pushnumber(L, height);
|
lua_pushnumber(L, height);
|
||||||
|
@ -417,28 +382,20 @@ namespace Automation4 {
|
||||||
if (wxFileName::FileExists(filename)) {
|
if (wxFileName::FileExists(filename)) {
|
||||||
LuaScriptReader script_reader(filename);
|
LuaScriptReader script_reader(filename);
|
||||||
if (lua_load(L, script_reader.reader_func, &script_reader, filename.utf8_str())) {
|
if (lua_load(L, script_reader.reader_func, &script_reader, filename.utf8_str())) {
|
||||||
lua_pushfstring(L, "Error loading Lua module \"%s\":\n\n%s", filename.utf8_str().data(), lua_tostring(L, -1));
|
return luaL_error(L, "Error loading Lua module \"%s\":\n\n%s", filename.utf8_str().data(), lua_tostring(L, -1));
|
||||||
lua_error(L);
|
|
||||||
return lua_gettop(L) - pretop;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lua_gettop(L) - pretop;
|
return lua_gettop(L) - pretop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param L
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
int LuaScript::LuaInclude(lua_State *L)
|
int LuaScript::LuaInclude(lua_State *L)
|
||||||
{
|
{
|
||||||
LuaScript *s = GetScriptObject(L);
|
LuaScript *s = GetScriptObject(L);
|
||||||
|
|
||||||
if (!lua_isstring(L, 1)) {
|
if (!lua_isstring(L, 1))
|
||||||
lua_pushstring(L, "Argument to include must be a string");
|
return luaL_error(L, "Argument to include must be a string");
|
||||||
lua_error(L);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
wxString fnames(lua_tostring(L, 1), wxConvUTF8);
|
wxString fnames(lua_tostring(L, 1), wxConvUTF8);
|
||||||
|
|
||||||
wxFileName fname(fnames);
|
wxFileName fname(fnames);
|
||||||
|
@ -452,63 +409,42 @@ namespace Automation4 {
|
||||||
} else {
|
} else {
|
||||||
// absolute path, do nothing
|
// absolute path, do nothing
|
||||||
}
|
}
|
||||||
if (!fname.IsOk() || !fname.FileExists()) {
|
if (!fname.IsOk() || !fname.FileExists())
|
||||||
lua_pushfstring(L, "Lua include not found: %s", fnames.mb_str(wxConvUTF8).data());
|
return luaL_error(L, "Lua include not found: %s", fnames.utf8_str().data());
|
||||||
lua_error(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
LuaScriptReader script_reader(fname.GetFullPath());
|
LuaScriptReader script_reader(fname.GetFullPath());
|
||||||
if (lua_load(L, script_reader.reader_func, &script_reader, fname.GetFullName().mb_str(wxConvUTF8))) {
|
if (lua_load(L, script_reader.reader_func, &script_reader, fname.GetFullName().utf8_str()))
|
||||||
lua_pushfstring(L, "Error loading Lua include \"%s\":\n\n%s", fname.GetFullPath().mb_str(wxConvUTF8).data(), lua_tostring(L, -1));
|
return luaL_error(L, "Error loading Lua include \"%s\":\n\n%s", fname.GetFullPath().utf8_str().data(), lua_tostring(L, -1));
|
||||||
lua_error(L);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int pretop = lua_gettop(L) - 1; // don't count the function value itself
|
int pretop = lua_gettop(L) - 1; // don't count the function value itself
|
||||||
lua_call(L, 0, LUA_MULTRET);
|
lua_call(L, 0, LUA_MULTRET);
|
||||||
return lua_gettop(L) - pretop;
|
return lua_gettop(L) - pretop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param L
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
int LuaScript::LuaFrameFromMs(lua_State *L)
|
int LuaScript::LuaFrameFromMs(lua_State *L)
|
||||||
{
|
{
|
||||||
int ms = (int)lua_tonumber(L, -1);
|
int ms = lua_tointeger(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (VideoContext::Get()->TimecodesLoaded()) {
|
if (VideoContext::Get()->TimecodesLoaded())
|
||||||
lua_pushnumber(L, VideoContext::Get()->FrameAtTime(ms, agi::vfr::START));
|
lua_pushnumber(L, VideoContext::Get()->FrameAtTime(ms, agi::vfr::START));
|
||||||
return 1;
|
else
|
||||||
} else {
|
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param L
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
int LuaScript::LuaMsFromFrame(lua_State *L)
|
int LuaScript::LuaMsFromFrame(lua_State *L)
|
||||||
{
|
{
|
||||||
int frame = (int)lua_tonumber(L, -1);
|
int frame = lua_tointeger(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
if (VideoContext::Get()->TimecodesLoaded()) {
|
if (VideoContext::Get()->TimecodesLoaded())
|
||||||
lua_pushnumber(L, VideoContext::Get()->TimeAtFrame(frame, agi::vfr::START));
|
lua_pushnumber(L, VideoContext::Get()->TimeAtFrame(frame, agi::vfr::START));
|
||||||
return 1;
|
else
|
||||||
} else {
|
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief DOCME
|
|
||||||
/// @param L
|
|
||||||
/// @return
|
|
||||||
///
|
|
||||||
int LuaScript::LuaVideoSize(lua_State *L)
|
int LuaScript::LuaVideoSize(lua_State *L)
|
||||||
{
|
{
|
||||||
VideoContext *ctx = VideoContext::Get();
|
VideoContext *ctx = VideoContext::Get();
|
||||||
|
@ -577,10 +513,7 @@ namespace Automation4 {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
// add the Feature object
|
// add the Feature object
|
||||||
s->features.push_back(this);
|
myid = s->RegisterFeature(this);
|
||||||
|
|
||||||
// get the index+1 it was pushed into
|
|
||||||
myid = (int)s->features.size()-1;
|
|
||||||
|
|
||||||
// create table with the functions
|
// create table with the functions
|
||||||
// get features table
|
// get features table
|
||||||
|
|
|
@ -271,46 +271,8 @@ namespace Automation4 {
|
||||||
void ThrowError();
|
void ThrowError();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
/// @class LuaScript
|
|
||||||
/// @brief DOCME
|
|
||||||
///
|
|
||||||
/// DOCME
|
|
||||||
class LuaScript : public Script {
|
|
||||||
friend class LuaFeature;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
/// DOCME
|
|
||||||
lua_State *L;
|
|
||||||
|
|
||||||
void Create(); // load script and create internal structures etc.
|
|
||||||
void Destroy(); // destroy internal structures, unreg features and delete environment
|
|
||||||
|
|
||||||
static LuaScript* GetScriptObject(lua_State *L);
|
|
||||||
|
|
||||||
static int LuaTextExtents(lua_State *L);
|
|
||||||
static int LuaInclude(lua_State *L);
|
|
||||||
static int LuaModuleLoader(lua_State *L);
|
|
||||||
static int LuaFrameFromMs(lua_State *L);
|
|
||||||
static int LuaMsFromFrame(lua_State *L);
|
|
||||||
static int LuaVideoSize(lua_State *L);
|
|
||||||
|
|
||||||
public:
|
|
||||||
LuaScript(const wxString &filename);
|
|
||||||
virtual ~LuaScript();
|
|
||||||
|
|
||||||
virtual void Reload();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void LuaThreadedCall(lua_State *L, int nargs, int nresults, wxString const& title, wxWindow *parent, bool can_open_config);
|
void LuaThreadedCall(lua_State *L, int nargs, int nresults, wxString const& title, wxWindow *parent, bool can_open_config);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class LuaFeatureMacro
|
/// @class LuaFeatureMacro
|
||||||
/// @brief DOCME
|
/// @brief DOCME
|
||||||
|
@ -334,8 +296,6 @@ namespace Automation4 {
|
||||||
virtual void Process(AssFile *subs, std::vector<int> &selected, int active, wxWindow * const progress_parent);
|
virtual void Process(AssFile *subs, std::vector<int> &selected, int active, wxWindow * const progress_parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class LuaFeatureFilter
|
/// @class LuaFeatureFilter
|
||||||
/// @brief DOCME
|
/// @brief DOCME
|
||||||
|
@ -367,4 +327,45 @@ namespace Automation4 {
|
||||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LuaScript : public Script {
|
||||||
|
lua_State *L;
|
||||||
|
|
||||||
|
wxString name;
|
||||||
|
wxString description;
|
||||||
|
wxString author;
|
||||||
|
wxString version;
|
||||||
|
|
||||||
|
std::vector<Feature*> features;
|
||||||
|
|
||||||
|
/// load script and create internal structures etc.
|
||||||
|
void Create();
|
||||||
|
/// destroy internal structures, unreg features and delete environment
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
static int LuaTextExtents(lua_State *L);
|
||||||
|
static int LuaInclude(lua_State *L);
|
||||||
|
static int LuaModuleLoader(lua_State *L);
|
||||||
|
static int LuaFrameFromMs(lua_State *L);
|
||||||
|
static int LuaMsFromFrame(lua_State *L);
|
||||||
|
static int LuaVideoSize(lua_State *L);
|
||||||
|
|
||||||
|
public:
|
||||||
|
LuaScript(const wxString &filename);
|
||||||
|
~LuaScript();
|
||||||
|
|
||||||
|
static LuaScript* GetScriptObject(lua_State *L);
|
||||||
|
|
||||||
|
int RegisterFeature(Feature *feature);
|
||||||
|
|
||||||
|
// Script implementation
|
||||||
|
void Reload();
|
||||||
|
|
||||||
|
wxString GetName() const { return name; }
|
||||||
|
wxString GetDescription() const { return description; }
|
||||||
|
wxString GetAuthor() const { return author; }
|
||||||
|
wxString GetVersion() const { return version; }
|
||||||
|
bool GetLoadedState() const { return L != 0; }
|
||||||
|
|
||||||
|
std::vector<Feature*> GetFeatures() const { return features; }
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue