|
libpsynth 0.2.1
|
00001 /*************************************************************************** 00002 * * 00003 * PSYCHOSYNTH * 00004 * =========== * 00005 * * 00006 * Copyright (C) 2007 by Juan Pedro Bolivar Puente * 00007 * * 00008 * This program is free software: you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation, either version 3 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 00020 * * 00021 ***************************************************************************/ 00022 00023 #ifndef PSYNTH_WORLD_H 00024 #define PSYNTH_WORLD_H 00025 00026 #include <list> 00027 #include <map> 00028 #include <iostream> 00029 00030 #include <psynth/synth/audio_info.hpp> 00031 #include <psynth/world/patcher.hpp> 00032 #include <psynth/graph/node.hpp> 00033 #include <psynth/graph/node_output.hpp> 00034 #include <psynth/graph/node_mixer.hpp> 00035 #include <psynth/graph/node_manager.hpp> 00036 #include <psynth/graph/node_factory_manager.hpp> 00037 00038 namespace psynth 00039 { 00040 00041 class world; 00042 class world_node_listener; 00043 00044 class world_node 00045 { 00046 friend class world; 00047 00048 graph::node* m_nod; /* TODO: Use node_manager::Iterator instead? */ 00049 world* m_world; 00050 00051 world_node (graph::node* nod, world* world) : 00052 m_nod (nod), m_world (world) {}; 00053 00054 public: 00055 world_node () 00056 : m_nod (NULL) 00057 , m_world (NULL) 00058 {} 00059 00060 world_node(const world_node& o) 00061 : m_nod(o.m_nod) 00062 , m_world(o.m_world) 00063 {}; 00064 00065 bool is_null () const { 00066 return m_nod == NULL; 00067 }; 00068 00069 int get_id () const { 00070 return m_nod->get_id (); 00071 }; 00072 00073 int get_type () const { 00074 return m_nod->get_type (); 00075 }; 00076 00077 const std::string& get_name () { 00078 return m_nod->get_name (); 00079 }; 00080 00081 world* get_world() { 00082 return m_world; 00083 } 00084 00085 inline void add_listener (world_node_listener* cl); 00086 00087 inline void delete_listener (world_node_listener* cl); 00088 00089 inline void delete_me (); 00090 00091 inline void activate (); 00092 00093 inline void deactivate (); 00094 00095 template <typename T> 00096 inline void set_param (int id, const T& data); 00097 00098 template <typename T> 00099 inline void set_param (const std::string& name, const T& data); 00100 00101 void attach_watch (int type, int in_sock, graph::watch* watch) { 00102 m_nod->attach_watch (type, in_sock, watch); 00103 } 00104 00105 void detach_watch (int type, int in_sock, graph::watch* watch) { 00106 m_nod->detach_watch (type, in_sock, watch); 00107 } 00108 00109 int get_param_id (const std::string& name) const { 00110 return m_nod->get_param(name).get_id (); 00111 } 00112 00113 const std::string& get_param_name (int id) const { 00114 return m_nod->param(id).get_name (); 00115 } 00116 00117 int get_param_type (int id) const { 00118 return m_nod->param(id).type(); 00119 } 00120 00121 int get_param_type (const std::string& name) const { 00122 return m_nod->get_param(name).type(); 00123 } 00124 00125 template <typename T> 00126 void get_param (int id, T& data) const { 00127 m_nod->param(id).get(data); 00128 } 00129 00130 template <typename T> 00131 void get_param (const std::string& name, T& data) const { 00132 m_nod->get_param(name).get(data); 00133 } 00134 00135 bool operator== (const world_node& o) const { 00136 return m_nod == o.m_nod; 00137 } 00138 00139 bool operator!= (const world_node& o) const { 00140 return m_nod != o.m_nod; 00141 } 00142 }; 00143 00144 class world_listener 00145 { 00146 public: 00147 virtual ~world_listener() {}; 00148 virtual void handle_add_node (world_node& nod) = 0; 00149 virtual void handle_delete_node (world_node& nod) = 0; 00150 }; 00151 00152 class world_node_listener 00153 { 00154 public: 00155 virtual ~world_node_listener () {}; 00156 virtual void handle_activate_node (world_node& nod) = 0; 00157 virtual void handle_deactivate_node (world_node& nod) = 0; 00158 virtual void handle_set_param_node (world_node& ob, int id) = 0; 00159 }; 00160 00161 struct world_patcher_event 00162 { 00163 world_node src; 00164 world_node dest; 00165 int src_socket; 00166 int dest_socket; 00167 int socket_type; 00168 00169 world_patcher_event (const world_node& s, const world_node& d, 00170 int ss, int ds, int st) : 00171 src(s), dest(d), src_socket(ss), dest_socket(ds), socket_type(st) {} 00172 }; 00173 00174 class world_patcher_listener 00175 { 00176 public: 00177 virtual ~world_patcher_listener () {}; 00178 virtual void handle_link_added (const world_patcher_event& ev) = 0; 00179 virtual void handle_link_deleted (const world_patcher_event& ev) = 0; 00180 }; 00181 00182 class world_subject 00183 { 00184 typedef std::list<world_node_listener*>::iterator node_listener_iter; 00185 typedef std::list<world_listener*>::iterator listener_iter; 00186 00187 std::list<world_listener*> m_listeners; 00188 std::list<world_patcher_listener*> m_patch_list; 00189 std::map<int, std::list<world_node_listener*> > m_nod_listeners; 00190 std::list<world_node_listener*> m_all_nod_list; 00191 00192 protected: 00193 void notify_add_node (world_node& nod); 00194 void notify_delete_node (world_node& nod); 00195 void notify_activate_node (world_node& nod); 00196 void notify_deactivate_node (world_node& nod); 00197 void notify_set_param_node (world_node& nod, int param_id); 00198 void notify_link_added (const world_patcher_event& ev); 00199 void notify_link_deleted (const world_patcher_event& ev); 00200 00201 public: 00202 void add_world_listener (world_listener* cl) { 00203 m_listeners.push_back(cl); 00204 }; 00205 00206 void add_world_patcher_listener (world_patcher_listener* cl) { 00207 m_patch_list.push_back(cl); 00208 }; 00209 00210 void add_world_node_listener (world_node_listener* cl) { 00211 m_all_nod_list.push_back(cl); 00212 }; 00213 00214 void add_world_node_listener (world_node& nod, world_node_listener* cl) { 00215 std::map<int, std::list<world_node_listener*> >::iterator it; 00216 00217 if ((it = m_nod_listeners.find(nod.get_id ())) != m_nod_listeners.end()) 00218 it->second.push_back(cl); 00219 }; 00220 00221 void delete_world_listener (world_listener* cl) { 00222 m_listeners.remove(cl); 00223 }; 00224 00225 void delete_world_patcher_listener (world_patcher_listener* cl) { 00226 m_patch_list.remove(cl); 00227 }; 00228 00229 void delete_world_node_listener (world_node_listener* cl) { 00230 m_all_nod_list.remove(cl); 00231 }; 00232 00233 void delete_world_node_listener (world_node& nod, world_node_listener* cl) { 00234 std::map<int, std::list<world_node_listener*> >::iterator it; 00235 00236 if ((it = m_nod_listeners.find(nod.get_id())) != m_nod_listeners.end()) 00237 it->second.remove(cl); 00238 }; 00239 }; 00240 00241 class world : public world_subject, 00242 public patcher_listener 00243 { 00244 audio_info m_info; 00245 00246 base::mgr_auto_ptr<patcher> m_patcher; 00247 00248 graph::node_manager m_node_mgr; 00249 graph::node_output* m_output; 00250 graph::node_audio_mixer* m_mixer; 00251 int m_last_id; 00252 graph::node_factory_manager m_nodfact; 00253 00254 static const int MIXER_CHANNELS = 16; 00255 00256 void register_default_node_factory (); 00257 00258 public: 00259 enum { 00260 OUTPUT_ID = 0, 00261 MIXER_ID, 00262 MIN_USER_ID = 1024 00263 }; 00264 00265 world (const audio_info& info); 00266 ~world (); 00267 00268 void clear (); 00269 00270 const audio_info& get_info () const { 00271 return m_info; 00272 }; 00273 00274 void set_info (const audio_info& info) { 00275 if (m_info != info) 00276 m_node_mgr.set_info (info); 00277 } 00278 00279 void register_node_factory (graph::node_factory& f) { 00280 m_nodfact.register_factory (f); 00281 } 00282 00283 world_node find_node (int id); 00284 00285 world_node add_node (int type); 00286 world_node add_node (const std::string& type_name); 00287 00288 template <typename T> 00289 void set_param_node (world_node& nod, int id, const T& data) { 00290 nod.m_nod->param(id).set(data); 00291 notify_set_param_node (nod, id); 00292 if (m_patcher) 00293 m_patcher->set_param_node (nod.m_nod, id); 00294 } 00295 00296 template <typename T> 00297 void set_param_node (world_node& nod, const std::string& name, const T& data) { 00298 graph::node_param& param = nod.m_nod->get_param(name); 00299 param.set (data); 00300 notify_set_param_node (nod, param.get_id()); 00301 if (m_patcher) 00302 m_patcher->set_param_node (nod.m_nod, param.get_id()); 00303 } 00304 00305 void delete_node (world_node& nod); 00306 00307 void activate_node (world_node& nod); 00308 00309 void deactivate_node (world_node& nod); 00310 00311 void attach_output (graph::audio_async_output_ptr out) { 00312 m_output->attach_output (out); 00313 }; 00314 00315 void attach_passive_output (graph::audio_output_ptr out) { 00316 m_output->attach_passive_output (out); 00317 }; 00318 00319 void detach_output (graph::audio_async_output_ptr out) { 00320 m_output->detach_output (out); 00321 }; 00322 00323 void detach_passive_output (graph::audio_output_ptr out) { 00324 m_output->detach_passive_output (out); 00325 }; 00326 00327 void set_patcher (base::mgr_ptr<patcher> pat); 00328 00329 void unset_patcher (); 00330 00331 void update () { 00332 if (m_patcher) 00333 m_patcher->update(); 00334 } 00335 00336 void handle_link_added (const patcher_event& ev) { 00337 notify_link_added (world_patcher_event (world_node(ev.src,this), 00338 world_node(ev.dest,this), 00339 ev.src_socket, 00340 ev.dest_socket, 00341 ev.socket_type)); 00342 }; 00343 00344 void handle_link_deleted (const patcher_event& ev) { 00345 notify_link_deleted (world_patcher_event (world_node(ev.src,this), 00346 world_node(ev.dest,this), 00347 ev.src_socket, 00348 ev.dest_socket, 00349 ev.socket_type)); 00350 } 00351 }; 00352 00353 template <typename T> 00354 void world_node::set_param (int id, const T& data) { 00355 m_world->set_param_node (*this, id, data); 00356 }; 00357 00358 template <typename T> 00359 void world_node::set_param (const std::string& name, const T& data) { 00360 m_world->set_param_node (*this, name, data); 00361 }; 00362 00363 void world_node::add_listener (world_node_listener* cl) { 00364 m_world->add_world_node_listener (*this, cl); 00365 } 00366 00367 void world_node::delete_listener (world_node_listener* cl) { 00368 m_world->delete_world_node_listener (*this, cl); 00369 } 00370 00371 void world_node::activate () { 00372 m_world->activate_node (*this); 00373 } 00374 00375 void world_node::delete_me () { 00376 m_world->delete_node (*this); 00377 } 00378 00379 void world_node::deactivate () { 00380 m_world->deactivate_node (*this); 00381 } 00382 00383 } /* namespace psynth */ 00384 00385 #endif /* PSYNTH_WORLD_H */
1.7.4