form_loader - ryzom/ryzomcore GitHub Wiki


title: Reading sheets using the form loader description: How to load and read Georges form data at runtime using UFormLoader and UFormElm published: true date: 2023-03-16T23:03:38.891Z tags: editor: markdown dateCreated: 2022-03-16T10:34:59.938Z

Loading

For simple loading of sheets, you need to do the following.

  1. Add the search path for the sheets you want to load using CPath::addSearchPath().

  2. The required .dfn and .typ files must also be in a search path.

  3. Create a Georges form loader.

    NLGEORGES::UFormLoader *formLoader = NLGEORGES::UFormLoader::createLoader();

    This loader can be used to load many sheets, so keep it around and reuse it. {.is-info}

  4. Load a form.

    NLMISC::CSmartPtr<NLGEORGES::UForm> form = formLoader->loadForm("the_sheet_file.sheet_type");

    sheet_type is the extension of the sheet file. It must match a DFN name — for example foo.dfn allows loading of *.foo sheets.

    In other words, when loadForm is passed bar.foo as an input file, it will try to find the foo.dfn format file. If it doesn't find it, the loading fails.

  5. When done with all loading, release the loader.

    NLGEORGES::UFormLoader::releaseLoader(formLoader);

Reading values

Now you have the form you can access data using the form interface by getting the root element:

const NLGEORGES::UFormElm &root = form->getRootNode();

Then you can access data by name using dot notation for nested fields and bracket notation for arrays:

// Read a simple value
sint32 hitPoints;
root.getValueByName(hitPoints, "HitPoints");

// Read a nested struct value
float posX;
root.getValueByName(posX, "PositionData.x");

// Read from an array of structs
std::string name;
root.getValueByName(name, "CoolFilesInfo[0].ShortName");

Supported types

getValueByName has overloads for the following C++ types:

C++ Type Georges Type
std::string String
bool Any (parsed from string)
sint8, uint8, sint16, uint16 UnsignedInt / SignedInt
sint32, uint32 UnsignedInt / SignedInt
float, double Double
NLMISC::CRGBA Color

All getValueByName overloads return bool indicating success, and take an optional TEval parameter controlling evaluation mode:

  • Eval (default) — fully evaluates the value, resolving references and formulas.
  • Formula — evaluates enum definitions but not formulas/references.
  • NoEval — returns the raw string without any evaluation.

Writing values

There is an equivalent setValueByName for modifying form values at runtime:

root.setValueByName(500, "HitPoints");

The setValueByName overloads accept an optional bool *created output parameter that indicates whether the value was newly created (rather than overwriting an existing one).

Working with arrays

To iterate over an array, first get the array node, then query its size:

const NLGEORGES::UFormElm *arrayNode;
root.getNodeByName(&arrayNode, "TestArray");
if (arrayNode)
{
    uint size;
    arrayNode->getArraySize(size);
    for (uint i = 0; i < size; ++i)
    {
        std::string value;
        arrayNode->getArrayValue(value, i);
        nlinfo("TestArray[%d] = %s", i, value.c_str());
    }
}

For arrays of structs, use getArrayNode to get individual struct elements:

const NLGEORGES::UFormElm *arrayNode;
root.getNodeByName(&arrayNode, "CoolFilesInfo");
if (arrayNode)
{
    uint size;
    arrayNode->getArraySize(size);
    for (uint i = 0; i < size; ++i)
    {
        const NLGEORGES::UFormElm *structNode;
        arrayNode->getArrayNode(&structNode, i);
        if (structNode)
        {
            std::string shortName;
            uint32 ranking;
            structNode->getValueByName(shortName, "ShortName");
            structNode->getValueByName(ranking, "Ranking");
        }
    }
}

Working with structs

To enumerate fields in a struct without knowing their names in advance:

uint structSize;
root.getStructSize(structSize);
for (uint i = 0; i < structSize; ++i)
{
    std::string fieldName;
    root.getStructNodeName(i, fieldName);
    nlinfo("Field %d: %s", i, fieldName.c_str());
}

UFormElm reference

Key methods on UFormElm:

Method Description
getValueByName(result, name) Read a value by dot/bracket path
setValueByName(value, name) Write a value by dot/bracket path
getNodeByName(&node, name) Get a child node by path
isStruct() / isAtom() / isVirtualStruct() Query the node type
getStructSize(size) Get the number of fields in a struct
getStructNodeName(index, name) Get a field name by index
getStructNode(index, &node) Get a field node by index
getArraySize(size) Get the number of elements in an array
getArrayNode(&node, index) Get an array element by index
getArrayValue(result, index) Read an array element value by index
getDfnName(name) Get the DFN filename for this struct node

Source

⚠️ **GitHub.com Fallback** ⚠️