Error reporting: add SGModelData context support

Allow us to pass the current error-context from the main thread
into the osgDB loader thread. This is necessary so we can attribute
AIModel (etc) load problems to the correct source.
This commit is contained in:
James Turner 2021-02-24 14:45:17 +00:00 committed by Automatic Release Builder
parent 7e76667af0
commit 81a489d81d
4 changed files with 46 additions and 9 deletions

View File

@ -78,17 +78,31 @@ void setErrorContextCallback(ContextCallback cb)
static_contextCallback = cb; static_contextCallback = cb;
} }
ErrorReportContext::ErrorReportContext(const std::string& key, const std::string& value) : _key(key) ErrorReportContext::ErrorReportContext(const std::string& key, const std::string& value)
{ {
if (static_contextCallback) { if (static_contextCallback) {
_keys.push_back(key);
static_contextCallback(key, value); static_contextCallback(key, value);
} }
} }
ErrorReportContext::ErrorReportContext(const ContextMap& context)
{
if (static_contextCallback) {
for (const auto& p : context) {
_keys.push_back(p.first);
static_contextCallback(p.first, p.second);
}
}
}
ErrorReportContext::~ErrorReportContext() ErrorReportContext::~ErrorReportContext()
{ {
if (static_contextCallback) { if (static_contextCallback) {
static_contextCallback(_key, "POP"); // pop all our keys
for (const auto& k : _keys) {
static_contextCallback(k, "POP");
}
} }
} }

View File

@ -16,7 +16,9 @@
#pragma once #pragma once
#include <functional> #include <functional>
#include <map>
#include <string> #include <string>
#include <vector>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
@ -70,10 +72,18 @@ class ErrorReportContext
{ {
public: public:
ErrorReportContext(const std::string& key, const std::string& value); ErrorReportContext(const std::string& key, const std::string& value);
using ContextMap = std::map<std::string, std::string>;
/**
Allow establishing multiple context values in a single operation
*/
ErrorReportContext(const ContextMap& context);
~ErrorReportContext(); ~ErrorReportContext();
private: private:
const std::string _key; std::vector<std::string> _keys;
}; };
/** /**

View File

@ -29,12 +29,13 @@
#include <osgDB/Registry> #include <osgDB/Registry>
#include <simgear/constants.h> #include <simgear/constants.h>
#include <simgear/debug/ErrorReportingCallback.hxx>
#include <simgear/misc/ResourceManager.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/scene/model/ModelRegistry.hxx> #include <simgear/scene/model/ModelRegistry.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx> #include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/misc/ResourceManager.hxx>
#include "SGReaderWriterXML.hxx" #include "SGReaderWriterXML.hxx"
@ -140,6 +141,10 @@ SGModelLib::loadModel(const string &path,
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get()); opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data); opt->setModelData(data);
// establish the error report context so we can attribute any load
// errors correctly
simgear::ErrorReportContext ec(data->getErrorContext());
if (load2DPanels) { if (load2DPanels) {
opt->setLoadPanel(static_panelFunc); opt->setLoadPanel(static_panelFunc);
} }
@ -159,6 +164,9 @@ SGModelLib::loadDeferredModel(const string &path, SGPropertyNode *prop_root,
proxyNode->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER); proxyNode->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
proxyNode->setFileName(0, path); proxyNode->setFileName(0, path);
// establish the error report context so we can attribute any load
// errors correctly
simgear::ErrorReportContext ec(data->getErrorContext());
osg::ref_ptr<SGReaderWriterOptions> opt; osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions()); opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
@ -191,6 +199,10 @@ SGModelLib::loadPagedModel(SGPropertyNode *prop_root, SGModelData *data, SGModel
unsigned int simple_models = 0; unsigned int simple_models = 0;
osg::PagedLOD *plod = new osg::PagedLOD; osg::PagedLOD *plod = new osg::PagedLOD;
// establish the error report context so we can attribute any load
// errors correctly
simgear::ErrorReportContext ec(data->getErrorContext());
osg::ref_ptr<SGReaderWriterOptions> opt; osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions()); opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get()); opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());

View File

@ -18,12 +18,9 @@
#ifndef _SG_MODEL_LIB_HXX #ifndef _SG_MODEL_LIB_HXX
#define _SG_MODEL_LIB_HXX 1 #define _SG_MODEL_LIB_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h> // for SG_USING_STD #include <simgear/compiler.h> // for SG_USING_STD
#include <map>
#include <string> #include <string>
#include <osg/Node> #include <osg/Node>
@ -112,6 +109,10 @@ public:
virtual void modelLoaded(const std::string& path, SGPropertyNode *prop, virtual void modelLoaded(const std::string& path, SGPropertyNode *prop,
osg::Node* branch) = 0; osg::Node* branch) = 0;
virtual SGModelData* clone() const = 0; virtual SGModelData* clone() const = 0;
using ErrorContext = std::map<std::string, std::string>;
virtual ErrorContext getErrorContext() const = 0;
}; };
/* /*