object_id.h


Overview

Note

The term ECU in this document refers to Embedded C Utilities, the shorthand name for this project.

Allows users to identify different types stored in the same data structure without conflicting ID values.

Theory

Object ID Overview

An object ID is a unique integer value that can be assigned to different data types. The scheme presented in this module prevents an object ID used internally by ECU and a user’s object ID from sharing the same value. This is accomplished by starting user-defined object ID’s at ECU_USER_OBJECT_ID_BEGIN:

enum user_object_ids
{
    USER_OBJECT_ID_1 = ECU_USER_OBJECT_ID_BEGIN,
    USER_OBJECT_ID_2,
    USER_OBJECT_ID_3
};

ECU_USER_OBJECT_ID_BEGIN is guaranteed to always be 0. IDs less than ECU_USER_OBJECT_ID_BEGIN are reserved for internal use by ECU library. Therefore reserved IDs are always negative. User-defined IDs are always >= 0.

Example

The following example stores different node types in the same linked list (dlist.h) and uses the object ID scheme to identify them:

/* User-defined object IDs. */
enum user_object_ids
{
    TYPE1 = ECU_USER_OBJECT_ID_BEGIN,
    TYPE2,
    TYPE3
};

/* Data types of nodes stored in linked list. */
struct type1
{
    int a;
    struct ecu_dnode node;
};

struct type2
{
    struct ecu_dnode node;
    int b;
};

struct type3
{
    int c;
    struct ecu_dnode node;
    int d;
};

struct ecu_dlist_iterator iterator;
struct ecu_dlist list;
struct type1 node1;
struct type2 node2;
struct type3 node3;

/* Construct list and nodes. Assign object IDs to each node to identify their data types. */
ecu_dlist_ctor(&list);
ecu_dnode_ctor(&node1.node, ECU_DNODE_DESTROY_UNUSED, TYPE1);
ecu_dnode_ctor(&node2.node, ECU_DNODE_DESTROY_UNUSED, TYPE2);
ecu_dnode_ctor(&node3.node, ECU_DNODE_DESTROY_UNUSED, TYPE3);

/* Add nodes to list. */
ecu_dlist_push_back(&list, &node1.node);
ecu_dlist_push_back(&list, &node2.node);
ecu_dlist_push_back(&list, &node3.node);

/* Iterate over list. Use object ID to identify the data type stored in each node. */
ECU_DLIST_FOR_EACH(i, &iterator, &list)
{
    switch (ecu_dnode_id(i))
    {
        case TYPE1:
        {
            struct type1 *me = ECU_DNODE_GET_ENTRY(i, struct type1, node);
            me->a = 5;
            break;
        }

        case TYPE2:
        {
            struct type2 *me = ECU_DNODE_GET_ENTRY(i, struct type2, node);
            me->b = 10;
            break;
        }

        case TYPE3:
        {
            struct type3 *me = ECU_DNODE_GET_ENTRY(i, struct type3, node);
            me->c = 15;
            me->d = 20;
            break;
        }

        default:
        {
            break;
        }
    }
}

API