Fix scvim regsitry file for updated filename (thanks Carlo Capocasa)
[supercollider.git] / server / supernova / sc / sc_ugen_factory.hpp
blob6e706bd1bf7cd145f97de7320907ba75047c79be
1 // prototype of a supercollider-synthdef-based synth prototype
2 // Copyright (C) 2009 Tim Blechmann
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program; see the file COPYING. If not, write to
16 // the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 // Boston, MA 02111-1307, USA.
19 #ifndef SC_UGEN_FACTORY_HPP
20 #define SC_UGEN_FACTORY_HPP
22 #include <boost/intrusive/set.hpp>
23 #include <boost/intrusive/unordered_set.hpp>
24 #include <boost/checked_delete.hpp>
26 #include "sc_synthdef.hpp"
27 #include "sc_synth.hpp"
28 #include "sc_plugin_interface.hpp"
30 #include "SC_InterfaceTable.h"
31 #include "SC_Unit.h"
33 #include "utilities/named_hash_entry.hpp"
35 namespace nova {
36 namespace bi = boost::intrusive;
38 struct sc_unitcmd_def:
39 public named_hash_entry
41 const UnitCmdFunc func;
43 sc_unitcmd_def(const char * cmd_name, UnitCmdFunc func):
44 named_hash_entry(cmd_name), func(func)
47 void run(Unit * unit, struct sc_msg_iter *args)
49 (func)(unit, args);
53 class sc_ugen_def:
54 public aligned_class,
55 public named_hash_entry
57 private:
58 const size_t alloc_size;
59 const UnitCtorFunc ctor;
60 const UnitDtorFunc dtor;
61 const uint32_t flags;
63 static const std::size_t unitcmd_set_bucket_count = 4;
64 typedef bi::unordered_set< sc_unitcmd_def,
65 bi::constant_time_size<false>,
66 bi::power_2_buckets<true>,
67 bi::store_hash<true>
68 > unitcmd_set_type;
70 unitcmd_set_type::bucket_type unitcmd_set_buckets[unitcmd_set_bucket_count];
71 unitcmd_set_type unitcmd_set;
73 public:
74 sc_ugen_def(const char *inUnitClassName, size_t inAllocSize,
75 UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags):
76 named_hash_entry(inUnitClassName), alloc_size(inAllocSize), ctor(inCtor), dtor(inDtor), flags(inFlags),
77 unitcmd_set(unitcmd_set_type::bucket_traits(unitcmd_set_buckets, unitcmd_set_bucket_count))
80 Unit * construct(sc_synthdef::unit_spec_t const & unit_spec, sc_synth * s, World * world, linear_allocator & allocator);
82 void initialize(Unit * unit)
84 (*ctor)(unit);
87 void destruct(Unit * unit)
89 if (dtor)
90 (*dtor)(unit);
93 bool cant_alias(void) const
95 return flags & kUnitDef_CantAliasInputsToOutputs;
98 std::size_t memory_requirement(void) const
100 return alloc_size;
103 bool add_command(const char * cmd_name, UnitCmdFunc func);
104 void run_unit_command(const char * cmd_name, Unit * unit, struct sc_msg_iter *args);
107 struct sc_bufgen_def:
108 public named_hash_entry
110 const BufGenFunc func;
112 sc_bufgen_def(const char * name, BufGenFunc func):
113 named_hash_entry(name), func(func)
116 sample * run(World * world, uint32_t buffer_index, struct sc_msg_iter *args);
119 struct sc_cmdplugin_def:
120 public named_hash_entry
122 const PlugInCmdFunc func;
123 void * user_data;
125 sc_cmdplugin_def(const char * name, PlugInCmdFunc func, void * user_data):
126 named_hash_entry(name), func(func), user_data(user_data)
129 void run(World * world, struct sc_msg_iter *args, void *replyAddr)
131 (func)(world, user_data, args, replyAddr);
135 class sc_plugin_container
137 static const std::size_t ugen_set_bucket_count = 512;
138 typedef bi::unordered_set< sc_ugen_def,
139 bi::constant_time_size<false>,
140 bi::power_2_buckets<true>,
141 bi::store_hash<true>
142 > ugen_set_type;
144 static const std::size_t bufgen_set_bucket_count = 64;
145 typedef bi::unordered_set< sc_bufgen_def,
146 bi::constant_time_size<false>,
147 bi::power_2_buckets<true>,
148 bi::store_hash<true>
149 > bufgen_set_type;
151 static const std::size_t cmdplugin_set_bucket_count = 8;
152 typedef bi::unordered_set< sc_cmdplugin_def,
153 bi::constant_time_size<false>,
154 bi::power_2_buckets<true>,
155 bi::store_hash<true>
156 > cmdplugin_set_type;
158 ugen_set_type::bucket_type ugen_set_buckets[ugen_set_bucket_count];
159 ugen_set_type ugen_set;
161 bufgen_set_type::bucket_type bufgen_set_buckets[bufgen_set_bucket_count];
162 bufgen_set_type bufgen_set;
164 cmdplugin_set_type::bucket_type cmdplugin_set_buckets[cmdplugin_set_bucket_count];
165 cmdplugin_set_type cmdplugin_set;
167 protected:
168 sc_plugin_container (void):
169 ugen_set(ugen_set_type::bucket_traits(ugen_set_buckets, ugen_set_bucket_count)),
170 bufgen_set(bufgen_set_type::bucket_traits(bufgen_set_buckets, bufgen_set_bucket_count)),
171 cmdplugin_set(cmdplugin_set_type::bucket_traits(cmdplugin_set_buckets, cmdplugin_set_bucket_count))
174 ~sc_plugin_container (void)
176 ugen_set.clear_and_dispose(boost::checked_delete<sc_ugen_def>);
177 bufgen_set.clear_and_dispose(boost::checked_delete<sc_bufgen_def>);
178 cmdplugin_set.clear_and_dispose(boost::checked_delete<sc_cmdplugin_def>);
181 public:
182 void register_ugen(const char *inUnitClassName, size_t inAllocSize,
183 UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags);
185 void register_bufgen(const char * name, BufGenFunc func);
187 sc_ugen_def * find_ugen(c_string const & name);
189 bool register_ugen_command_function(const char * ugen_name, const char * cmd_name, UnitCmdFunc);
190 bool register_cmd_plugin(const char * cmd_name, PlugInCmdFunc func, void * user_data);
192 sample * run_bufgen(World * world, const char * name, uint32_t buffer_index, struct sc_msg_iter *args);
193 bool run_cmd_plugin(World * world , const char * name, struct sc_msg_iter *args, void *replyAddr);
196 /** factory class for supercollider ugens
198 * \todo do we need to take care of thread safety? */
199 class sc_ugen_factory:
200 public sc_plugin_interface,
201 public sc_plugin_container
203 public:
204 ~sc_ugen_factory(void)
206 close_handles();
209 /* @{ */
210 /** ugen count handling */
211 void allocate_ugens(uint32_t count)
213 ugen_count_ += count;
216 void free_ugens(uint32_t count)
218 ugen_count_ -= count;
221 uint32_t ugen_count(void) const
223 return ugen_count_;
225 /* @} */
227 void load_plugin_folder(boost::filesystem::path const & path);
228 void load_plugin(boost::filesystem::path const & path);
230 private:
231 void close_handles(void);
233 uint32_t ugen_count_;
234 std::vector<void*> open_handles;
237 extern sc_ugen_factory * sc_factory;
239 } /* namespace nova */
242 #endif /* SC_UGEN_FACTORY_HPP */