task Grapher::TryUpdateGraph()

in src/GraphControl/Control/Grapher.cpp [326:455]


    task<bool> Grapher::TryUpdateGraph(bool keepCurrentView)
    {
        optional<vector<shared_ptr<IEquation>>> initResult = nullopt;
        bool successful = false;
        m_errorCode = 0;
        m_errorType = 0;

        if (m_renderMain && m_graph != nullptr)
        {
            unique_ptr<IExpression> graphExpression;
            wstring request;

            auto validEqs = GetGraphableEquations();

            // Will be set to true if the previous graph should be kept in the event of an error
            bool shouldKeepPreviousGraph = false;

            if (!validEqs.empty())
            {
                request = s_getGraphOpeningTags;

                int numValidEquations = 0;
                for (Equation ^ eq : validEqs)
                {
                    if (eq->IsValidated)
                    {
                        shouldKeepPreviousGraph = true;
                    }

                    if (numValidEquations++ > 0)
                    {
                        if (!UseCommaDecimalSeperator)
                        {
                            request += L"<mo>,</mo>";
                        }
                        else
                        {
                            request += L"<mo>;</mo>";
                        }
                    }
                    auto equationRequest = eq->GetRequest()->Data();

                    // If the equation request failed, then fail graphing.
                    if (equationRequest == nullptr)
                    {
                        co_return false;
                    }

                    unique_ptr<IExpression> expr;
                    wstring parsableEquation = s_getGraphOpeningTags;
                    parsableEquation += equationRequest;
                    parsableEquation += s_getGraphClosingTags;

                    // Wire up the corresponding error to an error message in the UI at some point
                    if (!(expr = m_solver->ParseInput(parsableEquation, m_errorCode, m_errorType)))
                    {
                        co_return false;
                    }

                    request += equationRequest;
                }

                request += s_getGraphClosingTags;
            }

            if (graphExpression = m_solver->ParseInput(request, m_errorCode, m_errorType))
            {
                initResult = TryInitializeGraph(keepCurrentView, graphExpression.get());

                if (initResult != nullopt)
                {
                    auto graphedEquations = initResult.value();

                    for (int i = 0; i < validEqs.size(); i++)
                    {
                        validEqs[i]->GraphedEquation = graphedEquations[i];
                    }

                    UpdateGraphOptions(m_graph->GetOptions(), validEqs);
                    SetGraphArgs(m_graph);

                    m_renderMain->Graph = m_graph;

                    // It is possible that the render fails, in that case fall through to explicit empty initialization
                    co_await m_renderMain->RunRenderPassAsync(false);
                    if (m_renderMain->IsRenderPassSuccesful())
                    {
                        UpdateVariables();
                        successful = true;
                    }
                    else
                    {
                        // If we failed to render then we have already lost the previous graph
                        shouldKeepPreviousGraph = false;
                        initResult = nullopt;
                        m_solver->HRErrorToErrorInfo(m_renderMain->GetRenderError(), m_errorCode, m_errorType);
                    }
                }
                else
                {
                    m_solver->HRErrorToErrorInfo(m_graph->GetInitializationError(), m_errorCode, m_errorType);
                }
            }

            if (initResult == nullopt)
            {
                // Do not re-initialize the graph to empty if there are still valid equations graphed
                if (!shouldKeepPreviousGraph)
                {
                    initResult = TryInitializeGraph(false, nullptr);
                    if (initResult != nullopt)
                    {
                        UpdateGraphOptions(m_graph->GetOptions(), vector<Equation ^>());
                        SetGraphArgs(m_graph);

                        m_renderMain->Graph = m_graph;
                        co_await m_renderMain->RunRenderPassAsync();

                        UpdateVariables();

                        // Initializing an empty graph is only a success if there were no equations to graph.
                        successful = (validEqs.size() == 0);
                    }
                }
            }
        }

        // Return true if we were able to graph and render all graphable equations
        co_return successful;
    }