1
0
Fork 0

AIManager cleanups, no functionality change.

This commit is contained in:
James Turner 2012-11-21 14:03:17 +00:00
parent 258d387d15
commit 77ca03da4d
2 changed files with 66 additions and 85 deletions

View file

@ -20,9 +20,12 @@
#include <cstring> #include <cstring>
#include <simgear/sg_inlines.h>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
#include <boost/mem_fn.hpp>
#include <boost/foreach.hpp>
#include <Main/globals.hxx> #include <Main/globals.hxx>
@ -49,20 +52,12 @@ FGAIManager::FGAIManager() :
cb_ai_detailed(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD, cb_ai_detailed(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD,
fgGetNode("/sim/rendering/static-lod/ai-detailed", true))) fgGetNode("/sim/rendering/static-lod/ai-detailed", true)))
{ {
_dt = 0.0;
mNumAiModels = 0;
for (unsigned i = 0; i < FGAIBase::MAX_OBJECTS; ++i)
mNumAiTypeModels[i] = 0;
} }
FGAIManager::~FGAIManager() { FGAIManager::~FGAIManager()
ai_list_iterator ai_list_itr = ai_list.begin(); {
std::for_each(ai_list.begin(), ai_list.end(), boost::mem_fn(&FGAIBase::unbind));
while(ai_list_itr != ai_list.end()) {
(*ai_list_itr)->unbind();
++ai_list_itr;
}
} }
void void
@ -120,15 +115,10 @@ FGAIManager::postinit() {
} }
void void
FGAIManager::reinit() { FGAIManager::reinit()
{
update(0.0); update(0.0);
std::for_each(ai_list.begin(), ai_list.end(), boost::mem_fn(&FGAIBase::reinit));
ai_list_iterator ai_list_itr = ai_list.begin();
while(ai_list_itr != ai_list.end()) {
(*ai_list_itr)->reinit();
++ai_list_itr;
}
} }
void void
@ -143,6 +133,26 @@ FGAIManager::unbind() {
root->untie("count"); root->untie("count");
} }
void FGAIManager::removeDeadItem(FGAIBase* base)
{
FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("traffic-manager");
if (tmgr) {
tmgr->release(base->getID());
}
SGPropertyNode *props = base->_getProps();
props->setBoolValue("valid", false);
base->unbind();
// for backward compatibility reset properties, so that aircraft,
// which don't know the <valid> property, keep working
// TODO: remove after a while
props->setIntValue("id", -1);
props->setBoolValue("radar/in-range", false);
props->setIntValue("refuel/tanker", false);
}
void void
FGAIManager::update(double dt) { FGAIManager::update(double dt) {
// initialize these for finding nearest thermals // initialize these for finding nearest thermals
@ -152,42 +162,27 @@ FGAIManager::update(double dt) {
if (!enabled->getBoolValue()) if (!enabled->getBoolValue())
return; return;
FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("traffic-manager"); fetchUserState();
_dt = dt;
ai_list_iterator ai_list_itr = ai_list.begin(); // partition the list into dead followed by alive
ai_list_iterator firstAlive =
while(ai_list_itr != ai_list.end()) { std::stable_partition(ai_list.begin(), ai_list.end(), boost::mem_fn(&FGAIBase::getDie));
if ((*ai_list_itr)->getDie()) { // clean up each item and finally remove from the container
tmgr->release((*ai_list_itr)->getID()); for (ai_list_iterator it=ai_list.begin(); it != firstAlive; ++it) {
--mNumAiModels; removeDeadItem(*it);
--(mNumAiTypeModels[(*ai_list_itr)->getType()]);
FGAIBase *base = (*ai_list_itr).get();
SGPropertyNode *props = base->_getProps();
props->setBoolValue("valid", false);
base->unbind();
// for backward compatibility reset properties, so that aircraft,
// which don't know the <valid> property, keep working
// TODO: remove after a while
props->setIntValue("id", -1);
props->setBoolValue("radar/in-range", false);
props->setIntValue("refuel/tanker", false);
ai_list_itr = ai_list.erase(ai_list_itr);
} else {
fetchUserState();
if ((*ai_list_itr)->isa(FGAIBase::otThermal)) {
FGAIBase *base = (*ai_list_itr).get();
processThermal((FGAIThermal*)base);
} else {
(*ai_list_itr)->update(_dt);
}
++ai_list_itr;
}
} }
ai_list.erase(ai_list.begin(), firstAlive);
// every remaining item is alive
BOOST_FOREACH(FGAIBase* base, ai_list) {
if (base->isa(FGAIBase::otThermal)) {
processThermal(dt, (FGAIThermal*)base);
} else {
base->update(dt);
}
} // of live AI objects iteration
thermal_lift_node->setDoubleValue( strength ); // for thermals thermal_lift_node->setDoubleValue( strength ); // for thermals
} }
@ -196,18 +191,13 @@ FGAIManager::update(double dt) {
void void
FGAIManager::updateLOD(SGPropertyNode* node) FGAIManager::updateLOD(SGPropertyNode* node)
{ {
ai_list_iterator ai_list_itr = ai_list.begin(); SG_UNUSED(node);
while(ai_list_itr != ai_list.end()) std::for_each(ai_list.begin(), ai_list.end(), boost::mem_fn(&FGAIBase::updateLOD));
{
(*ai_list_itr)->updateLOD();
++ai_list_itr;
}
} }
void void
FGAIManager::attach(FGAIBase *model) FGAIManager::attach(FGAIBase *model)
{ {
//unsigned idx = mNumAiTypeModels[model->getType()];
const char* typeString = model->getTypeString(); const char* typeString = model->getTypeString();
SGPropertyNode* root = globals->get_props()->getNode("ai/models", true); SGPropertyNode* root = globals->get_props()->getNode("ai/models", true);
SGPropertyNode* p; SGPropertyNode* p;
@ -229,8 +219,7 @@ FGAIManager::attach(FGAIBase *model)
p = root->getNode(typeString, i, true); p = root->getNode(typeString, i, true);
model->setManager(this, p); model->setManager(this, p);
ai_list.push_back(model); ai_list.push_back(model);
++mNumAiModels;
++(mNumAiTypeModels[model->getType()]);
model->init(model->getType()==FGAIBase::otAircraft model->init(model->getType()==FGAIBase::otAircraft
|| model->getType()==FGAIBase::otMultiplayer || model->getType()==FGAIBase::otMultiplayer
|| model->getType()==FGAIBase::otStatic); || model->getType()==FGAIBase::otStatic);
@ -245,8 +234,6 @@ FGAIManager::destroyObject( int ID ) {
while(ai_list_itr != ai_list.end()) { while(ai_list_itr != ai_list.end()) {
if ((*ai_list_itr)->getID() == ID) { if ((*ai_list_itr)->getID() == ID) {
--mNumAiModels;
--(mNumAiTypeModels[(*ai_list_itr)->getType()]);
(*ai_list_itr)->unbind(); (*ai_list_itr)->unbind();
ai_list_itr = ai_list.erase(ai_list_itr); ai_list_itr = ai_list.erase(ai_list_itr);
} else } else
@ -258,7 +245,7 @@ FGAIManager::destroyObject( int ID ) {
int int
FGAIManager::getNumAiObjects(void) const FGAIManager::getNumAiObjects(void) const
{ {
return mNumAiModels; return ai_list.size();
} }
void void
@ -280,8 +267,8 @@ FGAIManager::fetchUserState( void ) {
// only keep the results from the nearest thermal // only keep the results from the nearest thermal
void void
FGAIManager::processThermal( FGAIThermal* thermal ) { FGAIManager::processThermal( double dt, FGAIThermal* thermal ) {
thermal->update(_dt); thermal->update(dt);
if ( thermal->_getRange() < range_nearest ) { if ( thermal->_getRange() < range_nearest ) {
range_nearest = thermal->_getRange(); range_nearest = thermal->_getRange();
@ -436,6 +423,9 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range
ai_list_iterator ai_list_itr = ai_list.begin(); ai_list_iterator ai_list_itr = ai_list.begin();
ai_list_iterator end = ai_list.end(); ai_list_iterator end = ai_list.end();
SGGeod pos(SGGeod::fromDegFt(lon, lat, alt));
SGVec3d cartPos(SGVec3d::fromGeod(pos));
while (ai_list_itr != end) { while (ai_list_itr != end) {
double tgt_alt = (*ai_list_itr)->_getAltitude(); double tgt_alt = (*ai_list_itr)->_getAltitude();
int type = (*ai_list_itr)->getType(); int type = (*ai_list_itr)->getType();
@ -452,11 +442,9 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range
continue; continue;
} }
double tgt_lat = (*ai_list_itr)->_getLatitude();
double tgt_lon = (*ai_list_itr)->_getLongitude();
int id = (*ai_list_itr)->getID(); int id = (*ai_list_itr)->getID();
double range = calcRange(lat, lon, tgt_lat, tgt_lon); double range = calcRange(cartPos, (*ai_list_itr));
//SG_LOG(SG_AI, SG_DEBUG, "AIManager: AI list size " //SG_LOG(SG_AI, SG_DEBUG, "AIManager: AI list size "
// << ai_list.size() // << ai_list.size()
@ -484,14 +472,10 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range
} }
double double
FGAIManager::calcRange(double lat, double lon, double lat2, double lon2) const FGAIManager::calcRange(const SGVec3d& aCartPos, FGAIBase* aObject) const
{ {
double course, az2, distance; double distM = dist(aCartPos, aObject->getCartPos());
return distM * SG_METER_TO_FEET;
//calculate the bearing and range of the second pos from the first
geo_inverse_wgs_84(lat, lon, lat2, lon2, &course, &az2, &distance);
distance *= SG_METER_TO_FEET;
return distance;
} }
//end AIManager.cxx //end AIManager.cxx

View file

@ -59,7 +59,7 @@ public:
} }
FGAIManager(); FGAIManager();
~FGAIManager(); virtual ~FGAIManager();
void init(); void init();
void postinit(); void postinit();
@ -95,11 +95,9 @@ public:
SGGeod& geodPos, double& hdng, SGVec3d& uvw); SGGeod& geodPos, double& hdng, SGVec3d& uvw);
private: private:
void removeDeadItem(FGAIBase* base);
int mNumAiTypeModels[FGAIBase::MAX_OBJECTS];
int mNumAiModels; double calcRange(const SGVec3d& aCartPos, FGAIBase* aObject) const;
double calcRange(double lat, double lon, double lat2, double lon2)const;
SGPropertyNode_ptr root; SGPropertyNode_ptr root;
SGPropertyNode_ptr enabled; SGPropertyNode_ptr enabled;
@ -128,14 +126,13 @@ private:
double user_agl; double user_agl;
double wind_from_east; double wind_from_east;
double wind_from_north; double wind_from_north;
double _dt;
void fetchUserState( void ); void fetchUserState( void );
// used by thermals // used by thermals
double range_nearest; double range_nearest;
double strength; double strength;
void processThermal( FGAIThermal* thermal ); void processThermal( double dt, FGAIThermal* thermal );
SGPropertyChangeCallback<FGAIManager> cb_ai_bare; SGPropertyChangeCallback<FGAIManager> cb_ai_bare;
SGPropertyChangeCallback<FGAIManager> cb_ai_detailed; SGPropertyChangeCallback<FGAIManager> cb_ai_detailed;