1
0
Fork 0

Error-reporting: attribute AIObjects from scenarios

Ensure scenario-path is propagated through model loading for AI objects.
This commit is contained in:
James Turner 2021-02-25 22:02:32 +00:00
parent e4ca169618
commit cbe46468d1
5 changed files with 45 additions and 13 deletions

View file

@ -39,11 +39,12 @@
#include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx>
#include <Main/globals.hxx>
#include <Main/ErrorReporter.hxx>
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
#include <Scripting/NasalSys.hxx>
#include <Scripting/NasalModelData.hxx>
#include <Scripting/NasalSys.hxx>
#include <Sound/fg_fx.hxx>
#include "AIFlightPlan.hxx"
@ -74,11 +75,19 @@ public:
return _errorContext;
}
void addErrorContext(const std::string& key, std::string& value)
void addErrorContext(const std::string& key, const std::string& value)
{
_errorContext[key] = value;
}
void captureErrorContext(const std::string& key)
{
const auto v = flightgear::ErrorReporter::threadSpecificContextValue(key);
if (!v.empty()) {
addErrorContext(key, v);
}
}
/** osg callback, thread-safe */
void modelLoaded(const std::string& path, SGPropertyNode *prop, osg::Node *n)
{
@ -618,6 +627,7 @@ bool FGAIBase::init(ModelSearchOrder searchOrder)
props->addChild("type")->setStringValue("AI");
_modeldata = new FGAIModelData(props);
_modeldata->addErrorContext("ai", _name);
_modeldata->captureErrorContext("scenario-path");
vector<string> model_list = resolveModelPath(searchOrder);
_model= SGModelLib::loadPagedModel(model_list, props, _modeldata);

View file

@ -602,14 +602,18 @@ FGAIBasePtr FGAIManager::getObjectFromProperty(const SGPropertyNode* aProp) cons
bool
FGAIManager::loadScenario( const string &id )
{
simgear::ErrorReportContext ec("scenario", id);
SGPropertyNode_ptr file = loadScenarioFile(id);
SGPath path;
SGPropertyNode_ptr file = loadScenarioFile(id, path);
if (!file) {
return false;
}
simgear::ErrorReportContext ec("scenario-path", path.utf8Str());
SGPropertyNode_ptr scNode = file->getChild("scenario");
if (!scNode) {
simgear::reportFailure(simgear::LoadFailure::Misconfigured,
simgear::ErrorCode::ScenarioLoad,
"No <scenario> element in file", path);
return false;
}
@ -655,7 +659,7 @@ FGAIManager::unloadAllScenarios()
SGPropertyNode_ptr
FGAIManager::loadScenarioFile(const std::string& scenarioName)
FGAIManager::loadScenarioFile(const std::string& scenarioName, SGPath& outPath)
{
auto s = fgGetNode("/sim/ai/scenarios");
if (!s) return {};
@ -666,6 +670,7 @@ FGAIManager::loadScenarioFile(const std::string& scenarioName)
for (auto n : s->getChildren("scenario")) {
if (n->getStringValue("id") == scenarioName) {
SGPath path{n->getStringValue("path")};
outPath = path;
simgear::ErrorReportContext ec("scenario-path", path.utf8Str());
try {
SGPropertyNode_ptr root = new SGPropertyNode;

View file

@ -75,7 +75,7 @@ public:
*/
static void registerScenarios(SGPropertyNode_ptr root = {});
static SGPropertyNode_ptr registerScenarioFile(SGPropertyNode_ptr root, const SGPath& p);
static SGPropertyNode_ptr loadScenarioFile(const std::string& id);
static SGPropertyNode_ptr loadScenarioFile(const std::string& id, SGPath& outPath);
FGAIBasePtr addObject(const SGPropertyNode* definition);
bool isVisible(const SGGeod& pos) const;

View file

@ -85,7 +85,7 @@ string_list static_errorIds = {
"error-aircraft-systems",
"error-input-device-config"
"error-ai-traffic-schedule",
"error-airport-data"};
};
string_list static_errorTypeIds = {
"error-type-unknown",
@ -270,6 +270,11 @@ public:
_displayNode->setStringValue("category", catLabel);
auto ns = globals->get_locale()->getLocalizedString("error-next-steps", "sys");
_displayNode->setStringValue("next-steps", ns);
// remove any existing error children
_displayNode->removeChildren("error");
@ -332,7 +337,7 @@ auto ErrorReporter::ErrorReporterPrivate::getAggregateForOccurence(const ErrorRe
return getAggregate(Aggregation::HangarAircraft, fullId);
}
if (oc.hasContextKey("scenery")) {
if (oc.hasContextKey("terrain-stg")) {
// determine if it's custom scenery, TerraSync or FGData
// bucket is no use here, we need to check the BTG/XML/STG path etc.
@ -340,7 +345,7 @@ auto ErrorReporter::ErrorReporterPrivate::getAggregateForOccurence(const ErrorRe
// STG references a model, XML or texture in FGData or TerraSync
// incorrectly, we attribute the error to the scenery, which is
// likely what we want/expect
const auto stgPath = oc.getContextValue("stg-path");
const auto stgPath = oc.getContextValue("terrain-stg");
if (simgear::strutils::starts_with(stgPath, _fgdataPathPrefix)) {
return getAggregate(Aggregation::FGData, {});
@ -360,9 +365,9 @@ auto ErrorReporter::ErrorReporterPrivate::getAggregateForOccurence(const ErrorRe
return getAggregate(Aggregation::CustomScenery, {});
}
if (oc.hasContextKey("scenario")) {
const auto scenarioPath = oc.getContextValue("scenario");
return getAggregate(Aggregation::InputDevice, scenarioPath);
if (oc.hasContextKey("scenario-path")) {
const auto scenarioPath = oc.getContextValue("scenario-path");
return getAggregate(Aggregation::Scenario, scenarioPath);
}
if (oc.hasContextKey("input-device")) {
@ -652,4 +657,14 @@ void ErrorReporter::shutdown()
}
}
std::string ErrorReporter::threadSpecificContextValue(const std::string& key)
{
auto it = thread_errorContextStack.find(key);
if (it == thread_errorContextStack.end())
return {};
return it->second.back();
}
} // namespace flightgear

View file

@ -43,6 +43,8 @@ public:
static const char* staticSubsystemClassId() { return "error-reporting"; }
static std::string threadSpecificContextValue(const std::string& key);
private:
class ErrorReporterPrivate;