Code Search for Developers
 
 
  

jcom.core.cpp from Jamoma at Krugle


Show jcom.core.cpp syntax highlighted

/* 
 * jcom.core
 * shared code used by the jamoma core externals
 * By Tim Place, Copyright © 2006
 * 
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html 
 */

#include "ext.h"		// Max externals header
#include "ext_obex.h"	// Obex header
#include "jcom.core.h"

#pragma mark -
#pragma mark Globals/Init/Etc.

t_symbol	*ps_done,
			*ps_none,					// ramp stuff
			*ps_linear,
			*ps_linear_q,
			*ps_low, 
			*ps_high, 
			*ps_both, 
			*ps_inc,					// increase, decrease
			*ps_dec,
			*ps_msg_generic, 				// types
			*ps_msg_int, 
			*ps_msg_float, 
			*ps_msg_symbol,
			*ps_msg_list,
			*ps_msg_toggle, 
			*ps_msg_none,				// this type only used by jcom.message
			*ps_jcom_hub, 
			*ps_feedback,
			*ps_module_name_get,		// common OSC messages according to the JIG
			*ps_dumpout,
			*ps_audio, 
			*ps_video, 
			*ps_control, 
			*ps_dispatched, 
			*ps_parameter_name,
			*ps_message_name,
			*ps_message_return,
			*ps_parameter_names_start, 
			*ps_parameter_names_end,			
			*ps_message_names_start, 
			*ps_message_names_end,
			*ps_return_names_start, 
			*ps_return_names_end,
			*ps_parameter_values_start,
			*ps_parameter_values_end,
			*ps_parameter_value,
			*ps_subscribe,				// subscribe stuff
			*ps_unsubscribe,
			*ps_release,
			*ps_subscribe_in,
			*ps_subscribe_out,
			*ps_subscribe_message,
			*ps_subscribe_parameter,
			*ps_subscribe_remote,
			*ps_subscribe_return,
			*ps_subscribe_init,
			*ps_subscribe_meter,
			*ps_inspector,
			*ps_num_inputs,				// signal inlets and outlets
			*ps_num_outputs,
			*ps_type,					// parameter/message/return attributes
			*ps_algorithm_type,
			*ps_name,
			*ps_range,
			*ps_clipmode,
			*ps_ramp,
			*ps_repetitions,
			*ps_description,
			*ps_value,
			*ps_sigcount,				// signals to module
			*ps_siglist,
			*ps_config_changed,
			*ps_algorithm,
			*ps_get_num_channels,
			*ps_module_type,			// module type
			*ps_poly,
			*ps_default,
			*ps_jitter,
			*ps_1U,
			*ps_algorithm_message,
			*ps_private,
			*ps__gui__,
			*ps__jcom_in__,
			*ps__jcom_out__,
			*ps___preview__,
			*ps_return,
			*ps_return_extended,
			*ps_go,
			*ps_init,
			*ps_ATTRIBUTES,
			*ps_BUILD,
			*ps_MODULE_NAME,			// name of this module class
			*ps_MODULE_TITLE,			// OSC name of this module instance
			*ps_PARAMETER,
			*ps_NEW_PRESETS_START,
			*ps_NEW_PRESETS,
			*ps_MENU_REBUILD,
			*ps_size,
			*ps_skin,
			*ps_jcom_send,	
			*ps_jcom_receive,
			*ps_jcom_remote_fromModule, 			
			*ps_jcom_remote_toModule,
			*ps_jcom_broadcast_fromHub,
			*ps_from_in_object,
			*ps_box,
			*ps_setcallback,
			*ps_link_in,				// common OSC messages, etc.
			*ps_link_out,
			*ps_unlink_in,
			*ps_unlink_out,
			*ps_audio_gain_midi,
			*ps_slash_audio_gain_midi,
			*ps_audio_mute,
			*ps_slash_audio_mute,
			*ps_audio_bypass,
			*ps_slash_audio_bypass,
			*ps_audio_mix,
			*ps_slash_audio_mix,
			*ps_audio_sample_rate,
			*ps_slash_audio_sample_rate,
			*ps_audio_meters_freeze,
			*ps_slash_audio_meters_freeze,
			*ps_video_mute,
			*ps_slash_video_mute,
			*ps_video_bypass,
			*ps_slash_video_bypass,
			*ps_video_freeze,
			*ps_slash_video_freeze,
			*ps_video_preview,
			*ps_slash_video_preview,			
			*ps_open,							// 	open
			*ps_slash_module_view_internals,	//	/module/view_internals
			*ps_slash_preset_slash_default,		// 	/preset/default
			*ps_slash_preset_slash_load,		// 	/preset/load
			*ps_slash_preset_slash_recall,
			*ps_slash_preset_slash_write,		// 	/preset/save
			*ps_slash_preset_slash_copy,		// 	/preset/save
			*ps_ui_slash_freeze,				//	ui/freeze
			*ps_slash_ui_slash_freeze,			//	/ui/freeze
			*ps_ui_slash_refresh,				//	ui/refresh
			*ps_slash_ui_slash_refresh,			//	/ui/refresh		
			*ps_register_meter,
			*ps_register_preview,
			*ps_voices,
			*ps_mute,
			*ps_target,
			*ps_sendlastvalue,
			*ps_sendbypassedvalue,
			*ps_star,
			*ps_priority;
			


void jcom_core_init(void)
{
	ps_done						= gensym("done");
	// ramp stuff
	ps_none						= gensym("none");
	ps_linear					= gensym("linear");
	ps_linear_q					= gensym("linear.q");
	ps_low						= gensym("low"); 
	ps_high						= gensym("high"); 
	ps_both						= gensym("both");
	// increase and decrease
	ps_inc						= gensym("inc");
	ps_dec						= gensym("dec");
	// types
	ps_msg_generic				= gensym("msg_generic"); 
	ps_msg_int					= gensym("msg_int"); 
	ps_msg_float				= gensym("msg_float"); 
	ps_msg_symbol				= gensym("msg_symbol");
	ps_msg_list					= gensym("msg_list");
	ps_msg_toggle				= gensym("msg_toggle");
	ps_msg_none					= gensym("msg_none");			// this type only used by jcom.message
	ps_jcom_hub					= gensym("jcom.hub"); 
    ps_feedback					= gensym("feedback");
	// common OSC messages according to the JIG
	ps_module_name_get			= gensym("/module_name/get");
	ps_dumpout					= gensym("dumpout");
	ps_audio					= gensym("audio");
	ps_video					= gensym("video");
	ps_control					= gensym("control");
	ps_dispatched				= gensym("dispatched");
	ps_parameter_name			= gensym("/parameter_name");
	ps_message_name				= gensym("/message_name");
	ps_message_return			= gensym("/return_name");
	ps_parameter_names_start	= gensym("/parameter_names_start");
	ps_parameter_names_end		= gensym("/parameter_names_end");
	ps_message_names_start		= gensym("/message_names_start"); 
	ps_message_names_end		= gensym("/message_names_end");
	ps_return_names_start		= gensym("/return_names_start");
	ps_return_names_end			= gensym("/return_names_end");
	ps_parameter_values_start	= gensym("/parameter_values_start");
	ps_parameter_values_end		= gensym("/parameter_values_end");
	ps_parameter_value			= gensym("/parameter_value");
	// subscribe stuff
    ps_subscribe				= gensym("subscribe");
	ps_unsubscribe				= gensym("unsubscribe");
	ps_release					= gensym("release");
	ps_subscribe_in				= gensym("subscribe_in"); 
	ps_subscribe_out			= gensym("subscribe_out"); 
	ps_subscribe_message		= gensym("subscribe_message"); 
	ps_subscribe_parameter		= gensym("subscribe_parameter"); 
	ps_subscribe_remote			= gensym("subscribe_remote"); 
	ps_subscribe_return			= gensym("subscribe_return");
	ps_subscribe_init			= gensym("subscribe_init");
	ps_subscribe_meter			= gensym("subscribe_meter");
	// signal inlets and outlets
	ps_num_inputs				= gensym("num_inputs");
	ps_num_outputs				= gensym("num_outputs");
	// parameter/message/return attributes
	ps_inspector				= gensym("inspector");
	ps_type						= gensym("type");
	ps_range					= gensym("range");
	ps_clipmode					= gensym("clipmode");
	ps_ramp						= gensym("ramp");
	ps_repetitions				= gensym("repetitions");
	ps_description				= gensym("description");
	ps_value					= gensym("value");
	ps_algorithm_type			= gensym("algorithm_type");
	ps_name						= gensym("name");
	// signals to module
	ps_sigcount					= gensym("sigcount");
	ps_siglist					= gensym("siglist");
	ps_config_changed			= gensym("config_changed");
	ps_algorithm				= gensym("algorithm");
	ps_get_num_channels			= gensym("get_num_channels");
	// module type
	ps_module_type				= gensym("module_type");
	ps_poly						= gensym("poly");
	ps_default					= gensym("default");
	ps_jitter					= gensym("jitter");
	ps_1U						= gensym("ps_1U");
	ps_algorithm_message		= gensym("algorithm_message");
	ps_private					= gensym("private");		// method called in the hub by jcom.remote
	ps__gui__					= gensym("__GUI__");		// name of jcom.remote in the gui
	ps__jcom_in__				= gensym("__jcom_in__");	// name of the module's jcom.in object
	ps__jcom_out__				= gensym("__jcom_out__");	// name of the module's jcom.out object
	ps___preview__				= gensym("__preview__");	// name of the remote for jitter preview matrices
	ps_return					= gensym("return");			// method called in the hub by jcom.return
	ps_return_extended			= gensym("return_extended");
	ps_go						= gensym("go");				// method in jcom.init called by the hub
	ps_init						= gensym("/init");			// method in the hub called from jcom.init
	ps_ATTRIBUTES				= gensym("ATTRIBUTES");
	ps_BUILD					= gensym("BUILD");
	ps_MODULE_NAME				= gensym("MODULE_NAME");	// name of this module class
	ps_MODULE_TITLE				= gensym("MODULE_TITLE");	// OSC id of of this module instance
	ps_PARAMETER				= gensym("PARAMETER");
	ps_NEW_PRESETS_START		= gensym("NEW_PRESETS_START");
	ps_NEW_PRESETS				= gensym("NEW_PRESETS");
	ps_MENU_REBUILD				= gensym("MENU_REBUILD");
	ps_size						= gensym("size");
	ps_skin						= gensym("skin");
	ps_jcom_send				= gensym("jcom.send");	
	ps_jcom_receive				= gensym("jcom.receive");
	ps_jcom_remote_fromModule 	= gensym("jcom.remote.module.from");	// different than in jamoma 0.3.x to avoid conflicts...
	ps_jcom_remote_toModule 	= gensym("jcom.remote.module.to");
	ps_jcom_broadcast_fromHub	= gensym("jcom.broadcast.hub.from");	// used to tell subscribers in a module to subscribe (hub has changed)
	ps_from_in_object			= gensym("from_in_object");	// messages to the jcom.out object
	ps_box						= gensym("box");
	ps_setcallback				= gensym("setcallback");
	ps_link_in					= gensym("link_in");
	ps_link_out					= gensym("link_out");
	ps_unlink_in				= gensym("unlink_in");
	ps_unlink_out				= gensym("unlink_out");
	ps_audio_gain_midi			= gensym("audio/gain/midi");		// used by the i/o objects...
	ps_slash_audio_gain_midi	= gensym("/audio/gain/midi");
	ps_audio_mute				= gensym("audio/mute");
	ps_slash_audio_mute			= gensym("/audio/mute");
	ps_audio_bypass				= gensym("audio/bypass");
	ps_slash_audio_bypass		= gensym("/audio/bypass");
	ps_audio_mix				= gensym("audio/mix");
	ps_slash_audio_mix			= gensym("/audio/mix");
	ps_audio_sample_rate		= gensym("audio/sample_rate");
	ps_slash_audio_sample_rate	= gensym("/audio/sample_rate");
	ps_audio_meters_freeze		= gensym("audio/meters/freeze");
	ps_slash_audio_meters_freeze = gensym("/audio/meters/freeze");
	ps_video_mute				= gensym("video/mute");
	ps_slash_video_mute			= gensym("/video/mute");
	ps_video_bypass				= gensym("video/bypass");
	ps_slash_video_bypass		= gensym("/video/bypass");
	ps_video_freeze				= gensym("video/freeze");
	ps_slash_video_freeze		= gensym("/video/freeze");
	ps_video_preview			= gensym("video/preview");
	ps_slash_video_preview		= gensym("/video/preview");	
	ps_register_meter			= gensym("register_meter");
	ps_register_preview			= gensym("register_preview");
	ps_open						= gensym("open");
	ps_slash_module_view_internals = gensym("/module/view_internals");
	ps_slash_preset_slash_default = gensym("/preset/default");
	ps_slash_preset_slash_load	= gensym("/preset/load");
	ps_slash_preset_slash_recall	= gensym("/preset/recall");
	ps_slash_preset_slash_write	= gensym("/preset/write");		
	ps_slash_preset_slash_copy	= gensym("/preset/copy");		
	ps_ui_slash_freeze			= gensym("ui/freeze");
	ps_slash_ui_slash_freeze	= gensym("/ui/freeze");
	ps_ui_slash_refresh			= gensym("ui/refresh");
	ps_slash_ui_slash_refresh	= gensym("/ui/refresh");
	ps_voices					= gensym("voices");
	ps_mute						= gensym("mute");
	ps_target					= gensym("target");
	ps_sendlastvalue			= gensym("sendlastvalue");
	ps_sendbypassedvalue		= gensym("sendbypassedvalue");
	ps_star						= gensym("*");
	ps_priority					= gensym("priority");
}


#pragma mark -
#pragma mark Hub Bindings

// Registering with the jcom.hub object
void *jcom_core_subscribe(void *x, t_symbol *name, t_patcher *container, t_symbol *object_type)
{
	t_patcher	*p = container;
	t_box		*b;
	t_class		*theclass;
	void		*hub = NULL;
	
again:	
	for(b = p->p_box; b; b = b->b_next){							// traverse the linked list of boxes in the patch
		theclass = object_class(b->b_firstin);
		if(object_classname_compare(b->b_firstin, ps_jcom_hub)){	// if this is a jcom.hub...
			object_method(b->b_firstin, ps_subscribe, name, x, object_type);
			hub = b->b_firstin;										// store the pointer
			break;													// then stop looking
		}
	}
	if(hub == NULL){							// failed to find a hub in the patch...
		if(p->p_vnewobj != NULL){				//	go one level higher and search there
			b = (t_box *)p->p_vnewobj;
			p = b->b_patcher;
			goto again;
		}
		else
			error("object named '%s' could not find a jcom.hub for subscribing", name->s_name);
	}
	return hub;
}


// Unregister from the jcom.hub object
//void jcom_core_unsubscribe(void *hub, t_symbol *name)
void jcom_core_unsubscribe(void *hub, void *object)
{
	if(hub)
		object_method(hub, ps_unsubscribe, object);
}


#pragma mark -
#pragma mark Atom Utilities

// Copying all of the elements should be faster than branching and copying one element
//	(that's the theory anyway...)
void jcom_core_atom_copy(t_atom *dst, t_atom *src)
{
	dst->a_type = src->a_type;
	dst->a_w.w_long = src->a_w.w_long;
	dst->a_w.w_float = src->a_w.w_float;
	dst->a_w.w_sym = src->a_w.w_sym;
}


bool jcom_core_atom_compare(t_symbol *type, t_atom *a1, t_atom *a2)
{
	if(type == ps_msg_float){				// float is first so that it gets process the most quickly
		if(atom_getfloat(a1) == atom_getfloat(a2))
			return 1;
	}
	else if((type == ps_msg_int) || (type == ps_msg_toggle)){
		if(atom_getlong(a1) == atom_getlong(a2))
			return 1;
	}
	else if(type == ps_msg_symbol){
		if(atom_getsym(a1) == atom_getsym(a2))
			return 1;
	}
	else if((type == ps_msg_generic) || (type == ps_msg_list)){
		// type msg_list should be checked here as well.  If type == msg_list and this function is called
		// it means we are dealing with a list of length 1, so we only need to compare one atom anyway.
		
		// note that if the two are of different types, then they are obviously not the same
		if((a1->a_type == A_LONG) && (a2->a_type == A_LONG)){
			if(a1->a_w.w_long == a2->a_w.w_long)
				return 1;
		}
		else if((a1->a_type == A_FLOAT) && (a2->a_type == A_FLOAT)){
			if(a1->a_w.w_float == a2->a_w.w_float)
				return 1;
		}
		else if((a1->a_type == A_SYM) && (a2->a_type == A_SYM)){
			if(a1->a_w.w_sym == a2->a_w.w_sym)
				return 1;
		}
	}
	else
		error("atom_compare: cannot do comparison on this data type");
		
	return 0;
}



void jcom_core_file_writeline(t_filehandle *fh, long *the_eof, char *the_text)
{
	char 	tempstring[4096];
	short	err = 0;
	long	len = 0;
	
	strcpy(tempstring, the_text);
	strcat(tempstring, "\n");
	len = strlen(tempstring);
	err = sysfile_write(*fh, &len, &tempstring);
	if(err){
		error("jamoma: sysfile_write error (%d)", err);
		return;
	}
	*the_eof = *the_eof + len;
}


// Compare Strings: Is s2 after s1 in alphabetical order?
bool jcom_core_string_compare(char *s1, char *s2)
{
	short i;
	short len1 = strlen(s1);
	short len2 = strlen(s2);
	bool result = false;
	bool keepgoing = true;
	
	if(len2 < len1)
		len1 = len2;	// only compare the characters of the short string
		
	for(i=0; i<len1 && keepgoing; i++){
		if(s1[i] < s2[i]){
			result = true;
			keepgoing = false;
		}
		else if(s1[i] > s2[i])
			keepgoing = false;
	}
	return result;
}


// Load an external for internal use
// returns true if successful
bool jcom_core_loadextern(t_symbol *objectname, t_symbol *argument, t_object **object)
{
	t_atom		a;
	t_class 	*c = NULL;
	t_object	*p = NULL;

	c = class_findbyname(ps_box, objectname);	// presumably ps_jcom_send or ps_jcom_receive
	if(!c){
		p = (t_object *)newinstance(objectname, 0, NULL);
		if(p){
			c = class_findbyname(ps_box, objectname);
			freeobject(p);
			p = NULL;
		}
		else{
			error("jamoma: could not load extern (%s) within the core", objectname->s_name);
			return false;
		}
	}

	if(*object != NULL)			// if there was an object set previously, free it first...
		object_free(object);

	atom_setsym(&a, argument);
	*object = (t_object *)object_new_typed(CLASS_BOX, objectname, 1, &a);
	return true;
}


// Function the translates a Max path+filename combo into a correct absolutepath
void jcom_core_getfilepath(short in_path, char *in_filename, char *out_filepath)
{
	char	path[512];
	
	path_topathname(in_path, in_filename, path);

	#ifdef MAC_VERSION
		char *temppath;
		temppath = strchr(path, ':');
		*temppath = '\0';
		temppath += 1;
		
		// at this point temppath points to the path after the volume, and out_filepath points to the volume
		sprintf(out_filepath, "/Volumes/%s%s", path, temppath);
	#else // WIN_VERSION
		strcpy(out_filepath, path);
	#endif
}



// Add attributes that are common to many subscribers (such as parameter, message, and return)
void jcom_core_subscriber_classinit_common(t_class *c, t_object *attr, long offset, bool define_name)
{
	long 		attrflags = 0;
	long		attroffset;

	// METHODS
	class_addmethod(c, (method)jcom_core_subscriber_hubrelease,	"release",		A_CANT, 0);	// notification of hub being freed
	class_addmethod(c, (method)object_obex_dumpout,				"dumpout",		A_CANT, 0);  
	class_addmethod(c, (method)object_obex_quickref,			"quickref",		A_CANT, 0);

	// ATTRIBUTE: name
	if(define_name){
		attroffset = offset + calcoffset(t_jcom_core_subscriber_common, attr_name);
		attr = attr_offset_new("name", _sym_symbol, attrflags,
			(method)0, (method)jcom_core_subscriber_attribute_common_setname,
	 		attroffset);
		class_addattr(c, attr);	
	}
}


void jcom_core_subscriber_classinit_extended(t_class *c, t_object *attr, long offset, bool define_name)
{
	long 		attrflags = 0;
	long		attroffset;

	jcom_core_subscriber_classinit_common(c, attr, offset, define_name);

	// ATTRIBUTE: range <low, high>
	attroffset = offset + calcoffset(t_jcom_core_subscriber_extended, attr_range);
	attr = attr_offset_array_new("range", _sym_float32, 2, attrflags,
		(method)0, (method)0, 
		offset + calcoffset(t_jcom_core_subscriber_extended, attr_range_len), attroffset);
	class_addattr(c, attr);

	// ATTRIBUTE: repetitions - 0 means repetitive values are not allowed, 1 means they are
	attroffset = offset + calcoffset(t_jcom_core_subscriber_extended, attr_repetitions);
	attr = attr_offset_new("repetitions", _sym_long, attrflags,
		(method)0, (method)0, 
		attroffset);
	class_addattr(c, attr);

	// ATTRIBUTE: type 
	// this is not defined here because some objects (i.e jcom.parameter) need to treat this in different ways
	
	// ATTRIBUTE: clipmode - options are none, low, high, both
	attroffset = offset + calcoffset(t_jcom_core_subscriber_extended, attr_clipmode);
	attr = attr_offset_new("clipmode", _sym_symbol, attrflags,
		(method)0, (method)0, 
		attroffset);
	class_addattr(c, attr);

	// ATTRIBUTE: description - does nothing, but is accessed by jcom.dispatcher for /autodoc generation
	attroffset = offset + calcoffset(t_jcom_core_subscriber_extended, attr_description);
	attr = attr_offset_new("description", _sym_symbol, attrflags,
		(method)0, (method)0, 
		attroffset);
	class_addattr(c, attr);	
}


// arg is subscriber name
void jcom_core_subscriber_new_common(t_jcom_core_subscriber_common *x, t_symbol *name, t_symbol *subscriber_type)
{
	t_atom 	a;
	
	x->subscriber_type = subscriber_type;
	x->custom_subscribe = NULL;
	x->hub = NULL;
	x->obj_hub_broadcast = NULL;
	x->module_name = _sym_nothing;

	// we call the function directly here rather than use object_attr_setvalueof() 
	// because parameters with pattr bindings don't actually have their own 'name' attribute
	atom_setsym(&a, name);
	jcom_core_subscriber_attribute_common_setname(x, NULL, 1, &a);
 	
	object_obex_lookup(x, gensym("#P"), (t_object **)&x->container);
	if(!x->container)
		x->container = (t_patcher *)gensym("#P")->s_thing;
	
	// set up the jcom.receive the listens to broadcast messages from the hub
	if(!jcom_core_loadextern(ps_jcom_receive, ps_jcom_broadcast_fromHub, &x->obj_hub_broadcast))
		error("jcom.core: loading jcom.receive extern failed");
	else
		object_method(x->obj_hub_broadcast, ps_setcallback, &jcom_core_broadcast_callback, x);
	
}


void jcom_core_subscriber_new_extended(t_jcom_core_subscriber_extended *x, t_symbol *name, t_symbol *subscriber_type)
{
	jcom_core_subscriber_new_common((t_jcom_core_subscriber_common *)x, name, subscriber_type);
	
	x->attr_range[0] = 0.0;
	x->attr_range[1] = 1.0;
	x->attr_clipmode = ps_none;
	x->attr_description = _sym_nothing;
	x->attr_type = ps_msg_generic;
	x->attr_repetitions = 1;
}


// COMMON ATTRIBUTE: name
t_max_err jcom_core_subscriber_attribute_common_setname(t_jcom_core_subscriber_common *x, void *attr, long argc, t_atom *argv)
{	
	t_symbol *arg = atom_getsym(argv);
	x->attr_name = arg;

	if(arg->s_name[strlen(arg->s_name)-1] == '*')
		x->has_wildcard = true;
	else
		x->has_wildcard = false;

	return MAX_ERR_NONE;
	#pragma unused(attr)
}


// function for registering with the jcom.hub object
void jcom_core_subscriber_subscribe(t_jcom_core_subscriber_common *x)
{
	if(x->hub == NULL){			// do not allow multiple subscribes of this object 
		x->hub = jcom_core_subscribe(x, x->attr_name, x->container, x->subscriber_type);
		if(x->hub)
			x->module_name = (t_symbol *)object_method(x->hub, ps_module_name_get);
		if(x->custom_subscribe)
			x->custom_subscribe(x);
	}
}


// Notification that the hub no longer exists
void jcom_core_subscriber_hubrelease(t_jcom_core_subscriber_common *x)
{
	x->hub = NULL;
}


// Set a custom subscribe method
void jcom_core_subscriber_setcustomsubscribe_method(t_jcom_core_subscriber_common *x, t_subscribe_method meth)
{
	x->custom_subscribe = meth;
}


// Unsubscribe and common freeing code
void jcom_core_subscriber_common_free(t_jcom_core_subscriber_common *x)
{
	jcom_core_unsubscribe(x->hub, x);
	x->hub = NULL;
	object_free(x->obj_hub_broadcast);
	x->obj_hub_broadcast = NULL;
}


// receive messages from our internal jcom.receive external
void jcom_core_broadcast_callback(void *z, t_symbol *msg, short argc, t_atom *argv)
{
	t_jcom_core_subscriber_common	*x = (t_jcom_core_subscriber_common *)z;
	
	if(msg == gensym("hub.changed"))
		defer_low(x, (method)jcom_core_subscriber_subscribe, 0, 0, 0);
}




See more files for this project here

Jamoma

Jamoma is a flexible framework for the creation of modules in Max, MSP, and Jitter

Project homepage: http://sourceforge.net/projects/jamoma
Programming language(s): C++,JavaScript,XML
License: other

  Info.plist
  infoplist_versionmaker.pl
  jcom.core.cpp
  jcom.core.h
  jcom.io.h
  jcom.list.h
  jcom.prefix.pch
  jcom.sendreceive.h