diff --git a/simgear/io/sg_binobj.cxx b/simgear/io/sg_binobj.cxx index 543b0446..6a9f7899 100644 --- a/simgear/io/sg_binobj.cxx +++ b/simgear/io/sg_binobj.cxx @@ -41,9 +41,10 @@ #include #include +#include +#include #include #include -#include #include #include "lowlevel.hxx" @@ -502,6 +503,8 @@ bool SGBinObject::read_bin( const SGPath& file ) unsigned int nbytes; sgSimpleBuffer buf( 32768 ); // 32 Kb + simgear::ErrorReportContext ec("btg", file.utf8Str()); + // zero out structures gbs_center = SGVec3d(0, 0, 0); gbs_radius = 0.0; diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index d62d3aeb..2500eb9f 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -67,9 +67,13 @@ #include #include -#include +#include +#include +#include +#include #include #include +#include #include #include #include @@ -936,10 +940,8 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, string fileName = SGModelLib::findDataFile(shaderName, options); if (fileName.empty()) { - SG_LOG(SG_INPUT, SG_ALERT, "Could not locate shader" << shaderName); - if (!compositorEnabled) { - reportError("Missing shader", shaderName); - } + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::MissingShader, + "Couldn't locate shader:" + shaderName, sg_location{shaderName}); throw BuilderException(string("couldn't find shader ") + shaderName); @@ -1486,13 +1488,15 @@ void mergeSchemesFallbacks(Effect *effect, const SGReaderWriterOptions *options) // passes. bool Effect::realizeTechniques(const SGReaderWriterOptions* options) { + simgear::ErrorReportContext ec{"effect", getName()}; + if (getPropertyRoot()->getBoolValue("/sim/version/compositor-support", false)) mergeSchemesFallbacks(this, options); if (_isRealized) return true; + PropertyList tniqList = root->getChildren("technique"); - for (PropertyList::iterator itr = tniqList.begin(), e = tniqList.end(); itr != e; ++itr) buildTechnique(this, *itr, options); diff --git a/simgear/scene/material/TextureBuilder.cxx b/simgear/scene/material/TextureBuilder.cxx index a314bd2a..fd049e5d 100644 --- a/simgear/scene/material/TextureBuilder.cxx +++ b/simgear/scene/material/TextureBuilder.cxx @@ -39,12 +39,13 @@ #include #include +#include +#include #include #include #include #include #include -#include namespace simgear { @@ -280,9 +281,10 @@ bool setAttrs(const TexTuple& attrs, Texture* tex, #else result = osgDB::readRefImageFile(imageName, options); #endif - } catch (std::bad_alloc& ba) { - SG_LOG(SG_GL, SG_ALERT, "Bad allocation loading:" << imageName); - // todo: report low memory warning + } catch (std::exception& e) { + simgear::reportFailure(simgear::LoadFailure::OutOfMemory, simgear::ErrorCode::LoadingTexture, + string{"osgDB::readRefImageFile failed:"} + e.what(), + SGPath::fromUtf8(imageName)); return false; } @@ -304,6 +306,9 @@ bool setAttrs(const TexTuple& attrs, Texture* tex, tex->setMaxAnisotropy(SGSceneFeatures::instance()->getTextureFilter()); } else { SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file " << imageName); + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::LoadingTexture, + "osgDB::readRefImageFile failed:" + result.message(), + SGPath::fromUtf8(imageName)); return false; } @@ -588,8 +593,8 @@ Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* const SGPropertyNode* texturesProp = getEffectPropertyChild(effect, props, "images"); const SGPropertyNode* crossProp = getEffectPropertyChild(effect, props, "image"); if (!texturesProp && !crossProp) { + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::LoadingTexture, "No images defined for cube map"); throw BuilderException("no images defined for cube map"); - return NULL; // This is redundant } // Using 6 separate images @@ -770,6 +775,9 @@ Texture* CubeMapBuilder::build(Effect* effect, Pass* pass, const SGPropertyNode* return cubeTexture.release(); } else { + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::LoadingTexture, + "Could not load cube-map image:" + result.message(), + sg_location{texname}); throw BuilderException("Could not load cube cross"); } } @@ -850,6 +858,9 @@ Texture* Texture3DBuilder::build(Effect* effect, Pass* pass, tex->setImage(image3d.get()); } else { SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file " << imageName); + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::LoadingTexture, + "osgDB::readRefImageFile failed:" + result.message(), + SGPath::fromUtf8(imageName)); return NULL; } diff --git a/simgear/scene/model/SGReaderWriterXML.cxx b/simgear/scene/model/SGReaderWriterXML.cxx index 53d71583..bfd00771 100644 --- a/simgear/scene/model/SGReaderWriterXML.cxx +++ b/simgear/scene/model/SGReaderWriterXML.cxx @@ -35,12 +35,13 @@ #include #include -#include +#include +#include #include #include -#include #include #include +#include #include "modellib.hxx" #include "SGReaderWriterXML.hxx" @@ -81,6 +82,7 @@ SGReaderWriterXML::readNode(const std::string& name, const osgDB::Options* options) const { std::string fileName = osgDB::findDataFile(name, options); + simgear::ErrorReportContext ec{"model-xml", fileName}; osg::Node *result=0; try { @@ -262,8 +264,10 @@ sgLoad3DModel_internal(const SGPath& path, SGPropertyNode *overlay) { if (!path.exists()) { - SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << path << "\""); - return std::make_tuple(0, (osg::Node *) NULL); + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::XMLModelLoad, + "Failed to load model XML: not found", path); + SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load file: \"" << path << "\""); + return std::make_tuple(0, (osg::Node*)NULL); } osg::ref_ptr options; @@ -291,6 +295,8 @@ sgLoad3DModel_internal(const SGPath& path, try { readProperties(modelpath, props); } catch (const sg_exception &t) { + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::XMLModelLoad, + "Failed to load model XML:" + t.getFormattedMessage(), t.getLocation()); SG_LOG(SG_IO, SG_DEV_ALERT, "Failed to load xml: " << t.getFormattedMessage()); throw; @@ -305,9 +311,12 @@ sgLoad3DModel_internal(const SGPath& path, if (props->hasValue("/path")) { string modelPathStr = props->getStringValue("/path"); modelpath = SGModelLib::findDataFile(modelPathStr, NULL, modelDir); - if (modelpath.isNull()) + if (modelpath.isNull()) { + simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::ThreeDModelLoad, + "Model not found:" + modelPathStr, sg_location{modelPathStr}); throw sg_io_exception("Model file not found: '" + modelPathStr + "'", - path); + path, {}, false); + } if (props->hasValue("/texture-path")) { string texturePathStr = props->getStringValue("/texture-path"); @@ -343,9 +352,13 @@ sgLoad3DModel_internal(const SGPath& path, #else modelResult = osgDB::readRefNodeFile(modelpath.utf8Str(), options.get()); #endif - if (!modelResult.validNode()) + if (!modelResult.validNode()) { + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::XMLModelLoad, + "Failed to load 3D model:" + modelResult.message(), modelpath); throw sg_io_exception("Failed to load 3D model:" + modelResult.message(), - modelpath); + modelpath, {}, false); + } + model = copyModel(modelResult.getNode()); // Add an extra reference to the model stored in the database. // That is to avoid expiring the object from the cache even if diff --git a/simgear/scene/model/animation.cxx b/simgear/scene/model/animation.cxx index 9636a1d1..9edb8e0e 100644 --- a/simgear/scene/model/animation.cxx +++ b/simgear/scene/model/animation.cxx @@ -39,9 +39,11 @@ #include #include +#include #include #include #include + #include #include #include @@ -455,6 +457,9 @@ SGAnimation::~SGAnimation() } if (!info.empty()) { + reportFailure(LoadFailure::Misconfigured, ErrorCode::XMLModelLoad, + "Could not find at least one of the following object for animation:" + info, + SGPath::fromUtf8(_modelData.getPath())); SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find at least one of the following" " objects for animation: " << info << " in file: " << _modelData.getPath()); } @@ -773,10 +778,16 @@ bool SGAnimation::setCenterAndAxisFromObject(osg::Node *rootNode, SGVec3d& cente object_group->setNodeMask(0); } else { + reportFailure(LoadFailure::Misconfigured, ErrorCode::XMLModelLoad, + "Could not find valid line segment for axis animation:" + axis_object_name, + SGPath::fromUtf8(_modelData.getPath())); SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find a valid line segment for animation: " << axis_object_name << " in file: " << _modelData.getPath()); } } else if (can_warn) { + reportFailure(LoadFailure::Misconfigured, ErrorCode::XMLModelLoad, + "Could not find object for axis animation:" + axis_object_name, + SGPath::fromUtf8(_modelData.getPath())); SG_LOG(SG_IO, SG_DEV_ALERT, "Could not find at least one of the following objects for axis animation: " << axis_object_name << " in file: " << _modelData.getPath()); } } diff --git a/simgear/scene/tgdb/ReaderWriterSTG.cxx b/simgear/scene/tgdb/ReaderWriterSTG.cxx index 57ed1ca1..6d7db879 100644 --- a/simgear/scene/tgdb/ReaderWriterSTG.cxx +++ b/simgear/scene/tgdb/ReaderWriterSTG.cxx @@ -38,10 +38,12 @@ #include #include -#include -#include #include +#include #include +#include +#include + #include #include #include @@ -594,8 +596,9 @@ struct ReaderWriterSTG::_ModelBin { std::string terrain_name = string("terrain ").append(bucket.gen_index_str()); terrainGroup->setName(terrain_name); + simgear::ErrorReportContext ec{"bucket", bucket.gen_index_str()}; + if (_foundBase) { - for (auto stgObject : _objectList) { osg::ref_ptr node; #if OSG_VERSION_LESS_THAN(3,4,0) node = osgDB::readNodeFile(stgObject._name, stgObject._options.get()); diff --git a/simgear/scene/tgdb/SGReaderWriterBTG.cxx b/simgear/scene/tgdb/SGReaderWriterBTG.cxx index fa0a2175..11734805 100644 --- a/simgear/scene/tgdb/SGReaderWriterBTG.cxx +++ b/simgear/scene/tgdb/SGReaderWriterBTG.cxx @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -62,13 +63,15 @@ SGReaderWriterBTG::readNode(const std::string& fileName, const SGReaderWriterOptions* sgOptions; sgOptions = dynamic_cast(options); osg::Node* result = NULL; + simgear::ErrorReportContext ec{"btg", fileName}; try { result = SGLoadBTG(fileName, sgOptions); if (!result) return ReadResult::FILE_NOT_HANDLED; } catch (sg_exception& e) { - SG_LOG(SG_IO, SG_WARN, "error reading:" << fileName << ":" << - e.getFormattedMessage()); + simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::BTGLoad, + "Failed to load BTG file:" + e.getFormattedMessage(), + e.getLocation()); return ReadResult::ERROR_IN_READING_FILE; }