Skip to content

Commit

Permalink
supernova: implement /u_cmd handler
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Blechmann <tim@klingt.org>
  • Loading branch information
timblechmann committed Dec 24, 2010
1 parent 9caad67 commit 8b68f8b
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 60 deletions.
26 changes: 26 additions & 0 deletions server/supernova/sc/sc_osc_handler.cpp
Expand Up @@ -2909,7 +2909,24 @@ void handle_p_new(received_message const & msg)
}
}

void handle_u_cmd(received_message const & msg, int size)
{
sc_msg_iter args(size, msg.AddressPattern());

int node_id = args.geti();

server_node * target_synth = find_node(node_id);

if (target_synth == NULL || target_synth->is_group())
return;

sc_synth * synth = static_cast<sc_synth*>(target_synth);

int ugen_index = args.geti();
const char * cmd_name = args.gets();

synth->apply_unit_cmd(cmd_name, ugen_index, &args);
}

} /* namespace */

Expand Down Expand Up @@ -3053,6 +3070,10 @@ void sc_osc_handler::handle_message_int_address(received_message const & message
handle_b_alloc<realtime>(message, endpoint);
break;

case cmd_u_cmd:
handle_u_cmd(message, msg_size);
break;

case cmd_b_free:
handle_b_free<realtime>(message, endpoint);
break;
Expand Down Expand Up @@ -3494,6 +3515,11 @@ void sc_osc_handler::handle_message_sym_address(received_message const & message
return;
}

if (strcmp(address+1, "u_cmd") == 0) {
handle_u_cmd(message, msg_size);
return;
}

if (strcmp(address+1, "status") == 0) {
handle_status<realtime>(endpoint);
return;
Expand Down
7 changes: 7 additions & 0 deletions server/supernova/sc/sc_plugin_interface.cpp
Expand Up @@ -294,6 +294,12 @@ bool define_bufgen(const char * name, BufGenFunc func)
}
}

bool define_unitcmd(const char * unitClassName, const char * cmdName, UnitCmdFunc inFunc)
{
return nova::sc_factory->register_ugen_command_function(unitClassName, cmdName, inFunc);
}


bool define_plugincmd(const char * name, PlugInCmdFunc func, void * user_data)
{
std::cerr << "plugin commands not implemented: " << name << std::endl;
Expand Down Expand Up @@ -520,6 +526,7 @@ void sc_plugin_interface::initialize(void)
sc_interface.fDefineUnit = &define_unit;
sc_interface.fDefineBufGen = &define_bufgen;
sc_interface.fDefinePlugInCmd = &define_plugincmd;
sc_interface.fDefineUnitCmd = &define_unitcmd;

/* interface functions */
sc_interface.fNodeEnd = &node_end;
Expand Down
10 changes: 10 additions & 0 deletions server/supernova/sc/sc_synth.cpp
Expand Up @@ -231,6 +231,16 @@ void sc_synth::map_control_buses_audio (const char * slot_name, int audio_bus_in
map_control_buses_audio(index, audio_bus_index, count);
}

void sc_synth::apply_unit_cmd(const char * unit_cmd, unsigned int unit_index, struct sc_msg_iter *args)
{
Unit * unit = units[unit_index];
sc_ugen_def * def = reinterpret_cast<sc_ugen_def*>(unit->mUnitDef);

UnitCmdFunc func = def->find_command(unit_cmd);
(func)(unit, args);
}


void sc_synth::run(void)
{
perform();
Expand Down
2 changes: 2 additions & 0 deletions server/supernova/sc/sc_synth.hpp
Expand Up @@ -128,6 +128,8 @@ class sc_synth:
trace = 1;
}

void apply_unit_cmd(const char * unit_cmd, unsigned int unit_index, struct sc_msg_iter *args);

private:
void run_traced(void);

Expand Down
85 changes: 85 additions & 0 deletions server/supernova/sc/sc_ugen_factory.cpp
Expand Up @@ -33,6 +33,63 @@
namespace nova
{

namespace
{

template<typename def>
struct compare_def
{
bool operator()(def const & lhs,
std::string const & rhs) const
{
return lhs.name() < rhs;
}

bool operator()(std::string const & lhs,
def const & rhs) const
{
return lhs < rhs.name();
}

bool operator()(def const & lhs,
const char * rhs) const
{
return (strcmp(lhs.name().c_str(), rhs) < 0);
}

bool operator()(const char * lhs,
def const & rhs) const
{
return (strcmp(lhs, rhs.name().c_str()) < 0);
}
};

template<typename def>
struct equal_def
{
bool operator()(def const & lhs,
std::string const & rhs) const
{
return lhs.name() == rhs;
}

bool operator()(std::string const & lhs,
def const & rhs) const
{
return lhs == rhs.name();
}
};

template<typename def>
struct hash_def
{
std::size_t operator()(std::string const & value)
{
return def::hash(value);
}
};

}

sc_ugen_factory * sc_factory;

Expand Down Expand Up @@ -119,6 +176,23 @@ Unit * sc_ugen_def::construct(sc_synthdef::unit_spec_t const & unit_spec, sc_syn
return unit;
}

bool sc_ugen_def::add_command(const char* cmd_name, UnitCmdFunc func)
{
sc_unitcmd_def * def = new sc_unitcmd_def(cmd_name, func);
commands.insert(*def);
return true;
}

UnitCmdFunc sc_ugen_def::find_command(const char * cmd_name)
{
unit_commands_set::iterator it = commands.find(cmd_name, compare_def<sc_unitcmd_def>());

if (it == commands.end())
return NULL;
else
return it->func;
}

void sc_ugen_factory::load_plugin_folder (boost::filesystem::path const & path)
{
using namespace boost::filesystem;
Expand Down Expand Up @@ -174,6 +248,7 @@ void sc_ugen_factory::close_handles(void)
{}
#endif


void sc_ugen_factory::register_ugen(const char *inUnitClassName, size_t inAllocSize,
UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags)
{
Expand Down Expand Up @@ -209,4 +284,14 @@ sc_ugen_def * sc_ugen_factory::find_ugen(std::string const & name)
return &*it;
}

bool sc_ugen_factory::register_ugen_command_function(const char * ugen_name, const char * cmd_name,
UnitCmdFunc func)
{
sc_ugen_def * def = find_ugen(ugen_name);
if (!def)
return false;
return def->add_command(cmd_name, func);
}


} /* namespace nova */
95 changes: 35 additions & 60 deletions server/supernova/sc/sc_ugen_factory.hpp
Expand Up @@ -34,6 +34,34 @@ namespace nova
{
namespace bi = boost::intrusive;


struct sc_unitcmd_def:
public bi::set_base_hook<>
{
const std::string name_;

public:
const UnitCmdFunc func;

sc_unitcmd_def(const char * cmd_name, UnitCmdFunc func):
name_(cmd_name), func(func)
{}

std::string const & name(void) const
{
return name_;
}

public:
/* sort by name */
friend bool operator< (sc_unitcmd_def const & a,
sc_unitcmd_def const & b)
{
return a.name_ < b.name_;
}
};


class sc_ugen_def:
public bi::unordered_set_base_hook<>
{
Expand All @@ -44,6 +72,9 @@ class sc_ugen_def:
const UnitDtorFunc dtor;
const uint32_t flags;

typedef bi::set<sc_unitcmd_def> unit_commands_set;
unit_commands_set commands;

public:
sc_ugen_def(const char *inUnitClassName, size_t inAllocSize,
UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags);
Expand Down Expand Up @@ -86,13 +117,8 @@ class sc_ugen_def:
return alloc_size;
}

public:
/* sort by name */
friend bool operator< (sc_ugen_def const & a,
sc_ugen_def const & b)
{
return a.name_ < b.name_;
}
bool add_command(const char * cmd_name, UnitCmdFunc func);
UnitCmdFunc find_command(const char * cmd_name);

friend bool operator== (sc_ugen_def const & a,
sc_ugen_def const & b)
Expand Down Expand Up @@ -142,59 +168,6 @@ class sc_ugen_factory:

typedef bi::set<sc_bufgen_def> bufgen_set_t;

template<typename def>
struct compare_def
{
bool operator()(def const & lhs,
std::string const & rhs) const
{
return lhs.name() < rhs;
}

bool operator()(std::string const & lhs,
def const & rhs) const
{
return lhs < rhs.name();
}

bool operator()(def const & lhs,
const char * rhs) const
{
return (strcmp(lhs.name().c_str(), rhs) < 0);
}

bool operator()(const char * lhs,
def const & rhs) const
{
return (strcmp(lhs, rhs.name().c_str()) < 0);
}
};

template<typename def>
struct equal_def
{
bool operator()(def const & lhs,
std::string const & rhs) const
{
return lhs.name() == rhs;
}

bool operator()(std::string const & lhs,
def const & rhs) const
{
return lhs == rhs.name();
}
};

template<typename def>
struct hash_def
{
std::size_t operator()(std::string const & value)
{
return def::hash(value);
}
};

ugen_set_type::bucket_type node_buckets[ugen_set_bucket_count];
ugen_set_type ugen_set;

Expand Down Expand Up @@ -244,6 +217,8 @@ class sc_ugen_factory:

sc_ugen_def * find_ugen(std::string const & name);

bool register_ugen_command_function(const char * ugen_name, const char * cmd_name, UnitCmdFunc);

private:
void close_handles(void);
uint32_t ugen_count_;
Expand Down

0 comments on commit 8b68f8b

Please sign in to comment.