AutomationLine time-unit conversion and paste API update
[ardour.git] / gtk2_ardour / luainstance.cc
index b7963737ccc606ef4d6def4b55ec5c5d045579a9..d8a1ce6382d1bf72c310f42aeb7d88bcd706e703 100644 (file)
@@ -34,6 +34,7 @@
 #include "ardour_ui.h"
 #include "public_editor.h"
 #include "region_selection.h"
+#include "luadialog.h"
 #include "luainstance.h"
 #include "luasignal.h"
 #include "marker.h"
@@ -548,6 +549,51 @@ LuaInstance::bind_cairo (lua_State* L)
 
 }
 
+void
+LuaInstance::bind_dialog (lua_State* L)
+{
+       luabridge::getGlobalNamespace (L)
+               .beginNamespace ("LuaDialog")
+
+               .beginClass <LuaDialog::Message> ("Message")
+               .addConstructor <void (*) (std::string const&, std::string const&, LuaDialog::Message::MessageType, LuaDialog::Message::ButtonType)> ()
+               .addFunction ("run", &LuaDialog::Message::run)
+               .endClass ()
+
+               .beginClass <LuaDialog::Dialog> ("Dialog")
+               .addConstructor <void (*) (std::string const&, luabridge::LuaRef)> ()
+               .addCFunction ("run", &LuaDialog::Dialog::run)
+               .endClass ()
+
+               /* enums */
+               .beginNamespace ("MessageType")
+               .addConst ("Info", LuaDialog::Message::Info)
+               .addConst ("Warning", LuaDialog::Message::Warning)
+               .addConst ("Question", LuaDialog::Message::Question)
+               .addConst ("Error", LuaDialog::Message::Error)
+               .endNamespace ()
+
+               .beginNamespace ("ButtonType")
+               .addConst ("OK", LuaDialog::Message::OK)
+               .addConst ("Close", LuaDialog::Message::Close)
+               .addConst ("Cancel", LuaDialog::Message::Cancel)
+               .addConst ("Yes_No", LuaDialog::Message::Yes_No)
+               .addConst ("OK_Cancel", LuaDialog::Message::OK_Cancel)
+               .endNamespace ()
+
+               .beginNamespace ("Response")
+               .addConst ("OK", 0)
+               .addConst ("Cancel", 1)
+               .addConst ("Close", 2)
+               .addConst ("Yes", 3)
+               .addConst ("No", 4)
+               .addConst ("None", -1)
+               .endNamespace ()
+
+               .endNamespace ();
+
+}
+
 void
 LuaInstance::register_classes (lua_State* L)
 {
@@ -557,6 +603,7 @@ LuaInstance::register_classes (lua_State* L)
        LuaBindings::osc (L);
 
        bind_cairo (L);
+       bind_dialog (L);
        register_hooks (L);
 
        luabridge::getGlobalNamespace (L)
@@ -977,7 +1024,6 @@ LuaInstance::init ()
                        ""
                        "  local function serialize (name, value)"
                        "   local rv = name .. ' = '"
-                       "   collectgarbage()"
                        "   if type(value) == \"number\" or type(value) == \"string\" or type(value) == \"nil\" then"
                        "    return rv .. basic_serialize(value) .. ' '"
                        "   elseif type(value) == \"table\" then"
@@ -985,7 +1031,6 @@ LuaInstance::init ()
                        "    for k,v in pairs(value) do"
                        "     local fieldname = string.format(\"%s[%s]\", name, basic_serialize(k))"
                        "     rv = rv .. serialize(fieldname, v) .. ' '"
-                       "     collectgarbage()" // string concatenation allocates a new string
                        "    end"
                        "    return rv;"
                        "   elseif type(value) == \"function\" then"
@@ -1190,11 +1235,14 @@ LuaInstance::interactive_add (LuaScriptInfo::ScriptType type, int id)
        LuaScriptParamList lsp = LuaScriptParams::script_params (spi, param_function);
 
        ScriptParameterDialog spd (_("Set Script Parameters"), spi, reg, lsp);
-       switch (spd.run ()) {
-               case Gtk::RESPONSE_ACCEPT:
-                       break;
-               default:
-                       return false;
+
+       if (!spd.need_interation ()) {
+               switch (spd.run ()) {
+                       case Gtk::RESPONSE_ACCEPT:
+                               break;
+                       default:
+                               return false;
+               }
        }
 
        LuaScriptParamPtr lspp (new LuaScriptParam("x-script-origin", "", spi->path, false));
@@ -1241,7 +1289,7 @@ LuaInstance::get_action_state ()
        g_free (b64);
 
        XMLNode* script_node = new XMLNode (X_("ActionScript"));
-       script_node->add_property (X_("lua"), LUA_VERSION);
+       script_node->set_property (X_("lua"), LUA_VERSION);
        script_node->add_content (b64s);
 
        return *script_node;
@@ -1600,17 +1648,25 @@ LuaCallback::get_state (void)
                luabridge::LuaRef savedstate ((*_lua_save)());
                saved = savedstate.cast<std::string>();
        }
-       lua.collect_garbage ();
+
+       lua.collect_garbage (); // this may be expensive:
+       /* Editor::instant_save() calls Editor::get_state() which
+        * calls LuaInstance::get_hook_state() which in turn calls
+        * this LuaCallback::get_state() for every registered hook.
+        *
+        * serialize in _lua_save() allocates many small strings
+        * on the lua-stack, collecting them all may take a ms.
+        */
 
        gchar* b64 = g_base64_encode ((const guchar*)saved.c_str (), saved.size ());
        std::string b64s (b64);
        g_free (b64);
 
        XMLNode* script_node = new XMLNode (X_("LuaCallback"));
-       script_node->add_property (X_("lua"), LUA_VERSION);
-       script_node->add_property (X_("id"), _id.to_s ());
-       script_node->add_property (X_("name"), _name);
-       script_node->add_property (X_("signals"), _signals.to_string ());
+       script_node->set_property (X_("lua"), LUA_VERSION);
+       script_node->set_property (X_("id"), _id.to_s ());
+       script_node->set_property (X_("name"), _name);
+       script_node->set_property (X_("signals"), _signals.to_string ());
        script_node->add_content (b64s);
        return *script_node;
 }
@@ -1676,7 +1732,6 @@ LuaCallback::init (void)
                        ""
                        "  local function serialize (name, value)"
                        "   local rv = name .. ' = '"
-                       "   collectgarbage()"
                        "   if type(value) == \"number\" or type(value) == \"string\" or type(value) == \"nil\" then"
                        "    return rv .. basic_serialize(value) .. ' '"
                        "   elseif type(value) == \"table\" then"
@@ -1684,7 +1739,6 @@ LuaCallback::init (void)
                        "    for k,v in pairs(value) do"
                        "     local fieldname = string.format(\"%s[%s]\", name, basic_serialize(k))"
                        "     rv = rv .. serialize(fieldname, v) .. ' '"
-                       "     collectgarbage()" // string concatenation allocates a new string
                        "    end"
                        "    return rv;"
                        "   elseif type(value) == \"function\" then"