Error-reporting: attribute AIObjects from scenarios
Ensure scenario-path is propagated through model loading for AI objects.
This commit is contained in:
parent
e4ca169618
commit
cbe46468d1
5 changed files with 45 additions and 13 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
|
||||
static const char* staticSubsystemClassId() { return "error-reporting"; }
|
||||
|
||||
static std::string threadSpecificContextValue(const std::string& key);
|
||||
|
||||
private:
|
||||
class ErrorReporterPrivate;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue