Sending and Receiving Remotely Editable Data#

The following data types can be sent to PVRTune for editing:

  • bool

  • enum

  • float

  • int

  • string

All of these items are stored as instances of SSPSCommsLibraryItem with eType stating the data type of the item and pData containing the actual item.

The name of the item, as it appears in PVRTune, is based on the value of pszName. Full stops placed in pszName can be used to create categories and sub-categories which PVRTune displays as a foldable tree view. For example:

  • Category namnes:

Category-A.SubCategory-A.Item-1
Category-A.SubCategory-A.Item-2
Category-A.SubCategory-B.Item-1
Category-B.SubCategory-A.Item-1
Category-B.SubCategory-A.Item-2
  • Foldable tree view:

 Category-A.
     SubCategory-A.
         Item-1
         Item-2
     SubCategory-B.
         Item-1
Category-B.
    SubCategory-A.
        Item-1
        Item-2

The process of sending and receiving editable data consists of three steps:

  1. Initialising the editable data;

  2. Sending the data to PVRTune at initialisation time;

  3. Retrieving updates to the data.

The first two steps are usually performed simulatneously, and as such, the examples identified next follow this approach.

Additional Initialisation Steps#

There are a few additional initialisation steps which are required when sending editable data:

  1. Set up enumerators of possible editable items, one for each data type. From this, determine the total number of editable items.

enum PVRScopeEditableFloats     {
    eARBITRARY_EDITABLE_FLOAT,
    eNUMBER_OF_EDITABLE_FLOATS
};
enum PVRScopeEditableStrings     {
    eARBITRARY_EDITABLE_STRING,
    eNUMBER_OF_EDITABLE_STRINGS
}

const unsigned int numEditableItems= (unsigned int)eNUMBER_OF_EDITABLE_FLOATS + (unsigned int)eNUMBER_OF_EDITABLE_STRINGS;
  1. Create the editable item array.

SSPSCommsLibraryItem editableItemArray[numEditableItems];
  1. Initialise the editable items by giving them default values.

for(unsigned int i = 0; i < numEditableItems; i++) { // Set some arbitrary float data float arbitrary
    Float = 3.5f;
    float arbitraryString = "Arbitrary String";

    // Create an editable float object
    SSPSCommsLibraryTypeFloat scopeFloat;
    editableItemArray[i].pszName = arbitraryString;
    editableItemArray[i].eType = eSPSCommsLibTypeFloat;
    scopeFloat.fCurrent = arbitraryFloat;
    scopeFloat.fMin = 0.0f;
    scopeFloat.fMax = 200.0f;

    // Add the float object to the editable item
    editableItemArray[i].itemData = (const char*)&scopeFloat;
    editableItemArray[i].nDataLength = sizeof(scopeFloat);
}
  1. Send the editable items to PVRTune.

pplLibraryCreate(PVRScopeComms, editableItemArray, numEditableItems);

Retrieving Updated Data#

After initialisation, updated data can be retrieved using the steps below.

  1. Create a number of temporary variables to hold the updated data.

// Used to determine the length of strings
unsigned int itemLength(0);
// Used to determine which item in 'editableItemArray' the updated refers to
unsigned int itemNum(0)
// A pointer to the edited item
const char* itemData(NULL);
// A float to store the returned value in
float arbitraryFloat= 0.0f;
  1. In a loop, retrieve each dirty item.

while(pplLibraryDirtyGetFirst(PVRScopeComms, itemNum, itemLength, &itemData))
{
  1. Determine the items type based on its item number (based on the enumerators created in Step 1).

if(itemNum < eNUMBER_OF_EDITABLE_FLOATS)
{
  1. Retrieve the editable item. For example, retrieving a float:

        SSPSCommsLibraryTypeFloat* newItemData=(SSPSCommsLibraryTypeFloat*)itemData;
        arbitraryFloat = newItemData->fCurrent;
    }
}

Note

Retrieving strings is a special case. The string should be created in advance and retrieved as follows:

arbitraryString.assign(itemData, itemLength);
  1. Use the retrieved data to update the application.

Full source code#

/*********************************************************************************************
*
* This example code consists of six steps:
*
* 1. Create an array of editable items
* 2. Setup PVRScopeComms
* 3. Create default values for the editable items
* 4. Submit the array of editable items to PVRTune
* 5. Retrieve the updated items from PVRTune
* 6. Shutdown PVRScopeComms
*
*********************************************************************************************/

#include <stdlib>
#include "PVRScopeComms.h"

// Step 1. Create an array of editable items
enum PVRScopeEditableFloats
{
    eARBITRARY_EDITABLE_FLOAT,
    eNUMBER_OF_EDITABLE_FLOATS
};
enum PVRScopeEditableStrings
{
    eARBITRARY_EDITABLE_STRING,
    eNUMBER_OF_EDITABLE_STRINGS
};
const unsigned int numEditableItems = (unsigned int)eNUMBER_OF_EDITABLE_FLOATS
                                    + (unsigned int)eNUMBER_OF_EDITABLE_STRINGS;
SSPSCommsLibraryItem editableItemArray[numEditableItems];

// Step 2. Setup PVRScopeComms
SSPSCommsData* PVRScopeComms;
std::string timelineTitle = "Example";
PVRScopeComms = pplInitialise(timelineTitle,
                              (unsigned int)timelineTitle.length());

// Step 3. Create default values for the editable items
float arbitraryFloat = 3.5f;
float arbitraryString = "Arbitrary String";
for(unsigned int i = 0; i < numEditableItems; ++i)
{
    // If the editable item is a float
    if(i < eNUMBER_OF_EDITABLE_FLOATS)
    {
        // Create the float
        SSPSCommsLibraryTypeFloat scopeFloat;
        switch(i)
        {
        case eARBITRARY_EDITABLE_FLOAT:
            // Set its starting values
            editableItemArray[i].pszName = "Arbitrary Float";
            editableItemArray[i].eType   = eSPSCommsLibTypeFloat;
            scopeFloat.fCurrent          = arbitraryFloat;
            scopeFloat.fMin              = 0.0f;
            scopeFloat.fMax              = 200.0f;
            break;
        default:
            return false;
        }

    // Add the float object to the editable item
    editableItemArray[i].itemData = (const char*)&scopeFloat;
    editableItemArray[i].nDataLength = sizeof(scopeFloat);
    }

    else  // The editable item is a string (because we're only using strings and floats)
    {
        switch(i - eNUMBER_OF_EDITABLE_FLOATS)
        {
        case eARBITRARY_EDITABLE_STRING:
            // Set its starting balues
            editableItemArray[i].pszName = "Arbitrary String";
            editableItemArray[i].eType = eSPSCommsLibTypeString;
            editableItemArray[i].itemData = arbitraryString.c_str();
            editableItemArray[i].nDataLength = arbitraryString.length();
            break;
        default:
            return false;
        }
    }
    editableItemArray[i].nNameLength = (unsigned int) strlen(editableItemArray[i].pszName);
}

// Step 4. Submit the array of editable items to PVRTune
if(!pplLibraryCreate(PVRScopeComms, editableItemArray, numEditableItems))
{
                // Error handling goes here
}

// Sleep for a bit so we have time to receive some data from PVRTune
Sleep(1000);

// Step 5. Retrieve the updated items from PVRTune
unsigned int itemNum(0);
unsigned int itemLength(0);
const char* itemData(NULL);
while(pplLibraryDirtyGetFirst(PVRScopeComms, itemNum, itemLength, &itemData))
{
    // Update the item referred to by 'itemNum' with 'data'
    if(itemNum < eNUMBER_OF_EDITABLE_FLOATS)
    {
        switch(itemNum)
        {
        case eARBITRARY_EDITABLE_FLOAT:
        {
            SSPSCommsLibraryTypeFloat* newItemData = (SSPSCommsLibraryTypeFloat*)itemData;
            arbitraryFloat = newItemData->fCurrent;
            break;
        }
        default:
        {
            // Handle unknown float
            break;
        }
        }
    }
    else
    }
        switch(itemNum-eNUMBER_OF_EDITABLE_FLOATS)
        {
        case eARBITRARY_EDITABLE_STRING:
        {
            arbitraryString.assign(itemData, itemLength);
            break;
        }
        default:
        {
            // Handle unknown string
            break;
        }
    }
 }

// Step 6. Shutdown PVRScopeComms
pplShutdown(PVRScopeComms);