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;
}