.. _ogn_tutorial_arrayData:

Tutorial 5 - Array Data Node
============================

Array data consists of multiple elements of a simple type whose count is only known at runtime.
For example *float[]* or *double[]*. This node takes an array of floats and a multiplier and generates an
output array consisting of the product of the two.

OgnTutorialArrayData.ogn
------------------------
The *ogn* file shows the implementation of a node named
"omni.graph.tutorials.ArrayData", which has a float value and float array input with one float array output.

.. literalinclude:: ../../../../../source/extensions/omni.graph.tutorials/tutorials/tutorial5/OgnTutorialArrayData.ogn
    :linenos:
    :language: json

OgnTutorialArrayData.cpp
------------------------
The *cpp* file contains the implementation of the compute method, which
multiplies the float value by each member of the float array.

Note how the attribute Array values can be accessed as though they were a simple *std::vector* type.

.. literalinclude:: ../../../../../source/extensions/omni.graph.tutorials/tutorials/tutorial5/OgnTutorialArrayData.cpp
    :linenos:
    :language: c++

Array Attribute Access
----------------------
The attribute access is as described in :ref:`ogn_tutorial_simpleData` except that the exact return types
of the attributes are different in order to support array member access.

Full definition of the array wrapper classes can be found in the interface file *omni/graph/core/ogn/array.h*,
though they do behave in a manner consistent with *std::array*, supporting iterators, standard algorithms, random access
through either ``operator[]`` or the ``at(index)`` function, the ``empty()`` and ``size()`` functions, and access to
the raw underlying data using the function ``data()``. The non-const version also supports assignment and the
``resize()`` function for modifying its contents.

+---------------------+--------------------------------+
| Database Function   | Returned Type                  |
+=====================+================================+
| inputs.original()   | const ogn::const_array<float>& |
+---------------------+--------------------------------+
| inputs.multiplier() | const float&                   |
+---------------------+--------------------------------+
| outputs.result()    | ogn::array<float>&             |
+---------------------+--------------------------------+

These wrapper classes are similar in concept to ``std::span``, which handles unmanaged pointer+size data. In this case
the data is being managed by the Fabric. Modifications to the wrapper class data will directly modify the underlying
data in the Fabric.

You can still use the *auto* declarations on these types, and the array attributes have an additional ``size()``
method added for convenience.

.. code-block:: c++

    bool compute(OgnTutorialArrayDataDatabase& db)
    {
        const auto& multiplier = db.inputs.multiplier();
        const auto& original = db.inputs.original();
        size_t originalSize = db.inputs.original.size();
        auto& result = db.outputs.result();
    };
