bumping version to 3.5-rc1
[supercollider.git] / server / supernova / sc / sc_ugen_factory.hpp
blob4534b19750fade30964ac23d141e430795b05b95
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
37 namespace bi = boost::intrusive;
39 struct sc_unitcmd_def:
40 public named_hash_entry
42 const UnitCmdFunc func;
44 sc_unitcmd_def(const char * cmd_name, UnitCmdFunc func):
45 named_hash_entry(cmd_name), func(func)
48 void run(Unit * unit, struct sc_msg_iter *args)
50 (func)(unit, args);
54 class sc_ugen_def:
55 public aligned_class,
56 public named_hash_entry
58 private:
59 const size_t alloc_size;
60 const UnitCtorFunc ctor;
61 const UnitDtorFunc dtor;
62 const uint32_t flags;
64 static const std::size_t unitcmd_set_bucket_count = 4;
65 typedef bi::unordered_set< sc_unitcmd_def,
66 bi::constant_time_size<false>,
67 bi::power_2_buckets<true>,
68 bi::store_hash<true>
69 > unitcmd_set_type;
71 unitcmd_set_type::bucket_type unitcmd_set_buckets[unitcmd_set_bucket_count];
72 unitcmd_set_type unitcmd_set;
74 public:
75 sc_ugen_def(const char *inUnitClassName, size_t inAllocSize,
76 UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags):
77 named_hash_entry(inUnitClassName), alloc_size(inAllocSize), ctor(inCtor), dtor(inDtor), flags(inFlags),
78 unitcmd_set(unitcmd_set_type::bucket_traits(unitcmd_set_buckets, unitcmd_set_bucket_count))
81 Unit * construct(sc_synthdef::unit_spec_t const & unit_spec, sc_synth * s, World * world, char *& chunk);
83 void initialize(Unit * unit)
85 (*ctor)(unit);
88 void destruct(Unit * unit)
90 if (dtor)
91 (*dtor)(unit);
94 bool cant_alias(void) const
96 return flags & kUnitDef_CantAliasInputsToOutputs;
99 std::size_t memory_requirement(void) const
101 return alloc_size;
104 bool add_command(const char * cmd_name, UnitCmdFunc func);
105 void run_unit_command(const char * cmd_name, Unit * unit, struct sc_msg_iter *args);
108 struct sc_bufgen_def:
109 public named_hash_entry
111 const BufGenFunc func;
113 sc_bufgen_def(const char * name, BufGenFunc func):
114 named_hash_entry(name), func(func)
117 sample * run(World * world, uint32_t buffer_index, struct sc_msg_iter *args);
120 struct sc_cmdplugin_def:
121 public named_hash_entry
123 const PlugInCmdFunc func;
124 void * user_data;
126 sc_cmdplugin_def(const char * name, PlugInCmdFunc func, void * user_data):
127 named_hash_entry(name), func(func), user_data(user_data)
130 void run(World * world, struct sc_msg_iter *args, void *replyAddr)
132 (func)(world, user_data, args, replyAddr);
136 class sc_plugin_container
138 static const std::size_t ugen_set_bucket_count = 512;
139 typedef bi::unordered_set< sc_ugen_def,
140 bi::constant_time_size<false>,
141 bi::power_2_buckets<true>,
142 bi::store_hash<true>
143 > ugen_set_type;
145 static const std::size_t bufgen_set_bucket_count = 64;
146 typedef bi::unordered_set< sc_bufgen_def,
147 bi::constant_time_size<false>,
148 bi::power_2_buckets<true>,
149 bi::store_hash<true>
150 > bufgen_set_type;
152 static const std::size_t cmdplugin_set_bucket_count = 8;
153 typedef bi::unordered_set< sc_cmdplugin_def,
154 bi::constant_time_size<false>,
155 bi::power_2_buckets<true>,
156 bi::store_hash<true>
157 > cmdplugin_set_type;
159 ugen_set_type::bucket_type ugen_set_buckets[ugen_set_bucket_count];
160 ugen_set_type ugen_set;
162 bufgen_set_type::bucket_type bufgen_set_buckets[bufgen_set_bucket_count];
163 bufgen_set_type bufgen_set;
165 cmdplugin_set_type::bucket_type cmdplugin_set_buckets[cmdplugin_set_bucket_count];
166 cmdplugin_set_type cmdplugin_set;
168 protected:
169 sc_plugin_container (void):
170 ugen_set(ugen_set_type::bucket_traits(ugen_set_buckets, ugen_set_bucket_count)),
171 bufgen_set(bufgen_set_type::bucket_traits(bufgen_set_buckets, bufgen_set_bucket_count)),
172 cmdplugin_set(cmdplugin_set_type::bucket_traits(cmdplugin_set_buckets, cmdplugin_set_bucket_count))
175 ~sc_plugin_container (void)
177 ugen_set.clear_and_dispose(boost::checked_delete<sc_ugen_def>);
178 bufgen_set.clear_and_dispose(boost::checked_delete<sc_bufgen_def>);
179 cmdplugin_set.clear_and_dispose(boost::checked_delete<sc_cmdplugin_def>);
182 public:
183 void register_ugen(const char *inUnitClassName, size_t inAllocSize,
184 UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags);
186 void register_bufgen(const char * name, BufGenFunc func);
188 sc_ugen_def * find_ugen(c_string const & name);
190 bool register_ugen_command_function(const char * ugen_name, const char * cmd_name, UnitCmdFunc);
191 bool register_cmd_plugin(const char * cmd_name, PlugInCmdFunc func, void * user_data);
193 sample * run_bufgen(World * world, const char * name, uint32_t buffer_index, struct sc_msg_iter *args);
194 bool run_cmd_plugin(World * world , const char * name, struct sc_msg_iter *args, void *replyAddr);
197 /** factory class for supercollider ugens
199 * \todo do we need to take care of thread safety? */
200 class sc_ugen_factory:
201 public sc_plugin_interface,
202 public sc_plugin_container
204 public:
205 ~sc_ugen_factory(void)
207 close_handles();
210 /* @{ */
211 /** ugen count handling */
212 void allocate_ugens(uint32_t count)
214 ugen_count_ += count;
217 void free_ugens(uint32_t count)
219 ugen_count_ -= count;
222 uint32_t ugen_count(void) const
224 return ugen_count_;
226 /* @} */
228 void load_plugin_folder(boost::filesystem::path const & path);
229 void load_plugin(boost::filesystem::path const & path);
231 private:
232 void close_handles(void);
234 uint32_t ugen_count_;
235 std::vector<void*> open_handles;
238 extern sc_ugen_factory * sc_factory;
240 } /* namespace nova */
243 #endif /* SC_UGEN_FACTORY_HPP */