X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FScripting%2FNasalPositioned.cxx;h=275929de2cf38b62204906126312eb08f861a062;hb=fc887b106bbb199ffe9c042b8271eae1be26c9aa;hp=fced59becc44b03c51c99a0e28175f8985768835;hpb=3e46c7998ce2bf23ec322d1dfe65c8da35621d51;p=flightgear.git diff --git a/src/Scripting/NasalPositioned.cxx b/src/Scripting/NasalPositioned.cxx index fced59bec..275929de2 100644 --- a/src/Scripting/NasalPositioned.cxx +++ b/src/Scripting/NasalPositioned.cxx @@ -124,6 +124,17 @@ static naRef stringToNasal(naContext c, const std::string& s) s.length()); } +static bool convertToNum(naRef v, double& result) +{ + naRef n = naNumValue(v); + if (naIsNil(n)) { + return false; // couldn't convert + } + + result = n.num; + return true; +} + static WayptFlag wayptFlagFromString(const char* s) { if (!strcmp(s, "sid")) return WPT_DEPARTURE; @@ -432,6 +443,8 @@ static const char* waypointCommonGetMember(naContext c, Waypt* wpt, const char* } else { *out = stringToNasal(c, wpt->flag(WPT_OVERFLIGHT) ? "flyOver" : "flyBy"); } + } else if (!strcmp(fieldName, "heading_course")) { + *out = naNum(wpt->headingRadialDeg()); } else { return NULL; // member not found } @@ -450,6 +463,10 @@ static void waypointCommonSetMember(naContext c, Waypt* wpt, const char* fieldNa } wpt->setFlag(f, true); + } else if (!strcmp(fieldName, "fly_type")) { + if (!naIsString(value)) naRuntimeError(c, "fly_type must be a string"); + bool flyOver = (strcmp(naStr_data(value), "flyOver") == 0); + wpt->setFlag(WPT_OVERFLIGHT, flyOver); } } @@ -556,6 +573,8 @@ static const char* flightplanGhostGetMember(naContext c, void* g, naRef field, n else if (!strcmp(fieldName, "star_trans")) *out = ghostForProcedure(c, fp->starTransition()); else if (!strcmp(fieldName, "approach")) *out = ghostForProcedure(c, fp->approach()); else if (!strcmp(fieldName, "current")) *out = naNum(fp->currentIndex()); + else if (!strcmp(fieldName, "aircraftCategory")) *out = stringToNasal(c, fp->icaoAircraftCategory()); + else if (!strcmp(fieldName, "followLegTrackToFix")) *out = naNum(fp->followLegTrackToFixes()); else { return 0; } @@ -678,6 +697,12 @@ static void flightplanGhostSetMember(naContext c, void* g, naRef field, naRef va } naRuntimeError(c, "bad argument type setting approach"); + } else if (!strcmp(fieldName, "aircraftCategory")) { + if (!naIsString(value)) naRuntimeError(c, "aircraftCategory must be a string"); + fp->setIcaoAircraftCategory(naStr_data(value)); + } else if (!strcmp(fieldName, "followLegTrackToFix")) { + int b = (int) value.num; + fp->setFollowLegTrackToFixes(b); } } @@ -1118,7 +1143,11 @@ static naRef f_airport_comms(naContext c, naRef me, int argc, naRef* args) naRef comms = naNewVector(c); // if we have an explicit type, return a simple vector of frequencies - if (argc > 0 && naIsScalar(args[0])) { + if (argc > 0 && !naIsString(args[0])) { + naRuntimeError(c, "airport.comms argument must be a frequency type name"); + } + + if (argc > 0) { std::string commName = naStr_data(args[0]); FGPositioned::Type commType = FGPositioned::typeFromName(commName); @@ -1323,20 +1352,10 @@ static naRef f_airport_parking(naContext c, naRef me, int argc, naRef* args) } FGAirportDynamics* dynamics = apt->getDynamics(); - PositionedIDVec parkings = flightgear::NavDataCache::instance()->airportItemsOfType(apt->guid(), - FGPositioned::PARKING); - - BOOST_FOREACH(PositionedID parking, parkings) { - // filter out based on availability and type - if (onlyAvailable && !dynamics->isParkingAvailable(parking)) { - continue; - } - - FGParking* park = dynamics->getParking(parking); - if (!type.empty() && (park->getType() != type)) { - continue; - } - + FGParkingList parkings = dynamics->getParkings(onlyAvailable, type); + FGParkingList::const_iterator it; + for (it = parkings.begin(); it != parkings.end(); ++it) { + FGParkingRef park = *it; const SGGeod& parkLoc = park->geod(); naRef ph = naNewHash(c); hashset(c, ph, "name", stringToNasal(c, park->getName())); @@ -1778,18 +1797,25 @@ public: { callDelegateMethod("endOfFlightPlan"); } + + virtual void activated() + { + callDelegateMethod("activated"); + } private: void callDelegateMethod(const char* method) { naRef f; - if (naMember_cget(_nasal->context(), _instance, method, &f) == 0) { - return; // no method on the delegate + naContext ctx = naNewContext(); + + if (naMember_cget(ctx, _instance, method, &f) != 0) { + naRef arg[1]; + arg[0] = ghostForFlightPlan(ctx, _plan); + _nasal->callMethod(f, _instance, 1, arg, naNil()); } - naRef arg[1]; - arg[0] = ghostForFlightPlan(_nasal->context(), _plan); - _nasal->callMethod(f, _instance, 1, arg, naNil()); + naFreeContext(ctx); } FGNasalSys* _nasal; @@ -1798,6 +1824,7 @@ private: int _gcSaveKey; }; + class NasalFPDelegateFactory : public FlightPlan::DelegateFactory { public: @@ -1808,7 +1835,7 @@ public: _gcSaveKey = _nasal->gcSave(_func); } - ~NasalFPDelegateFactory() + virtual ~NasalFPDelegateFactory() { _nasal->gcRelease(_gcSaveKey); } @@ -1816,13 +1843,18 @@ public: virtual FlightPlan::Delegate* createFlightPlanDelegate(FlightPlan* fp) { naRef args[1]; - args[0] = ghostForFlightPlan(_nasal->context(), fp); + naContext ctx = naNewContext(); + args[0] = ghostForFlightPlan(ctx, fp); naRef instance = _nasal->call(_func, 1, args, naNil()); - if (naIsNil(instance)) { - return NULL; - } - return new NasalFPDelegate(fp, _nasal, instance); + FlightPlan::Delegate* result = NULL; + if (!naIsNil(instance)) { + // will GC-save instance + result = new NasalFPDelegate(fp, _nasal, instance); + } + + naFreeContext(ctx); + return result; } private: FGNasalSys* _nasal; @@ -1830,6 +1862,20 @@ private: int _gcSaveKey; }; +static std::vector static_nasalDelegateFactories; + +void shutdownNasalPositioned() +{ + std::vector::iterator it; + for (it = static_nasalDelegateFactories.begin(); + it != static_nasalDelegateFactories.end(); ++it) + { + FlightPlan::unregisterDelegateFactory(*it); + delete (*it); + } + static_nasalDelegateFactories.clear(); +} + static naRef f_registerFPDelegate(naContext c, naRef me, int argc, naRef* args) { if ((argc < 1) || !naIsFunc(args[0])) { @@ -1838,7 +1884,7 @@ static naRef f_registerFPDelegate(naContext c, naRef me, int argc, naRef* args) NasalFPDelegateFactory* factory = new NasalFPDelegateFactory(args[0]); FlightPlan::registerDelegateFactory(factory); - + static_nasalDelegateFactories.push_back(factory); return naNil(); } @@ -2176,19 +2222,41 @@ static naRef f_flightplan_finish(naContext c, naRef me, int argc, naRef* args) return naNil(); } +static naRef f_flightplan_indexOfWp(naContext c, naRef me, int argc, naRef* args) +{ + FlightPlan* fp = flightplanGhost(me); + if (!fp) { + naRuntimeError(c, "flightplan.indexOfWP called on non-flightplan object"); + } + + FGPositioned* positioned = positionedGhost(args[0]); + if (positioned) { + return naNum(fp->findWayptIndex(positioned)); + } + + SGGeod pos; + int argOffset = geodFromArgs(args, 0, argc, pos); + if (argOffset > 0) { + return naNum(fp->findWayptIndex(pos)); + } + + return naNum(-1); +} + static naRef f_leg_setSpeed(naContext c, naRef me, int argc, naRef* args) { FlightPlan::Leg* leg = fpLegGhost(me); if (!leg) { naRuntimeError(c, "leg.setSpeed called on non-flightplan-leg object"); } - - if (argc < 2) { - naRuntimeError(c, "bad arguments to leg.setSpeed"); - } - + + double speed = 0.0; + if ((argc < 2) || !convertToNum(args[0], speed)) + naRuntimeError(c, "bad arguments to setSpeed"); + RouteRestriction rr = routeRestrictionFromString(naStr_data(args[1])); - leg->setSpeed(rr, args[0].num); + leg->setSpeed(rr, speed); + return naNil(); } @@ -2199,12 +2267,13 @@ static naRef f_leg_setAltitude(naContext c, naRef me, int argc, naRef* args) naRuntimeError(c, "leg.setAltitude called on non-flightplan-leg object"); } - if (argc < 2) { - naRuntimeError(c, "bad arguments to leg.setAltitude"); - } - + double alt = 0.0; + if ((argc < 2) || !convertToNum(args[0], alt)) + naRuntimeError(c, "bad arguments to leg.setAltitude"); + RouteRestriction rr = routeRestrictionFromString(naStr_data(args[1])); - leg->setAltitude(rr, args[0].num); + leg->setAltitude(rr, alt); + return naNil(); } @@ -2239,11 +2308,12 @@ static naRef f_leg_courseAndDistanceFrom(naContext c, naRef me, int argc, naRef* SGGeod pos; geodFromArgs(args, 0, argc, pos); - - double courseDeg; - double distanceM; - boost::tie(courseDeg, distanceM) = leg->waypoint()->courseAndDistanceFrom(pos); - + + RoutePath path(leg->owner()); + SGGeod wpPos = path.positionForIndex(leg->index()); + double courseDeg, az2, distanceM; + SGGeodesy::inverse(pos, wpPos, courseDeg, az2, distanceM); + naRef result = naNewVector(c); naVec_append(result, naNum(courseDeg)); naVec_append(result, naNum(distanceM * SG_METER_TO_NM)); @@ -2345,7 +2415,6 @@ static naRef f_procedure_route(naContext c, naRef me, int argc, naRef* args) WayptVec r; Approach* app = (Approach*) proc; if (!app->route(iaf, r)) { - SG_LOG(SG_NASAL, SG_WARN, "procedure.route failed for Approach somehow"); return naNil(); } @@ -2403,10 +2472,10 @@ static struct { const char* name; naCFunction func; } funcs[] = { }; -naRef initNasalPositioned(naRef globals, naContext c, naRef gcSave) +naRef initNasalPositioned(naRef globals, naContext c) { airportPrototype = naNewHash(c); - hashset(c, gcSave, "airportProto", airportPrototype); + naSave(c, airportPrototype); hashset(c, airportPrototype, "runway", naNewFunc(c, naNewCCode(c, f_airport_runway))); hashset(c, airportPrototype, "runwaysWithoutReciprocals", naNewFunc(c, naNewCCode(c, f_airport_runwaysWithoutReciprocals))); @@ -2424,7 +2493,7 @@ naRef initNasalPositioned(naRef globals, naContext c, naRef gcSave) hashset(c, airportPrototype, "tostring", naNewFunc(c, naNewCCode(c, f_airport_toString))); flightplanPrototype = naNewHash(c); - hashset(c, gcSave, "flightplanProto", flightplanPrototype); + naSave(c, flightplanPrototype); hashset(c, flightplanPrototype, "getWP", naNewFunc(c, naNewCCode(c, f_flightplan_getWP))); hashset(c, flightplanPrototype, "currentWP", naNewFunc(c, naNewCCode(c, f_flightplan_currentWP))); @@ -2440,21 +2509,22 @@ naRef initNasalPositioned(naRef globals, naContext c, naRef gcSave) hashset(c, flightplanPrototype, "clone", naNewFunc(c, naNewCCode(c, f_flightplan_clone))); hashset(c, flightplanPrototype, "pathGeod", naNewFunc(c, naNewCCode(c, f_flightplan_pathGeod))); hashset(c, flightplanPrototype, "finish", naNewFunc(c, naNewCCode(c, f_flightplan_finish))); + hashset(c, flightplanPrototype, "indexOfWP", naNewFunc(c, naNewCCode(c, f_flightplan_indexOfWp))); waypointPrototype = naNewHash(c); - hashset(c, gcSave, "wayptProto", waypointPrototype); + naSave(c, waypointPrototype); hashset(c, waypointPrototype, "navaid", naNewFunc(c, naNewCCode(c, f_waypoint_navaid))); hashset(c, waypointPrototype, "runway", naNewFunc(c, naNewCCode(c, f_waypoint_runway))); hashset(c, waypointPrototype, "airport", naNewFunc(c, naNewCCode(c, f_waypoint_airport))); procedurePrototype = naNewHash(c); - hashset(c, gcSave, "procedureProto", procedurePrototype); + naSave(c, procedurePrototype); hashset(c, procedurePrototype, "transition", naNewFunc(c, naNewCCode(c, f_procedure_transition))); hashset(c, procedurePrototype, "route", naNewFunc(c, naNewCCode(c, f_procedure_route))); fpLegPrototype = naNewHash(c); - hashset(c, gcSave, "fpLegProto", fpLegPrototype); + naSave(c, fpLegPrototype); hashset(c, fpLegPrototype, "setSpeed", naNewFunc(c, naNewCCode(c, f_leg_setSpeed))); hashset(c, fpLegPrototype, "setAltitude", naNewFunc(c, naNewCCode(c, f_leg_setAltitude))); hashset(c, fpLegPrototype, "path", naNewFunc(c, naNewCCode(c, f_leg_path)));