summaryrefslogtreecommitdiff
path: root/gtk2_ardour/luainstance.h
blob: adf2ff4a16ddc7ef23374cc67be6d8bc2b6a3b90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
 * Copyright (C) 2016-2018 Robin Gareus <robin@gareus.org>
 *
 * 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.
 */

#ifndef __gtkardour_luainstance_h__
#define __gtkardour_luainstance_h__

#include <bitset>

#include <cairo.h>

#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;
}

typedef std::bitset<LuaSignal::LAST_SIGNAL> 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 (void);
	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<void> drop_callback;

protected:
	void session_going_away ();

private:
	LuaState lua;

	PBD::ID _id;
	std::string _name;
	ActionHook _signals;

	void reconnect ();
	template <class T> 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 <typename T, typename S> void connect_0 (enum LuaSignal::LuaSignal, T, S*);
	template <typename T> void proxy_0 (enum LuaSignal::LuaSignal, T);

	template <typename T, typename C1> void connect_1 (enum LuaSignal::LuaSignal, T, PBD::Signal1<void, C1>*);
	template <typename T, typename C1> void proxy_1 (enum LuaSignal::LuaSignal, T, C1);

	template <typename T, typename C1, typename C2> void connect_2 (enum LuaSignal::LuaSignal, T, PBD::Signal2<void, C1, C2>*);
	template <typename T, typename C1, typename C2> void proxy_2 (enum LuaSignal::LuaSignal, T, C1, C2);

	template <typename T, typename C1, typename C2, typename C3> void connect_3 (enum LuaSignal::LuaSignal, T, PBD::Signal3<void, C1, C2, C3>*);
	template <typename T, typename C1, typename C2, typename C3> void proxy_3 (enum LuaSignal::LuaSignal, T, C1, C2, C3);
};

typedef boost::shared_ptr<LuaCallback> LuaCallbackPtr;
typedef std::map<PBD::ID, LuaCallbackPtr> 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);
	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 (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<std::string> lua_action_names ();
	bool lua_action (const int, std::string&, std::string&, ARDOUR::LuaScriptParamList&);
	bool lua_action_has_icon (const int);
	sigc::signal<void,int,std::string> ActionChanged;

	/* callbacks */
	bool register_lua_slot (const std::string&, const std::string&, const ARDOUR::LuaScriptParamList&);
	bool unregister_lua_slot (const PBD::ID&);
	std::vector<PBD::ID> lua_slots () const;
	bool lua_slot_name (const PBD::ID&, std::string&) const;
	std::vector<std::string> lua_slot_names () const;
	bool lua_slot (const PBD::ID&, std::string&, std::string&, ActionHook&, ARDOUR::LuaScriptParamList&);
	sigc::signal<void,PBD::ID,std::string,ActionHook> SlotChanged;

	static PBD::Signal0<void> LuaTimerS; // deci-seconds (Timer every 1s)
	static PBD::Signal0<void> LuaTimerDS; // deci-seconds (Timer every .1s)
	static PBD::Signal0<void> SetSession; // emitted when a session is loaded

private:
	LuaInstance();
	static LuaInstance* _instance;

	void init ();
	void set_dirty ();
	void session_going_away ();
	void pre_seed_scripts ();

	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 every_second ();
	sigc::connection second_connection;

	void every_point_one_seconds ();
	sigc::connection point_one_second_connection;
};

#endif