Convert ValueTree to DynamicObject?

Here is some code that might be a starting point. It’s still an early on in it’s implementation, in that I just codified it a few weeks ago, to help me process JSON input. But I think the basic ‘tree walking’ structure of it will help you build some code to make ValueTree’s.

VarHelpers.h

#pragma once

#include "../JuceLibraryCode/JuceHeader.h"

namespace VarHelpers
{
    void addProperty (const var& object, String key, var value);
    var addSection (const var& object, String key);
    void forEachSection (const var& object, std::function<void (String key, const var& section)> sectionCallback);
    void forEachProperty (const var& object, std::function<void (String key, const var& property)> propertyCallback);
    String getVarAttribString (const var& theVar);
    void dumpVar (const var& theVar);
    const var& getSection (const var& theVar, Identifier key);
        
    template<class T>
    bool hasProperty (const var& theVar, Identifier property)
    {
        if (theVar.hasProperty (property))
        {
            if constexpr (std::is_same_v<T, int>)
            {
                if (theVar[property].isInt ())
                    return true;
            }
            else if constexpr (std::is_same_v<T, int64>)
            {
                if (theVar[property].isInt64 ())
                    return true;
            }
            else if constexpr (std::is_same_v<T, bool>)
            {
                if (theVar[property].isBool ())
                    return true;
            }
            else if constexpr (std::is_same_v<T, double>)
            {
                if (theVar[property].isDouble ())
                    return true;
            }
            else if constexpr (std::is_same_v<T, String>)
            {
                if (theVar[property].isString ())
                    return true;
            }
            else if constexpr (std::is_same_v<T, Array<var>>)
            {
                if (theVar[property].isArray ())
                    return true;
            }
        }
        return false;
    }

    template<class T>
    T getProperty (const var& theVar, Identifier property)
    {
        if constexpr (std::is_same_v<T, String>)
            return theVar[property].toString ();
        else
            return (T)theVar[property];
    }
};

VarHelpers.cpp

#include "VarHelpers.h"

namespace VarHelpers
{
    void addProperty (const var& object, String key, var value)
    {
        if (!key.isEmpty () && object.isObject ())
            object.getDynamicObject ()->setProperty (key, value);
    };

    var addSection (const var& object, String key)
    {
        if (!key.isEmpty () && object.isObject ())
        {
            var newSection (new DynamicObject);
            addProperty (object, key, newSection);
            return newSection;
        }

        return {};
    }

    void forEachSection (const var& object, std::function<void (String key, const var& section)> sectionCallback)
    {
        if (object.isObject ())
        {
            const auto dynamicObject = object.getDynamicObject ();
            const auto namedPropertySet = dynamicObject->getProperties ();
            for (const auto& namedProperty : namedPropertySet)
            {
                if (namedProperty.value.isObject ())
                    sectionCallback (namedProperty.name.toString (), namedProperty.value);
            }
        }
    }

    void forEachProperty (const var& object, std::function<void (String key, const var& property)> propertyCallback)
    {
        if (object.isObject ())
        {
            const auto dynamicObject = object.getDynamicObject ();
            const auto namedPropertySet = dynamicObject->getProperties ();
            for (const auto& namedProperty : namedPropertySet)
            {
                if (!namedProperty.value.isObject ())
                    propertyCallback (namedProperty.name.toString (), namedProperty.value);
            }

        }
    }

    String getVarAttribString (const var& theVar)
    {
        if (theVar.isVoid ())
            return "void";
        else if (theVar.isInt ())
            return "int";
        else if (theVar.isInt64 ())
            return "int64";
        else if (theVar.isBool ())
            return "bool";
        else if (theVar.isDouble ())
            return "double";
        else if (theVar.isString ())
            return "String";
        else if (theVar.isObject ())
            return "Object";
        else if (theVar.isArray ())
            return "Array";
        else if (theVar.isBinaryData ())
            return "BinaryData";
        else if (theVar.isMethod ())
            return "Method";

        return "unknown";
    };

    void dumpVar (const var& theVar)
    {
        if (theVar.isObject())
        {
            std::function<void (const var& theVar, String name, int indentLevel)> dumpSections = [&dumpSections](const var& theVar, String name, int indentLevel)
            {
                Logger::outputDebugString (String (std::string (indentLevel, ' ')) + String ("<") + (name.isEmpty () ? String ("noname") : name) + String (">"));
                VarHelpers::forEachProperty (theVar, [indentLevel](String key, const var& value)
                    {
                        Logger::outputDebugString (String (std::string (indentLevel + 1, ' ')) + key + " : " + VarHelpers::getVarAttribString (value));
                    });
                VarHelpers::forEachSection (theVar, [&dumpSections, indentLevel](String key, const var& value)
                    {
                        dumpSections (value, key, indentLevel + 1);
                    });
            };
            dumpSections (theVar, "", 0);
        }
        else
        {
            Logger::outputDebugString ("var type : " + VarHelpers::getVarAttribString (theVar));
        }
    }

    const var emptyVar;

    const var& getSection (const var& theVar, Identifier key)
    {
        if (const auto& section = theVar[key]; section.isObject ())
            return section;
        else
            return emptyVar;
    }
};
1 Like