/* * Copyright (C) 2016-2018 Robin Gareus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include "pbd/id.h" #include "pbd/signals.h" #include "pbd/xml++.h" #include "ardour/luascripting.h" #include "ardour/lua_script_params.h" #include "ardour/luabindings.h" #include "ardour/session_handle.h" #include "lua/luastate.h" #include "luasignal.h" namespace luabridge { class LuaRef; } namespace Gtk { class Window; } typedef std::bitset ActionHook; class LuaCallback : public ARDOUR::SessionHandlePtr, public sigc::trackable { public: LuaCallback (ARDOUR::Session*, const std::string&, const std::string&, const ActionHook&, const ARDOUR::LuaScriptParamList&); LuaCallback (ARDOUR::Session*, XMLNode & node); ~LuaCallback (); XMLNode& get_state () const; void set_session (ARDOUR::Session *); const PBD::ID& id () const { return _id; } const std::string& name () const { return _name; } ActionHook signals () const { return _signals; } bool lua_slot (std::string&, std::string&, ActionHook&, ARDOUR::LuaScriptParamList&); PBD::Signal0 drop_callback; protected: void session_going_away (); private: LuaState lua; PBD::ID _id; std::string _name; ActionHook _signals; void reconnect (); template void reconnect_object (T); void init (); luabridge::LuaRef * _lua_add; luabridge::LuaRef * _lua_get; luabridge::LuaRef * _lua_call; luabridge::LuaRef * _lua_save; luabridge::LuaRef * _lua_load; PBD::ScopedConnectionList _connections; template void connect_0 (enum LuaSignal::LuaSignal, T, S*); template void proxy_0 (enum LuaSignal::LuaSignal, T); template void connect_1 (enum LuaSignal::LuaSignal, T, PBD::Signal1*); template void proxy_1 (enum LuaSignal::LuaSignal, T, C1); template void connect_2 (enum LuaSignal::LuaSignal, T, PBD::Signal2*); template void proxy_2 (enum LuaSignal::LuaSignal, T, C1, C2); template void connect_3 (enum LuaSignal::LuaSignal, T, PBD::Signal3*); template void proxy_3 (enum LuaSignal::LuaSignal, T, C1, C2, C3); template void connect_4 (enum LuaSignal::LuaSignal, T, PBD::Signal4*); template void proxy_4 (enum LuaSignal::LuaSignal, T, C1, C2, C3, C4); }; typedef std::shared_ptr LuaCallbackPtr; typedef std::map LuaCallbackMap; class LuaInstance : public PBD::ScopedConnectionList, public ARDOUR::SessionHandlePtr { public: static LuaInstance* instance(); static void destroy_instance(); ~LuaInstance(); static void register_classes (lua_State* L, bool sandbox); static void register_hooks (lua_State* L); static void bind_cairo (lua_State* L); static void bind_dialog (lua_State* L); static void render_action_icon (cairo_t* cr, int w, int h, uint32_t c, void* i); void set_session (ARDOUR::Session* s); int set_state (const XMLNode&); XMLNode& get_action_state (void); XMLNode& get_hook_state (void); int load_state (); int save_state (); bool interactive_add (Gtk::Window&, ARDOUR::LuaScriptInfo::ScriptType, int); /* actions */ void call_action (const int); void render_icon (int i, cairo_t*, int, int, uint32_t); bool set_lua_action (const int, const std::string&, const std::string&, const ARDOUR::LuaScriptParamList&); bool remove_lua_action (const int); bool lua_action_name (const int, std::string&); std::vector lua_action_names (); bool lua_action (const int, std::string&, std::string&, ARDOUR::LuaScriptParamList&); bool lua_action_has_icon (const int); sigc::signal ActionChanged; /* callbacks */ bool register_lua_slot (const std::string&, const std::string&, const ARDOUR::LuaScriptParamList&); bool unregister_lua_slot (const PBD::ID&); std::vector lua_slots () const; bool lua_slot_name (const PBD::ID&, std::string&) const; std::vector lua_slot_names () const; bool lua_slot (const PBD::ID&, std::string&, std::string&, ActionHook&, ARDOUR::LuaScriptParamList&); sigc::signal SlotChanged; static PBD::Signal0 LuaTimerS; // deci-seconds (Timer every 1s) static PBD::Signal0 LuaTimerDS; // deci-seconds (Timer every .1s) static PBD::Signal0 SetSession; // emitted when a session is loaded static PBD::Signal0 SelectionChanged; // emitted when editor selection changes private: LuaInstance(); static LuaInstance* _instance; void init (); void set_dirty (); void session_going_away (); void pre_seed_scripts (); void pre_seed_script (std::string const&, int&); LuaState lua; luabridge::LuaRef * _lua_call_action; luabridge::LuaRef * _lua_render_icon; luabridge::LuaRef * _lua_add_action; luabridge::LuaRef * _lua_del_action; luabridge::LuaRef * _lua_get_action; luabridge::LuaRef * _lua_load; luabridge::LuaRef * _lua_save; luabridge::LuaRef * _lua_clear; LuaCallbackMap _callbacks; PBD::ScopedConnectionList _slotcon; void selection_changed (); void every_second (); sigc::connection second_connection; void every_point_one_seconds (); sigc::connection point_one_second_connection; };