Profile Session::save_state
[ardour.git] / libs / ardour / session_state.cc
index fcd16788d839ddf95faee637c25d70f61442de51..db7cbf2c0a594ac2ddf47306b2f04a77e8f3af1b 100644 (file)
 
 #include "control_protocol/control_protocol.h"
 
+#include "LuaBridge/LuaBridge.h"
+
 #include "i18n.h"
 #include <locale.h>
 
@@ -780,6 +782,10 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                return 1;
        }
 
+#ifndef NDEBUG
+       const int64_t save_start_time = g_get_monotonic_time();
+#endif
+
        /* tell sources we're saving first, in case they write out to a new file
         * which should be saved with the state rather than the old one */
        for (SourceMap::const_iterator i = sources.begin(); i != sources.end(); ++i) {
@@ -877,6 +883,10 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
                StateSaved (snapshot_name); /* EMIT SIGNAL */
        }
 
+#ifndef NDEBUG
+       const int64_t elapsed_time_us = g_get_monotonic_time() - save_start_time;
+       cerr << "saved state in " << setprecision (1) << elapsed_time_us / 1000. << " ms\n";
+#endif
        return 0;
 }
 
@@ -1249,6 +1259,26 @@ Session::state (bool full_state)
                node->add_child_copy (*_extra_xml);
        }
 
+       {
+               Glib::Threads::Mutex::Lock lm (lua_lock);
+               std::string saved;
+               {
+                       luabridge::LuaRef savedstate ((*_lua_save)());
+                       saved = savedstate.cast<std::string>();
+               }
+               lua.collect_garbage ();
+               lm.release ();
+
+               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_("Script"));
+               script_node->add_property (X_("lua"), LUA_VERSION);
+               script_node->add_content (b64s);
+               node->add_child_nocopy (*script_node);
+       }
+
        return *node;
 }
 
@@ -1459,6 +1489,21 @@ Session::set_state (const XMLNode& node, int version)
                ControlProtocolManager::instance().set_state (*child, version);
        }
 
+       if ((child = find_named_node (node, "Script"))) {
+               for (XMLNodeList::const_iterator n = child->children ().begin (); n != child->children ().end (); ++n) {
+                       if (!(*n)->is_content ()) { continue; }
+                       gsize size;
+                       guchar* buf = g_base64_decode ((*n)->content ().c_str (), &size);
+                       try {
+                               Glib::Threads::Mutex::Lock lm (lua_lock);
+                               (*_lua_load)(std::string ((const char*)buf, size));
+                       } catch (luabridge::LuaException const& e) {
+                               cerr << "LuaException:" << e.what () << endl;
+                       }
+                       g_free (buf);
+               }
+       }
+
        update_route_record_state ();
 
        /* here beginneth the second phase ... */