/*======================================================

FILE:      AEEInterface.h

SERVICES:  Macros and typedefs necessary to declare a 
           BREW-style interface

GENERAL DESCRIPTION:

  BREW's COM-style binary interface specification is 
  a little cumbersome to craft in C, these macros
  and types make BREW headers a little cleaner.

PUBLIC CLASSES AND STATIC FUNCTIONS:

    AEEINTERFACE, et al.

INITIALIZATION & SEQUENCING REQUIREMENTS:

	See Exported Routines

        Copyright © 2004 QUALCOMM Incorporated.
               All Rights Reserved.
            QUALCOMM Proprietary/GTDR
=====================================================*/
#ifndef AEEINTERFACE_H
#define AEEINTERFACE_H /* #ifndef AEEINTERFACE_H */

#include "AEEComdef.h"

#define VTBL(iname)       iname##Vtbl


#define INHERIT_IBase(iname) \
  uint32  (*AddRef)         (iname*);\
  uint32  (*Release)        (iname*)



/*
   ||
   || There's a problem with QINTERFACE(): it wastes namespace and forces
   ||   implementers to choose a name for a type that's unnecessarily
   ||   different from the interface name, since the QINTERFACE macro
   ||   makes an interface into a concrete type with only one member(!),
   ||   the vtable.
   ||
   || The macros below have all the same type-safety of the QINTERFACE()
   ||   macros, but don't force a concrete type on the object, allowing
   ||   implementers of interfaces to use the same type names, thus
   ||   obviating the need to do a type cast on entry to a method.
   ||
   || It should be easy to redefine QINTERFACE and its descendants
   ||   in terms of the below.
   ||
*/
#define AEEVTBL(iname) iname##Vtbl

#define AEEINTERFACE(iname) \
           typedef struct AEEVTBL(iname) AEEVTBL(iname); \
           struct AEEVTBL(iname)

#define AEEINTERFACE_(iname,ibasename) \
            typedef struct AEEVTBL(iname) AEEVTBL(iname); \
            struct AEEVTBL(iname)

#define AEEGETPVTBL(p,iname)  (*((AEEVTBL(iname) **)((void *)p)))

#define AEEINITVTBL(p,iname,vt)  (AEEGETPVTBL(p,iname) = (AEEVTBL(iname)*)&vt)

// Define an AEE interface
// (Assumes INHERIT_IClass exists for IClass)
#define AEEINTERFACE_DEFINE(iname)\
            typedef struct iname iname;\
            AEEINTERFACE(iname) {\
               INHERIT_##iname(iname);\
            }


#endif /* #ifndef AEEINTERFACE_H */
