#include <sys/types.h>
#include <sys/stat.h>
#include <fstream>
+#include <sstream>
#include <plib/ul.h>
static naRef f_geodinfo(naContext c, naRef me, int argc, naRef* args)
{
#define HASHSET(s,l,n) naHash_set(matdata, naStr_fromdata(naNewString(c),s,l),n)
- if(argc != 2) naRuntimeError(c, "geodinfo() expects 2 arguments: lat, lon");
+ if(argc < 2 || argc > 3)
+ naRuntimeError(c, "geodinfo() expects 2 or 3 arguments: lat, lon [, maxalt]");
double lat = naNumValue(args[0]).num;
double lon = naNumValue(args[1]).num;
- double elev;
+ double elev = argc == 3 ? naNumValue(args[2]).num : 10000;
const SGMaterial *mat;
- if(!globals->get_scenery()->get_elevation_m(lat, lon, 10000.0, elev, &mat))
+ SGGeod geod = SGGeod::fromDegM(lon, lat, elev);
+ if(!globals->get_scenery()->get_elevation_m(geod, elev, &mat))
return naNil();
naRef vec = naNewVector(c);
naVec_append(vec, naNum(elev));
#undef HASHSET
}
+
class AirportInfoFilter : public FGAirport::AirportFilter
{
public:
- AirportInfoFilter() :
- type(FGPositioned::AIRPORT)
- { }
-
- virtual FGPositioned::Type minType() const {
- return type;
- }
-
- virtual FGPositioned::Type maxType() const {
- return type;
- }
-
- FGPositioned::Type type;
+ AirportInfoFilter() : type(FGPositioned::AIRPORT) {
+ }
+
+ virtual FGPositioned::Type minType() const {
+ return type;
+ }
+
+ virtual FGPositioned::Type maxType() const {
+ return type;
+ }
+
+ FGPositioned::Type type;
};
// Returns data hash for particular or nearest airport of a <type>, or nil
static SGConstPropertyNode_ptr lonn = fgGetNode("/position/longitude-deg", true);
SGGeod pos;
FGAirport* apt = NULL;
-
+
if(argc >= 2 && naIsNum(args[0]) && naIsNum(args[1])) {
pos = SGGeod::fromDeg(args[1].num, args[0].num);
args += 2;
AirportInfoFilter filter; // defaults to airports only
if(argc == 0) {
- // fine, just fall through and use AIRPORT
+ // fall through and use AIRPORT
} else if(argc == 1 && naIsString(args[0])) {
const char *s = naStr_data(args[0]);
- if (!strcmp(s, "airport")) filter.type = FGPositioned::AIRPORT;
+ if(!strcmp(s, "airport")) filter.type = FGPositioned::AIRPORT;
else if(!strcmp(s, "seaport")) filter.type = FGPositioned::SEAPORT;
else if(!strcmp(s, "heliport")) filter.type = FGPositioned::HELIPORT;
else {
// user provided an <id>, hopefully
apt = FGAirport::findByIdent(s);
if (!apt) {
- naRuntimeError(c, "airportinfo() couldn't find airport:%s", s);
+ naRuntimeError(c, "airportinfo() couldn't find airport: %s", s);
return naNil();
}
}
naRuntimeError(c, "airportinfo() with invalid function arguments");
return naNil();
}
-
- if (!apt) {
+
+ if(!apt) {
apt = FGAirport::findClosest(pos, maxRange, &filter);
if(!apt) return naNil();
}
-
+
string id = apt->ident();
string name = apt->name();
// set runway hash
naRef rwys = naNewHash(c);
- for (unsigned int r=0; r<apt->numRunways(); ++r) {
+ for(unsigned int r=0; r<apt->numRunways(); ++r) {
FGRunway* rwy(apt->getRunwayByIndex(r));
naRef rwyid = naStr_fromdata(naNewString(c),
const char *s = "nasal-dir-initialized";
SGPropertyNode *signal = fgGetNode("/sim/signals", true);
signal->setBoolValue(s, true);
- signal->removeChildren(s);
+ signal->removeChildren(s, false);
// Pull scripts out of the property tree, too
loadPropertyScripts();
if(n->hasChild("module"))
module = n->getStringValue("module");
- // allow multiple files to be specified within in a single
+ // allow multiple files to be specified within a single
// Nasal module tag
int j = 0;
SGPropertyNode *fn;
j++;
}
- // Old code which only allowed a single file to be specified per module
- /*
- const char* file = n->getStringValue("file");
- if(!n->hasChild("file")) file = 0; // Hrm...
- if(file) {
- SGPath p(globals->get_fg_root());
- p.append(file);
- loadModule(p, module);
- }
- */
-
const char* src = n->getStringValue("script");
if(!n->hasChild("script")) src = 0; // Hrm...
if(src)
return naNil();
}
- int type = argc > 3 && naIsNum(args[3]) ? (int)args[3].num : 1;
+ int init = argc > 2 && naIsNum(args[2]) ? int(args[2].num) : 0;
+ int type = argc > 3 && naIsNum(args[3]) ? int(args[3].num) : 1;
FGNasalListener *nl = new FGNasalListener(node, code, this,
- gcSave(code), _listenerId, type);
+ gcSave(code), _listenerId, init, type);
- bool initial = argc > 2 && naTrue(args[2]);
- node->addChangeListener(nl, initial);
+ node->addChangeListener(nl, init);
_listener[_listenerId] = nl;
return naNum(_listenerId++);
// FGNasalListener class.
FGNasalListener::FGNasalListener(SGPropertyNode *node, naRef code,
- FGNasalSys* nasal, int key, int id, int type) :
+ FGNasalSys* nasal, int key, int id,
+ int init, int type) :
_node(node),
_code(code),
_gcKey(key),
_id(id),
_nas(nasal),
+ _init(init),
_type(type),
_active(0),
_dead(false),
- _first_call(true),
_last_int(0L),
_last_float(0.0)
{
+ if(_type == 0 && !_init)
+ changed(node);
}
FGNasalListener::~FGNasalListener()
void FGNasalListener::valueChanged(SGPropertyNode* node)
{
if(_type < 2 && node != _node) return; // skip child events
- if(_type > 0 || changed(_node) || _first_call)
+ if(_type > 0 || changed(_node) || _init)
call(node, naNum(0));
- _first_call = false;
+ _init = 0;
}
void FGNasalListener::childAdded(SGPropertyNode*, SGPropertyNode* child)
// destructor the <unload> script. The latter happens when the model branch
// is removed from the scene graph.
+unsigned int FGNasalModelData::_module_id = 0;
+
void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop,
osg::Node *)
{
if(!load && !_unload)
return;
- _module = path;
- if(_props)
- _module += ':' + _props->getPath();
+ std::stringstream m;
+ m << "__model" << _module_id++;
+ _module = m.str();
+
const char *s = load ? load->getStringValue() : "";
naRef arg[2];
arg[0] = nasalSys->propNodeGhost(_root);
arg[1] = nasalSys->propNodeGhost(prop);
- nasalSys->createModule(_module.c_str(), _module.c_str(), s, strlen(s),
+ nasalSys->createModule(_module.c_str(), path.c_str(), s, strlen(s),
_root, 2, arg);
- _props = 0;
}
FGNasalModelData::~FGNasalModelData()