From b148cfd85de3b5739e13bc9280f861539cdf6628 Mon Sep 17 00:00:00 2001 From: Jens Ayton Date: Fri, 23 May 2008 07:51:00 +0000 Subject: [PATCH] More work on JavaScript error checking. More rigourous! More informative! More not buggy! And, conversely, probably also more buggy. I've almost certainly broken something silly. Also moved JS nova-related functionality into Sun. git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1648 127b21dd-08f5-0310-b4b7-95ae10353056 --- Oolite.xcodeproj/project.pbxproj | 6 +- Resources/Scripts/oolite-global-prefix.js | 7 + Resources/Scripts/oolite-nova-mission.js | 6 +- src/Cocoa/debug-exports.exp | 6 +- src/Core/Debug/OOJSConsole.m | 28 +- src/Core/Entities/PlanetEntity.m | 10 +- .../Entities/PlayerEntityLegacyScriptEngine.m | 2 - src/Core/Entities/ShipEntity.m | 4 +- src/Core/OOCacheManager.m | 2 +- src/Core/Scripting/OOJSCall.m | 6 +- src/Core/Scripting/OOJSClock.m | 31 +- src/Core/Scripting/OOJSEntity.m | 6 +- src/Core/Scripting/OOJSGlobal.m | 16 +- src/Core/Scripting/OOJSMission.m | 16 +- src/Core/Scripting/OOJSMissionVariables.m | 8 +- src/Core/Scripting/OOJSOolite.m | 4 +- src/Core/Scripting/OOJSPlanet.m | 10 +- src/Core/Scripting/OOJSPlayer.m | 18 +- src/Core/Scripting/OOJSQuaternion.m | 6 +- src/Core/Scripting/OOJSScript.m | 2 +- src/Core/Scripting/OOJSShip.m | 44 +-- src/Core/Scripting/OOJSSound.m | 2 +- src/Core/Scripting/OOJSSoundSource.m | 4 +- src/Core/Scripting/OOJSSpecialFunctions.m | 2 +- src/Core/Scripting/OOJSStation.m | 4 +- src/Core/Scripting/OOJSSun.m | 59 +++- src/Core/Scripting/OOJSSystem.m | 313 +++++++++++------- src/Core/Scripting/OOJSTimer.m | 58 ++-- src/Core/Scripting/OOJSVector.m | 8 +- src/Core/Scripting/OOJSWorldScripts.m | 2 +- src/Core/Scripting/OOJavaScriptEngine.h | 21 +- src/Core/Scripting/OOJavaScriptEngine.m | 30 +- 32 files changed, 443 insertions(+), 298 deletions(-) diff --git a/Oolite.xcodeproj/project.pbxproj b/Oolite.xcodeproj/project.pbxproj index 40ff967b..20242908 100644 --- a/Oolite.xcodeproj/project.pbxproj +++ b/Oolite.xcodeproj/project.pbxproj @@ -1020,7 +1020,7 @@ 083325DC09DDBCDE00F5B8E4 /* OOColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOColor.m; sourceTree = ""; }; 083DB4D30A70E51E00B419B2 /* OOBrain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOBrain.h; sourceTree = ""; }; 083DB4D40A70E51E00B419B2 /* OOBrain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOBrain.m; sourceTree = ""; }; - 0865432206B8447D000CA0AB /* OoliteDev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OoliteDev.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0865432206B8447D000CA0AB /* Oolite.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Oolite.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0878FD2F086EF845004CB752 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 1A020E0A0D020AFB00C3F51E /* changedScriptHandlers.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = changedScriptHandlers.plist; sourceTree = ""; }; @@ -1688,7 +1688,7 @@ 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 0865432206B8447D000CA0AB /* OoliteDev.app */, + 0865432206B8447D000CA0AB /* Oolite.app */, 1A71E6F30BCE340C00CD5C13 /* libpng.a */, ); name = Products; @@ -2912,7 +2912,7 @@ name = Oolite; productInstallPath = "$(HOME)/Applications"; productName = Oolite; - productReference = 0865432206B8447D000CA0AB /* OoliteDev.app */; + productReference = 0865432206B8447D000CA0AB /* Oolite.app */; productType = "com.apple.product-type.application"; }; 1A71E6F20BCE340C00CD5C13 /* libpng-custom */ = { diff --git a/Resources/Scripts/oolite-global-prefix.js b/Resources/Scripts/oolite-global-prefix.js index 016bae86..43d732ca 100644 --- a/Resources/Scripts/oolite-global-prefix.js +++ b/Resources/Scripts/oolite-global-prefix.js @@ -147,3 +147,10 @@ system.legacy_spawn = function() { special.jsWarning("system.legacy_spawn() is deprecated (and never worked), use Ship.spawn() instead."); } + + +system.setSunNova = function(delay) +{ + special.jsWarning("system.setSunNova() is deprecated, use system.sun.goNova() instead."); + if (this.sun) this.sun.goNova(delay); +} diff --git a/Resources/Scripts/oolite-nova-mission.js b/Resources/Scripts/oolite-nova-mission.js index f6330188..1c6d79e9 100644 --- a/Resources/Scripts/oolite-nova-mission.js +++ b/Resources/Scripts/oolite-nova-mission.js @@ -85,7 +85,7 @@ this.choiceEvaluation = function() missionVariables.nova = "NOVA_ESCAPE_HERO"; player.launch(); this.blowUpAllStations(); - system.setSunNova(30); + system.sun.goNova(30); missionVariables.novacount = null; } else @@ -93,7 +93,7 @@ this.choiceEvaluation = function() // mission.choice = "NO", or null when player launched without a choice. missionVariables.nova = "NOVA_ESCAPE_COWARD"; player.commsMessage(expandDescription("[oolite-nova-coward]"), 4.5); - system.setSunNova(3); + system.sun.goNova(3); missionVariables.novacount = null; } @@ -185,7 +185,7 @@ this.shipWillExitWitchspace = function () // call this as soon as possible so o { missionVariables.nova = "TWO_HRS_TO_ZERO"; player.fuelLeakRate = 25; - system.setSunNova(7200); + system.sun.goNova(7200); player.consoleMessage(expandDescription("[danger-fuel-leak]"), 4.5); player.call("setPlanetinfo:", "market = none"); player.call("setPlanetinfo:", "sun_gone_nova = YES"); diff --git a/src/Cocoa/debug-exports.exp b/src/Cocoa/debug-exports.exp index af380a6a..03a60fe0 100644 --- a/src/Cocoa/debug-exports.exp +++ b/src/Cocoa/debug-exports.exp @@ -40,15 +40,15 @@ _JS_InitClass _JS_NewObject _JS_PropertyStub _JS_ResolveStub -_OOReportJavaScriptBadPropertySelector -_OOReportJavaScriptError +_OOReportJSBadPropertySelector +_OOReportJSError _JS_InternString _JS_AddNamedRoot _JS_RemoveRoot _JSValueToObject _JS_ValueToNumber _JS_SetProperty -_OOReportJavaScriptWarning +_OOReportJSWarning _OOBooleanFromObject _ScanClassToString _EntityStatusToString diff --git a/src/Core/Debug/OOJSConsole.m b/src/Core/Debug/OOJSConsole.m index 58927a20..b32ae96d 100644 --- a/src/Core/Debug/OOJSConsole.m +++ b/src/Core/Debug/OOJSConsole.m @@ -195,7 +195,7 @@ static JSBool ConsoleGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Console", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Console", JSVAL_TO_INT(name)); return NO; } @@ -219,7 +219,7 @@ static JSBool ConsoleSetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Console", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Console", JSVAL_TO_INT(name)); return NO; } @@ -246,7 +246,7 @@ static JSBool ConsoleSettingsDeleteProperty(JSContext *context, JSObject *this, monitor = JSObjectToObject(context, this); if (![monitor isKindOfClass:[OODebugMonitor class]]) { - OOReportJavaScriptError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); + OOReportJSError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); return NO; } @@ -268,8 +268,8 @@ static JSBool ConsoleSettingsGetProperty(JSContext *context, JSObject *this, jsv monitor = JSObjectToObject(context, this); if (![monitor isKindOfClass:[OODebugMonitor class]]) { - OOReportJavaScriptError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); - return YES; + OOReportJSError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); + return NO; } value = [monitor configurationValueForKey:key]; @@ -291,8 +291,8 @@ static JSBool ConsoleSettingsSetProperty(JSContext *context, JSObject *this, jsv monitor = JSObjectToObject(context, this); if (![monitor isKindOfClass:[OODebugMonitor class]]) { - OOReportJavaScriptError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); - return YES; + OOReportJSError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); + return NO; } if (JSVAL_IS_NULL(*inValue) || JSVAL_IS_VOID(*inValue)) @@ -308,7 +308,7 @@ static JSBool ConsoleSettingsSetProperty(JSContext *context, JSObject *this, jsv } else { - OOReportJavaScriptWarning(context, @"debugConsole.settings: could not convert %@ to native object.", [NSString stringWithJavaScriptValue:*inValue inContext:context]); + OOReportJSWarning(context, @"debugConsole.settings: could not convert %@ to native object.", [NSString stringWithJavaScriptValue:*inValue inContext:context]); } } @@ -328,7 +328,7 @@ static JSBool ConsoleConsoleMessage(JSContext *context, JSObject *this, uintN ar monitor = JSObjectToObject(context, this); if (![monitor isKindOfClass:[OODebugMonitor class]]) { - OOReportJavaScriptError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); + OOReportJSError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); return NO; } @@ -349,7 +349,7 @@ static JSBool ConsoleConsoleMessage(JSContext *context, JSObject *this, uintN ar { if (colorKey == nil) { - OOReportJavaScriptWarning(context, @"Console.consoleMessage() called with no parameters."); + OOReportJSWarning(context, @"Console.consoleMessage() called with no parameters."); } else { @@ -376,8 +376,8 @@ static JSBool ConsoleClearConsole(JSContext *context, JSObject *this, uintN argc monitor = JSObjectToObject(context, this); if (![monitor isKindOfClass:[OODebugMonitor class]]) { - OOReportJavaScriptError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); - return YES; + OOReportJSError(context, @"Expected OODebugMonitor, got %@ in %s. This is an internal error, please report it.", [monitor class], __PRETTY_FUNCTION__); + return NO; } [monitor clearJSConsole]; @@ -418,8 +418,8 @@ static JSBool ConsoleCallObjCMethod(JSContext *context, JSObject *this, uintN ar object = JSObjectToObject(context, this); if (object == nil) { - OOReportJavaScriptError(context, @"Attempt to call __callObjCMethod() for non-Objective-C object %@.", JSValToNSString(context, OBJECT_TO_JSVAL(this))); - return YES; + OOReportJSError(context, @"Attempt to call __callObjCMethod() for non-Objective-C object %@.", JSValToNSString(context, OBJECT_TO_JSVAL(this))); + return NO; } return OOJSCallObjCObjectMethod(context, object, [object jsClassName], argc, argv, outResult); diff --git a/src/Core/Entities/PlanetEntity.m b/src/Core/Entities/PlanetEntity.m index 0521df43..3dfcbe43 100644 --- a/src/Core/Entities/PlanetEntity.m +++ b/src/Core/Entities/PlanetEntity.m @@ -2110,15 +2110,19 @@ double longitudeFromVector(Vector v) - (BOOL) goneNova { - return throw_sparks&&(velocity.x <= 0); + return throw_sparks && velocity.x <= 0; } - (void) setGoingNova:(BOOL) yesno inTime:(double)interval { throw_sparks = yesno; - if ((throw_sparks)&&(interval >= 0.0)) - velocity.x = interval; + if (throw_sparks) + { + OOLog(@"script.debug.setSunNovaIn", @"NOVA activated! time until Nova : %.1f s", interval); + velocity.x = fmax(interval, 0.0); + } + velocity.y = 0; velocity.z = 10000; } diff --git a/src/Core/Entities/PlayerEntityLegacyScriptEngine.m b/src/Core/Entities/PlayerEntityLegacyScriptEngine.m index e0f740a4..1cf94ebd 100644 --- a/src/Core/Entities/PlayerEntityLegacyScriptEngine.m +++ b/src/Core/Entities/PlayerEntityLegacyScriptEngine.m @@ -98,7 +98,6 @@ static NSString * const kOOLogDebugProcessSceneStringAddModel = @"script.debug.p static NSString * const kOOLogDebugProcessSceneStringAddLocalPlanet = @"script.debug.processSceneString.addLocalPlanet"; static NSString * const kOOLogDebugProcessSceneStringAddTargetPlanet = @"script.debug.processSceneString.addTargetPlanet"; static NSString * const kOOLogDebugProcessSceneStringAddBillboard = @"script.debug.processSceneString.addBillboard"; -static NSString * const kOOLogDebugSetSunNovaIn = @"script.debug.setSunNovaIn"; static NSString * const kOOLogTraceScriptAction = @"script.debug.trace.scriptAction"; static NSString * const kOOLogTraceTestCondition = @"script.debug.trace.testCondition"; @@ -2128,7 +2127,6 @@ static int scriptRandomSeed = -1; // ensure proper random function { double time_until_nova = [time_value doubleValue]; [[UNIVERSE sun] setGoingNova:YES inTime: time_until_nova]; - OOLog(kOOLogDebugSetSunNovaIn, @"NOVA activated! time until Nova : %.1f s", time_until_nova); } diff --git a/src/Core/Entities/ShipEntity.m b/src/Core/Entities/ShipEntity.m index 5781ed9a..2ed109a8 100644 --- a/src/Core/Entities/ShipEntity.m +++ b/src/Core/Entities/ShipEntity.m @@ -859,12 +859,10 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change ex_pos.z += dd * 6.0 * (randf() - 0.5); [escorter setPosition:ex_pos]; - [escorter setStatus:STATUS_IN_FLIGHT]; - [escorter setPrimaryRole:defaultRole]; //for mothership - [escorter setScanClass:scanClass]; // you are the same as I + if ([self bounty] == 0) [escorter setBounty:0]; // Avoid dirty escorts for clean mothers [UNIVERSE addEntity:escorter]; diff --git a/src/Core/OOCacheManager.m b/src/Core/OOCacheManager.m index 47f9a55e..a679af3a 100644 --- a/src/Core/OOCacheManager.m +++ b/src/Core/OOCacheManager.m @@ -64,7 +64,7 @@ static NSString * const kCacheKeyCaches = @"_caches"; enum { kEndianTagValue = 0x12345678UL, - kFormatVersionValue = 17 + kFormatVersionValue = 18 }; diff --git a/src/Core/Scripting/OOJSCall.m b/src/Core/Scripting/OOJSCall.m index c30b4228..6ef82284 100644 --- a/src/Core/Scripting/OOJSCall.m +++ b/src/Core/Scripting/OOJSCall.m @@ -78,11 +78,11 @@ BOOL OOJSCallObjCObjectMethod(JSContext *context, id object, NSString *jsClassNa if (type == kMethodTypeInvalid) { - OOReportJavaScriptError(context, @"%@.call(): method %@ cannot be called from JavaScript.", jsClassName, selectorString); + OOReportJSError(context, @"%@.call(): method %@ cannot be called from JavaScript.", jsClassName, selectorString); } else if (MethodExpectsParameter(type) && !haveParameter) { - OOReportJavaScriptError(context, @"%@.call(): method %@ requires a parameter.", jsClassName, selectorString); + OOReportJSError(context, @"%@.call(): method %@ requires a parameter.", jsClassName, selectorString); } else { @@ -116,7 +116,7 @@ BOOL OOJSCallObjCObjectMethod(JSContext *context, id object, NSString *jsClassNa } else { - OOReportJavaScriptError(context, @"%@.call(): %@ does not respond to method %@.", jsClassName, object, selectorString); + OOReportJSError(context, @"%@.call(): %@ does not respond to method %@.", jsClassName, object, selectorString); } return success; diff --git a/src/Core/Scripting/OOJSClock.m b/src/Core/Scripting/OOJSClock.m index 59dc08e3..7757822c 100644 --- a/src/Core/Scripting/OOJSClock.m +++ b/src/Core/Scripting/OOJSClock.m @@ -112,6 +112,7 @@ void InitOOJSClock(JSContext *context, JSObject *global) static JSBool ClockGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue) { + BOOL OK = NO; PlayerEntity *player = nil; double clockTime; @@ -122,55 +123,63 @@ static JSBool ClockGetProperty(JSContext *context, JSObject *this, jsval name, j switch (JSVAL_TO_INT(name)) { case kClock_absoluteSeconds: - JS_NewDoubleValue(context, [UNIVERSE getTime], outValue); + OK = JS_NewDoubleValue(context, [UNIVERSE getTime], outValue); break; case kClock_seconds: - JS_NewDoubleValue(context, clockTime, outValue); + OK = JS_NewDoubleValue(context, clockTime, outValue); break; case kClock_minutes: - JS_NewDoubleValue(context, floor(clockTime / 60.0), outValue); + OK = JS_NewDoubleValue(context, floor(clockTime / 60.0), outValue); break; case kClock_hours: - JS_NewDoubleValue(context, floor(clockTime / 3600.0), outValue); + OK = JS_NewDoubleValue(context, floor(clockTime / 3600.0), outValue); break; case kClock_secondsComponent: *outValue = INT_TO_JSVAL(fmod(clockTime, 60.0)); + OK = YES; break; case kClock_minutesComponent: *outValue = INT_TO_JSVAL(fmod(floor(clockTime / 60.0), 60.0)); + OK = YES; break; case kClock_hoursComponent: *outValue = INT_TO_JSVAL(fmod(floor(clockTime / 3600.0), 24.0)); + OK = YES; break; case kClock_days: case kClock_daysComponent: *outValue = INT_TO_JSVAL(floor(clockTime / 86400.0)); + OK = YES; break; case kClock_clockString: *outValue = [[player dial_clock] javaScriptValueInContext:context]; + OK = YES; break; case kClock_isAdjusting: *outValue = BOOLToJSVal([player clockAdjusting]); + OK = YES; break; default: - OOReportJavaScriptBadPropertySelector(context, @"Clock", JSVAL_TO_INT(name)); - return NO; + OOReportJSBadPropertySelector(context, @"Clock", JSVAL_TO_INT(name)); } - return YES; + return OK; } +// *** Methods *** + +// toString() : String static JSBool JSClockToString(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { *outResult = [[OOPlayerForScripting() dial_clock] javaScriptValueInContext:context]; @@ -178,13 +187,13 @@ static JSBool JSClockToString(JSContext *context, JSObject *this, uintN argc, js } +// clockStringForTime(time : Number) : String static JSBool ClockClockStringForTime(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { double time; - if (JS_ValueToNumber(context, argv[0], &time)) - { - *outResult = [ClockToString(time, NO) javaScriptValueInContext:context]; - } + if (EXPECT_NOT(!JS_ValueToNumber(context, argv[0], &time))) return NO; + + *outResult = [ClockToString(time, NO) javaScriptValueInContext:context]; return YES; } diff --git a/src/Core/Scripting/OOJSEntity.m b/src/Core/Scripting/OOJSEntity.m index a4307f88..d105a71d 100644 --- a/src/Core/Scripting/OOJSEntity.m +++ b/src/Core/Scripting/OOJSEntity.m @@ -207,7 +207,7 @@ BOOL EntityFromArgumentList(JSContext *context, NSString *scriptClass, NSString // Failed; report bad parameters, if given a class and function. if (scriptClass != nil && function != nil) { - OOReportJavaScriptWarning(context, @"%@.%@(): expected entity or universal ID, got %@.", scriptClass, function, [NSString stringWithJavaScriptParameters:argv count:1 inContext:context]); + OOReportJSWarning(context, @"%@.%@(): expected entity or universal ID, got %@.", scriptClass, function, [NSString stringWithJavaScriptParameters:argv count:1 inContext:context]); return NO; } } @@ -310,7 +310,7 @@ static JSBool EntityGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Entity", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Entity", JSVAL_TO_INT(name)); return NO; } @@ -338,7 +338,7 @@ static JSBool EntitySetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Entity", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Entity", JSVAL_TO_INT(name)); return NO; } diff --git a/src/Core/Scripting/OOJSGlobal.m b/src/Core/Scripting/OOJSGlobal.m index 77ce6765..b3b06531 100644 --- a/src/Core/Scripting/OOJSGlobal.m +++ b/src/Core/Scripting/OOJSGlobal.m @@ -135,7 +135,7 @@ static JSBool GlobalGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Global", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Global", JSVAL_TO_INT(name)); return NO; } @@ -144,6 +144,9 @@ static JSBool GlobalGetProperty(JSContext *context, JSObject *this, jsval name, } +// *** Methods *** + +// log([messageClass : String,] message : string, ...) static JSBool GlobalLog(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { NSString *message = nil; @@ -214,14 +217,11 @@ static JSBool GlobalRandomInhabitantsDescription(JSContext *context, JSObject *t { NSString *string = nil; Random_Seed aSeed; - JSBool isPlural; - - if (!JS_ValueToBoolean(context, argv[0], &isPlural)) - { - isPlural = NO; - } + JSBool isPlural = YES; - make_pseudo_random_seed( &aSeed); + if (!JS_ValueToBoolean(context, argv[0], &isPlural)) isPlural = NO; + + make_pseudo_random_seed(&aSeed); string = [UNIVERSE generateSystemInhabitants:aSeed plural:isPlural]; *outResult = [string javaScriptValueInContext:context]; diff --git a/src/Core/Scripting/OOJSMission.m b/src/Core/Scripting/OOJSMission.m index 98bedbe4..43eefb8a 100644 --- a/src/Core/Scripting/OOJSMission.m +++ b/src/Core/Scripting/OOJSMission.m @@ -119,7 +119,7 @@ static JSBool MissionGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Mission", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Mission", JSVAL_TO_INT(name)); return NO; } @@ -144,7 +144,7 @@ static JSBool MissionSetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Mission", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Mission", JSVAL_TO_INT(name)); return NO; } @@ -152,6 +152,9 @@ static JSBool MissionSetProperty(JSContext *context, JSObject *this, jsval name, } +// *** Methods *** + +// showMissionScreen() static JSBool MissionShowMissionScreen(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { PlayerEntity *player = OOPlayerForScripting(); @@ -162,6 +165,7 @@ static JSBool MissionShowMissionScreen(JSContext *context, JSObject *obj, uintN } +// showShipModel(modelName : String) static JSBool MissionShowShipModel(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { PlayerEntity *player = OOPlayerForScripting(); @@ -173,6 +177,7 @@ static JSBool MissionShowShipModel(JSContext *context, JSObject *obj, uintN argc } +// markSystem(systemCoords : String) static JSBool MissionMarkSystem(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { PlayerEntity *player = OOPlayerForScripting(); @@ -185,6 +190,7 @@ static JSBool MissionMarkSystem(JSContext *context, JSObject *obj, uintN argc, j } +// unmarkSystem(systemCoords : String) static JSBool MissionUnmarkSystem(JSContext *context, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { PlayerEntity *player = OOPlayerForScripting(); @@ -197,6 +203,7 @@ static JSBool MissionUnmarkSystem(JSContext *context, JSObject *obj, uintN argc, } +// addMessageTextKey(textKey : String) static JSBool MissionAddMessageTextKey(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -209,6 +216,7 @@ static JSBool MissionAddMessageTextKey(JSContext *context, JSObject *this, uintN } +// addMessageText(text : String) static JSBool MissionAddMessageText(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -221,6 +229,7 @@ static JSBool MissionAddMessageText(JSContext *context, JSObject *this, uintN ar } +// setBackgroundImage(imageName : String) static JSBool MissionSetBackgroundImage(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -233,6 +242,7 @@ static JSBool MissionSetBackgroundImage(JSContext *context, JSObject *this, uint } +// setMusic(musicName : String) static JSBool MissionSetMusic(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -245,6 +255,7 @@ static JSBool MissionSetMusic(JSContext *context, JSObject *this, uintN argc, js } +// setChoicesKey(choicesKey : String) static JSBool MissionSetChoicesKey(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -288,6 +299,7 @@ static JSBool MissionSetInstructionsKey(JSContext *context, JSObject *this, uint } +// clearMissionScreen() static JSBool MissionClearMissionScreen(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); diff --git a/src/Core/Scripting/OOJSMissionVariables.m b/src/Core/Scripting/OOJSMissionVariables.m index 6c57481a..fa5caaeb 100644 --- a/src/Core/Scripting/OOJSMissionVariables.m +++ b/src/Core/Scripting/OOJSMissionVariables.m @@ -100,8 +100,8 @@ static JSBool MissionVariablesGetProperty(JSContext *context, JSObject *this, js } if (isNumber) { - JSBool ok = JS_NewDoubleValue(context, [value doubleValue], outValue); - if (!ok) *outValue = JSVAL_VOID; + BOOL OK = JS_NewDoubleValue(context, [value doubleValue], outValue); + if (!OK) *outValue = JSVAL_VOID; } } @@ -120,7 +120,7 @@ static JSBool MissionVariablesGetProperty(JSContext *context, JSObject *this, js *outValue = JSVAL_NULL; } } - return JS_TRUE; + return YES; } @@ -135,5 +135,5 @@ static JSBool MissionVariablesSetProperty(JSContext *context, JSObject *this, js [player setMissionVariable:objValue forKey:key]; } - return JS_TRUE; + return YES; } diff --git a/src/Core/Scripting/OOJSOolite.m b/src/Core/Scripting/OOJSOolite.m index 6f4c3494..47044811 100644 --- a/src/Core/Scripting/OOJSOolite.m +++ b/src/Core/Scripting/OOJSOolite.m @@ -119,7 +119,7 @@ static JSBool OoliteGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Oolite", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Oolite", JSVAL_TO_INT(name)); return NO; } @@ -144,7 +144,7 @@ static NSArray *VersionComponents(void) returns -1 if the current version of Oolite is less than versionSpec, 0 if they are equal, and 1 if the current version is newer. versionSpec may be a string or an array. Example: - if (0 < oolite.compareVersion("1.70")) Log("Old version of Oolite!") + if (0 < oolite.compareVersion("1.70")) log("Old version of Oolite!") else this.doStuffThatRequires170() */ static JSBool OoliteCompareVersion(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) diff --git a/src/Core/Scripting/OOJSPlanet.m b/src/Core/Scripting/OOJSPlanet.m index 9a1a7945..1c92c63a 100644 --- a/src/Core/Scripting/OOJSPlanet.m +++ b/src/Core/Scripting/OOJSPlanet.m @@ -169,7 +169,7 @@ static JSBool PlanetGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Planet", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Planet", JSVAL_TO_INT(name)); return NO; } return YES; @@ -187,7 +187,7 @@ static JSBool PlanetSetProperty(JSContext *context, JSObject *this, jsval name, { default: - OOReportJavaScriptBadPropertySelector(context, @"Planet", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Planet", JSVAL_TO_INT(name)); return NO; } @@ -206,19 +206,19 @@ static JSBool PlanetSetTexture(JSContext *context, JSObject *this, uintN argc, j name = [NSString stringWithJavaScriptValue:*argv inContext:context]; if([player status] != STATUS_LAUNCHING && [player status] != STATUS_EXITING_WITCHSPACE) { - OOReportJavaScriptError(context, @"Planet.%@ must be called only during shipWillLaunchFromStation or shipWillExitWitchspace.", @"setTexture"); + OOReportJSError(context, @"Planet.%@ must be called only during shipWillLaunchFromStation or shipWillExitWitchspace.", @"setTexture"); return YES; } if (name != nil) { if (![thisEnt setUpPlanetFromTexture:name]) { - OOReportJavaScriptError(context, @"Planet.%@(\"%@\"): cannot set texture for planet.", @"setTexture", name); + OOReportJSError(context, @"Planet.%@(\"%@\"): cannot set texture for planet.", @"setTexture", name); } } else { - OOReportJavaScriptError(context, @"Planet.%@(): no texture name specified.", @"setTexture"); + OOReportJSError(context, @"Planet.%@(): no texture name specified.", @"setTexture"); } return YES; } diff --git a/src/Core/Scripting/OOJSPlayer.m b/src/Core/Scripting/OOJSPlayer.m index f05adb5d..950fad84 100644 --- a/src/Core/Scripting/OOJSPlayer.m +++ b/src/Core/Scripting/OOJSPlayer.m @@ -285,7 +285,7 @@ static JSBool PlayerGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Player", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Player", JSVAL_TO_INT(name)); return NO; } @@ -327,7 +327,7 @@ static JSBool PlayerSetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Player", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Player", JSVAL_TO_INT(name)); return NO; } @@ -367,7 +367,7 @@ static JSBool PlayerSetEquipmentStatus(JSContext *context, JSObject *this, uintN if ([UNIVERSE strict]) { - OOReportJavaScriptError(context, @"Cannot set equipment status while in strict mode."); + OOReportJSError(context, @"Cannot set equipment status while in strict mode."); *outResult = BOOLToJSVal(NO); return YES; } @@ -388,7 +388,7 @@ static JSBool PlayerSetEquipmentStatus(JSContext *context, JSObject *this, uintN statusSet = [OOPlayerForScripting() hasEquipmentItem:name] || [OOPlayerForScripting() hasEquipmentItem:damagedName]; } else - OOReportJavaScriptError(context, @"Second parameter for setEquipmentStatus must be either \"EQUIPMENT_OK\" or \"EQUIPMENT_DAMAGED\"."); + OOReportJSError(context, @"Second parameter for setEquipmentStatus must be either \"EQUIPMENT_OK\" or \"EQUIPMENT_DAMAGED\"."); *outResult = BOOLToJSVal(statusSet); @@ -429,26 +429,26 @@ static JSBool PlayerAwardCargo(JSContext *context, JSObject *this, uintN argc, j type = [UNIVERSE commodityForName:typeString]; if (type == NSNotFound) { - OOReportJavaScriptError(context, @"Unknown cargo type \"%@\".", typeString); + OOReportJSError(context, @"Unknown cargo type \"%@\".", typeString); return YES; } if (!JS_ValueToInt32(context, argv[1], &amount)) { - OOReportJavaScriptError(context, @"Expected cargo quantity (integer), got \"%@\".", JSValToNSString(context, argv[1])); + OOReportJSError(context, @"Expected cargo quantity (integer), got \"%@\".", JSValToNSString(context, argv[1])); return YES; } if (amount < 0) { - OOReportJavaScriptError(context, @"Cargo quantity (%i) is negative.", amount); + OOReportJSError(context, @"Cargo quantity (%i) is negative.", amount); return YES; } unit = [UNIVERSE unitsForCommodity:type]; if ([OOPlayerForScripting() specialCargo] != nil && unit == UNITS_TONS) { - OOReportJavaScriptError(context, @"Cargo hold full with special cargo, cannot award \"%@\".", typeString); + OOReportJSError(context, @"Cargo hold full with special cargo, cannot award \"%@\".", typeString); return YES; } @@ -468,7 +468,7 @@ static JSBool PlayerRemoveAllCargo(JSContext *context, JSObject *this, uintN arg } else { - OOReportJavaScriptError(context, @"Player.removeAllCargo() may only be called when the player is docked."); + OOReportJSError(context, @"Player.removeAllCargo() may only be called when the player is docked."); } return YES; } diff --git a/src/Core/Scripting/OOJSQuaternion.m b/src/Core/Scripting/OOJSQuaternion.m index 2fe6b2ab..c4de70bb 100644 --- a/src/Core/Scripting/OOJSQuaternion.m +++ b/src/Core/Scripting/OOJSQuaternion.m @@ -261,7 +261,7 @@ BOOL QuaternionFromArgumentList(JSContext *context, NSString *scriptClass, NSStr if (QuaternionFromArgumentListNoError(context, argc, argv, outQuaternion, outConsumed)) return YES; else { - OOReportJavaScriptBadArguments(context, scriptClass, function, argc, argv, + OOReportJSBadArguments(context, scriptClass, function, argc, argv, @"Could not construct quaternion from parameters", @"Quaternion, Entity or four numbers"); return NO; @@ -336,7 +336,7 @@ static JSBool QuaternionGetProperty(JSContext *context, JSObject *this, jsval na break; default: - OOReportJavaScriptBadPropertySelector(context, @"Quaternion", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Quaternion", JSVAL_TO_INT(name)); return NO; } @@ -372,7 +372,7 @@ static JSBool QuaternionSetProperty(JSContext *context, JSObject *this, jsval na break; default: - OOReportJavaScriptBadPropertySelector(context, @"Quaternion", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Quaternion", JSVAL_TO_INT(name)); return NO; } diff --git a/src/Core/Scripting/OOJSScript.m b/src/Core/Scripting/OOJSScript.m index 614283a3..b84fb55d 100644 --- a/src/Core/Scripting/OOJSScript.m +++ b/src/Core/Scripting/OOJSScript.m @@ -329,7 +329,7 @@ static JSFunctionSpec sScriptMethods[] = if (![notedChanges containsObject:key]) { [notedChanges addObject:key]; - OOReportJavaScriptWarning(context, @"The event handler %@ has been renamed to %@. The script %@ must be updated. The old form will not be supported in future versions of Oolite!", oldName, eventName, self->name); + OOReportJSWarning(context, @"The event handler %@ has been renamed to %@. The script %@ must be updated. The old form will not be supported in future versions of Oolite!", oldName, eventName, self->name); } } } diff --git a/src/Core/Scripting/OOJSShip.m b/src/Core/Scripting/OOJSShip.m index abbf2139..cf94a701 100644 --- a/src/Core/Scripting/OOJSShip.m +++ b/src/Core/Scripting/OOJSShip.m @@ -418,7 +418,7 @@ static JSBool ShipGetProperty(JSContext *context, JSObject *this, jsval name, js break; default: - OOReportJavaScriptBadPropertySelector(context, @"Ship", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Ship", JSVAL_TO_INT(name)); return NO; } @@ -445,7 +445,7 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsval name, js case kShip_shipDescription: if ([entity isPlayer]) { - OOReportJavaScriptError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"name", @"name"); + OOReportJSError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"name", @"name"); } else { @@ -457,7 +457,7 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsval name, js case kShip_shipDisplayName: if ([entity isPlayer]) { - OOReportJavaScriptError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"displayName", @"displayName"); + OOReportJSError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"displayName", @"displayName"); } else { @@ -469,7 +469,7 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsval name, js case kShip_primaryRole: if ([entity isPlayer]) { - OOReportJavaScriptError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"primaryRole", @"primary role"); + OOReportJSError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"primaryRole", @"primary role"); } else { @@ -481,7 +481,7 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsval name, js case kShip_AIState: if ([entity isPlayer]) { - OOReportJavaScriptError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"AIState", @"AI state"); + OOReportJSError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"AIState", @"AI state"); } else { @@ -553,7 +553,7 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsval name, js case kShip_desiredSpeed: if ([entity isPlayer]) { - OOReportJavaScriptError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"desiredSpeed", @"desired speed"); + OOReportJSError(context, @"Ship.%@ [setter]: cannot set %@ for player.", @"desiredSpeed", @"desired speed"); } else { @@ -565,7 +565,7 @@ static JSBool ShipSetProperty(JSContext *context, JSObject *this, jsval name, js break; default: - OOReportJavaScriptBadPropertySelector(context, @"Ship", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Ship", JSVAL_TO_INT(name)); return NO; } @@ -588,12 +588,12 @@ static JSBool ShipSetScript(JSContext *context, JSObject *this, uintN argc, jsva } else { - OOReportJavaScriptError(context, @"Ship.%@(\"%@\"): cannot set script for player.", @"setScript", name); + OOReportJSError(context, @"Ship.%@(\"%@\"): cannot set script for player.", @"setScript", name); } } else { - OOReportJavaScriptError(context, @"Ship.%@(): no script name specified.", @"setScript"); + OOReportJSError(context, @"Ship.%@(): no script name specified.", @"setScript"); } return YES; } @@ -614,12 +614,12 @@ static JSBool ShipSetAI(JSContext *context, JSObject *this, uintN argc, jsval *a } else { - OOReportJavaScriptError(context, @"Ship.%@(\"%@\"): cannot modify AI for player.", @"setAI", name); + OOReportJSError(context, @"Ship.%@(\"%@\"): cannot modify AI for player.", @"setAI", name); } } else { - OOReportJavaScriptError(context, @"Ship.%@(): no AI state machine specified.", @"setAI"); + OOReportJSError(context, @"Ship.%@(): no AI state machine specified.", @"setAI"); } return YES; } @@ -641,12 +641,12 @@ static JSBool ShipSwitchAI(JSContext *context, JSObject *this, uintN argc, jsval } else { - OOReportJavaScriptWarning(context, @"Ship.%@(\"%@\"): cannot modify AI for player.", @"switchAI", name); + OOReportJSWarning(context, @"Ship.%@(\"%@\"): cannot modify AI for player.", @"switchAI", name); } } else { - OOReportJavaScriptWarning(context, @"Ship.%@(): no AI state machine specified.", @"switchAI"); + OOReportJSWarning(context, @"Ship.%@(): no AI state machine specified.", @"switchAI"); } return YES; } @@ -668,12 +668,12 @@ static JSBool ShipExitAI(JSContext *context, JSObject *this, uintN argc, jsval * } else { - OOReportJavaScriptWarning(context, @"Ship.exitAI(): cannot cannot exit current AI state machine because there are no suspended state machines."); + OOReportJSWarning(context, @"Ship.exitAI(): cannot cannot exit current AI state machine because there are no suspended state machines."); } } else { - OOReportJavaScriptWarning(context, @"Ship.exitAI(): cannot modify AI for player."); + OOReportJSWarning(context, @"Ship.exitAI(): cannot modify AI for player."); } return YES; } @@ -695,12 +695,12 @@ static JSBool ShipReactToAIMessage(JSContext *context, JSObject *this, uintN arg } else { - OOReportJavaScriptWarning(context, @"Ship.%@(\"%@\"): cannot modify AI for player.", @"reactToAIMessage", message); + OOReportJSWarning(context, @"Ship.%@(\"%@\"): cannot modify AI for player.", @"reactToAIMessage", message); } } else { - OOReportJavaScriptWarning(context, @"Ship.%@(): no message specified.", @"reactToAIMessage"); + OOReportJSWarning(context, @"Ship.%@(): no message specified.", @"reactToAIMessage"); } return YES; } @@ -783,7 +783,7 @@ static JSBool ShipDumpCargo(JSContext *context, JSObject *this, uintN argc, jsva if ([thisEnt isPlayer] && [(PlayerEntity *)thisEnt isDocked]) { - OOReportJavaScriptWarning(context, @"Player.dumpCargo(): can't dump cargo while docked, ignoring."); + OOReportJSWarning(context, @"Player.dumpCargo(): can't dump cargo while docked, ignoring."); return YES; } @@ -806,7 +806,7 @@ static JSBool ShipSpawn(JSContext *context, JSObject *this, uintN argc, jsval *a role = [NSString stringWithJavaScriptValue:*argv inContext:context]; if (role == nil) { - OOReportJavaScriptError(context, @"Expected role (string), got \"%@\".", JSValToNSString(context, argv[0])); + OOReportJSError(context, @"Expected role (string), got \"%@\".", JSValToNSString(context, argv[0])); return YES; } @@ -814,7 +814,7 @@ static JSBool ShipSpawn(JSContext *context, JSObject *this, uintN argc, jsval *a { if (!JS_ValueToInt32(context, argv[1], &count) || count < 1) { - OOReportJavaScriptError(context, @"Expected spawn count (positive integer), got \"%@\".", JSValToNSString(context, argv[1])); + OOReportJSError(context, @"Expected spawn count (positive integer), got \"%@\".", JSValToNSString(context, argv[1])); return YES; } } @@ -872,14 +872,14 @@ static JSBool ShipRunLegacyScriptActions(JSContext *context, JSObject *this, uin target = JSValueToObject(context, argv[0]); if (![target isKindOfClass:[ShipEntity class]]) { - OOReportJavaScriptWarning(context, @"First argument of runLegacyScriptActions must be a Ship."); + OOReportJSWarning(context, @"First argument of runLegacyScriptActions must be a Ship."); return YES; } actions = JSValueToObject(context, argv[1]); if (![actions isKindOfClass:[NSArray class]]) { - OOReportJavaScriptWarning(context, @"Second argument of runLegacyScriptActions must be an Array."); + OOReportJSWarning(context, @"Second argument of runLegacyScriptActions must be an Array."); return YES; } diff --git a/src/Core/Scripting/OOJSSound.m b/src/Core/Scripting/OOJSSound.m index e3912aa2..d4c2cfce 100644 --- a/src/Core/Scripting/OOJSSound.m +++ b/src/Core/Scripting/OOJSSound.m @@ -146,7 +146,7 @@ static JSBool SoundGetProperty(JSContext *context, JSObject *this, jsval name, j break; default: - OOReportJavaScriptBadPropertySelector(context, @"Sound", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Sound", JSVAL_TO_INT(name)); return NO; } diff --git a/src/Core/Scripting/OOJSSoundSource.m b/src/Core/Scripting/OOJSSoundSource.m index 67e8c08b..58f813de 100644 --- a/src/Core/Scripting/OOJSSoundSource.m +++ b/src/Core/Scripting/OOJSSoundSource.m @@ -154,7 +154,7 @@ static JSBool SoundSourceGetProperty(JSContext *context, JSObject *this, jsval n break; default: - OOReportJavaScriptBadPropertySelector(context, @"SoundSource", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"SoundSource", JSVAL_TO_INT(name)); return NO; } @@ -194,7 +194,7 @@ static JSBool SoundSourceSetProperty(JSContext *context, JSObject *this, jsval n break; default: - OOReportJavaScriptBadPropertySelector(context, @"SoundSource", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"SoundSource", JSVAL_TO_INT(name)); return NO; } diff --git a/src/Core/Scripting/OOJSSpecialFunctions.m b/src/Core/Scripting/OOJSSpecialFunctions.m index 074fa484..d4ecc1ac 100644 --- a/src/Core/Scripting/OOJSSpecialFunctions.m +++ b/src/Core/Scripting/OOJSSpecialFunctions.m @@ -64,7 +64,7 @@ OOJSValue *JSSpecialFunctionsObjectWrapper(JSContext *context) static JSBool SpecialJsWarning(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { OOSetJSWarningOrErrorStackSkip(1); - OOReportJavaScriptWarning(context, @"%@", [NSString stringWithJavaScriptValue:argv[0] inContext:context]); + OOReportJSWarning(context, @"%@", [NSString stringWithJavaScriptValue:argv[0] inContext:context]); OOSetJSWarningOrErrorStackSkip(0); return YES; } diff --git a/src/Core/Scripting/OOJSStation.m b/src/Core/Scripting/OOJSStation.m index fba9b281..846c2fb9 100644 --- a/src/Core/Scripting/OOJSStation.m +++ b/src/Core/Scripting/OOJSStation.m @@ -150,7 +150,7 @@ static JSBool StationGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Station", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Station", JSVAL_TO_INT(name)); return NO; } return YES; @@ -184,7 +184,7 @@ static JSBool StationSetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Station", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Station", JSVAL_TO_INT(name)); return NO; } diff --git a/src/Core/Scripting/OOJSSun.m b/src/Core/Scripting/OOJSSun.m index 2ac9dcdb..56c4cc18 100644 --- a/src/Core/Scripting/OOJSSun.m +++ b/src/Core/Scripting/OOJSSun.m @@ -36,6 +36,8 @@ static BOOL JSSunGetPlanetEntity(JSContext *context, JSObject *SunObj, PlanetEnt static JSBool SunGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue); +static JSBool SunGoNova(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); +static JSBool SunCancelNova(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); static JSExtendedClass sSunClass = @@ -64,7 +66,9 @@ static JSExtendedClass sSunClass = enum { // Property IDs - kSun_radius, // Radius of sun in metres. + kSun_radius, // Radius of sun in metres, number, read-only + kSun_hasGoneNova, // Has sun gone nova, boolean, read-only + kSun_isGoingNova // Will sun go nova, boolean, read-only }; @@ -72,6 +76,8 @@ static JSPropertySpec sSunProperties[] = { // JS name ID flags { "radius", kSun_radius, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY }, + { "hasGoneNova", kSun_hasGoneNova, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY }, + { "isGoingNova", kSun_isGoingNova, JSPROP_PERMANENT | JSPROP_ENUMERATE | JSPROP_READONLY }, { 0 } }; @@ -79,6 +85,8 @@ static JSPropertySpec sSunProperties[] = static JSFunctionSpec sSunMethods[] = { // JS name Function min args + { "goNova", SunGoNova, 1 }, + { "cancelNova", SunCancelNova, 0 }, { 0 } }; @@ -116,21 +124,62 @@ static BOOL JSSunGetPlanetEntity(JSContext *context, JSObject *stationObj, Plane static JSBool SunGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue) { + BOOL OK = NO; PlanetEntity *sun = nil; if (!JSVAL_IS_INT(name)) return YES; - if (!JSSunGetPlanetEntity(context, this, &sun)) return NO; + if (EXPECT_NOT(!JSSunGetPlanetEntity(context, this, &sun))) return NO; switch (JSVAL_TO_INT(name)) { case kSun_radius: - JS_NewDoubleValue(context, [sun radius], outValue); + OK = JS_NewDoubleValue(context, [sun radius], outValue); + break; + + case kSun_hasGoneNova: + *outValue = BOOLToJSVal([sun goneNova]); + OK = YES; + break; + + case kSun_isGoingNova: + *outValue = BOOLToJSVal([sun willGoNova] && ![sun goneNova]); + OK = YES; break; default: - OOReportJavaScriptBadPropertySelector(context, @"Sun", JSVAL_TO_INT(name)); - return NO; + OOReportJSBadPropertySelector(context, @"Sun", JSVAL_TO_INT(name)); + } + return OK; +} + + +// *** Methods *** + +// goNova([delay : Number]) +static JSBool SunGoNova(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) +{ + PlanetEntity *sun = nil; + jsdouble delay = 0; + + if (EXPECT_NOT(!JSSunGetPlanetEntity(context, this, &sun))) return NO; + if (argc > 0 && EXPECT_NOT(!JS_ValueToNumber(context, argv[0], &delay))) return NO; + + [sun setGoingNova:YES inTime:delay]; + return YES; +} + + +// cancelNova() +static JSBool SunCancelNova(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) +{ + PlanetEntity *sun = nil; + + if (EXPECT_NOT(!JSSunGetPlanetEntity(context, this, &sun))) return NO; + + if ([sun willGoNova] && ![sun goneNova]) + { + [sun setGoingNova:NO inTime:0]; } return YES; } diff --git a/src/Core/Scripting/OOJSSystem.m b/src/Core/Scripting/OOJSSystem.m index 485ec0ca..64956245 100644 --- a/src/Core/Scripting/OOJSSystem.m +++ b/src/Core/Scripting/OOJSSystem.m @@ -62,7 +62,6 @@ static JSBool SystemToString(JSContext *context, JSObject *this, uintN argc, jsv static JSBool SystemAddPlanet(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); static JSBool SystemAddMoon(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); static JSBool SystemSendAllShipsAway(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); -static JSBool SystemSetSunNova(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); static JSBool SystemCountShipsWithRole(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); static JSBool SystemShipsWithPrimaryRole(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); static JSBool SystemShipsWithRole(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult); @@ -158,7 +157,6 @@ static JSFunctionSpec sSystemMethods[] = { "addPlanet", SystemAddPlanet, 1 }, { "addMoon", SystemAddMoon, 1 }, { "sendAllShipsAway", SystemSendAllShipsAway, 1 }, - { "setSunNova", SystemSetSunNova, 1 }, { "countShipsWithRole", SystemCountShipsWithRole, 1 }, { "shipsWithPrimaryRole", SystemShipsWithPrimaryRole, 1 }, { "shipsWithRole", SystemShipsWithRole, 1 }, @@ -306,7 +304,7 @@ static JSBool SystemGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"System", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"System", JSVAL_TO_INT(name)); return NO; } @@ -317,6 +315,7 @@ static JSBool SystemGetProperty(JSContext *context, JSObject *this, jsval name, static JSBool SystemSetProperty(JSContext *context, JSObject *this, jsval name, jsval *value) { + BOOL OK = NO; PlayerEntity *player = nil; OOGalaxyID galaxy; OOSystemID system; @@ -342,18 +341,30 @@ static JSBool SystemSetProperty(JSContext *context, JSObject *this, jsval name, { case kSystem_name: stringValue = JSValToNSString(context, *value); - if (stringValue != nil) [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_NAME value:stringValue]; + if (stringValue != nil) + { + [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_NAME value:stringValue]; + OK = YES; + } break; case kSystem_description: stringValue = JSValToNSString(context, *value); - if (stringValue != nil) [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_DESCRIPTION value:stringValue]; + if (stringValue != nil) + { + [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_DESCRIPTION value:stringValue]; + OK = YES; + } break; case kSystem_inhabitantsDescription: stringValue = JSValToNSString(context, *value); - if (stringValue != nil) [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_INHABITANTS value:stringValue]; - break; + if (stringValue != nil) + { + [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_INHABITANTS value:stringValue]; + OK = YES; + } + break; case kSystem_government: if (JS_ValueToInt32(context, *value, &iValue)) @@ -361,6 +372,7 @@ static JSBool SystemSetProperty(JSContext *context, JSObject *this, jsval name, if (iValue < 0) iValue = 0; if (7 < iValue) iValue = 7; [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_GOVERNMENT value:[NSNumber numberWithInt:iValue]]; + OK = YES; } break; @@ -370,6 +382,7 @@ static JSBool SystemSetProperty(JSContext *context, JSObject *this, jsval name, if (iValue < 0) iValue = 0; if (7 < iValue) iValue = 7; [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_ECONOMY value:[NSNumber numberWithInt:iValue]]; + OK = YES; } break; @@ -379,6 +392,7 @@ static JSBool SystemSetProperty(JSContext *context, JSObject *this, jsval name, if (iValue < 0) iValue = 0; if (15 < iValue) iValue = 15; [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_TECHLEVEL value:[NSNumber numberWithInt:iValue]]; + OK = YES; } break; @@ -386,6 +400,7 @@ static JSBool SystemSetProperty(JSContext *context, JSObject *this, jsval name, if (JS_ValueToInt32(context, *value, &iValue)) { [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_POPULATION value:[NSNumber numberWithInt:iValue]]; + OK = YES; } break; @@ -393,94 +408,99 @@ static JSBool SystemSetProperty(JSContext *context, JSObject *this, jsval name, if (JS_ValueToInt32(context, *value, &iValue)) { [UNIVERSE setSystemDataForGalaxy:galaxy planet:system key:KEY_PRODUCTIVITY value:[NSNumber numberWithInt:iValue]]; + OK = YES; } break; default: - OOReportJavaScriptBadPropertySelector(context, @"System", JSVAL_TO_INT(name)); - return NO; + OOReportJSBadPropertySelector(context, @"System", JSVAL_TO_INT(name)); } + + // Hmm, what are these for? Who put them here? -- Ahruman 20080523 [UNIVERSE generateSystemData:kNilRandomSeed]; [UNIVERSE generateSystemData:sCurrentSystem]; - return YES; + return OK; } // *** Methods *** +// toString() : String static JSBool SystemToString(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { - NSString *systemDesc = nil; - PlayerEntity *player = nil; + PlayerEntity *player = OOPlayerForScripting(); + NSString *systemDesc = nil; - player = [PlayerEntity sharedPlayer]; systemDesc = [NSString stringWithFormat:@"[System %u:%u \"%@\"]", [player currentGalaxyID], [player currentSystemID], [[UNIVERSE currentSystemData] objectForKey:KEY_NAME]]; *outResult = [systemDesc javaScriptValueInContext:context]; return YES; } +// addPlanet(key : String) static JSBool SystemAddPlanet(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { - PlayerEntity *player = OOPlayerForScripting(); + PlayerEntity *player = OOPlayerForScripting(); + NSString *key = nil; - if (argc > 0 && JSVAL_IS_STRING(argv[0])) + key = JSValToNSString(context, argv[0]); + if (EXPECT_NOT(key == nil)) { - NSString *key = JSValToNSString(context, argv[0]); - [player addPlanet:key]; + OOReportJSBadArguments(context, @"System", @"addPlanet", argc, argv, @"Expected planet key, got", nil); + return NO; } + + [player addPlanet:key]; return YES; } +// addMoon(key : String) static JSBool SystemAddMoon(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { - PlayerEntity *player = OOPlayerForScripting(); + PlayerEntity *player = OOPlayerForScripting(); + NSString *key = nil; - if (argc > 0 && JSVAL_IS_STRING(argv[0])) + key = JSValToNSString(context, argv[0]); + if (EXPECT_NOT(key == nil)) { - NSString *key = JSValToNSString(context, argv[0]); - [player addMoon:key]; + OOReportJSBadArguments(context, @"System", @"addMoon", argc, argv, @"Expected planet key, got", nil); + return NO; } + + [player addMoon:key]; return YES; } +// sendAllShipsAway() static JSBool SystemSendAllShipsAway(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); [player sendAllShipsAway]; - - return YES; -} - - -static JSBool SystemSetSunNova(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) -{ - PlayerEntity *player = OOPlayerForScripting(); - - NSString *key = JSValToNSString(context, argv[0]); - [player setSunNovaIn:key]; - return YES; } +// countShipsWithRole(role : String) : Number static JSBool SystemCountShipsWithRole(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { NSString *role = nil; - int count; role = JSValToNSString(context, argv[0]); - count = [UNIVERSE countShipsWithRole:role]; - *outResult = INT_TO_JSVAL(count); + if (EXPECT_NOT(role == nil)) + { + OOReportJSBadArguments(context, @"System", @"countShipsWithRole", argc, argv, @"Invalid arguments", @"role"); + return NO; + } + *outResult = INT_TO_JSVAL([UNIVERSE countShipsWithRole:role]); return YES; } -// function shipsWithPrimaryRole(role : String [, relativeTo : Entity [, range : Number]]) : Array (Entity) +// shipsWithPrimaryRole(role : String [, relativeTo : Entity [, range : Number]]) : Array (Entity) static JSBool SystemShipsWithPrimaryRole(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { NSString *role = nil; @@ -488,25 +508,31 @@ static JSBool SystemShipsWithPrimaryRole(JSContext *context, JSObject *this, uin double range = -1; NSArray *result = nil; - // Get role argument - if (argc >= 1) + role = JSValToNSString(context, *argv); + if (EXPECT_NOT(role == nil)) { - role = JSValToNSString(context, *argv); - argv++; argc--; + OOReportJSBadArguments(context, @"System", @"shipsWithPrimaryRole", argc, argv, @"Invalid arguments", @"role and optional reference entity and range"); + return NO; } // Get optional arguments - if (role != nil && !GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range)) role = nil; + if (!GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range)) return NO; // Search for entities - if (role != nil) result = FindShips(HasPrimaryRolePredicate, role, relativeTo, range); - - if (result != nil) *outResult = [result javaScriptValueInContext:context]; - return YES; + result = FindShips(HasPrimaryRolePredicate, role, relativeTo, range); + if (result != nil) + { + *outResult = [result javaScriptValueInContext:context]; + return YES; + } + else + { + return NO; + } } -// function shipsWithRole(role : String [, relativeTo : Entity [, range : Number]]) : Array (Entity) +// shipsWithRole(role : String [, relativeTo : Entity [, range : Number]]) : Array (Entity) static JSBool SystemShipsWithRole(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { NSString *role = nil; @@ -514,25 +540,31 @@ static JSBool SystemShipsWithRole(JSContext *context, JSObject *this, uintN argc double range = -1; NSArray *result = nil; - // Get role argument - if (argc >= 1) + role = JSValToNSString(context, *argv); + if (EXPECT_NOT(role == nil)) { - role = JSValToNSString(context, *argv); - argv++; argc--; + OOReportJSBadArguments(context, @"System", @"shipsWithRole", argc, argv, @"Invalid arguments", @"role and optional reference entity and range"); + return NO; } // Get optional arguments - if (role != nil && !GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range)) role = nil; + if (EXPECT_NOT(!GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range))) return NO; // Search for entities - if (role != nil) result = FindShips(HasRolePredicate, role, relativeTo, range); - - if (result != nil) *outResult = [result javaScriptValueInContext:context]; - return YES; + result = FindShips(HasRolePredicate, role, relativeTo, range); + if (result != nil) + { + *outResult = [result javaScriptValueInContext:context]; + return YES; + } + else + { + return NO; + } } -// function entitiesWithScanClass(scanClass : String [, relativeTo : Entity [, range : Number]]) : Array (Entity) +// entitiesWithScanClass(scanClass : String [, relativeTo : Entity [, range : Number]]) : Array (Entity) static JSBool SystemEntitiesWithScanClass(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { NSString *scString = nil; @@ -541,35 +573,38 @@ static JSBool SystemEntitiesWithScanClass(JSContext *context, JSObject *this, ui double range = -1; NSArray *result = nil; - // Get scan class argument - if (argc >= 1) + scString = JSValToNSString(context, *argv); + if (scString == nil) { - scString = JSValToNSString(context, *argv); - argv++; argc--; + OOReportJSBadArguments(context, @"System", @"entitiesWithScanClass", argc, argv, @"Invalid arguments", @"scan class and optional reference entity and range"); + return NO; } - if (scString != nil) + scanClass = StringToScanClass(scString); + if (EXPECT_NOT(scanClass == CLASS_NOT_SET)) { - scanClass = StringToScanClass(scString); - if (scanClass == CLASS_NOT_SET) - { - OOReportJavaScriptError(context, @"Invalid scan class specifier \"%@\"", scString); - return YES; - } + OOReportJSErrorForCaller(context, @"System", @"entitiesWithScanClass", @"Invalid scan class specifier \"%@\"", scString); + return NO; } // Get optional arguments - if (scanClass != CLASS_NOT_SET && !GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range)) scanClass = CLASS_NOT_SET; + if (EXPECT_NOT(!GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range))) return NO; // Search for entities - if (scanClass != CLASS_NOT_SET) result = FindJSVisibleEntities(HasScanClassPredicate, [NSNumber numberWithInt:scanClass], relativeTo, range); - - if (result != nil) *outResult = [result javaScriptValueInContext:context]; - return YES; + result = FindJSVisibleEntities(HasScanClassPredicate, [NSNumber numberWithInt:scanClass], relativeTo, range); + if (result != nil) + { + *outResult = [result javaScriptValueInContext:context]; + return YES; + } + else + { + return NO; + } } -// function filteredEntities(this : Object, predicate : Function [, relativeTo : Entity [, range : Number]]) : Array (Entity) +// filteredEntities(this : Object, predicate : Function [, relativeTo : Entity [, range : Number]]) : Array (Entity) static JSBool SystemFilteredEntities(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { JSObject *jsThis = NULL; @@ -579,26 +614,30 @@ static JSBool SystemFilteredEntities(JSContext *context, JSObject *this, uintN a NSArray *result = nil; // Get this and predicate arguments - if (argc >= 2) + function = JS_ValueToFunction(context, argv[1]); + if (EXPECT_NOT(function == NULL || !JS_ValueToObject(context, argv[0], &jsThis))) { - function = JS_ValueToFunction(context, argv[1]); - if (function != NULL && !JS_ValueToObject(context, argv[0], &jsThis)) function = NULL; - argv += 2; argc -= 2; + OOReportJSBadArguments(context, @"System", @"filteredEntities", argc, argv, @"Invalid arguments", @"this, predicate function, and optional reference entity and range"); + return NO; } // Get optional arguments - if (function != NULL && !GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range)) function = NULL; + if (EXPECT_NOT(!GetRelativeToAndRange(context, &argc, &argv, &relativeTo, &range))) return NO; // Search for entities - if (function != NULL) - { - JSFunctionPredicateParameter param = { context, function, jsThis, NO }; - result = FindJSVisibleEntities(JSFunctionPredicate, ¶m, relativeTo, range); - if (param.errorFlag) result = nil; // Exception in predicate - } + JSFunctionPredicateParameter param = { context, function, jsThis, NO }; + result = FindJSVisibleEntities(JSFunctionPredicate, ¶m, relativeTo, range); + if (EXPECT_NOT(param.errorFlag)) return NO; - if (result != nil) *outResult = [result javaScriptValueInContext:context]; - return YES; + if (result != nil) + { + *outResult = [result javaScriptValueInContext:context]; + return YES; + } + else + { + return NO; + } } @@ -616,7 +655,7 @@ static JSBool SystemAddShips(JSContext *context, JSObject *this, uintN argc, jsv role = JSValToNSString(context, argv[0]); if (!JS_ValueToInt32(context, argv[1], &count) || count < 1 || 64 < count) { - OOReportJavaScriptError(context, @"System.%@(): expected positive count, got %@.", @"addShips", JSValToNSString(context, argv[1])); + OOReportJSError(context, @"System.%@(): expected positive count, got %@.", @"addShips", JSValToNSString(context, argv[1])); return YES; } @@ -630,23 +669,25 @@ static JSBool SystemAddShips(JSContext *context, JSObject *this, uintN argc, jsv } // Note: need a way to specify the use of witchspace-in effects (as in legacy_addShips). - OOReportJavaScriptError(context, @"System.addShips(): not implemented."); + OOReportJSError(context, @"System.addShips(): not implemented."); return YES; } #endif - +// legacy_addShips(role : String, count : Number) static JSBool SystemLegacyAddShips(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { NSString *role = nil; int32 count; role = JSValToNSString(context, argv[0]); - if (!JS_ValueToInt32(context, argv[1], &count) || count < 1 || 64 < count) + if (EXPECT_NOT(role == nil || + !JS_ValueToInt32(context, argv[1], &count) || + count < 1 || 64 < count)) { - OOReportJavaScriptError(context, @"System.%@(): expected positive count, got %@.", @"legacy_addShips", JSValToNSString(context, argv[1])); - return YES; + OOReportJSBadArguments(context, @"System", @"legacy_addShips", argc, argv, @"Invalid arguments", @"role and positive count no greater than 64"); + return NO; } while (count--) [UNIVERSE witchspaceShipWithPrimaryRole:role]; @@ -655,6 +696,7 @@ static JSBool SystemLegacyAddShips(JSContext *context, JSObject *this, uintN arg } +// legacy_addSystemShips(role : String, count : Number, location : Number) static JSBool SystemLegacyAddSystemShips(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { jsdouble position; @@ -662,19 +704,22 @@ static JSBool SystemLegacyAddSystemShips(JSContext *context, JSObject *this, uin int32 count; role = JSValToNSString(context, argv[0]); - if (!JS_ValueToInt32(context, argv[1], &count) || count < 1 || 64 < count) + if (EXPECT_NOT(role == nil || + !JS_ValueToInt32(context, argv[1], &count) || + count < 1 || 64 < count || + !JS_ValueToNumber(context, argv[2], &position))) { - OOReportJavaScriptError(context, @"System.%@(): expected positive count, got %@.", @"legacy_addSystemShips", JSValToNSString(context, argv[1])); - return YES; + OOReportJSBadArguments(context, @"System", @"legacy_addSystemShips", argc, argv, @"Invalid arguments", @"role, positive count no greater than 64, and position along route"); + return NO; } - JS_ValueToNumber(context, argv[2], &position); while (count--) [UNIVERSE addShipWithRole:role nearRouteOneAt:position]; return YES; } +// legacy_addShipsAt(role : String, count : Number, coordScheme : Number, coords : vectorExpression) static JSBool SystemLegacyAddShipsAt(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -685,15 +730,16 @@ static JSBool SystemLegacyAddShipsAt(JSContext *context, JSObject *this, uintN a NSString *arg = nil; role = JSValToNSString(context, argv[0]); - if (!JS_ValueToInt32(context, argv[1], &count) || count < 1 || 64 < count) - { - OOReportJavaScriptError(context, @"System.%@(): expected positive count, got %@.", @"legacy_addShipsAt", JSValToNSString(context, argv[1])); - return YES; - } - coordScheme = JSValToNSString(context, argv[2]); - - if (!VectorFromArgumentList(context, @"System", @"legacy_addShipsAt", argc - 3, argv + 3, &where, NULL)) return YES; + if (EXPECT_NOT(role == nil || + !JS_ValueToInt32(context, argv[1], &count) || + count < 1 || 64 < count || + coordScheme == nil || + !VectorFromArgumentListNoError(context, argc - 3, argv + 3, &where, NULL))) + { + OOReportJSBadArguments(context, @"System", @"legacy_addShipsAt", argc, argv, @"Invalid arguments", @"role, positive count no greater than 64, coordinate scheme and coordinates"); + return NO; + } arg = [NSString stringWithFormat:@"%@ %d %@ %f %f %f", role, count, coordScheme, where.x, where.y, where.z]; [player addShipsAt:arg]; @@ -702,6 +748,7 @@ static JSBool SystemLegacyAddShipsAt(JSContext *context, JSObject *this, uintN a } +// legacy_addShipsAtPrecisely(role : String, count : Number, coordScheme : Number, coords : vectorExpression) static JSBool SystemLegacyAddShipsAtPrecisely(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -712,15 +759,16 @@ static JSBool SystemLegacyAddShipsAtPrecisely(JSContext *context, JSObject *this NSString *arg = nil; role = JSValToNSString(context, argv[0]); - if (!JS_ValueToInt32(context, argv[1], &count) || count < 1 || 64 < count) - { - OOReportJavaScriptError(context, @"System.%@(): expected positive count, got %@.", @"legacy_addShipsAtPrecisely", JSValToNSString(context, argv[1])); - return YES; - } - coordScheme = JSValToNSString(context, argv[2]); - - if (!VectorFromArgumentList(context, @"System", @"legacy_addShipsAtPrecisely", argc - 3, argv + 3, &where, NULL)) return YES; + if (EXPECT_NOT(role == nil || + !JS_ValueToInt32(context, argv[1], &count) || + count < 1 || 64 < count || + coordScheme == nil || + !VectorFromArgumentListNoError(context, argc - 3, argv + 3, &where, NULL))) + { + OOReportJSBadArguments(context, @"System", @"legacy_addShipsAtPrecisely", argc, argv, @"Invalid arguments", @"role, positive count no greater than 64, coordinate scheme and coordinates"); + return NO; + } arg = [NSString stringWithFormat:@"%@ %d %@ %f %f %f", role, count, coordScheme, where.x, where.y, where.z]; [player addShipsAtPrecisely:arg]; @@ -729,6 +777,7 @@ static JSBool SystemLegacyAddShipsAtPrecisely(JSContext *context, JSObject *this } +// legacy_addShipsWithinRadius(role : String, count : Number, coordScheme : Number, coords : vectorExpression, radius : Number) static JSBool SystemLegacyAddShipsWithinRadius(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { PlayerEntity *player = OOPlayerForScripting(); @@ -741,18 +790,17 @@ static JSBool SystemLegacyAddShipsWithinRadius(JSContext *context, JSObject *thi uintN consumed = 0; role = JSValToNSString(context, argv[0]); - if (!JS_ValueToInt32(context, argv[1], &count) || count < 1 || 64 < count) - { - OOReportJavaScriptError(context, @"System.%@(): expected positive count, got %@.", @"legacy_addShipWithinRadius", JSValToNSString(context, argv[1])); - return YES; - } - coordScheme = JSValToNSString(context, argv[2]); - - if (!VectorFromArgumentList(context, @"System", @"legacy_addShipWithinRadius", argc - 3, argv + 3, &where, &consumed)) return YES; - argc += consumed; - argv += consumed; - JS_ValueToNumber(context, argv[3], &radius); + if (EXPECT_NOT(role == nil || + !JS_ValueToInt32(context, argv[1], &count) || + count < 1 || 64 < count || + coordScheme == nil || + !VectorFromArgumentListNoError(context, argc - 3, argv + 3, &where, &consumed) || + !JS_ValueToNumber(context, argv[3 + consumed], &radius))) + { + OOReportJSBadArguments(context, @"System", @"legacy_addShipWithinRadius", argc, argv, @"Invalid arguments", @"role, positive count no greater than 64, coordinate scheme, coordinates and radius"); + return NO; + } arg = [NSString stringWithFormat:@"%@ %d %@ %f %f %f %f", role, count, coordScheme, where.x, where.y, where.z, radius]; [player addShipsWithinRadius:arg]; @@ -761,15 +809,26 @@ static JSBool SystemLegacyAddShipsWithinRadius(JSContext *context, JSObject *thi } +// legacy_spawnShip(key : string) static JSBool SystemLegacySpawnShip(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { - PlayerEntity *player = OOPlayerForScripting(); + NSString *key = nil; + OOPlayerForScripting(); // For backwards-compatibility - [player spawnShip:JSValToNSString(context, argv[0])]; + key = JSValToNSString(context, argv[0]); + if (key == nil) + { + OOReportJSBadArguments(context, @"System", @"legacy_addShipWithinRadius", argc, argv, @"Invalid arguments", @"ship key"); + return NO; + } + + [UNIVERSE spawnShip:key]; return YES; } +// *** Helper functions *** + static BOOL GetRelativeToAndRange(JSContext *context, uintN *ioArgc, jsval **ioArgv, Entity **outRelativeTo, double *outRange) { // No NULL arguments accepted. @@ -850,7 +909,7 @@ static JSBool SystemStaticSystemNameForID(JSContext *context, JSObject *this, ui if (!JS_ValueToInt32(context, argv[0], &systemID) || systemID < 0 || 255 < systemID) { - OOReportJavaScriptError(context, @"%@(): expected system ID from 0 to 255, got %@.", @"systemNameForID", JSValToNSString(context, argv[0])); + OOReportJSError(context, @"%@(): expected system ID from 0 to 255, got %@.", @"systemNameForID", JSValToNSString(context, argv[0])); return YES; } diff --git a/src/Core/Scripting/OOJSTimer.m b/src/Core/Scripting/OOJSTimer.m index 89a46ad4..da6640a9 100644 --- a/src/Core/Scripting/OOJSTimer.m +++ b/src/Core/Scripting/OOJSTimer.m @@ -249,54 +249,56 @@ static BOOL JSTimerGetTimer(JSContext *context, JSObject *entityObj, OOJSTimer * static JSBool TimerGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue) { OOJSTimer *timer = nil; + BOOL OK = NO; if (!JSVAL_IS_INT(name)) return YES; - if (!JSTimerGetTimer(context, this, &timer)) return NO; + if (EXPECT_NOT(!JSTimerGetTimer(context, this, &timer))) return NO; switch (JSVAL_TO_INT(name)) { case kTimer_nextTime: - JS_NewDoubleValue(context, [timer nextTime], outValue); - break; + OK = JS_NewDoubleValue(context, [timer nextTime], outValue); case kTimer_interval: - JS_NewDoubleValue(context, [timer interval], outValue); - break; + OK = JS_NewDoubleValue(context, [timer interval], outValue); case kTimer_isPersistent: *outValue = BOOLToJSVal([timer isPersistent]); + OK = YES; break; case kTimer_isRunning: *outValue = BOOLToJSVal([timer isScheduled]); + OK = YES; break; default: - OOReportJavaScriptBadPropertySelector(context, @"Timer", JSVAL_TO_INT(name)); - return NO; + OOReportJSBadPropertySelector(context, @"Timer", JSVAL_TO_INT(name)); } - return YES; + return OK; } static JSBool TimerSetProperty(JSContext *context, JSObject *this, jsval name, jsval *value) { + BOOL OK = YES; OOJSTimer *timer = nil; double fValue; JSBool bValue; if (!JSVAL_IS_INT(name)) return YES; - if (!JSTimerGetTimer(context, this, &timer)) return NO; + if (EXPECT_NOT(!JSTimerGetTimer(context, this, &timer))) return NO; switch (JSVAL_TO_INT(name)) { case kTimer_nextTime: if (JS_ValueToNumber(context, *value, &fValue)) { + OK = YES; if (![timer setNextTime:fValue]) { - OOReportJavaScriptWarning(context, @"Ignoring attempt to change next fire time for running timer %@.", timer); + OOReportJSWarning(context, @"Ignoring attempt to change next fire time for running timer %@.", timer); } } break; @@ -304,6 +306,7 @@ static JSBool TimerSetProperty(JSContext *context, JSObject *this, jsval name, j case kTimer_interval: if (JS_ValueToNumber(context, *value, &fValue)) { + OK = YES; [timer setInterval:fValue]; } break; @@ -311,16 +314,16 @@ static JSBool TimerSetProperty(JSContext *context, JSObject *this, jsval name, j case kTimer_isPersistent: if (JS_ValueToBoolean(context, *value, &bValue)) { + OK = YES; [timer setPersistent:bValue]; } break; default: - OOReportJavaScriptBadPropertySelector(context, @"Timer", JSVAL_TO_INT(name)); - return NO; + OOReportJSBadPropertySelector(context, @"Timer", JSVAL_TO_INT(name)); } - return YES; + return OK; } @@ -332,7 +335,7 @@ static void TimerFinalize(JSContext *context, JSObject *this) { if ([timer isScheduled]) { - OOReportJavaScriptWarning(context, @"Timer %@ is being garbage-collected while still running. You must keep a reference to all running timers, or they will stop unpredictably!", timer); + OOReportJSWarning(context, @"Timer %@ is being garbage-collected while still running. You must keep a reference to all running timers, or they will stop unpredictably!", timer); } [timer release]; JS_SetPrivate(context, this, NULL); @@ -353,25 +356,22 @@ static JSBool TimerConstruct(JSContext *context, JSObject *inThis, uintN argc, j { if (!JS_ValueToObject(context, argv[0], &this)) { - // Should be TypeException, but SpiderMonkey doesn't seem to have a sane way to throw exceptions at the moment. - OOReportJavaScriptError(context, @"Could not construct Timer because %@ argument ('%@') is not %@.", "first", "this", "an object"); - return YES; + OOReportJSError(context, @"Could not construct Timer because %@ argument ('%@') is not %@.", "first", "this", "an object"); + return NO; } } function = JS_ValueToFunction(context, argv[1]); if (function == NULL) { - // Should be TypeException, but SpiderMonkey doesn't seem to have a sane way to throw exceptions at the moment. - OOReportJavaScriptError(context, @"Could not construct Timer because %@ argument ('%@') is not %@.", "second", "function", "a function"); - return YES; + OOReportJSError(context, @"Could not construct Timer because %@ argument ('%@') is not %@.", "second", "function", "a function"); + return NO; } if (!JS_ValueToNumber(context, argv[2], &delay)) { - // Should be TypeException, but SpiderMonkey doesn't seem to have a sane way to throw exceptions at the moment. - OOReportJavaScriptError(context, @"Could not construct Timer because %@ argument ('%@') is not %@.", "third", "delay", "a number"); - return YES; + OOReportJSError(context, @"Could not construct Timer because %@ argument ('%@') is not %@.", "third", "delay", "a number"); + return NO; } // Fourth argument is optional. @@ -395,23 +395,27 @@ static JSBool TimerConstruct(JSContext *context, JSObject *inThis, uintN argc, j } -// Methods +// *** Methods *** + +// start() : Boolean static JSBool TimerStart(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { OOJSTimer *thisTimer = nil; - if (JSTimerGetTimer(context, this, &thisTimer)) *outResult = BOOLToJSVal([thisTimer scheduleTimer]); - else *outResult = JSVAL_TRUE; + if (EXPECT_NOT(!JSTimerGetTimer(context, this, &thisTimer))) return NO; + *outResult = BOOLToJSVal([thisTimer scheduleTimer]); return YES; } +// stop() static JSBool TimerStop(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult) { OOJSTimer *thisTimer = nil; - if (JSTimerGetTimer(context, this, &thisTimer)) [thisTimer unscheduleTimer]; + if (EXPECT_NOT(!JSTimerGetTimer(context, this, &thisTimer))) return NO; + [thisTimer unscheduleTimer]; return YES; } diff --git a/src/Core/Scripting/OOJSVector.m b/src/Core/Scripting/OOJSVector.m index f60f4303..a927385c 100644 --- a/src/Core/Scripting/OOJSVector.m +++ b/src/Core/Scripting/OOJSVector.m @@ -276,7 +276,7 @@ BOOL VectorFromArgumentList(JSContext *context, NSString *scriptClass, NSString if (VectorFromArgumentListNoError(context, argc, argv, outVector, outConsumed)) return YES; else { - OOReportJavaScriptBadArguments(context, scriptClass, function, argc, argv, + OOReportJSBadArguments(context, scriptClass, function, argc, argv, @"Could not construct vector from parameters", @"Vector, Entity or three numbers"); return NO; @@ -346,7 +346,7 @@ static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Vector", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Vector", JSVAL_TO_INT(name)); return NO; } @@ -378,7 +378,7 @@ static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsval name, break; default: - OOReportJavaScriptBadPropertySelector(context, @"Vector", JSVAL_TO_INT(name)); + OOReportJSBadPropertySelector(context, @"Vector", JSVAL_TO_INT(name)); return NO; } @@ -723,7 +723,7 @@ static JSBool VectorStaticInterpolate(JSContext *context, JSObject *this, uintN return VectorToJSValue(context, result, outResult); INSUFFICIENT_ARGUMENTS: - OOReportJavaScriptBadArguments(context, @"Vector", @"interpolate", inArgc, inArgv, + OOReportJSBadArguments(context, @"Vector", @"interpolate", inArgc, inArgv, @"Insufficient parameters", @"vector expression, vector expression and number"); return NO; diff --git a/src/Core/Scripting/OOJSWorldScripts.m b/src/Core/Scripting/OOJSWorldScripts.m index fee88cd5..d4de0e44 100644 --- a/src/Core/Scripting/OOJSWorldScripts.m +++ b/src/Core/Scripting/OOJSWorldScripts.m @@ -105,7 +105,7 @@ static JSBool WorldScriptsEnumerate(JSContext *context, JSObject *object) for (nameEnum = [names objectEnumerator]; (name = [nameEnum nextObject]); ) { - JS_DefineProperty(context, object, [name UTF8String], JSVAL_NULL, WorldScriptsGetProperty, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT); + if (!JS_DefineProperty(context, object, [name UTF8String], JSVAL_NULL, WorldScriptsGetProperty, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) return NO; } return YES; diff --git a/src/Core/Scripting/OOJavaScriptEngine.h b/src/Core/Scripting/OOJavaScriptEngine.h index 104f4efe..450c12cd 100644 --- a/src/Core/Scripting/OOJavaScriptEngine.h +++ b/src/Core/Scripting/OOJavaScriptEngine.h @@ -84,16 +84,21 @@ enum @end -void OOReportJavaScriptError(JSContext *context, NSString *format, ...); -void OOReportJavaScriptErrorWithArguments(JSContext *context, NSString *format, va_list args); -void OOReportJavaScriptErrorForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...); +/* Error and warning reporters. + + Note that after reporting an error in a JavaScript callback, the caller + must return NO to signal an error. +*/ +void OOReportJSError(JSContext *context, NSString *format, ...); +void OOReportJSErrorWithArguments(JSContext *context, NSString *format, va_list args); +void OOReportJSErrorForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...); -void OOReportJavaScriptWarning(JSContext *context, NSString *format, ...); -void OOReportJavaScriptWarningWithArguments(JSContext *context, NSString *format, va_list args); -void OOReportJavaScriptWarningForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...); +void OOReportJSWarning(JSContext *context, NSString *format, ...); +void OOReportJSWarningWithArguments(JSContext *context, NSString *format, va_list args); +void OOReportJSWarningForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...); -void OOReportJavaScriptBadPropertySelector(JSContext *context, NSString *className, jsint selector); -void OOReportJavaScriptBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription); +void OOReportJSBadPropertySelector(JSContext *context, NSString *className, jsint selector); +void OOReportJSBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription); /* OOSetJSWarningOrErrorStackSkip() diff --git a/src/Core/Scripting/OOJavaScriptEngine.m b/src/Core/Scripting/OOJavaScriptEngine.m index a72a5239..8f9d8050 100644 --- a/src/Core/Scripting/OOJavaScriptEngine.m +++ b/src/Core/Scripting/OOJavaScriptEngine.m @@ -444,17 +444,17 @@ static NSString *CallerPrefix(NSString *scriptClass, NSString *function) } -void OOReportJavaScriptError(JSContext *context, NSString *format, ...) +void OOReportJSError(JSContext *context, NSString *format, ...) { va_list args; va_start(args, format); - OOReportJavaScriptErrorWithArguments(context, format, args); + OOReportJSErrorWithArguments(context, format, args); va_end(args); } -void OOReportJavaScriptErrorForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...) +void OOReportJSErrorForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...) { va_list args; NSString *msg = nil; @@ -463,12 +463,12 @@ void OOReportJavaScriptErrorForCaller(JSContext *context, NSString *scriptClass, msg = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); - OOReportJavaScriptError(context, @"%@%@", CallerPrefix(scriptClass, function), msg); + OOReportJSError(context, @"%@%@", CallerPrefix(scriptClass, function), msg); [msg release]; } -void OOReportJavaScriptErrorWithArguments(JSContext *context, NSString *format, va_list args) +void OOReportJSErrorWithArguments(JSContext *context, NSString *format, va_list args) { NSString *msg = nil; @@ -478,17 +478,17 @@ void OOReportJavaScriptErrorWithArguments(JSContext *context, NSString *format, } -void OOReportJavaScriptWarning(JSContext *context, NSString *format, ...) +void OOReportJSWarning(JSContext *context, NSString *format, ...) { va_list args; va_start(args, format); - OOReportJavaScriptWarningWithArguments(context, format, args); + OOReportJSWarningWithArguments(context, format, args); va_end(args); } -void OOReportJavaScriptWarningForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...) +void OOReportJSWarningForCaller(JSContext *context, NSString *scriptClass, NSString *function, NSString *format, ...) { va_list args; NSString *msg = nil; @@ -497,12 +497,12 @@ void OOReportJavaScriptWarningForCaller(JSContext *context, NSString *scriptClas msg = [[NSString alloc] initWithFormat:format arguments:args]; va_end(args); - OOReportJavaScriptWarning(context, @"%@%@", CallerPrefix(scriptClass, function), msg); + OOReportJSWarning(context, @"%@%@", CallerPrefix(scriptClass, function), msg); [msg release]; } -void OOReportJavaScriptWarningWithArguments(JSContext *context, NSString *format, va_list args) +void OOReportJSWarningWithArguments(JSContext *context, NSString *format, va_list args) { NSString *msg = nil; @@ -512,18 +512,18 @@ void OOReportJavaScriptWarningWithArguments(JSContext *context, NSString *format } -void OOReportJavaScriptBadPropertySelector(JSContext *context, NSString *className, jsint selector) +void OOReportJSBadPropertySelector(JSContext *context, NSString *className, jsint selector) { - OOReportJavaScriptError(context, @"Internal error: bad property identifier %i in property accessor for class %@.", selector, className); + OOReportJSError(context, @"Internal error: bad property identifier %i in property accessor for class %@.", selector, className); } -void OOReportJavaScriptBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription) +void OOReportJSBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription) { message = [NSString stringWithFormat:@"%@ %@", message, [NSString stringWithJavaScriptParameters:argv count:argc inContext:context]]; if (expectedArgsDescription != nil) message = [NSString stringWithFormat:@"%@ -- expected %@", message, expectedArgsDescription]; - OOReportJavaScriptErrorForCaller(context, scriptClass, function, @"%@.", message); + OOReportJSErrorForCaller(context, scriptClass, function, @"%@.", message); } @@ -538,7 +538,7 @@ BOOL NumberFromArgumentList(JSContext *context, NSString *scriptClass, NSString if (NumberFromArgumentListNoError(context, argc, argv, outNumber, outConsumed)) return YES; else { - OOReportJavaScriptBadArguments(context, scriptClass, function, argc, argv, + OOReportJSBadArguments(context, scriptClass, function, argc, argv, @"Expected number, got", NULL); return NO; }