testobex example in pattrsdk.pdf

    Jul 11 2006 | 9:47 pm
    hello, I tried compiling the testobex external in the pattrsdk.pdf and found a few errors. I corrected the errors but still the example does not work correctly.
    firstly, void *class_testobex was declared but then was used as testobex_class twice. so i changed it to class_testobex.
    secondly, the attribute 'operand' was registered but then 'data' was used in place of 'operand' . I changed all instances of 'data' to 'operand' and it compiled fine.
    When i set up a test in max however, the output value was always 0. I did put a value for operand in the object 'command line' ie @operand 34
    any idea on how to correct this?

    • Jul 12 2006 | 7:09 pm
      I decided to post the source. It is the same as in pattrsdk.pdf with the changes i mentioned.
      I have it working when i manually set operand to the value (which i commented out here), so maybe i am confused by the point of //handle attribute arguments (e.g. @operand 0.5) attr_args_process(x, ac, av);
      does it not set the values of the attributes to the variable you create and register with class_addattr(c, attr); ?
      #include "ext.h" #include "ext_obex.h" typedef struct _testobex { t_object ob; void *obex; float operand; void *out; } t_testobex;
      void *class_testobex; void *testobex_new(t_symbol *s, long ac, t_atom *av); void testobex_free(t_testobex *x); void testobex_int(t_testobex *x, long d); void testobex_float(t_testobex *x, double f);
      void main(void) { t_class *c; t_object *attr; long attrflags = 0;
      // define the class – A_GIMME required for attributes c = class_new("testobex", (method)testobex_new, (method)testobex_free, sizeof(t_testobex), (method)0L, A_GIMME, 0);
      // register the obex object's offset class_obexoffset_set(c, calcoffset(t_testobex, obex));
      // create and register an attribute (attr_offset) attr = attr_offset_new("operand", _sym_float32, attrflags, (method)0L, (method)0L, calcoffset(t_testobex, operand)); class_addattr(c, attr);
      // create and register some methods class_addmethod(c, (method)testobex_int, "int", A_LONG, 0); class_addmethod(c, (method)testobex_float, "float", A_FLOAT, 0);
      // add dumpout and quickref methods class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0); class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);
      // register the class as an instantiable box class_register(CLASS_BOX, c);
      // set the global class variable class_testobex = c; }
      void *testobex_new(t_symbol *s, long ac, t_atom *av) { t_testobex *x = NULL; // allocate a new object if (x = (t_testobex *)object_alloc(class_testobex)) { // important: initialize class members before processing // attribute args. otherwise, you might replace data. x->operand = 0;
      //handle attribute arguments (e.g. @operand 0.5) attr_args_process(x, ac, av);
      // if (ac > 1) x->operand = atom_getlong(av+1);
      // create a dumpout outlet, used by attributes object_obex_store(x, _sym_dumpout, outlet_new(x, NULL)); // create another outlet x->out = outlet_new(x, NULL); } return x; }
      void testobex_free(t_testobex *x) { ; // nix }
      void testobex_int(t_testobex *x, long d) { // int in, int out outlet_int(x->out, (long)((float)d * x->operand)); }
      void testobex_float(t_testobex *x, double f) { // float in, float out outlet_float(x->out, f * x->operand); }