listeners_intern.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 334 行

C
334
字号
/* * * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. *  * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). *  * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA *  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. *//** * @file * * @ingroup AMS * * This is reference implementation of the Generic Listeners API. * It contains basic functions to work with linked lists. */#include <string.h>              /* for memcpy() */#include <pcsl_memory.h>#include <listeners_intern.h>/** Maximum number of different listener types */#define MAX_LISTENER_TYPES 10/** * A list to track the information about the registered listeners. */static GenericListener* g_pRegisteredListeners[MAX_LISTENER_TYPES];/** * Array with * (listener type; index of the listeners list in g_pRegisteredListeners[]) * pairs. */static int g_listenerIdxByType[MAX_LISTENER_TYPES * 2];/** Indicates if the Listeners Subsystem is already initialized. */static int g_listenersInitDone = 0;/** * Finds the given type of listener in the g_listenerIdxByType[] array * of pairs and returns an index of the corresponding listeners list * in the g_pRegisteredListeners[] array. * * @param listenerType type of listener to look for * * @return index of the list containing listeners of the given type *         or -1 if it is not found */static intget_listeners_list_index(int listenerType) {    int i;    for (i = 0; i < MAX_LISTENER_TYPES; i++) {        int n = (i << 1);        if (g_listenerIdxByType[n] == listenerType) {            return g_listenerIdxByType[n + 1];        }    }    return -1;}/** * Adds a new type of listener to the internal array containing * the associations between the listener types and the index of the * list with pointers to the callback functions in another array. * If such type of listeners is already registered, returns an index * of the corresponding list like get_listeners_list_index(). * * @param listenerType a new type of listener to add * * @return index of the list containing listeners of the given type *         or -1 if it doesn't exist and can't be added (the list is full) */static intadd_listener_type(int listenerType) {    int i, firstFreeIdx = -1;    for (i = 0; i < MAX_LISTENER_TYPES; i++) {        int n = (i << 1);        if (g_listenerIdxByType[n] == listenerType) {            /* list of listeners of this type already exists, do nothing */            return g_listenerIdxByType[n + 1];        } else if (firstFreeIdx == -1 &&                   g_listenerIdxByType[n] == LISTENER_TYPE_INVALID) {            firstFreeIdx = n;        }    }    if (firstFreeIdx != -1) {        /*         * There are no listeners of this type registered yet, trying         * to find the first unused entry in g_pRegisteredListeners.         */        int freeIdxForList = -1;        for (i = 0; i < MAX_LISTENER_TYPES; i++) {            if (!g_pRegisteredListeners[i]) {                freeIdxForList = i;                break;            }        }        if (freeIdxForList != -1) {            /* add a listenerType => index of the listeners list association */            g_listenerIdxByType[firstFreeIdx++] = listenerType;            g_listenerIdxByType[firstFreeIdx]   = freeIdxForList;            return freeIdxForList;        }    }    return -1;}/** * Removes an association of the given listener's type with an index of the * corresponding listeners list in the g_pRegisteredListeners[] array. * * @param listenerType type of listener for which the association *                     must be removed */static voidremove_listener_type(int listenerType) {    int i;    for (i = 0; i < MAX_LISTENER_TYPES; i++) {        int n = (i << 1);        if (g_listenerIdxByType[n] == listenerType) {            g_listenerIdxByType[n++] = LISTENER_TYPE_INVALID;            g_listenerIdxByType[n]   = LISTENER_TYPE_INVALID;            break;        }    }}/** * Initializes the Listeners subsystem. * * @return error code (ALL_OK if successful) */MIDPErrorinit_listeners_impl() {    if (g_listenersInitDone) {        /* Already initialized */        return ALL_OK;    }    memset((char*)g_pRegisteredListeners, 0, sizeof(g_pRegisteredListeners));    memset((char*)g_listenerIdxByType, (char)LISTENER_TYPE_INVALID,           sizeof(g_listenerIdxByType));    return ALL_OK;}/** * Returns a list of listeners of the given type. * * @param listenerType type of listeners which should be returned * * @return linked list of the event listeners of the given type *         or NULL if no listeners of this type are registered */const GenericListener*get_event_listeners_impl(int listenerType) {    const GenericListener* pListener = NULL;    if (listenerType >= 0 && listenerType < MAX_LISTENER_TYPES) {        int index = get_listeners_list_index(listenerType);        if (index >= 0) {            pListener = g_pRegisteredListeners[index];        }    }    return pListener;}/** * Adds a generic listener to the linked list of registered listeners. * * @param pListenerData a structure with listener's parameters. * The first member of this structure must be of GenericListener type. * * @return error code: ALL_OK if successful, *                     OUT_OF_MEMORY if not enough memory, *                     BAD_PARAMS if pListenerData is NULL *                                or pListenerData->dataSize is invalid */MIDPErroradd_event_listener_impl(const GenericListener* pListenerData) {    GenericListener *pNewListener;    int index;    /* validate the parameters */    if (pListenerData == NULL) {        return BAD_PARAMS;    }    if (pListenerData->dataSize < (int)sizeof(GenericListener)) {        return BAD_PARAMS;    }    index = add_listener_type(pListenerData->listenerType);    if (index < 0) {        /*         * Too many types of listeners are registered,         * not enough space for this one.         */        return OUT_OF_MEMORY;    }    /* allocate memory for a new structure describing the listener */    pNewListener = (GenericListener*)pcsl_mem_malloc(pListenerData->dataSize);    if (pNewListener == NULL) {        return OUT_OF_MEMORY;    }    memcpy((char*)pNewListener, (const char*)pListenerData,           pListenerData->dataSize);    pNewListener->pNext = g_pRegisteredListeners[index];    g_pRegisteredListeners[index] = pNewListener;    return ALL_OK;}/** * Unregisters the given listener of the specified type. * * @param fn_callback pointer to the listener function * @param listenerType type of events this listener listens for * * @return error code: ALL_OK if successful, *                     NOT_FOUND if the listener was not found */MIDPErrorremove_event_listener_impl(void* fn_callback, int listenerType) {    GenericListener *pListener, *pPrev = NULL;    int index;    index = get_listeners_list_index(listenerType);    if (index < 0) {        return NOT_FOUND;    }    pListener = g_pRegisteredListeners[index];    while (pListener) {        if (pListener->fn_callback == fn_callback) {            if (pPrev) {                pPrev->pNext = pListener->pNext;            } else {                g_pRegisteredListeners[index] = pListener->pNext;                if (g_pRegisteredListeners[index] == NULL) {                    remove_listener_type(listenerType);                }            }            pcsl_mem_free(pListener);            return ALL_OK;        }        pPrev = pListener;        pListener = pListener->pNext;    }    return NOT_FOUND;}/** * Unregisters all registered listeners of the given type. * * @param listenerType type of the listeners that must be unregistered * or LISTENER_TYPE_ANY to unregister all listeners * * @return error code (ALL_OK if successful) */MIDPErrorremove_all_event_listeners_impl(int listenerType) {    GenericListener *pListener, *pTmpListener, *pPrev = NULL;    int index = -1;    do {        if (listenerType == LISTENER_TYPE_ANY) {            /* walk through all indices from 0 to MAX_LISTENER_TYPES */            index++;        } else {            index = get_listeners_list_index(listenerType);        }        if (index < 0 || index == MAX_LISTENER_TYPES) {            /* there are no listeners of the given type */            break;        }        pListener = g_pRegisteredListeners[index];        while (pListener) {            pTmpListener = pListener->pNext;            if (pPrev) {                pPrev->pNext = pTmpListener;            } else {                g_pRegisteredListeners[index] = pTmpListener;            }            pcsl_mem_free(pListener);            pListener = pTmpListener;        }    } while (1);    return ALL_OK;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?