/**
 * 
 * nodeClone
 * 
 * Data structures for cloning RxPacket's during RxPipeline execution 
 * 
 * Copyright (c) Criterion Software Limited
 */

/****************************************************************************
 *                                                                          *
 * module : nodeClone.h                                                     *
 *                                                                          *
 * purpose: see nodeClone.c                                                 *
 *                                                                          *
 ****************************************************************************/

#ifndef NODECLONE_H
#define NODECLONE_H

#include "p2core.h"
 
/****************************************************************************
 Global types
 */

/* RWPUBLIC */

typedef struct RxPacketCacheCluster RxPacketCacheCluster;

/**
 * \ingroup rwcoregeneric
 * \struct RxPacketCacheCluster
 * structure containing a cache of an \ref RxCluster's
 * within an \ref RxPacketCache 
 */
struct RxPacketCacheCluster
{
    RwUInt32            slot;       /**< A \ref RwUInt32 index into the \ref RxPacketCache's
                                     * array of RxPacketCacheCluster's */
    RwUInt16            flags;      /**< A cache of the original cluster's flags */
    RwUInt16            stride;     /**< A cache of the original cluster's stride */
    void               *data;       /**< A cache of the original cluster's data */
    RwUInt32            numAlloced; /**< A cache of the original cluster's numAlloced */
    RwUInt32            numUsed;    /**< A cache of the original cluster's numUsed */
    RxPipelineCluster  *clusterRef; /**< A cache of the original cluster's \ref RxPipelineCluster */
};
typedef struct RxPacketCache RxPacketCache;

/**
 * \ingroup rwcoregeneric
 * \struct RxPacketCache
 * structure containing a cache of a \ref RxPacket */
struct RxPacketCache
{
    RwUInt16             packetFlags; /**< A cache of the original packet's flags */
    RwUInt16             pad[1];      /**< Alignment padding */
    RwUInt32             numClusters; /**< The number of present clusters in the
                                       * original packet when it was cloned */
    RwBool               lastCloneDone;/**< Once the cache has been cloned by \ref RxPacketCacheClone
                                       * with (lastClone == TRUE), it should not be used again! */
    RwUInt32             pad2[1];      /**< Alignment padding */
    RxPacketCacheCluster clusters[1]; /**< An array of \ref RxPacketCacheCluster's,
                                       * extending beyond 1 element */
};
    

typedef struct RxNodeCloneInitData RxNodeCloneInitData;
/**
 * \ingroup rwcoregeneric
 * \struct RxNodeCloneInitData
 * structure with which to initialize 
 * clone a \ref RxNodeDefinition, 
 * through \ref RxNodeDefinitionCloneCreate and
 * set up cloned \ref RxPipelineNode modes, through
 * \ref RxPipelineNodeCloneDefineModes */
struct RxNodeCloneInitData
{
    RwUInt32   numModes;   /**< Specifies the number of modes in
                              which the node should operate */
    RwUInt32   numOutputs; /**< Specifies the number of outputs of this
                              Clone node, which is also the maximum
                              number of outputs to which any one mode
                              may dispatch packets */
    RwUInt32  *modeSizes;  /**< Specifies the number of outputs to which
                              each mode dispatches packets */
    RwUInt32 **modes;      /**< An array of numModes pointers to arrays
                              (of length numOutputs) specifying the
                              outputs, in order, to which each mode
                              should dispatch packets (output zero is
                              the first output) */
};

/**
 * \ingroup rwcoregeneric
 * \struct RxNodeCloneData
 * structure which is the private
 * data of Clone nodes \ref RxPipelineNode */
typedef struct RxNodeCloneData RxNodeCloneData;
struct RxNodeCloneData
{
    RwBool optimized;         /**< \ref RwBool specifying whether \ref RxPipelineNodeCloneOptimize
                               * has been run on this \ref RxPipelineNode yet */
    RwUInt32 currentMode;     /**< \ref RwUInt32 The current mode of operation */
    RxNodeCloneInitData *data;/**< A pointer to \ref RxNodeCloneInitData data
                               * specifying the modes of operation */
};
/* RWPUBLICEND */

/****************************************************************************
 Global ptototypes
 */

/* RWPUBLIC */

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

extern RxNodeDefinition *RxNodeDefinitionCloneCreate(RxNodeCloneInitData *data);
extern RwBool            RxPipelineNodeCloneDefineModes(
                             RxPipeline          *pipeline,
                             RxPipelineNode      *node,
                             RxNodeCloneInitData   *data);
extern RwBool            RxNodeDefinitionCloneDestroy(RxNodeDefinition *def);
extern RwBool            RxPipelineNodeCloneOptimize(RxPipeline     *pipeline,
                                                     RxPipelineNode *node);

#ifdef    __cplusplus
}
#endif /* __cplusplus */

/* RWPUBLICEND */

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

/* Utility functions for cloning packets - into the core eventually */
extern RxPacketCache *RxPacketCacheCreate(RxPacket               *packet,
                                          RxPipelineNodeInstance *node,
                                          RxHeap                 *heap);
extern RxPacket      *RxPacketCacheClone( RxPacketCache          *cache,
                                          RxPipelineNodeInstance *node,
                                          RwBool                  lastClone);
extern void           RxPacketCacheDestroy(RxPacketCache         *cache,
                                           RxHeap                *heap);

#ifdef    __cplusplus
}
#endif /* __cplusplus */

#endif /* NODECLONE_H */


