How to get the type of a object method given a t_object* object and its methodname?


    Jun 01 2020 | 9:27 pm
    Hi,
    I'm struggling to find the right function in the c-api to query if a method that isabout to be called via send message is a GIMME, A_LONG, ...
    If I have a t_object* obj of the target object with a t_symbol* methodname (eg bang) and I'd like to get the type of the method (named by methodname) what is the current documented way?
    As an aside, I found in ext_obex.h, there an undocumented method which looked promising:
    t_method_object *object_getmethod_object(t_object *x, t_symbol *methodname)
    where t_method_object is struct which has a messlist_entry which is an single entry in a t_messlist
    I tested as follows:
    t_method_object* mobj = object_getmethod_object(obj, methodname);
    t_messlist m_entry = mobj->messlist_entry;
    post("MESSLIST_ENTRY method_name %s type %s", m_entry.m_sym->s_name,
         m_entry.m_type);
    I was able to get the name of the method (m_entry.m_sym) but m_entry.m_type was empty.
    Given that this is undocumented, I wasn't hoping for much but is there a canonical way to do this?
    Any help would be really really appreciated.
    Shakeeb

    • Jun 02 2020 | 2:47 am
      I believe the function that you are looking for is defined in ext_obex.h and it is prototyped as follows: t_messlist *object_mess(t_object *x, t_symbol *methodname);
      - Luigi
    • Jun 02 2020 | 4:23 am
      Thanks very much, Luigi. You are super helpful as always!
      S
    • Jun 02 2020 | 5:54 am
      Unfortunately, I tried object_mess and got the same result as before (an empty m_type). I tried it with untyped and typed methods but in all cases, empty.
      I'm surprised that m_type in t_messlist holds method type information, since it's a char[]
      typedef struct messlist { struct symbol *m_sym; // Name of the message method m_fun; // Method associated w/ the message char m_type[MSG_MAXARG + 1]; // Argument type information } t_messlist;
      Since I'm interested in programmatically figuring out whether a method is a A_GIMME or not, i.e. typed or untyped. These are defined e_max_atomtypes (see below) which also contains a remark recommending to use a long instead to represent the value: "While these values are defined in an enum, you should use a long to represent the value". Why is m_type in t_messlist then a char[] and why is it empty? Now I'm totally confused...
      /** the list of officially recognized types, including pseudotypes for
      	commas and semicolons.  Used in two places: 1. the reader, when it reads
      	a string, returns long, float, sym, comma, semi, or dollar;
      	and 2. each object method comes with an array of them saying what types
      	it needs, from among long, float, sym, obj, gimme, and cant.
       
      	@ingroup atom
       
      	@remark	While these values are defined in an enum, you should use a long to represent the value.
      			Using the enum type creates ambiguity in struct size and is subject to various inconsistent 
      			compiler settings.
      */
      typedef enum {
      	A_NOTHING = 0,	///< no type, thus no atom
      	A_LONG,			///< long integer
      	A_FLOAT,		///< 32-bit float
      	A_SYM,			///< t_symbol pointer
      	A_OBJ,			///< t_object pointer (for argtype lists; passes the value of sym)
      	A_DEFLONG,		///< long but defaults to zero
      	A_DEFFLOAT,		///< float, but defaults to zero
      	A_DEFSYM,		///< symbol, defaults to ""
      	A_GIMME,		///< request that args be passed as an array, the routine will check the types itself.
      	A_CANT,			///< cannot typecheck args
      	A_SEMI,			///< semicolon
      	A_COMMA,		///< comma
      	A_DOLLAR,		///< dollar
      	A_DOLLSYM,		///< dollar
      	A_GIMMEBACK,	///< request that args be passed as an array, the routine will check the types itself. can return atom value in final atom ptr arg. function returns long error code 0 = no err. see gimmeback_meth typedef
      	A_DEFER	=		0x41,	///< A special signature for declaring methods. This is like A_GIMME, but the call is deferred.
      	A_USURP =		0x42,	///< A special signature for declaring methods. This is like A_GIMME, but the call is deferred and multiple calls within one servicing of the queue are filtered down to one call.
      	A_DEFER_LOW =	0x43,	///< A special signature for declaring methods. This is like A_GIMME, but the call is deferref to the back of the queue.
      	A_USURP_LOW =	0x44	///< A special signature for declaring methods. This is like A_GIMME, but the call is deferred to the back of the queue and multiple calls within one servicing of the queue are filtered down to one call.
      } e_max_atomtypes;
      Any help figuring this out would be appreciated.
      Thanks,
      S
    • Jun 02 2020 | 8:08 am
      Hi Shakeeb, I will share some code with you that hopefully will clear up your confusion. Here is how you post to the Max window various methods that your object may support:
      void myobj_printmess(t_myobj *x, t_symbol *methodname) { t_messlist *mess = object_mess((t_object *)x, methodname); if (mess) { object_post(NULL, "method name: %s, type: %d", mess->m_sym->s_name, mess->m_type[0]); } }
      m_type[0] holds one of the values defined in e_max_atomtypes. I don't know why it is defined as a char. My guess would be that the t_messlist data structure is a very old piece of code, and back at the time when it was written they were probably trying to minimize the memory footprint of the struct.
      Please let me know if it works for you.
      - Luigi
    • Jun 02 2020 | 8:27 am
      Thanks so much for your help and patience, Luigi. It totally makes sense now, but you can appreciate how this can be confusing (-:
      I also find the mix of the public, private, documented, undocumented and deprecated methods in the c-api confusing (object_mess is a case in point). I wonder if it would be possible to have a header file which contains only fully documented, public and non-deprecated methods.
      I guess min-devkit and min-api ( https://github.com/Cycling74/min-api) are trying to do this but I then again I suppose this is also another layer on top of the c-api which is unlikely to be rewritten.
      S
    • Jun 02 2020 | 9:37 am
      Yes, I absolutely agree with you, Shakeeb. This is confusing. I am glad it's making sense now, though.
      Best
      - Luigi