Difference between revisions of "Overriding OM GET()"

From MorphOS Library

(Added a note of importance of returning TRUE for recognized attributes.)
m
Line 2: Line 2:
  
  
The ''OM_GET()'' method, used for getting an attribute from an object, receives opGet structure as its message. The structure is defined in the ''<intuition/classusr.h>'' header file:
+
The ''OM_GET()'' method, used for getting an attribute from an object, receives an opGet structure as its message. The structure is defined in the ''<intuition/classusr.h>'' header file:
  
 
  struct opGet
 
  struct opGet
Line 11: Line 11:
 
  };
 
  };
  
Unlike ''[[Overriding OM_SET()|OM_SET()]]'', this method handles only one attribute at a time. The attribute is placed in ''opg_AttrID'' field. The field ''opg_Storage'' is a '''pointer''' to a place where the attribute value should be stored. It is defined as a pointer to ULONG, but it may point to anything (for example to some larger structure). It allows for passing attributes not fitting in a 32-bit variable. Because ''OM_GET()'' does not have a taglist iteration loop, its implementation is simple:
+
Unlike ''[[Overriding OM_SET()|OM_SET()]]'', this method handles only one attribute at a time. The attribute is placed in the ''opg_AttrID'' field. The field ''opg_Storage'' is a '''pointer''' to a place where the attribute value should be stored. It is defined as a pointer to ULONG, but it may point to anything (for example to some larger structure). It allows for passing attributes not fitting in a 32-bit variable. Because ''OM_GET()'' does not have a taglist iteration loop, its implementation is simple:
  
 
  IPTR MyClassGet(Class *cl, Object *obj, struct opGet *msg)
 
  IPTR MyClassGet(Class *cl, Object *obj, struct opGet *msg)
Line 29: Line 29:
 
  }
 
  }
  
The implementation consists of a ''switch'' statement with ''cases'' for all recognized attributes. If an attribute is recognized, the method should return ''TRUE''. It is very important, as [[Event Driven Programming, Notifications#Notifications in MUI|MUI notifications]] rely on OM_GET() and will not work on the attribute if ''TRUE'' is not returned. Unknown attributes are passed to the superclass. The ''DoSuperMethodA()'' call may be alternatively placed as the ''default'' clause of the ''switch'' statement. It is important that ''msg->opg_Storage'' is '''deferenced''' when storing the attribute value. If the value type is not integer, a typecast is needed. For a value type ''T'', the deferention combined with typecast is denoted as ''*(T*)''.
+
The implementation consists of a ''switch'' statement with ''cases'' for all recognized attributes. If an attribute is recognized, the method should return ''TRUE''. It is very important, as [[Event Driven Programming, Notifications#Notifications in MUI|MUI notifications]] rely on OM_GET() and will not work on the attribute if ''TRUE'' is not returned. Unknown attributes are passed to the superclass. The ''DoSuperMethodA()'' call may be alternatively placed as the ''default'' clause of the ''switch'' statement. It is important that ''msg->opg_Storage'' is '''dereferenced''' when storing the attribute value. If the value type is not integer, a typecast is needed. For a value type ''T'', the dereferencing combined with typecast is denoted as ''*(T*)''.

Revision as of 08:05, 7 January 2011

Grzegorz Kraszewski


The OM_GET() method, used for getting an attribute from an object, receives an opGet structure as its message. The structure is defined in the <intuition/classusr.h> header file:

struct opGet
{
  ULONG  MethodID;           /* always OM_GET (0x104) */
  ULONG  opg_AttrID;
  ULONG *opg_Storage;
};

Unlike OM_SET(), this method handles only one attribute at a time. The attribute is placed in the opg_AttrID field. The field opg_Storage is a pointer to a place where the attribute value should be stored. It is defined as a pointer to ULONG, but it may point to anything (for example to some larger structure). It allows for passing attributes not fitting in a 32-bit variable. Because OM_GET() does not have a taglist iteration loop, its implementation is simple:

IPTR MyClassGet(Class *cl, Object *obj, struct opGet *msg)
{
  switch (msg->opg_AttrID)
  {
    case Some_Integer_Tag:
      *msg->opg_Storage = /* value of the tag */;
    return TRUE;

    case Some_String_Tag:
      *(char**)msg->opg_Storage = "a fixed string value";
    return TRUE;
  }

  return DoSuperMethodA(cl, obj, (Msg)msg);
}

The implementation consists of a switch statement with cases for all recognized attributes. If an attribute is recognized, the method should return TRUE. It is very important, as MUI notifications rely on OM_GET() and will not work on the attribute if TRUE is not returned. Unknown attributes are passed to the superclass. The DoSuperMethodA() call may be alternatively placed as the default clause of the switch statement. It is important that msg->opg_Storage is dereferenced when storing the attribute value. If the value type is not integer, a typecast is needed. For a value type T, the dereferencing combined with typecast is denoted as *(T*).