void PlotManager::render(boost::function<void(DisplayState)> outputFunction) { // make sure the graphics path exists (may have been blown away // by call to dev.off or other call to removeAllPlots) Error error = graphicsPath_.ensureDirectory(); if (error) { Error graphicsError(errc::PlotFileError, error, ERROR_LOCATION); logAndReportError(graphicsError, ERROR_LOCATION); return; } // clear changes flag setDisplayHasChanges(false); // optional manipulator structure json::Value plotManipulatorJson; if (hasPlot()) // write image for active plot { // copy current contents of the display to the active plot files Error error = activePlot().renderFromDisplay(); if (error) { // no such file error expected in the case of an invalid graphics // context (because generation of the PNG would have failed) bool pngNotFound = error.cause() && isPathNotFoundError(error.cause()); // only log if this wasn't png not found if (!pngNotFound) { // for r code execution errors we just report them if (r::isCodeExecutionError(error)) reportError(error); else logAndReportError(error, ERROR_LOCATION); } return; } // get manipulator activePlot().manipulatorAsJson(&plotManipulatorJson); } else // write "empty" image { // create an empty file FilePath emptyImageFilePath = graphicsPath_.complete(emptyImageFilename()); error = writeStringToFile(emptyImageFilePath, std::string()); if (error) { Error graphicsError(errc::PlotRenderingError, error, ERROR_LOCATION); logAndReportError(graphicsError, ERROR_LOCATION); return; } } // call output function DisplayState currentState(imageFilename(), plotManipulatorJson, r::session::graphics::device::getWidth(), r::session::graphics::device::getHeight(), activePlotIndex(), plotCount()); outputFunction(currentState); }