1
0
Fork 0

Maintenance: AIManager

SPDX tags.
eliminate variable shadowing with outer scope.
spelling.
This commit is contained in:
scttgs0 2023-05-22 12:23:28 -05:00
parent 16f7291110
commit 540cd7b56e
2 changed files with 123 additions and 150 deletions

View file

@ -23,27 +23,27 @@
#include <Main/sentryIntegration.hxx>
#include <Scripting/NasalSys.hxx>
#include "AIManager.hxx"
#include "AIAircraft.hxx"
#include "AIShip.hxx"
#include "AIBallistic.hxx"
#include "AIStorm.hxx"
#include "AIThermal.hxx"
#include "AICarrier.hxx"
#include "AIStatic.hxx"
#include "AIMultiplayer.hxx"
#include "AITanker.hxx"
#include "AIWingman.hxx"
#include "AIGroundVehicle.hxx"
#include "AIEscort.hxx"
#include "AIGroundVehicle.hxx"
#include "AIManager.hxx"
#include "AIMultiplayer.hxx"
#include "AIShip.hxx"
#include "AIStatic.hxx"
#include "AIStorm.hxx"
#include "AITanker.hxx"
#include "AIThermal.hxx"
#include "AIWingman.hxx"
static bool static_haveRegisteredScenarios = false;
class FGAIManager::Scenario
{
public:
Scenario(FGAIManager* man, const std::string& nm, SGPropertyNode* scenarios) :
_internalName(nm)
Scenario(FGAIManager* man, const std::string& nm, SGPropertyNode* scenarios) : _internalName(nm)
{
simgear::ErrorReportContext ec("scenario-name", _internalName);
for (auto scEntry : scenarios->getChildren("entry")) {
@ -94,6 +94,7 @@ public:
nasalSys->deleteModule(moduleName.c_str());
}
private:
std::vector<FGAIBasePtr> _objects;
std::string _internalName;
@ -102,15 +103,13 @@ private:
///////////////////////////////////////////////////////////////////////////////
FGAIManager::FGAIManager() :
cb_ai_bare(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD,
fgGetNode("/sim/rendering/static-lod/aimp-bare", true))),
cb_ai_detailed(SGPropertyChangeCallback<FGAIManager>(this, &FGAIManager::updateLOD,
fgGetNode("/sim/rendering/static-lod/aimp-detailed", true))),
cb_interior(SGPropertyChangeCallback<FGAIManager>(this, &FGAIManager::updateLOD,
fgGetNode("/sim/rendering/static-lod/aimp-interior", true)))
FGAIManager::FGAIManager() : cb_ai_bare(SGPropertyChangeCallback<FGAIManager>(this, &FGAIManager::updateLOD,
fgGetNode("/sim/rendering/static-lod/aimp-bare", true))),
cb_ai_detailed(SGPropertyChangeCallback<FGAIManager>(this, &FGAIManager::updateLOD,
fgGetNode("/sim/rendering/static-lod/aimp-detailed", true))),
cb_interior(SGPropertyChangeCallback<FGAIManager>(this, &FGAIManager::updateLOD,
fgGetNode("/sim/rendering/static-lod/aimp-interior", true)))
{
}
FGAIManager::~FGAIManager()
@ -118,18 +117,18 @@ FGAIManager::~FGAIManager()
std::for_each(ai_list.begin(), ai_list.end(), std::mem_fn(&FGAIBase::unbind));
}
void
FGAIManager::init() {
void FGAIManager::init()
{
root = fgGetNode("sim/ai", true);
enabled = root->getNode("enabled", true);
thermal_lift_node = fgGetNode("/environment/thermal-lift-fps", true);
wind_from_east_node = fgGetNode("/environment/wind-from-east-fps",true);
wind_from_north_node = fgGetNode("/environment/wind-from-north-fps",true);
wind_from_east_node = fgGetNode("/environment/wind-from-east-fps", true);
wind_from_north_node = fgGetNode("/environment/wind-from-north-fps", true);
user_altitude_agl_node = fgGetNode("/position/altitude-agl-ft", true);
user_speed_node = fgGetNode("/velocities/uBody-fps", true);
user_altitude_agl_node = fgGetNode("/position/altitude-agl-ft", true);
user_speed_node = fgGetNode("/velocities/uBody-fps", true);
globals->get_commands()->addCommand("load-scenario", this, &FGAIManager::loadScenarioCommand);
globals->get_commands()->addCommand("unload-scenario", this, &FGAIManager::unloadScenarioCommand);
@ -142,7 +141,7 @@ FGAIManager::init() {
// users's aircraft, that mimicks the user aircraft's behavior.
_userAircraft = new FGAIAircraft;
_userAircraft->setCallSign ( fgGetString("/sim/multiplay/callsign") );
_userAircraft->setCallSign(fgGetString("/sim/multiplay/callsign"));
_userAircraft->setGeodPos(globals->get_aircraft_position());
_userAircraft->setPerformance("", "jet_transport");
_userAircraft->setHeading(fgGetDouble("/orientation/heading-deg"));
@ -167,7 +166,7 @@ void FGAIManager::registerScenarios(SGPropertyNode_ptr root)
// depending on if we're using a carrier startup, this function may get
// called early or during normal FGAIManager init, so guard against double
// invocation.
// we clear this flag on shudtdown so reset works as expected
// we clear this flag on shutdown so reset works as expected
if (static_haveRegisteredScenarios)
return;
@ -205,7 +204,7 @@ void FGAIManager::registerScenarios(SGPropertyNode_ptr root)
for (auto xmlPath : dir.children(simgear::Dir::TYPE_FILE, ".xml")) {
registerScenarioFile(root, xmlPath);
} // of xml files in the scenario dir iteration
} // of scenario dirs iteration
} // of scenario dirs iteration
}
SGPropertyNode_ptr FGAIManager::registerScenarioFile(SGPropertyNode_ptr root, const SGPath& xmlPath)
@ -236,7 +235,7 @@ SGPropertyNode_ptr FGAIManager::registerScenarioFile(SGPropertyNode_ptr root, co
sNode->setStringValue("name", xs->getStringValue("name"));
} else {
auto cleanedName = bareName;
// replace _ and - in bareName with spaces
// replace _ and - in bareName with spaces
// auto s = simgear::strutils::srep
sNode->setStringValue("name", cleanedName);
}
@ -258,8 +257,7 @@ SGPropertyNode_ptr FGAIManager::registerScenarioFile(SGPropertyNode_ptr root, co
return sNode;
}
void
FGAIManager::postinit()
void FGAIManager::postinit()
{
// postinit, so that it can access the Nasal subsystem
@ -283,8 +281,7 @@ FGAIManager::postinit()
}
}
void
FGAIManager::reinit()
void FGAIManager::reinit()
{
// shutdown scenarios
unloadAllScenarios();
@ -296,8 +293,7 @@ FGAIManager::reinit()
postinit();
}
void
FGAIManager::shutdown()
void FGAIManager::shutdown()
{
unloadAllScenarios();
@ -326,21 +322,21 @@ FGAIManager::shutdown()
globals->get_commands()->removeCommand("remove-aiobject");
}
void
FGAIManager::bind() {
void FGAIManager::bind()
{
root = globals->get_props()->getNode("ai/models", true);
root->tie("count", SGRawValueMethods<FGAIManager, int>(*this,
&FGAIManager::getNumAiObjects));
&FGAIManager::getNumAiObjects));
}
void
FGAIManager::unbind() {
void FGAIManager::unbind()
{
root->untie("count");
}
void FGAIManager::removeDeadItem(FGAIBase* base)
{
SGPropertyNode *props = base->_getProps();
SGPropertyNode* props = base->_getProps();
props->setBoolValue("valid", false);
base->unbind();
@ -353,8 +349,7 @@ void FGAIManager::removeDeadItem(FGAIBase* base)
props->setIntValue("refuel/tanker", false);
}
void
FGAIManager::update(double dt)
void FGAIManager::update(double dt)
{
// initialize these for finding nearest thermals
range_nearest = 10000.0;
@ -372,10 +367,10 @@ FGAIManager::update(double dt)
// partition the list into dead followed by alive
auto firstAlive =
std::stable_partition(ai_list.begin(), ai_list.end(), std::mem_fn(&FGAIBase::getDie));
std::stable_partition(ai_list.begin(), ai_list.end(), std::mem_fn(&FGAIBase::getDie));
// clean up each item and finally remove from the container
for (auto it=ai_list.begin(); it != firstAlive; ++it) {
for (auto it = ai_list.begin(); it != firstAlive; ++it) {
removeDeadItem(*it);
}
@ -392,45 +387,44 @@ FGAIManager::update(double dt)
base->update(dt);
}
} catch (sg_exception& e) {
SG_LOG(SG_AI, SG_WARN, "caught exception updating AI model:" << base->_getName()<< ", which will be killed."
"\n\tError:" << e.getFormattedMessage());
SG_LOG(SG_AI, SG_WARN, "caught exception updating AI model:" << base->_getName() << ", which will be killed."
"\n\tError:"
<< e.getFormattedMessage());
base->setDie(true);
}
} // of live AI objects iteration
} // of live AI objects iteration
thermal_lift_node->setDoubleValue( strength ); // for thermals
thermal_lift_node->setDoubleValue(strength); // for thermals
}
/** update LOD settings of all AI/MP models */
void
FGAIManager::updateLOD(SGPropertyNode* node)
void FGAIManager::updateLOD(SGPropertyNode* node)
{
SG_UNUSED(node);
std::for_each(ai_list.begin(), ai_list.end(), std::mem_fn(&FGAIBase::updateLOD));
}
void
FGAIManager::attach(const SGSharedPtr<FGAIBase> &model)
void FGAIManager::attach(const SGSharedPtr<FGAIBase>& model)
{
std::string_view typeString = model->getTypeString();
SGPropertyNode* root = globals->get_props()->getNode("ai/models", true);
SGPropertyNode* l_root = globals->get_props()->getNode("ai/models", true);
SGPropertyNode* p;
int i;
// find free index in the property tree, if we have
// more than 10000 mp-aircrafts in the property tree we should optimize the mp-server
// more than 10000 mp-aircraft in the property tree we should optimize the mp-server
for (i = 0; i < 10000; i++) {
p = root->getNode(static_cast<std::string>(typeString), i, false);
p = l_root->getNode(static_cast<std::string>(typeString), i, false);
if (!p || !p->getBoolValue("valid", false))
break;
if (p->getIntValue("id",-1)==model->getID()) {
p->setStringValue("callsign","***invalid node***"); //debug only, should never set!
if (p->getIntValue("id", -1) == model->getID()) {
p->setStringValue("callsign", "***invalid node***"); //debug only, should never set!
}
}
p = root->getNode(static_cast<std::string>(typeString), i, true);
p = l_root->getNode(static_cast<std::string>(typeString), i, true);
model->setManager(this, p);
ai_list.push_back(model);
@ -441,23 +435,21 @@ FGAIManager::attach(const SGSharedPtr<FGAIBase> &model)
bool FGAIManager::isVisible(const SGGeod& pos) const
{
double visibility_meters = _environmentVisiblity->getDoubleValue();
return ( dist(globals->get_view_position_cart(), SGVec3d::fromGeod(pos)) ) <= visibility_meters;
double visibility_meters = _environmentVisiblity->getDoubleValue();
return (dist(globals->get_view_position_cart(), SGVec3d::fromGeod(pos))) <= visibility_meters;
}
int
FGAIManager::getNumAiObjects() const
int FGAIManager::getNumAiObjects() const
{
return static_cast<int>(ai_list.size());
}
void
FGAIManager::fetchUserState( double dt )
void FGAIManager::fetchUserState(double dt)
{
globals->get_aircraft_orientation(user_heading, user_pitch, user_roll);
user_speed = user_speed_node->getDoubleValue() * 0.592484;
user_speed = user_speed_node->getDoubleValue() * 0.592484;
wind_from_east = wind_from_east_node->getDoubleValue();
wind_from_north = wind_from_north_node->getDoubleValue();
wind_from_north = wind_from_north_node->getDoubleValue();
user_altitude_agl = user_altitude_agl_node->getDoubleValue();
_userAircraft->setGeodPos(globals->get_aircraft_position());
@ -467,18 +459,17 @@ FGAIManager::fetchUserState( double dt )
}
// only keep the results from the nearest thermal
void
FGAIManager::processThermal( double dt, FGAIThermal* thermal ) {
void FGAIManager::processThermal(double dt, FGAIThermal* thermal)
{
thermal->update(dt);
if ( thermal->_getRange() < range_nearest ) {
if (thermal->_getRange() < range_nearest) {
range_nearest = thermal->_getRange();
strength = thermal->getStrength();
}
}
bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args, SGPropertyNode *)
bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args, SGPropertyNode*)
{
std::string name = args->getStringValue("name");
if (args->hasChild("load-property")) {
@ -506,7 +497,7 @@ bool FGAIManager::loadScenarioCommand(const SGPropertyNode* args, SGPropertyNode
return ok;
}
bool FGAIManager::unloadScenarioCommand(const SGPropertyNode * arg, SGPropertyNode * root)
bool FGAIManager::unloadScenarioCommand(const SGPropertyNode* arg, SGPropertyNode* root)
{
SG_UNUSED(root);
std::string name = arg->getStringValue("name");
@ -516,7 +507,7 @@ bool FGAIManager::unloadScenarioCommand(const SGPropertyNode * arg, SGPropertyNo
bool FGAIManager::addObjectCommand(const SGPropertyNode* arg, const SGPropertyNode* root)
{
SG_UNUSED(root);
if (!arg){
if (!arg) {
return false;
}
addObject(arg);
@ -553,14 +544,13 @@ FGAIBasePtr FGAIManager::addObject(const SGPropertyNode* definition)
}
ai->readFromScenario(const_cast<SGPropertyNode*>(definition));
if((ai->isValid())){
attach(ai);
if ((ai->isValid())) {
attach(ai);
SG_LOG(SG_AI, SG_DEBUG, "attached scenario " << ai->_getName());
}
else{
ai->setDie(true);
SG_LOG(SG_AI, SG_ALERT, "killed invalid scenario " << ai->_getName());
}
} else {
ai->setDie(true);
SG_LOG(SG_AI, SG_ALERT, "killed invalid scenario " << ai->_getName());
}
return ai;
}
@ -605,8 +595,7 @@ FGAIBasePtr FGAIManager::getObjectFromProperty(const SGPropertyNode* aProp) cons
return *it;
}
bool
FGAIManager::loadScenario( const std::string &id )
bool FGAIManager::loadScenario(const std::string& id)
{
SGPath path;
SGPropertyNode_ptr file = loadScenarioFile(id, path);
@ -629,8 +618,7 @@ FGAIManager::loadScenario( const std::string &id )
}
bool
FGAIManager::unloadScenario( const std::string &filename)
bool FGAIManager::unloadScenario(const std::string& filename)
{
auto it = _scenarios.find(filename);
if (it == _scenarios.end()) {
@ -638,7 +626,7 @@ FGAIManager::unloadScenario( const std::string &filename)
return false;
}
// remove /sim/ai node
// remove /sim/ai node
for (auto n : root->getChildren("scenario")) {
if (n->getStringValue() == filename) {
root->removeChild(n);
@ -651,13 +639,12 @@ FGAIManager::unloadScenario( const std::string &filename)
return true;
}
void
FGAIManager::unloadAllScenarios()
void FGAIManager::unloadAllScenarios()
{
std::for_each(_scenarios.begin(), _scenarios.end(),
[](const ScenarioDict::value_type& v) { delete v.second; });
// remove /sim/ai node
if(root) {
if (root) {
root->removeChildren("scenario");
}
_scenarios.clear();
@ -679,9 +666,8 @@ FGAIManager::loadScenarioFile(const std::string& scenarioName, SGPath& outPath)
SGPropertyNode_ptr root = new SGPropertyNode;
readProperties(path, root);
return root;
} catch (const sg_exception &t) {
SG_LOG(SG_AI, SG_ALERT, "Failed to load scenario '"
<< path << "': " << t.getFormattedMessage());
} catch (const sg_exception& t) {
SG_LOG(SG_AI, SG_ALERT, "Failed to load scenario '" << path << "': " << t.getFormattedMessage());
simgear::reportFailure(simgear::LoadFailure::BadData, simgear::ErrorCode::ScenarioLoad,
"Failed to laod scenario XML:" + t.getFormattedMessage(),
t.getLocation());
@ -692,7 +678,7 @@ FGAIManager::loadScenarioFile(const std::string& scenarioName, SGPath& outPath)
return {};
}
const FGAIBase *
const FGAIBase*
FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range)
{
ai_list_iterator ai_list_itr = ai_list.begin();
@ -705,17 +691,16 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range
FGAIBasePtr aiModel = *ai_list_itr;
FGAIBase::object_type type = aiModel->getType();
double tgt_alt = aiModel->_getAltitude();
int tgt_ht = aiModel->getCollisionHeight() + fuse_range;
int l_tgt_ht = aiModel->getCollisionHeight() + fuse_range;
if (fabs(tgt_alt - alt) > tgt_ht || type == FGAIBase::object_type::otBallistic
|| type == FGAIBase::object_type::otStorm || type == FGAIBase::object_type::otThermal ) {
//SG_LOG(SG_AI, SG_DEBUG, "AIManager: skipping "
// << fabs(tgt_alt - alt)
// << " "
// << type
// );
++ai_list_itr;
continue;
if (fabs(tgt_alt - alt) > l_tgt_ht || type == FGAIBase::object_type::otBallistic || type == FGAIBase::object_type::otStorm || type == FGAIBase::object_type::otThermal) {
//SG_LOG(SG_AI, SG_DEBUG, "AIManager: skipping "
// << fabs(tgt_alt - alt)
// << " "
// << type
// );
++ai_list_itr;
continue;
}
int id = (*ai_list_itr)->getID();
@ -731,16 +716,12 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range
// << " alt " << tgt_alt
// );
int tgt_length = aiModel->getCollisionLength() + fuse_range;
int l_tgt_length = aiModel->getCollisionLength() + fuse_range;
if (range < tgt_length){
if (range < l_tgt_length) {
SG_LOG(SG_AI, SG_DEBUG, "AIManager: HIT! "
<< " (h:" << tgt_ht << ", w:" << tgt_length << ")"
<< " type " << static_cast<int>(type)
<< " ID " << id
<< " range " << range
<< " alt " << tgt_alt
);
<< " (h:" << l_tgt_ht << ", w:" << l_tgt_length << ")"
<< " type " << static_cast<int>(type) << " ID " << id << " range " << range << " alt " << tgt_alt);
return aiModel.get();
}
++ai_list_itr;

View file

@ -1,24 +1,9 @@
// AIManager.hxx - David Culp - based on:
// AIMgr.hxx - definition of FGAIMgr
// - a global management class for FlightGear generated AI traffic
//
// Written by David Luff, started March 2002.
//
// Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
/*
* SPDX-FileName: AIManager.hxx
* SPDX-FileComment: a global management type for AI objects, based on David Luff's AIMgr
* SPDX-FileCopyrightText: Copyright (C) 2002 David C Luff - david.luff@nottingham.ac.uk
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
@ -56,19 +41,19 @@ public:
static const char* staticSubsystemClassId() { return "ai-model"; }
void updateLOD(SGPropertyNode* node);
void attach(const SGSharedPtr<FGAIBase> &model);
void attach(const SGSharedPtr<FGAIBase>& model);
const FGAIBase *calcCollision(double alt, double lat, double lon, double fuse_range);
const FGAIBase* calcCollision(double alt, double lat, double lon, double fuse_range);
inline double get_user_heading() const { return user_heading; }
inline double get_user_pitch() const { return user_pitch; }
inline double get_user_speed() const {return user_speed; }
inline double get_wind_from_east() const {return wind_from_east; }
inline double get_wind_from_north() const {return wind_from_north; }
inline double get_user_speed() const { return user_speed; }
inline double get_wind_from_east() const { return wind_from_east; }
inline double get_wind_from_north() const { return wind_from_north; }
inline double get_user_roll() const { return user_roll; }
inline double get_user_agl() const { return user_altitude_agl; }
bool loadScenario( const std::string &id );
bool loadScenario(const std::string& id);
/**
* Static helper to register scenarios. This has to happen very early because
@ -88,8 +73,9 @@ public:
*/
FGAIBasePtr getObjectFromProperty(const SGPropertyNode* aProp) const;
typedef std::vector <FGAIBasePtr> ai_list_type;
const ai_list_type& get_ai_list() const {
typedef std::vector<FGAIBasePtr> ai_list_type;
const ai_list_type& get_ai_list() const
{
return ai_list;
}
@ -104,13 +90,19 @@ public:
FGAIAircraft* getUserAircraft() const;
bool isRadarEnabled() const
{ return _radarEnabled; }
{
return _radarEnabled;
}
bool enableRadarDebug() const
{ return _radarDebugMode; }
{
return _radarDebugMode;
}
double radarRangeM() const
{ return _radarRangeM; }
{
return _radarRangeM;
}
private:
// FGSubmodelMgr is a friend for access to the AI_list
@ -126,13 +118,13 @@ private:
// Returns true on success, e.g. returns false if scenario is already loaded.
bool loadScenarioCommand(const SGPropertyNode* args, SGPropertyNode* root);
bool unloadScenarioCommand(const SGPropertyNode* args, SGPropertyNode* root);
bool addObjectCommand(const SGPropertyNode* arg, const SGPropertyNode* root);
bool removeObjectCommand(const SGPropertyNode* arg, const SGPropertyNode* root);
bool removeObject(const SGPropertyNode* args);
bool unloadScenario( const std::string &filename );
bool unloadScenario(const std::string& filename);
void unloadAllScenarios();
SGPropertyNode_ptr root;
@ -144,7 +136,7 @@ private:
SGPropertyNode_ptr wind_from_north_node;
SGPropertyNode_ptr _environmentVisiblity;
SGPropertyNode_ptr _groundSpeedKts_node;
ai_list_type ai_list;
double user_altitude_agl = 0.0;
@ -155,12 +147,12 @@ private:
double wind_from_east = 0.0;
double wind_from_north = 0.0;
void fetchUserState( double dt );
void fetchUserState(double dt);
// used by thermals
double range_nearest = 0.0;
double strength = 0.0;
void processThermal( double dt, FGAIThermal* thermal );
void processThermal(double dt, FGAIThermal* thermal);
SGPropertyChangeCallback<FGAIManager> cb_ai_bare;
SGPropertyChangeCallback<FGAIManager> cb_ai_detailed;
@ -171,10 +163,10 @@ private:
ScenarioDict _scenarios;
SGSharedPtr<FGAIAircraft> _userAircraft;
SGPropertyNode_ptr _simRadarControl,
_radarRangeNode, _radarDebugNode;
bool _radarEnabled = true,
_radarDebugMode = false;
_radarDebugMode = false;
double _radarRangeM = 0.0;
};