Code Search for Developers
 
 
  

jcom.change.cpp from Jamoma at Krugle


Show jcom.change.cpp syntax highlighted

/* 
 * jcom.change
 * External for Jamoma: filter out duplicate messages
 * By Tim Place, Copyright © 2005
 * 
 * License: This code is licensed under the terms of the GNU LGPL
 * http://www.gnu.org/licenses/lgpl.html 
 */

#include "ext.h"					// Max Header
#include "ext_strings.h"			// String Functions
#include "commonsyms.h"				// Common symbols used by the Max 4.5 API
#include "ext_obex.h"				// Max Object Extensions (attributes) Header
#define MAX_LIST_SIZE 256

enum type{
	msg_new,
	msg_int,
	msg_float,
	msg_list						// Also used for symbols
};

// Data Structure for this object
typedef struct _change			// Data Structure for this object
{
	t_object		ob;	
	void			*obex;
	void 			*change_Out[2];					// outlets
	void			*inlet_right;					// 2nd inlet+
	short 			last_argc;
	t_atom 			*last_argv;
	Symbol 			*last_input_symbol;
	t_atom			last_input_list[MAX_LIST_SIZE];
	long			last_input_int;
	float			last_input_float;
	type			last_input_type;
} t_change;

// Prototypes for methods
void change_assist(t_change *x, void *b, long m, long a, char *s);		// Assistance Method
void *change_new(void);													// New Object Creation Method
void change_free(t_change *x);
void change_anything(t_change *x, Symbol *msg, short argc, Atom *argv);	// Symbol method
void change_int(t_change *x, long value);
void change_float(t_change *x, double value);
float atom_getvalue(long index, short argc, t_atom *argv);
void atom_copy(t_atom *dst, t_atom *src);
bool atom_compare(Atom *in1, Atom *in2);

// Globals
t_class		*change_class;			// Required. Global pointing to this class

/************************************************************************************/
// Main() Function

int main(void)				// main recieves a copy of the Max function macros table
{
	long attrflags = 0;
	t_class *c;
	t_object *attr;
	
	common_symbols_init();

	// Define our class
	c = class_new("jcom.change",(method)change_new, (method)change_free, (short)sizeof(t_change), (method)0L, 0L, 0);
	class_obexoffset_set(c, calcoffset(t_change, obex));

	// Make methods accessible for our class: 
	class_addmethod(c, (method)change_int,				"int", A_GIMME, 0L);
	class_addmethod(c, (method)change_float,			"float", A_GIMME, 0L);
	class_addmethod(c, (method)change_anything,			"list",	A_GIMME, 0L);
	class_addmethod(c, (method)change_anything,			"anything", A_GIMME, 0L);
    class_addmethod(c, (method)change_assist, 			"assist", A_CANT, 0L); 
    class_addmethod(c, (method)object_obex_dumpout, 	"dumpout", A_CANT,0);  
    class_addmethod(c, (method)object_obex_quickref,	"quickref", A_CANT, 0);

	// Finalize our class
	class_register(CLASS_BOX, c);
	change_class = c;
	return 0;
}


/************************************************************************************/
// Object Life

void *change_new(void)
{
	short i;
	t_change *x;									// Declare an object (based on our struct)
	x = (t_change *)object_alloc(change_class);		// Create object, store pointer to it (get 1 inlet free)
	if(x){
		object_obex_store((void *)x, _sym_dumpout, (object *)outlet_new(x,NULL));	// dumpout	
		x->change_Out[1] = bangout(x);				// Create Outlets (right to left order)
	    x->change_Out[0] = outlet_new(x, 0);		//	...

	// Create Right Inlet (inletnum is 1)
		x->inlet_right = proxy_new(x, 1, 0L);

	// Init the temp storage
	for(i=0; i<MAX_LIST_SIZE; i++)
		atom_setsym(&(x->last_input_list[i]), _sym_nothing);			
	}
	x->last_input_type = msg_new;					// Makes sure that first message receive goes to left outlet
	return (x);										// Return pointer to our instance
}

void change_free(t_change *x)
{
	freeobject((t_object *)(x->inlet_right));
}


/************************************************************************************/
// Methods bound to input/inlets

// Method for Assistance Messages
void change_assist(t_change *x, void *b, long msg, long arg, char *dst)
{
	if(msg==1) 							// Inlets
		strcpy(dst, "Input");
	else if(msg==2){ 					// Outlets
		switch(arg){
			case 0: strcpy(dst, "Repetition Filtered Output"); break;
			case 1: strcpy(dst, "(bang) input is the same as the last input"); break;
			case 2: strcpy(dst, "dumpout"); break;
 		}
 	}
}


// INPUT: INT/FLOAT
void change_int(t_change *x, long value)
{
	long	inlet = proxy_getinlet((t_object *)x);

	if(inlet == 0){
		if((value != x->last_input_int) || (x->last_input_type != msg_int))
			outlet_int(x->change_Out[0], value);
		else
			outlet_bang(x->change_Out[1]);
	}
	x->last_input_int = value;
	x->last_input_type = msg_int;
}

void change_float(t_change *x, double value)
{
	long	inlet = proxy_getinlet((t_object *)x);

	if(inlet == 0){
		if((value != x->last_input_float) || (x->last_input_type != msg_float))
			outlet_float(x->change_Out[0], value);
		else
			outlet_bang(x->change_Out[1]);
	}
	x->last_input_float = value;
	x->last_input_type = msg_float;
}


// INPUT: LIST/SYMBOL
void change_anything(t_change *x, t_symbol *msg, short argc, t_atom *argv)
{	
	short 	i;
	bool	match = false;
	bool	mismatch = false;
	long	inlet = proxy_getinlet((t_object *)x);
											
	if(inlet == 0){
		if (x->last_input_type != msg_list)		// didn't receive a list/symbol last time
			mismatch = true;
		else if (msg != x->last_input_symbol)	// last list/symbol received didn't start with the same symbol
			mismatch = true;
		else if (argc != x->last_argc)			// last list/symbol was not the same length
			mismatch = true;
		else {									// check to see if the args are the same...
			for(i=0; i<argc; i++){
				match = atom_compare(&(x->last_input_list[i]), argv+i);			
				if(!match) mismatch = true;
			}
		}
			
		if(mismatch)							// output the input
			outlet_anything(x->change_Out[0], msg, argc, argv);		
		else									// All elements are the same, send a bang
			outlet_bang(x->change_Out[1]);		
	}		
	x->last_input_symbol = msg;					// Make copies of the input for the next time
	x->last_input_type = msg_list;
	x->last_argc = argc;
	for(i=0;i<argc;i++)
		atom_copy(&(x->last_input_list[i]), argv+i);
}


// A utility for copying an atom
void atom_copy(t_atom *dst, t_atom *src)
{
	//dst[0].a_type = src[0].a_type;
	switch(src[0].a_type){
		case A_LONG:
			//dst[0].a_w.w_long = src[0].a_w.w_long;
			atom_setlong(dst, atom_getlong(src));
			break;
		case A_FLOAT:
			//dst[0].a_w.w_float = src[0].a_w.w_float;
			atom_setfloat(dst, atom_getfloat(src));
			break;
		case A_SYM:
			//dst[0].a_w.w_sym = src[0].a_w.w_sym;
			atom_setsym(dst, atom_getsym(src));
			break;
		default:
			error("could not copy atom!");
			break;	
	}
}


// A utility for comparing two atoms
bool atom_compare(Atom *in1, Atom *in2)
{
	if((in1[0].a_type == A_LONG) && (in2[0].a_type == A_LONG)){
		//if(in1[0].a_w.w_long == in2[0].a_w.w_long)
		if((atom_getlong(in1))==(atom_getlong(in2)))
			return true;
	}
	else if((in1[0].a_type == A_FLOAT) && (in2[0].a_type == A_FLOAT)){
		if((atom_getfloat(in1))==(atom_getfloat(in2)))
		//if(in1[0].a_w.w_float == in2[0].a_w.w_float)
			return true;
	}
	else if((in1[0].a_type == A_SYM) && (in2[0].a_type == A_SYM)){
		if((atom_getsym(in1))==(atom_getsym(in2)))
		//if(in1[0].a_w.w_sym == in2[0].a_w.w_sym)
			return true;
	}
	return false;
}





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

  jcom.change.xcodeproj/
    project.pbxproj
  jcom.change.cpp
  jcom.change.def
  jcom.change.vcproj
  jcom_change.sln