1 /* 2 * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert 3 * Copyright (C) 2011 Pete Shorthose 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #pragma once 21 22 #ifndef SRC_HEADERS_JSONRPC_H_ 23 #define SRC_HEADERS_JSONRPC_H_ 24 25 #include "engine.h" 26 #include <bitset> 27 #include <queue> 28 #include <giomm/init.h> // NOLINT 29 #include <giomm/socketservice.h> 30 #include "jsonrpc_methods.h" 31 32 class GxService; 33 34 class JsonValue { 35 protected: JsonValue()36 JsonValue() {} ~JsonValue()37 virtual ~JsonValue() {} 38 friend class JsonArray; 39 public: 40 virtual double getFloat() const; 41 virtual int getInt() const; 42 virtual const Glib::ustring& getString() const; 43 virtual gx_system::JsonSubParser getSubParser() const; 44 }; 45 46 class JsonArray: public std::vector<JsonValue*> { 47 public: JsonArray()48 JsonArray():std::vector<JsonValue*>() {} 49 ~JsonArray(); 50 JsonValue *operator[](unsigned int i); 51 void append(gx_system::JsonParser& jp); 52 }; 53 54 class CmdConnection: public sigc::trackable { 55 public: 56 struct methodnames { 57 const char *name; 58 jsonrpc_method m_id; 59 }; 60 enum msg_type { 61 f_preset_changed, 62 f_state_changed, 63 f_freq_changed, 64 f_display, 65 f_display_state, 66 f_selection_done, 67 f_presetlist_changed, 68 f_log_message, 69 f_midi_changed, 70 f_midi_value_changed, 71 f_parameter_change_notify, 72 f_plugins_changed, 73 f_misc_msg, 74 f_units_changed, 75 END_OF_FLAGS 76 }; 77 private: 78 GxService& serv; 79 Glib::RefPtr<Gio::SocketConnection> connection; 80 std::list<std::string> outgoing; 81 unsigned int current_offset; 82 gx_system::JsonStringParser jp; 83 bool midi_config_mode; 84 std::bitset<END_OF_FLAGS> flags; 85 std::map<string,float> maxlevel; 86 private: 87 bool find_token(const Glib::ustring& token, msg_type *start, msg_type *end); activate(int n,bool v)88 void activate(int n, bool v) { flags.set(n, v); } 89 void exec(Glib::ustring cmd); 90 void call(gx_system::JsonWriter& jw, const methodnames *mn, JsonArray& params); 91 void notify(gx_system::JsonStringWriter& jw, const methodnames *mn, JsonArray& params); 92 bool request(gx_system::JsonStringParser& jp, gx_system::JsonStringWriter& jw, bool batch_start); 93 void write_error(gx_system::JsonWriter& jw, int code, const char *message); write_error(gx_system::JsonWriter & jw,int code,Glib::ustring & message)94 void write_error(gx_system::JsonWriter& jw, int code, Glib::ustring& message) { write_error(jw, code, message.c_str()); } 95 void error_response(gx_system::JsonWriter& jw, int code, const char *message); error_response(gx_system::JsonWriter & jw,int code,const Glib::ustring & message)96 void error_response(gx_system::JsonWriter& jw, int code, const Glib::ustring& message) { error_response(jw, code, message.c_str()); } send_notify_begin(gx_system::JsonStringWriter & jw,const char * method)97 void send_notify_begin(gx_system::JsonStringWriter& jw, const char *method) { jw.send_notify_begin(method); } 98 void send_notify_end(gx_system::JsonStringWriter& jw, bool send_out=true); 99 void listen(const Glib::ustring& tp); 100 void unlisten(const Glib::ustring& tp); 101 void process(gx_system::JsonStringParser& jp); 102 103 public: 104 CmdConnection(GxService& serv, const Glib::RefPtr<Gio::SocketConnection>& connection_); 105 ~CmdConnection(); 106 bool on_data_in(Glib::IOCondition cond); 107 bool on_data_out(Glib::IOCondition cond); 108 void send(gx_system::JsonStringWriter& jw); is_activated(msg_type n)109 bool is_activated(msg_type n) { return flags[n]; } update_maxlevel(const std::string & id,float v)110 void update_maxlevel(const std::string& id, float v) { float& m = maxlevel[id]; m = max(m, v); } 111 friend class UiBuilderVirt; 112 }; 113 114 struct broadcast_data { 115 gx_system::JsonStringWriter *jw; 116 CmdConnection::msg_type n; 117 CmdConnection *sender; 118 }; 119 120 class GxService: public Gio::SocketService { 121 private: 122 struct ChangedPlugin { 123 std::string id; 124 gx_engine::PluginChange::pc status; ChangedPluginChangedPlugin125 ChangedPlugin(const std::string& id_, gx_engine::PluginChange::pc status_): id(id_), status(status_) {} 126 }; 127 private: 128 gx_preset::GxSettings& settings; 129 gx_jack::GxJack& jack; 130 TunerSwitcher& tuner_switcher; 131 sigc::slot<void> quit_mainloop; 132 time_t oldest_unsaved; 133 time_t last_change; 134 sigc::connection save_conn; 135 std::list<CmdConnection*> connection_list; 136 std::queue<broadcast_data> broadcast_list; 137 gx_system::JsonStringWriter *jwc; 138 std::map<std::string,bool> *preg_map; 139 std::map<std::string,float> maxlevel; 140 private: 141 virtual bool on_incoming(const Glib::RefPtr<Gio::SocketConnection>& connection, 142 const Glib::RefPtr<Glib::Object>& source_object); 143 void save_state(); 144 void remove_connection(CmdConnection* p); 145 bool broadcast_listeners(CmdConnection::msg_type n, CmdConnection *sender = 0); 146 void broadcast(gx_system::JsonStringWriter& jw, CmdConnection::msg_type n, CmdConnection *sender = 0); 147 bool idle_broadcast_handler(); 148 void connect_value_changed_signal(gx_engine::Parameter *p); 149 150 // message formatting functions 151 void serialize_parameter_change(gx_system::JsonWriter& jw); 152 void ladspaloader_write_changes(gx_system::JsonWriter& jw, std::vector<ChangedPlugin>& changed_plugins); 153 154 // signal handler 155 void on_param_insert_remove(gx_engine::Parameter *p, bool insert); 156 void on_param_value_changed(gx_engine::Parameter *p); 157 void preset_changed(); 158 void on_engine_state_change(gx_engine::GxEngineState state); 159 void on_tuner_freq_changed(); 160 void display(const Glib::ustring& bank, const Glib::ustring& preset); 161 void set_display_state(TunerSwitcher::SwitcherState newstate); 162 void on_selection_done(bool v); 163 void on_presetlist_changed(); 164 void on_log_message(const string& msg, GxLogger::MsgType tp, bool plugged); 165 void on_midi_changed(); 166 void on_midi_value_changed(int ctl, int value); 167 void on_rack_unit_changed(bool stereo); 168 static void add_changed_plugin(gx_engine::Plugin* pl, gx_engine::PluginChange::pc v, 169 std::vector<ChangedPlugin>& vec); 170 void create_bluetooth_sockets(const Glib::ustring& host); 171 172 friend class CmdConnection; 173 public: 174 GxService(gx_preset::GxSettings& settings_, gx_jack::GxJack& jack_, 175 TunerSwitcher& tunerswitcher, sigc::slot<void> quit_mainloop_, 176 const Glib::ustring& host, int *port); 177 ~GxService(); 178 void send_rack_changed(bool stereo, CmdConnection *cmd); 179 void ladspaloader_update_plugins(gx_system::JsonWriter *jw, CmdConnection *cmd); 180 float update_maxlevel(const std::string& id, bool reset=false); 181 }; 182 183 const char *engine_state_to_string(gx_engine::GxEngineState s); 184 gx_engine::GxEngineState string_to_engine_state(const std::string& s); 185 186 #endif // SRC_HEADERS_JSONRPC_H_ 187