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

FILE:      AEESingleton.h

SERVICES:  ISingleton

GENERAL DESCRIPTION:

   Modules wishing to share data or an instance of
    a class among many consumers may implement
    it with ILocalStorage from their piModule 
    or use this utility class to simplify/bulletproof
    their implementation.

PUBLIC CLASSES AND STATIC FUNCTIONS:

    ISingleton

INITIALIZATION & SEQUENCING REQUIREMENTS:

    See Exported Routines

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

#include "AEEQueryInterface.h"

typedef int (*AEESingletonPFNCI)(void *pcxCI, AEECLSID cls, void **ppif);

#define AEEIID_SINGLETON 0x0101ed1f

#define INHERIT_ISingleton(iname) \
   INHERIT_IQueryInterface(iname); \
   int    (*CreateInstance)(iname *p,\
                            AEECLSID cls, void **ppif,\
                            AEESingletonPFNCI pfnCI, void *pcxCI);\
   uint32 (*Ref)(iname *p, AEECLSID cls, uint32 *puRefs, int nInc)

// declare the actual Singleton interface
AEEINTERFACE_DEFINE(ISingleton);

#define ISINGLETON_AddRef(p)               AEEGETPVTBL((p),ISingleton)->AddRef((p))
#define ISINGLETON_Release(p)              AEEGETPVTBL((p),ISingleton)->Release((p))
#define ISINGLETON_QueryInterface(p,i,ppo) AEEGETPVTBL((p),ISingleton)->QueryInterface((p),(i),(ppo))
#define ISINGLETON_CreateInstance(p,c,pp,cicf,cicx) \
                                           AEEGETPVTBL((p),ISingleton)->CreateInstance((p),(c),(pp),(cicf),(cicx))
#define ISINGLETON_Ref(p,c,pu,inc)         AEEGETPVTBL((p),ISingleton)->Ref((p),(c),(pu),(inc))

/*=====================================================================
  DATA STRUCTURE DOCUMENTATION
=======================================================================
=======================================================================

AEESingletonPFNCI

Description:

  AEESingletonPFNCI is a CreateInstance callback passed to 
   ISINGLETON_CreateInstance().

Definition:

  typedef int (*AEESingletonPFNCI)(void *pcxCI, AEECLSID cls, void **ppif);

Parameters:
   pcxCI: user context data, the same pcxCI as is passed to 
          ISINGLETON_CreateInstance().
   cls: the AEECLSID of the class to be created
   ppif: [out] pointer to pointer to new instance

Comments:
  None

See Also:
  ISINGLETON_CreateInstance()

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

/*=====================================================================
INTERFACES DOCUMENTATION
=======================================================================
=======================================================================
ISingleton Interface

The implementations of many classes require something like "global" 
  data.  In a globals-free environment (all read-only, position-
  independent code), BREW provides this service, which is designed to 
  help classes store data that has class scope.
  
Since the correct tracking of allocation for this class data requires
  reference counting, we can think of the static data as a special class
  itself, a singleton.  A special case of this is where a class 
  actually *is* a singleton (e.g. a utility or otherwise stateless class).

Modules wishing to store class data using this interface should use 
  the ISingleton interface exported by the piModule passed to their
  CreateInstance function (see AEEkShell.h).

ISingleton wraps up keeping track of class data and the thread-safety
  issues for doing addref, release, create and delete in class-instance 
  semantics.

ISingleton's methods are thread-safe.

=============================================================================

ISINGLETON_AddRef()

Description:
   This function is inherited from IBASE_AddRef(). 

See Also:
   ISINGLETON_Release()

=============================================================================

ISINGLETON_Release()


Description:
   This function is inherited from IBASE_Release(). 

See Also:
   ISINGLETON_AddRef()

=============================================================================

ISINGLETON_QueryInterface()


Description:
   This function is inherited from IQI_QueryInterface().

See Also:
   ISINGLETON_AddRef(), ISINGLETON_Release()

=============================================================================

ISINGLETON_CreateInstance()

Description:
   This function is wraps the actual CreateInstance (or new function) of a 
    singleton class.  If ISingleton has already created the class, it
    is addref'd and returned, otherwise, pfnCI is called to create the
    class.

Prototype:
   int ISINGLETON_CreateInstance(ISingleton *piSing,
                            AEECLSID cls, void **ppif,
                            AEESingletonPFNCI pfnCI, void *pcxCI);


Parameters:
    piSing : [in] : Pointer to the ISingleton Interface object.
    cls : [in] : 32-bit ClassID of the requested interface.
    ppif : [out] Pointer to be filled with a reference to the instance
    pfnCI : [in] where to call to create the instance if not already created
    pcxCI : [in] : Pointer to user data to be passed to pfnCI

Return Value:
    SUCCESS, class instance found or created
    other AEEError, on failure, depends on pfnCI

Comments:
    None

Version:
    Introduced BREW PK 3.1

See Also:
    IKSHELL_CreateInstance()

=============================================================================

ISINGLETON_Ref()

Description:
   This function is a thread-safe, per-class refcount modifier function.  
     When the refcount for the indicated class id goes to 0, ISingleton
     stops tracking the instance.

Prototype:
   uint32 ISINGLETON_Ref(ISingleton *piSing,
                         AEECLSID cls, uint32 *puRefs, int nInc)

Parameters:
    piSing : [in] : Pointer to the ISingleton Interface object.
    cls : [in] : 32-bit ClassID of the ref to be modified, used to 
                untrack if Ref() returns 0
    puRefs: [in/out] pointer to the singleton's refcount, is adjusted by 
                     nInc
    nInc : [in] value to add to *puRefs, use 1 for "AddRef" and -1 for 
              "Release"

Return Value:
    the resulting value of puRefs

Comments:
    if ISINGLETON_Ref() returns 0, the ISingleton has stopped tracking
     the singleton instance, and the caller can safely delete himself

Version:
    Introduced BREW PK 3.1

See Also:
    IBASE_AddRef(), IBASE_Release()

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


#endif /* #ifndef AEESINGLETON_H */
