Started deploying profiling and thread-safety macros - even if they don't work in Windows, they're useful elsewhere. Profiling is now used on all Vector3D and Quaternion methods, all System methods, and the hot path for System.addShips(). Disabled aggressive JS GC testing in Mac TestRelease builds, so that profiling results are vaguely useful.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3623 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2010-06-27 13:25:08 +00:00
parent 428c5a5f02
commit 18bebd07c7
10 changed files with 987 additions and 465 deletions

View File

@ -182,7 +182,7 @@ this.macros =
// **** Convenience functions -- copy this script and add your own here.
// List the enumerable properties of an object.
this.dumpObjectShort = function (x)
this.dumpObjectShort = function dumpObjectShort(x)
{
consoleMessage("dumpObject", x.toString() + ":");
for (var prop in x)
@ -195,7 +195,7 @@ this.dumpObjectShort = function (x)
}
this.performLegacyCommand = function (x)
this.performLegacyCommand = function performLegacyCommand(x)
{
var [command, params] = x.getOneToken();
return player.ship.call(command, params);
@ -203,7 +203,7 @@ this.performLegacyCommand = function (x)
// List the enumerable properties of an object, and their values.
this.dumpObjectLong = function (x)
this.dumpObjectLong = function dumpObjectLong(x)
{
consoleMessage("dumpObject", x.toString() + ":");
for (var prop in x)
@ -217,7 +217,7 @@ this.dumpObjectLong = function (x)
// Print the objects in a list on lines.
this.printList = function (l)
this.printList = function printList(l)
{
var length = l.length;
@ -229,7 +229,7 @@ this.printList = function (l)
}
this.setColorFromString = function (string, typeName)
this.setColorFromString = function setColorFromString(string, typeName)
{
// Slice of the first component, where components are separated by one or more spaces.
var [key, value] = string.getOneToken();
@ -247,7 +247,7 @@ this.setColorFromString = function (string, typeName)
// **** Conosole command handler
this.consolePerformJSCommand = function (command)
this.consolePerformJSCommand = function consolePerformJSCommand(command)
{
var originalCommand = command;
while (command.charAt(0) == " ")
@ -290,7 +290,7 @@ this.consolePerformJSCommand = function (command)
}
this.evaluate = function (command, type, PARAM)
this.evaluate = function evaluate(command, type, PARAM)
{
var result = eval(command);
if (result !== undefined)
@ -304,7 +304,7 @@ this.evaluate = function (command, type, PARAM)
// **** Macro handling
this.setMacro = function (parameters)
this.setMacro = function setMacro(parameters)
{
if (!parameters) return;
@ -325,7 +325,7 @@ this.setMacro = function (parameters)
}
this.deleteMacro = function (parameters)
this.deleteMacro = function deleteMacro(parameters)
{
if (!parameters) return;
@ -347,7 +347,7 @@ this.deleteMacro = function (parameters)
}
this.showMacro = function (parameters)
this.showMacro = function showMacro(parameters)
{
if (!parameters) return;
@ -366,7 +366,7 @@ this.showMacro = function (parameters)
}
this.performMacro = function (command)
this.performMacro = function performMacro(command)
{
if (!command) return;
@ -417,7 +417,7 @@ this.performMacro = function (command)
"" --> ["", null]
" " --> ["", null]
*/
String.prototype.getOneToken = function ()
String.prototype.getOneToken = function getOneToken()
{
var matcher = /\s+/g; // Regular expression to match one or more spaces.
matcher.lastIndex = 0;
@ -445,7 +445,7 @@ String.prototype.getOneToken = function ()
string literal as a JavaScript literal. (Used in performMacro() to echo
macro expansion.)
*/
String.prototype.substituteEscapeCodes = function ()
String.prototype.substituteEscapeCodes = function substituteEscapeCodes()
{
var string = this.replace(/\\/g, "\\\\"); // Convert \ to \\ -- must be first since well be introducing new \s below.
@ -491,7 +491,7 @@ function consoleMessage()
// Add inspect() method to all entities, to show inspector palette (Mac OS X only; no effect on other platforms).
Object.getPrototypeOf(Entity).inspect = function ()
Object.getPrototypeOf(Entity).inspect = function inspect()
{
debugConsole.inspectEntity(this);
}

View File

@ -85,6 +85,7 @@ MA 02110-1301, USA.
#import "OODebugFlags.h"
#import "OOScript.h"
#import "OOJavaScriptEngine.h"
#define kOOLogUnconvertedNSLog @"unclassified.ShipEntity"
@ -176,6 +177,8 @@ static GLfloat calcFuelChargeRate (GLfloat my_mass, GLfloat base_mass)
// Designated initializer
- (id)initWithKey:(NSString *)key definition:(NSDictionary *)dict
{
OOJS_PROFILE_ENTER
if (dict == nil)
{
// Is there any reason we should allow nil dictionary here? I think not. --Ahruman 2008-04-27
@ -210,11 +213,15 @@ static GLfloat calcFuelChargeRate (GLfloat my_mass, GLfloat base_mass)
maxFlightSpeed = 300;
}
return self;
OOJS_PROFILE_EXIT
}
- (BOOL) setUpFromDictionary:(NSDictionary *) shipDict
{
OOJS_PROFILE_ENTER
// Settings shared by players & NPCs.
//
// In order for default values to work and float values to not be junk,
@ -375,11 +382,15 @@ static GLfloat calcFuelChargeRate (GLfloat my_mass, GLfloat base_mass)
scriptInfo = [[shipDict oo_dictionaryForKey:@"script_info" defaultValue:nil] retain];
return YES;
OOJS_PROFILE_EXIT
}
- (BOOL) setUpShipFromDictionary:(NSDictionary *) shipDict
{
OOJS_PROFILE_ENTER
if (![self setUpFromDictionary:shipDict]) return NO;
// NPC-only settings.
@ -564,11 +575,15 @@ static GLfloat calcFuelChargeRate (GLfloat my_mass, GLfloat base_mass)
[self setShipScript:[shipDict oo_stringForKey:@"script"]];
return YES;
OOJS_PROFILE_EXIT
}
- (BOOL) setUpSubEntities: (NSDictionary *) shipDict
{
OOJS_PROFILE_ENTER
unsigned int i;
NSArray *plumes = [shipDict oo_arrayForKey:@"exhaust"];
@ -591,11 +606,15 @@ static GLfloat calcFuelChargeRate (GLfloat my_mass, GLfloat base_mass)
no_draw_distance = _profileRadius * _profileRadius * NO_DRAW_DISTANCE_FACTOR * NO_DRAW_DISTANCE_FACTOR * 2.0;
return YES;
OOJS_PROFILE_EXIT
}
- (BOOL) setUpOneSubentity:(NSDictionary *) subentDict
{
OOJS_PROFILE_ENTER
NSString *type = nil;
type = [subentDict oo_stringForKey:@"type"];
@ -607,6 +626,8 @@ static GLfloat calcFuelChargeRate (GLfloat my_mass, GLfloat base_mass)
{
return [self setUpOneStandardSubentity:subentDict asTurret:[type isEqualToString:@"ball_turret"]];
}
OOJS_PROFILE_EXIT
}
@ -4989,7 +5010,7 @@ NSComparisonResult ComparePlanetsBySurfaceDistance(id i1, id i2, void* context)
return;
}
//do not set to hulk here when crew is nill (or 0). Some things like missiles have no crew.
if (crew != nil) [crew autorelease];
[crew autorelease];
crew = [crewArray copy];
}

View File

@ -40,6 +40,7 @@ MA 02110-1301, USA.
#import "OOCharacter.h"
#import "OOScript.h"
#import "OOJavaScriptEngine.h"
#import "OODebugGLDrawing.h"
#import "OODebugFlags.h"
@ -711,6 +712,8 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
- (id)initWithKey:(NSString *)key definition:(NSDictionary *)dict
{
OOJS_PROFILE_ENTER
self = [super initWithKey:key definition:dict];
if (self != nil)
{
@ -722,6 +725,8 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
}
return self;
OOJS_PROFILE_EXIT
}
@ -755,6 +760,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
- (BOOL) setUpShipFromDictionary:(NSDictionary *) dict
{
OOJS_PROFILE_ENTER
isShip = YES;
isStation = YES;
@ -828,6 +834,8 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
[self setGroup:[self stationGroup]];
}
return YES;
OOJS_PROFILE_EXIT
}
@ -848,7 +856,6 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
port_position.y += bb.max.z * vk.y;
port_position.z += bb.max.z * vk.z;
}
}

View File

@ -116,12 +116,8 @@ MA 02110-1301, USA.
OOCharacter *castmember = [[[OOCharacter alloc] initWithGenSeed: r_seed andOriginalSystemSeed: o_seed] autorelease];
if ([castmember castInRole: c_role])
return castmember;
else
{
return castmember;
}
[castmember castInRole: c_role];
return castmember;
}
+ (OOCharacter *) characterWithDictionary:(NSDictionary *) c_dict

View File

@ -149,6 +149,8 @@ void InitOOJSQuaternion(JSContext *context, JSObject *global)
JSObject *JSQuaternionWithQuaternion(JSContext *context, Quaternion quaternion)
{
OOJS_PROFILE_ENTER
JSObject *result = NULL;
Quaternion *private = NULL;
@ -166,11 +168,15 @@ JSObject *JSQuaternionWithQuaternion(JSContext *context, Quaternion quaternion)
if (EXPECT_NOT(result == NULL)) free(private);
return result;
OOJS_PROFILE_EXIT
}
BOOL QuaternionToJSValue(JSContext *context, Quaternion quaternion, jsval *outValue)
{
OOJS_PROFILE_ENTER
JSObject *object = NULL;
assert(outValue != NULL);
@ -180,6 +186,8 @@ BOOL QuaternionToJSValue(JSContext *context, Quaternion quaternion, jsval *outVa
*outValue = OBJECT_TO_JSVAL(object);
return YES;
OOJS_PROFILE_EXIT
}
@ -193,6 +201,8 @@ BOOL JSValueToQuaternion(JSContext *context, jsval value, Quaternion *outQuatern
BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion *outQuaternion)
{
OOJS_PROFILE_ENTER
Quaternion *private = NULL;
Entity *entity = nil;
jsuint arrayLength;
@ -241,6 +251,8 @@ BOOL JSObjectGetQuaternion(JSContext *context, JSObject *quaternionObj, Quaterni
}
return NO;
OOJS_PROFILE_EXIT
}
@ -256,6 +268,8 @@ static BOOL GetThisQuaternion(JSContext *context, JSObject *quaternionObj, Quate
BOOL JSQuaternionSetQuaternion(JSContext *context, JSObject *quaternionObj, Quaternion quaternion)
{
OOJS_PROFILE_ENTER
Quaternion *private = NULL;
assert(quaternionObj != NULL);
@ -268,11 +282,15 @@ BOOL JSQuaternionSetQuaternion(JSContext *context, JSObject *quaternionObj, Quat
}
return NO;
OOJS_PROFILE_EXIT
}
static BOOL QuaternionFromArgumentListNoErrorInternal(JSContext *context, uintN argc, jsval *argv, Quaternion *outQuaternion, uintN *outConsumed, BOOL permitNumberList)
{
OOJS_PROFILE_ENTER
double w, x, y, z;
assert(argc != 0 && argv != NULL && outQuaternion != NULL);
@ -305,6 +323,8 @@ static BOOL QuaternionFromArgumentListNoErrorInternal(JSContext *context, uintN
if (outConsumed != NULL) *outConsumed = 4;
return YES;
OOJS_PROFILE_EXIT
}
@ -331,6 +351,8 @@ BOOL QuaternionFromArgumentListNoError(JSContext *context, uintN argc, jsval *ar
static JSBool QuaternionGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue)
{
OOJS_PROFILE_ENTER
Quaternion quaternion;
GLfloat value;
@ -361,11 +383,15 @@ static JSBool QuaternionGetProperty(JSContext *context, JSObject *this, jsval na
}
return JS_NewDoubleValue(context, value, outValue);
OOJS_PROFILE_EXIT
}
static JSBool QuaternionSetProperty(JSContext *context, JSObject *this, jsval name, jsval *value)
{
OOJS_PROFILE_ENTER
Quaternion quaternion;
jsdouble dval;
@ -401,6 +427,8 @@ static JSBool QuaternionSetProperty(JSContext *context, JSObject *this, jsval na
}
return JSQuaternionSetQuaternion(context, this, quaternion);
OOJS_PROFILE_EXIT
}
@ -418,6 +446,8 @@ static void QuaternionFinalize(JSContext *context, JSObject *this)
static JSBool QuaternionConstruct(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion quaternion = kZeroQuaternion;
Quaternion *private = NULL;
@ -453,11 +483,15 @@ static JSBool QuaternionConstruct(JSContext *context, JSObject *this, uintN argc
}
return YES;
OOJS_PROFILE_EXIT
}
static JSBool QuaternionEquality(JSContext *context, JSObject *this, jsval value, JSBool *outEqual)
{
OOJS_PROFILE_ENTER
Quaternion thisq, thatq;
// Note: "return YES" means no error, not equality.
@ -468,6 +502,8 @@ static JSBool QuaternionEquality(JSContext *context, JSObject *this, jsval value
*outEqual = quaternion_equal(thisq, thatq);
return YES;
OOJS_PROFILE_EXIT
}
@ -476,18 +512,24 @@ static JSBool QuaternionEquality(JSContext *context, JSObject *this, jsval value
// toString() : String
static JSBool QuaternionToString(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_NATIVE_ENTER(context)
Quaternion thisq;
if (EXPECT_NOT(!GetThisQuaternion(context, this, &thisq, @"toString"))) return NO;
*outResult = [QuaternionDescription(thisq) javaScriptValueInContext:context];
return YES;
OOJS_NATIVE_EXIT
}
// toSource() : String
static JSBool QuaternionToSource(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_NATIVE_ENTER(context)
Quaternion thisq;
if (EXPECT_NOT(!GetThisQuaternion(context, this, &thisq, @"toSource"))) return NO;
@ -495,12 +537,16 @@ static JSBool QuaternionToSource(JSContext *context, JSObject *this, uintN argc,
*outResult = [[NSString stringWithFormat:@"Quaternion(%g, %g, %g, %g)", thisq.w, thisq.x, thisq.y, thisq.z]
javaScriptValueInContext:context];
return YES;
OOJS_NATIVE_EXIT
}
// multiply(q : quaternionExpression) : Quaternion
static JSBool QuaternionMultiply(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion thisq, thatq, result;
if (EXPECT_NOT(!GetThisQuaternion(context, this, &thisq, @"multiply"))) return NO;
@ -509,12 +555,16 @@ static JSBool QuaternionMultiply(JSContext *context, JSObject *this, uintN argc,
result = quaternion_multiply(thisq, thatq);
return QuaternionToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// dot(q : quaternionExpression) : Number
static JSBool QuaternionDot(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion thisq, thatq;
double result;
@ -524,12 +574,16 @@ static JSBool QuaternionDot(JSContext *context, JSObject *this, uintN argc, jsva
result = quaternion_dot_product(thisq, thatq);
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// rotate(axis : vectorExpression, angle : Number) : Quaternion
static JSBool QuaternionRotate(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion thisq;
Vector axis;
double angle;
@ -547,12 +601,16 @@ static JSBool QuaternionRotate(JSContext *context, JSObject *this, uintN argc, j
// Else no angle specified, so don't rotate and pass value through unchanged.
return QuaternionToJSValue(context, thisq, outResult);
OOJS_PROFILE_EXIT
}
// rotateX(angle : Number) : Quaternion
static JSBool QuaternionRotateX(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion quat;
double angle;
@ -562,12 +620,16 @@ static JSBool QuaternionRotateX(JSContext *context, JSObject *this, uintN argc,
quaternion_rotate_about_x(&quat, angle);
return QuaternionToJSValue(context, quat, outResult);
OOJS_PROFILE_EXIT
}
// rotateY(angle : Number) : Quaternion
static JSBool QuaternionRotateY(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion quat;
double angle;
@ -577,12 +639,16 @@ static JSBool QuaternionRotateY(JSContext *context, JSObject *this, uintN argc,
quaternion_rotate_about_y(&quat, angle);
return QuaternionToJSValue(context, quat, outResult);
OOJS_PROFILE_EXIT
}
// rotateZ(angle : Number) : Quaternion
static JSBool QuaternionRotateZ(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion quat;
double angle;
@ -592,12 +658,16 @@ static JSBool QuaternionRotateZ(JSContext *context, JSObject *this, uintN argc,
quaternion_rotate_about_z(&quat, angle);
return QuaternionToJSValue(context, quat, outResult);
OOJS_PROFILE_EXIT
}
// normalize() : Quaternion
static JSBool QuaternionNormalize(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion quat;
if (EXPECT_NOT(!GetThisQuaternion(context, this, &quat, @"normalize"))) return NO;
@ -605,12 +675,16 @@ static JSBool QuaternionNormalize(JSContext *context, JSObject *this, uintN argc
quaternion_normalize(&quat);
return QuaternionToJSValue(context, quat, outResult);
OOJS_PROFILE_EXIT
}
// vectorForward() : Vector
static JSBool QuaternionVectorForward(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion thisq;
Vector result;
@ -619,12 +693,16 @@ static JSBool QuaternionVectorForward(JSContext *context, JSObject *this, uintN
result = vector_forward_from_quaternion(thisq);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// vectorUp() : Vector
static JSBool QuaternionVectorUp(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion thisq;
Vector result;
@ -633,12 +711,16 @@ static JSBool QuaternionVectorUp(JSContext *context, JSObject *this, uintN argc,
result = vector_up_from_quaternion(thisq);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// vectorRight() : Vector
static JSBool QuaternionVectorRight(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion thisq;
Vector result;
@ -647,12 +729,16 @@ static JSBool QuaternionVectorRight(JSContext *context, JSObject *this, uintN ar
result = vector_right_from_quaternion(thisq);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// toArray() : Array
static JSBool QuaternionToArray(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Quaternion thisq;
JSObject *result = NULL;
BOOL OK = YES;
@ -678,6 +764,8 @@ static JSBool QuaternionToArray(JSContext *context, JSObject *this, uintN argc,
if (!OK) *outResult = JSVAL_VOID;
return YES;
OOJS_PROFILE_EXIT
}
@ -686,5 +774,9 @@ static JSBool QuaternionToArray(JSContext *context, JSObject *this, uintN argc,
// random() : Quaternion
static JSBool QuaternionStaticRandom(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
return QuaternionToJSValue(context, OORandomQuaternion(), outResult);
OOJS_PROFILE_EXIT
}

File diff suppressed because it is too large Load Diff

View File

@ -288,6 +288,8 @@ static BOOL GetThisVector(JSContext *context, JSObject *vectorObj, Vector *outVe
BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector)
{
OOJS_PROFILE_ENTER
Vector *private = NULL;
if (EXPECT_NOT(vectorObj == NULL)) return NO;
@ -300,6 +302,8 @@ BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector)
}
return NO;
OOJS_PROFILE_EXIT
}
@ -366,6 +370,8 @@ BOOL VectorFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv,
static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue)
{
OOJS_PROFILE_ENTER
Vector vector;
GLfloat value;
@ -392,11 +398,15 @@ static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsval name,
}
return JS_NewDoubleValue(context, value, outValue);
OOJS_PROFILE_EXIT
}
static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsval name, jsval *value)
{
OOJS_PROFILE_ENTER
Vector vector;
jsdouble dval;
@ -428,11 +438,15 @@ static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsval name,
}
return JSVectorSetVector(context, this, vector);
OOJS_PROFILE_EXIT
}
static void VectorFinalize(JSContext *context, JSObject *this)
{
OOJS_PROFILE_ENTER
Vector *private = NULL;
private = JS_GetInstancePrivate(context, this, &sVectorClass.base, NULL);
@ -440,11 +454,15 @@ static void VectorFinalize(JSContext *context, JSObject *this)
{
free(private);
}
OOJS_PROFILE_EXIT_VOID
}
static JSBool VectorConstruct(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector vector = kZeroVector;
Vector *private = NULL;
@ -480,11 +498,15 @@ static JSBool VectorConstruct(JSContext *context, JSObject *this, uintN argc, js
}
return YES;
OOJS_PROFILE_EXIT
}
static JSBool VectorEquality(JSContext *context, JSObject *this, jsval value, JSBool *outEqual)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
*outEqual = NO;
@ -494,6 +516,8 @@ static JSBool VectorEquality(JSContext *context, JSObject *this, jsval value, JS
*outEqual = vector_equal(thisv, thatv);
return YES;
OOJS_PROFILE_EXIT
}
@ -502,18 +526,24 @@ static JSBool VectorEquality(JSContext *context, JSObject *this, jsval value, JS
// toString() : String
static JSBool VectorToString(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
if (EXPECT_NOT(!GetThisVector(context, this, &thisv, @"toString"))) return NO;
*outResult = [VectorDescription(thisv) javaScriptValueInContext:context];
return YES;
OOJS_NATIVE_EXIT
}
// toSource() : String
static JSBool VectorToSource(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
if (EXPECT_NOT(!GetThisVector(context, this, &thisv, @"toSource"))) return NO;
@ -521,6 +551,8 @@ static JSBool VectorToSource(JSContext *context, JSObject *this, uintN argc, jsv
*outResult = [[NSString stringWithFormat:@"Vector3D(%g, %g, %g)", thisv.x, thisv.y, thisv.z]
javaScriptValueInContext:context];
return YES;
OOJS_NATIVE_EXIT
}
@ -545,6 +577,8 @@ static JSBool VectorAdd(JSContext *context, JSObject *this, uintN argc, jsval *a
// subtract(v : vectorExpression) : Vector3D
static JSBool VectorSubtract(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv, result;
if (EXPECT_NOT(!GetThisVector(context, this, &thisv, @"subtract"))) return NO;
@ -553,12 +587,16 @@ static JSBool VectorSubtract(JSContext *context, JSObject *this, uintN argc, jsv
result = vector_subtract(thisv, thatv);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// distanceTo(v : vectorExpression) : Number
static JSBool VectorDistanceTo(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
GLfloat result;
@ -568,12 +606,16 @@ static JSBool VectorDistanceTo(JSContext *context, JSObject *this, uintN argc, j
result = distance(thisv, thatv);
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// squaredDistanceTo(v : vectorExpression) : Number
static JSBool VectorSquaredDistanceTo(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
GLfloat result;
@ -583,12 +625,16 @@ static JSBool VectorSquaredDistanceTo(JSContext *context, JSObject *this, uintN
result = distance2(thisv, thatv);
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// multiply(n : Number) : Vector3D
static JSBool VectorMultiply(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, result;
double scalar;
@ -598,12 +644,16 @@ static JSBool VectorMultiply(JSContext *context, JSObject *this, uintN argc, jsv
result = vector_multiply_scalar(thisv, scalar);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// dot(v : vectorExpression) : Number
static JSBool VectorDot(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
GLfloat result;
@ -613,12 +663,16 @@ static JSBool VectorDot(JSContext *context, JSObject *this, uintN argc, jsval *a
result = dot_product(thisv, thatv);
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// angleTo(v : vectorExpression) : Number
static JSBool VectorAngleTo(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
GLfloat result;
@ -628,12 +682,16 @@ static JSBool VectorAngleTo(JSContext *context, JSObject *this, uintN argc, jsva
result = acosf(dot_product(vector_normal(thisv), vector_normal(thatv)));
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// cross(v : vectorExpression) : Vector3D
static JSBool VectorCross(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv, result;
if (EXPECT_NOT(!GetThisVector(context, this, &thisv, @"cross"))) return NO;
@ -642,12 +700,16 @@ static JSBool VectorCross(JSContext *context, JSObject *this, uintN argc, jsval
result = true_cross_product(thisv, thatv);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// tripleProduct(v : vectorExpression, u : vectorExpression) : Number
static JSBool VectorTripleProduct(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv, theotherv;
GLfloat result;
uintN consumed;
@ -661,12 +723,16 @@ static JSBool VectorTripleProduct(JSContext *context, JSObject *this, uintN argc
result = triple_product(thisv, thatv, theotherv);
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// direction() : Vector3D
static JSBool VectorDirection(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, result;
if (EXPECT_NOT(!GetThisVector(context, this, &thisv, @"direction"))) return NO;
@ -674,12 +740,16 @@ static JSBool VectorDirection(JSContext *context, JSObject *this, uintN argc, js
result = vector_normal(thisv);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// magnitude() : Number
static JSBool VectorMagnitude(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv;
GLfloat result;
@ -688,12 +758,16 @@ static JSBool VectorMagnitude(JSContext *context, JSObject *this, uintN argc, js
result = magnitude(thisv);
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// squaredMagnitude() : Number
static JSBool VectorSquaredMagnitude(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv;
GLfloat result;
@ -702,12 +776,16 @@ static JSBool VectorSquaredMagnitude(JSContext *context, JSObject *this, uintN a
result = magnitude2(thisv);
return JS_NewDoubleValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// rotationTo(v : vectorExpression [, limit : Number]) : Quaternion
static JSBool VectorRotationTo(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, thatv;
double limit;
BOOL gotLimit;
@ -730,12 +808,16 @@ static JSBool VectorRotationTo(JSContext *context, JSObject *this, uintN argc, j
else result = quaternion_rotation_between(thisv, thatv);
return QuaternionToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// rotateBy(q : quaternionExpression) : Vector3D
static JSBool VectorRotateBy(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv, result;
Quaternion q;
@ -745,12 +827,16 @@ static JSBool VectorRotateBy(JSContext *context, JSObject *this, uintN argc, jsv
result = quaternion_rotate_vector(q, thisv);
return VectorToJSValue(context, result, outResult);
OOJS_PROFILE_EXIT
}
// toArray() : Array
static JSBool VectorToArray(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector thisv;
JSObject *result = NULL;
jsval nVal;
@ -774,12 +860,16 @@ static JSBool VectorToArray(JSContext *context, JSObject *this, uintN argc, jsva
}
return YES;
OOJS_PROFILE_EXIT
}
// toCoordinateSystem(coordScheme : String)
static JSBool VectorToCoordinateSystem(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
NSString *coordScheme = nil;
@ -800,12 +890,16 @@ static JSBool VectorToCoordinateSystem(JSContext *context, JSObject *this, uintN
OOJSResumeTimeLimiter();
return YES;
OOJS_NATIVE_EXIT
}
// fromCoordinateSystem(coordScheme : String)
static JSBool VectorFromCoordinateSystem(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_NATIVE_ENTER(context)
Vector thisv;
NSString *coordScheme = nil;
NSString *arg = nil;
@ -828,6 +922,8 @@ static JSBool VectorFromCoordinateSystem(JSContext *context, JSObject *this, uin
OOJSResumeTimeLimiter();
return YES;
OOJS_NATIVE_EXIT
}
@ -837,6 +933,8 @@ static JSBool VectorFromCoordinateSystem(JSContext *context, JSObject *this, uin
// interpolate(v : Vector3D, u : Vector3D, alpha : Number) : Vector3D
static JSBool VectorStaticInterpolate(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
Vector av, bv;
double interp;
Vector result;
@ -864,37 +962,51 @@ INSUFFICIENT_ARGUMENTS:
@"Insufficient parameters",
@"vector expression, vector expression and number");
return NO;
OOJS_PROFILE_EXIT
}
// random([maxLength : Number]) : Vector3D
static JSBool VectorStaticRandom(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
double maxLength;
if (argc == 0 || !NumberFromArgumentListNoError(context, argc, argv, &maxLength, NULL)) maxLength = 1.0;
return VectorToJSValue(context, OOVectorRandomSpatial(maxLength), outResult);
OOJS_PROFILE_EXIT
}
// randomDirection([scale : Number]) : Vector3D
static JSBool VectorStaticRandomDirection(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
double scale;
if (argc == 0 || !NumberFromArgumentListNoError(context, argc, argv, &scale, NULL)) scale = 1.0;
return VectorToJSValue(context, vector_multiply_scalar(OORandomUnitVector(), scale), outResult);
OOJS_PROFILE_EXIT
}
// randomDirectionAndLength([maxLength : Number]) : Vector3D
static JSBool VectorStaticRandomDirectionAndLength(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
double maxLength;
if (argc == 0 || !NumberFromArgumentListNoError(context, argc, argv, &maxLength, NULL)) maxLength = 1.0;
return VectorToJSValue(context, OOVectorRandomSpatial(maxLength), outResult);
OOJS_PROFILE_EXIT
}

View File

@ -433,7 +433,8 @@ void OOJSUnreachable(const char *function, const char *file, unsigned line) NO_
#endif // OOLITE_NATIVE_EXCEPTIONS
#define OOJS_PROFILE_EXIT OOJS_PROFILE_EXIT_VAL(NO)
#define OOJS_PROFILE_EXIT OOJS_PROFILE_EXIT_VAL(NO)
#define OOJS_PROFILE_EXIT_VOID return; OOJS_PROFILE_EXIT_VAL()

View File

@ -498,63 +498,71 @@ void OOJSDumpStack(NSString *logMessageClass, JSContext *context)
{
if (!OOLogWillDisplayMessagesInClass(logMessageClass)) return;
JSStackFrame *frame = NULL;
unsigned idx = 0;
while (JS_FrameIterator(context, &frame) != NULL)
{
JSScript *script = JS_GetFrameScript(context, frame);
NSString *desc = nil;
if (script != NULL)
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NS_DURING
JSStackFrame *frame = NULL;
unsigned idx = 0;
while (JS_FrameIterator(context, &frame) != NULL)
{
const char *fileName = JS_GetScriptFilename(context, script);
jsbytecode *PC = JS_GetFramePC(context, frame);
unsigned lineNo = JS_PCToLineNumber(context, script, PC);
JSScript *script = JS_GetFrameScript(context, frame);
NSString *desc = nil;
NSString *fileNameObj = [NSString stringWithUTF8String:fileName];
if (fileNameObj == nil) fileNameObj = [NSString stringWithCString:fileName encoding:NSISOLatin1StringEncoding];
NSString *shortFileName = [fileNameObj lastPathComponent];
if (![[shortFileName lowercaseString] isEqualToString:@"script.js"]) fileNameObj = shortFileName;
NSString *funcDesc = nil;
JSFunction *function = JS_GetFrameFunction(context, frame);
if (function != NULL)
if (script != NULL)
{
JSString *funcName = JS_GetFunctionId(function);
if (funcName != NULL)
const char *fileName = JS_GetScriptFilename(context, script);
jsbytecode *PC = JS_GetFramePC(context, frame);
unsigned lineNo = JS_PCToLineNumber(context, script, PC);
NSString *fileNameObj = [NSString stringWithUTF8String:fileName];
if (fileNameObj == nil) fileNameObj = [NSString stringWithCString:fileName encoding:NSISOLatin1StringEncoding];
NSString *shortFileName = [fileNameObj lastPathComponent];
if (![[shortFileName lowercaseString] isEqualToString:@"script.js"]) fileNameObj = shortFileName;
NSString *funcDesc = nil;
JSFunction *function = JS_GetFrameFunction(context, frame);
if (function != NULL)
{
funcDesc = [NSString stringWithJavaScriptString:funcName];
if (!JS_IsConstructorFrame(context, frame))
JSString *funcName = JS_GetFunctionId(function);
if (funcName != NULL)
{
funcDesc = [funcDesc stringByAppendingString:@"()"];
funcDesc = [NSString stringWithJavaScriptString:funcName];
if (!JS_IsConstructorFrame(context, frame))
{
funcDesc = [funcDesc stringByAppendingString:@"()"];
}
else
{
funcDesc = [NSString stringWithFormat:@"new %@()", funcDesc];
}
}
else
{
funcDesc = [NSString stringWithFormat:@"new %@()", funcDesc];
funcDesc = @"<anonymous function>";
}
}
else
{
funcDesc = @"<anonymous function>";
funcDesc = @"<not a function frame>";
}
desc = [NSString stringWithFormat:@"%@:%u %@", fileNameObj, lineNo, funcDesc];
}
else
else if (JS_IsNativeFrame(context, frame))
{
funcDesc = @"<not a function frame>";
desc = @"<Oolite native>";
}
desc = [NSString stringWithFormat:@"%@:%u %@", fileNameObj, lineNo, funcDesc];
OOLog(@"js.stackFrame", @"%4u %@", idx, desc);
idx++;
}
else if (JS_IsNativeFrame(context, frame))
{
desc = @"<Oolite native>";
}
OOLog(@"js.stackFrame", @"%4u %@", idx, desc);
idx++;
}
NS_HANDLER
OOLog(kOOLogException, @"Exception during JavaScript stack trace: %@:%@", [localException name], [localException reason]);
NS_ENDHANDLER
[pool release];
}
#endif
@ -583,11 +591,15 @@ void OOReportJSErrorForCaller(JSContext *context, NSString *scriptClass, NSStrin
va_list args;
NSString *msg = nil;
va_start(args, format);
msg = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
OOReportJSError(context, @"%@%@", CallerPrefix(scriptClass, function), msg);
NS_DURING
va_start(args, format);
msg = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
OOReportJSError(context, @"%@%@", CallerPrefix(scriptClass, function), msg);
NS_HANDLER
// Squash any secondary errors during error handling.
NS_ENDHANDLER
[msg release];
}
@ -596,8 +608,12 @@ void OOReportJSErrorWithArguments(JSContext *context, NSString *format, va_list
{
NSString *msg = nil;
msg = [[NSString alloc] initWithFormat:format arguments:args];
JS_ReportError(context, "%s", [msg UTF8String]);
NS_DURING
msg = [[NSString alloc] initWithFormat:format arguments:args];
JS_ReportError(context, "%s", [msg UTF8String]);
NS_HANDLER
// Squash any secondary errors during error handling.
NS_ENDHANDLER
[msg release];
}
@ -606,8 +622,12 @@ void OOReportJSErrorWithArguments(JSContext *context, NSString *format, va_list
void OOJSReportWrappedException(JSContext *context, id exception)
{
if ([exception isKindOfClass:[NSException class]]) OOReportJSError(context, @"Native exception: %@", [exception reason]);
else OOReportJSError(context, @"Unidentified native exception");
if (!JS_IsExceptionPending(context))
{
if ([exception isKindOfClass:[NSException class]]) OOReportJSError(context, @"Native exception: %@", [exception reason]);
else OOReportJSError(context, @"Unidentified native exception");
}
// Else, let the pending exception propagate.
}
@ -638,11 +658,15 @@ void OOReportJSWarningForCaller(JSContext *context, NSString *scriptClass, NSStr
va_list args;
NSString *msg = nil;
va_start(args, format);
msg = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
OOReportJSWarning(context, @"%@%@", CallerPrefix(scriptClass, function), msg);
NS_DURING
va_start(args, format);
msg = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
OOReportJSWarning(context, @"%@%@", CallerPrefix(scriptClass, function), msg);
NS_HANDLER
// Squash any secondary errors during error handling.
NS_ENDHANDLER
[msg release];
}
@ -651,8 +675,12 @@ void OOReportJSWarningWithArguments(JSContext *context, NSString *format, va_lis
{
NSString *msg = nil;
msg = [[NSString alloc] initWithFormat:format arguments:args];
JS_ReportWarning(context, "%s", [msg UTF8String]);
NS_DURING
msg = [[NSString alloc] initWithFormat:format arguments:args];
JS_ReportWarning(context, "%s", [msg UTF8String]);
NS_HANDLER
// Squash any secondary errors during error handling.
NS_ENDHANDLER
[msg release];
}
@ -665,11 +693,15 @@ void OOReportJSBadPropertySelector(JSContext *context, NSString *className, jsin
void OOReportJSBadArguments(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, NSString *message, NSString *expectedArgsDescription)
{
if (message == nil) message = @"Invalid arguments";
message = [NSString stringWithFormat:@"%@ %@", message, [NSString stringWithJavaScriptParameters:argv count:argc inContext:context]];
if (expectedArgsDescription != nil) message = [NSString stringWithFormat:@"%@ -- expected %@", message, expectedArgsDescription];
OOReportJSErrorForCaller(context, scriptClass, function, @"%@.", message);
NS_DURING
if (message == nil) message = @"Invalid arguments";
message = [NSString stringWithFormat:@"%@ %@", message, [NSString stringWithJavaScriptParameters:argv count:argc inContext:context]];
if (expectedArgsDescription != nil) message = [NSString stringWithFormat:@"%@ -- expected %@", message, expectedArgsDescription];
OOReportJSErrorForCaller(context, scriptClass, function, @"%@.", message);
NS_HANDLER
// Squash any secondary errors during error handling.
NS_ENDHANDLER
}
@ -693,6 +725,8 @@ BOOL NumberFromArgumentList(JSContext *context, NSString *scriptClass, NSString
BOOL NumberFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv, double *outNumber, uintN *outConsumed)
{
OOJS_PROFILE_ENTER
double value;
// Sanity checks.
@ -713,11 +747,15 @@ BOOL NumberFromArgumentListNoError(JSContext *context, uintN argc, jsval *argv,
*outNumber = value;
if (outConsumed != NULL) *outConsumed = 1;
return YES;
OOJS_PROFILE_EXIT
}
static BOOL ExtractString(NSString *string, jschar **outString, size_t *outLength)
{
OOJS_PROFILE_ENTER
assert(outString != NULL && outLength != NULL);
assert(sizeof (unichar) == sizeof (jschar)); // Should both be 16 bits
@ -729,11 +767,15 @@ static BOOL ExtractString(NSString *string, jschar **outString, size_t *outLengt
[string getCharacters:(unichar *)*outString];
return YES;
OOJS_PROFILE_EXIT
}
BOOL JSGetNSProperty(JSContext *context, JSObject *object, NSString *name, jsval *value)
{
OOJS_PROFILE_ENTER
jschar *buffer = NULL;
size_t length;
BOOL OK = NO;
@ -752,11 +794,15 @@ BOOL JSGetNSProperty(JSContext *context, JSObject *object, NSString *name, jsval
if (tempCtxt) [[OOJavaScriptEngine sharedEngine] releaseContext:context];
return OK;
OOJS_PROFILE_EXIT
}
BOOL JSSetNSProperty(JSContext *context, JSObject *object, NSString *name, jsval *value)
{
OOJS_PROFILE_ENTER
jschar *buffer = NULL;
size_t length;
BOOL OK = NO;
@ -775,11 +821,15 @@ BOOL JSSetNSProperty(JSContext *context, JSObject *object, NSString *name, jsval
if (tempCtxt) [[OOJavaScriptEngine sharedEngine] releaseContext:context];
return OK;
OOJS_PROFILE_EXIT
}
BOOL JSDefineNSProperty(JSContext *context, JSObject *object, NSString *name, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
{
OOJS_PROFILE_ENTER
jschar *buffer = NULL;
size_t length;
BOOL OK = NO;
@ -798,11 +848,15 @@ BOOL JSDefineNSProperty(JSContext *context, JSObject *object, NSString *name, js
if (tempCtxt) [[OOJavaScriptEngine sharedEngine] releaseContext:context];
return OK;
OOJS_PROFILE_EXIT
}
static JSObject *JSArrayFromNSArray(JSContext *context, NSArray *array)
{
OOJS_PROFILE_ENTER
JSObject *result = NULL;
unsigned i;
unsigned count;
@ -832,11 +886,15 @@ static JSObject *JSArrayFromNSArray(JSContext *context, NSArray *array)
NS_ENDHANDLER
return (JSObject *)result;
OOJS_PROFILE_EXIT
}
static BOOL JSNewNSArrayValue(JSContext *context, NSArray *array, jsval *value)
{
OOJS_PROFILE_ENTER
JSObject *object = NULL;
BOOL OK = YES;
@ -858,6 +916,8 @@ static BOOL JSNewNSArrayValue(JSContext *context, NSArray *array, jsval *value)
JS_LeaveLocalRootScopeWithResult(context, *value);
return OK;
OOJS_PROFILE_EXIT
}
@ -867,6 +927,8 @@ static BOOL JSNewNSArrayValue(JSContext *context, NSArray *array, jsval *value)
*/
static JSObject *JSObjectFromNSDictionary(JSContext *context, NSDictionary *dictionary)
{
OOJS_PROFILE_ENTER
JSObject *result = NULL;
BOOL OK = YES;
NSEnumerator *keyEnum = nil;
@ -918,11 +980,15 @@ static JSObject *JSObjectFromNSDictionary(JSContext *context, NSDictionary *dict
}
return (JSObject *)result;
OOJS_PROFILE_EXIT
}
static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary, jsval *value)
{
OOJS_PROFILE_ENTER
JSObject *object = NULL;
BOOL OK = YES;
@ -944,6 +1010,8 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
JS_LeaveLocalRootScopeWithResult(context, *value);
return OK;
OOJS_PROFILE_EXIT
}
@ -969,6 +1037,8 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
- (NSString *)javaScriptDescriptionWithClassName:(NSString *)className
{
OOJS_PROFILE_ENTER
NSString *components = nil;
NSString *description = nil;
@ -985,6 +1055,8 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
}
return description;
OOJS_PROFILE_EXIT
}
@ -1000,18 +1072,28 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
+ (id) valueWithJSValue:(jsval)value inContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
return [[[self alloc] initWithJSValue:value inContext:context] autorelease];
OOJS_PROFILE_EXIT
}
+ (id) valueWithJSObject:(JSObject *)object inContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
return [[[self alloc] initWithJSObject:object inContext:context] autorelease];
OOJS_PROFILE_EXIT
}
- (id) initWithJSValue:(jsval)value inContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
self = [super init];
if (self != nil)
{
@ -1028,6 +1110,8 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
if (tempCtxt) [[OOJavaScriptEngine sharedEngine] releaseContext:context];
}
return self;
OOJS_PROFILE_EXIT
}
@ -1060,6 +1144,8 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
// Convert a JSString to an NSString.
+ (id)stringWithJavaScriptString:(JSString *)string
{
OOJS_PROFILE_ENTER
jschar *chars = NULL;
size_t length;
@ -1067,11 +1153,15 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
length = JS_GetStringLength(string);
return [NSString stringWithCharacters:chars length:length];
OOJS_PROFILE_EXIT
}
+ (id)stringWithJavaScriptValue:(jsval)value inContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
// In some cases we didn't test the original stringWith... function for nil, causing difficult
// to track crashes. We now have two similar functions: stringWith... which never returns nil and
// stringOrNilWith... (alias JSValToNSString) which can return nil and is used in most cases.
@ -1080,11 +1170,15 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
if (JSVAL_IS_NULL(value)) return @"null";
return [self stringOrNilWithJavaScriptValue:value inContext:context];
OOJS_PROFILE_EXIT
}
+ (id)stringOrNilWithJavaScriptValue:(jsval)value inContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
JSString *string = NULL;
BOOL tempCtxt = NO;
@ -1099,11 +1193,15 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
if (tempCtxt) [[OOJavaScriptEngine sharedEngine] releaseContext:context];
return [NSString stringWithJavaScriptString:string];
OOJS_PROFILE_EXIT
}
+ (id)stringWithJavaScriptParameters:(jsval *)params count:(uintN)count inContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
if (params == NULL && count != 0) return nil;
uintN i;
@ -1133,11 +1231,15 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
[result appendString:@")"];
return result;
OOJS_PROFILE_EXIT
}
- (jsval)javaScriptValueInContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
size_t length;
unichar *buffer = NULL;
JSString *string = NULL;
@ -1154,11 +1256,15 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
free(buffer);
return STRING_TO_JSVAL(string);
OOJS_PROFILE_EXIT
}
+ (id)concatenationOfStringsFromJavaScriptValues:(jsval *)values count:(size_t)count separator:(NSString *)separator inContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
size_t i;
NSMutableString *result = nil;
NSString *element = nil;
@ -1178,11 +1284,15 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
}
return result;
OOJS_PROFILE_EXIT
}
- (NSString *)escapedForJavaScriptLiteral
{
OOJS_PROFILE_ENTER
NSMutableString *result = nil;
unsigned i, length;
unichar c;
@ -1240,6 +1350,8 @@ static BOOL JSNewNSDictionaryValue(JSContext *context, NSDictionary *dictionary,
}
[pool release];
return result;
OOJS_PROFILE_EXIT
}
@end
@ -1303,6 +1415,8 @@ const char *JSValueTypeDbg(jsval val)
- (jsval)javaScriptValueInContext:(JSContext *)context
{
OOJS_PROFILE_ENTER
jsval result;
BOOL isFloat = NO;
long long longLongValue;
@ -1342,6 +1456,8 @@ const char *JSValueTypeDbg(jsval val)
}
return result;
OOJS_PROFILE_EXIT
}
@end
@ -1359,6 +1475,8 @@ const char *JSValueTypeDbg(jsval val)
JSBool JSObjectWrapperToString(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
OOJS_PROFILE_ENTER
id object = nil;
NSString *description = nil;
JSClass *jsClass = NULL;
@ -1381,11 +1499,15 @@ JSBool JSObjectWrapperToString(JSContext *context, JSObject *this, uintN argc, j
*outResult = [description javaScriptValueInContext:context];
return YES;
OOJS_PROFILE_EXIT
}
void JSObjectWrapperFinalize(JSContext *context, JSObject *this)
{
OOJS_PROFILE_ENTER
id object = JS_GetPrivate(context, this);
if (object != nil)
{
@ -1393,11 +1515,15 @@ void JSObjectWrapperFinalize(JSContext *context, JSObject *this)
[object release];
JS_SetPrivate(context, this, nil);
}
OOJS_PROFILE_EXIT_VOID
}
JSBool JSObjectWrapperEquality(JSContext *context, JSObject *this, jsval value, JSBool *outEqual)
{
OOJS_PROFILE_ENTER
id thisObj, thatObj;
thisObj = JSObjectToObject(context, this);
@ -1405,11 +1531,15 @@ JSBool JSObjectWrapperEquality(JSContext *context, JSObject *this, jsval value,
*outEqual = [thisObj isEqual:thatObj];
return YES;
OOJS_PROFILE_EXIT
}
BOOL JSFunctionPredicate(Entity *entity, void *parameter)
{
OOJS_PROFILE_ENTER
JSFunctionPredicateParameter *param = parameter;
jsval args[1];
jsval rval = JSVAL_VOID;
@ -1440,17 +1570,25 @@ BOOL JSFunctionPredicate(Entity *entity, void *parameter)
}
return result;
OOJS_PROFILE_EXIT
}
BOOL JSEntityIsJavaScriptVisiblePredicate(Entity *entity, void *parameter)
{
OOJS_PROFILE_ENTER
return [entity isVisibleToScripts];
OOJS_PROFILE_EXIT
}
BOOL JSEntityIsJavaScriptSearchablePredicate(Entity *entity, void *parameter)
{
OOJS_PROFILE_ENTER
if (![entity isVisibleToScripts]) return NO;
if ([entity isShip])
{
@ -1476,6 +1614,8 @@ BOOL JSEntityIsJavaScriptSearchablePredicate(Entity *entity, void *parameter)
}
return YES; // would happen if we added a new script-visible class
OOJS_PROFILE_EXIT
}

View File

@ -72,6 +72,7 @@ MA 02110-1301, USA.
#import "OOAsyncWorkManager.h"
#import "OODebugFlags.h"
#import "OOLoggingExtended.h"
#import "OOJavaScriptEngine.h"
#if OO_LOCALIZATION_TOOLS
#import "OOConvertSystemDescriptions.h"
@ -2382,9 +2383,11 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
- (ShipEntity *) addShipAt:(Vector)pos withRole:(NSString *)role withinRadius:(GLfloat)radius
{
OOGovernmentID government = [[self currentSystemData] oo_unsignedCharForKey:KEY_GOVERNMENT];
OOJS_PROFILE_ENTER
ShipEntity *ship = [self newShipWithRole:role]; // is retained
if (ship)
if (ship != nil)
{
if (radius == NSNotFound)
{
@ -2406,46 +2409,60 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
}
if ([ship hasRole:@"cargopod"]) [self fillCargopodWithRandomCargo:ship];
if ([ship scanClass] == CLASS_NOT_SET) [ship setScanClass: CLASS_NEUTRAL];
OOScanClass scanClass = [ship scanClass];
if (scanClass == CLASS_NOT_SET)
{
scanClass = CLASS_NEUTRAL;
[ship setScanClass:scanClass];
}
if (![ship crew] && ![ship isUnpiloted] && !([ship scanClass] == CLASS_CARGO || [ship scanClass] == CLASS_ROCK))
if (!(scanClass == CLASS_CARGO || scanClass == CLASS_ROCK) && ![ship crew] && ![ship isUnpiloted])
{
[ship setCrew:[NSArray arrayWithObject:
[OOCharacter randomCharacterWithRole: role
andOriginalSystem: systems[Ranrot() & 255]]]];
[OOCharacter randomCharacterWithRole:role
andOriginalSystem:systems[Ranrot() & 255]]]];
}
[ship setPosition:pos];
Quaternion qr;
quaternion_set_random(&qr);
[ship setOrientation:qr];
[ship setOrientation:OORandomQuaternion()];
if ([role isEqual:@"trader"])
BOOL trader = [role isEqualToString:@"trader"];
if (trader)
{
// half of traders created anywhere will now have cargo.
if (randf() > 0.5f)
[ship setCargoFlag:(randf() < 0.66f ? CARGO_FLAG_FULL_PLENTIFUL : CARGO_FLAG_FULL_SCARCE)]; // most of them will carry the cargo produced in-system.
if (([ship pendingEscortCount] > 0)&&((Ranrot() % 7) < government)) // remove escorts if we feel safe
{
int nx = [ship pendingEscortCount] - 2 * (1 + (Ranrot() & 3)); // remove 2,4,6, or 8 escorts
[ship setPendingEscortCount:(nx > 0) ? nx : 0];
[ship setCargoFlag:(randf() < 0.66f ? CARGO_FLAG_FULL_PLENTIFUL : CARGO_FLAG_FULL_SCARCE)]; // most of them will carry the cargo produced in-system.
}
uint8_t pendingEscortCount = [ship pendingEscortCount];
if (pendingEscortCount > 0)
{
OOGovernmentID government = [[self currentSystemData] oo_unsignedCharForKey:KEY_GOVERNMENT];
if ((Ranrot() % 7) < government) // remove escorts if we feel safe
{
int nx = pendingEscortCount - 2 * (1 + (Ranrot() & 3)); // remove 2,4,6, or 8 escorts
[ship setPendingEscortCount:(nx > 0) ? nx : 0];
}
}
}
if (distance([self getWitchspaceExitPosition], pos) > SCANNER_MAX_RANGE) // nothing extra to do
if (distance([self getWitchspaceExitPosition], pos) > SCANNER_MAX_RANGE)
{
// nothing extra to do
[self addEntity:ship]; // STATUS_IN_FLIGHT, AI state GLOBAL - ship is retained globally
}
else // witchpace incoming traders & pirates need extra settings.
{
if ([role isEqual:@"trader"])
if (trader)
{
[ship setCargoFlag:CARGO_FLAG_FULL_SCARCE];
if (randf() > 0.10)
[ship switchAITo:@"route1traderAI.plist"];
else
[ship switchAITo:@"route2sunskimAI.plist"]; // route3 really, but the AI's the same
if (randf() > 0.10) [ship switchAITo:@"route1traderAI.plist"];
else [ship switchAITo:@"route2sunskimAI.plist"]; // route3 really, but the AI's the same
}
else if ([role isEqual:@"pirate"])
{
[ship setBounty: (Ranrot() & 7) + (Ranrot() & 7) + ((randf() < 0.05)? 63 : 23)]; // they already have a price on their heads
[ship setBounty:(Ranrot() & 7) + (Ranrot() & 7) + ((randf() < 0.05)? 63 : 23)]; // they already have a price on their heads
}
// Status changes inside the following call: AI state GLOBAL, then STATUS_EXITING_WITCHSPACE,
@ -2457,11 +2474,15 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
[ship release];
}
return ship;
OOJS_PROFILE_EXIT
}
- (NSArray *) addShipsAt:(Vector)pos withRole:(NSString *)role quantity:(unsigned)count withinRadius:(GLfloat)radius asGroup:(BOOL)isGroup
{
OOJS_PROFILE_ENTER
NSMutableArray *ships = [NSMutableArray arrayWithCapacity:count];
ShipEntity *ship = nil;
OOShipGroup *group = nil;
@ -2485,6 +2506,8 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
if ([ships count] == 0) return nil;
return [[ships copy] autorelease];
OOJS_PROFILE_EXIT
}
@ -2876,6 +2899,8 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter)
- (NSString *) randomShipKeyForRoleRespectingConditions:(NSString *)role
{
OOJS_PROFILE_ENTER
OOShipRegistry *registry = [OOShipRegistry sharedRegistry];
NSString *shipKey = nil;
OOMutableProbabilitySet *pset = nil;
@ -2918,11 +2943,15 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter)
// If we got here, some ships existed but all failed conditions test.
return nil;
OOJS_PROFILE_EXIT
}
- (ShipEntity *) newShipWithRole:(NSString *)role
{
OOJS_PROFILE_ENTER
ShipEntity *ship = nil;
NSString *shipKey = nil;
NSDictionary *shipInfo = nil;
@ -2954,11 +2983,15 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter)
}
return ship;
OOJS_PROFILE_EXIT
}
- (ShipEntity *) newShipWithName:(NSString *)shipKey usePlayerProxy:(BOOL)usePlayerProxy
{
OOJS_PROFILE_ENTER
NSDictionary *shipDict = nil;
ShipEntity *ship = nil;
@ -2990,6 +3023,8 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter)
// MKW 20090327 - retain count is actually 2!
return ship; // retain count = 1
OOJS_PROFILE_EXIT
}
@ -3001,6 +3036,8 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter)
- (Class) shipClassForShipDictionary:(NSDictionary *)dict
{
OOJS_PROFILE_ENTER
if (dict == nil) return Nil;
BOOL isStation = NO;
@ -3017,6 +3054,8 @@ static BOOL IsCandidateMainStationPredicate(Entity *entity, void *parameter)
isStation = [dict oo_boolForKey:@"is_carrier" defaultValue:isStation];
return isStation ? [StationEntity class] : [ShipEntity class];
OOJS_PROFILE_EXIT
}
@ -4881,6 +4920,8 @@ OOINLINE BOOL EntityInRange(Vector p1, Entity *e2, float range)
inRange:(double)range
ofEntity:(Entity *)e1
{
OOJS_PROFILE_ENTER
unsigned i;
Vector p1;
NSMutableArray *result = nil;
@ -4905,6 +4946,8 @@ OOINLINE BOOL EntityInRange(Vector p1, Entity *e2, float range)
}
return result;
OOJS_PROFILE_EXIT
}
@ -6067,6 +6110,8 @@ static NSDictionary *sCachedSystemData = nil;
- (NSDictionary *) generateSystemData:(Random_Seed) s_seed useCache:(BOOL) useCache
{
OOJS_PROFILE_ENTER
static Random_Seed cachedSeed = {0};
if (useCache)
@ -6134,11 +6179,15 @@ static NSDictionary *sCachedSystemData = nil;
[systemdata release];
return sCachedSystemData;
OOJS_PROFILE_EXIT
}
- (NSDictionary *) currentSystemData
{
OOJS_PROFILE_ENTER
if (![self inInterstellarSpace])
{
return [self generateSystemData:system_seed];
@ -6167,6 +6216,8 @@ static NSDictionary *sCachedSystemData = nil;
return interstellarDict;
}
OOJS_PROFILE_EXIT
}
@ -8088,20 +8139,6 @@ static OOComparisonResult comparePrice(id dict1, id dict2, void * context)
- (Vector) getWitchspaceExitPositionResettingRandomSeed:(BOOL)resetSeed
{
#if 0
Vector result;
if (resetSeed)
{
seed_RNG_only_for_planet_description(system_seed);
}
result.x = SCANNER_MAX_RANGE*(gen_rnd_number()/256.0 - 0.5); // offset by a set amount, up to 12.8 km
result.y = SCANNER_MAX_RANGE*(gen_rnd_number()/256.0 - 0.5);
result.z = SCANNER_MAX_RANGE*(gen_rnd_number()/256.0 - 0.5);
return result;
#else
if (resetSeed)
{
// Generate three random numbers so that anything implicitly relying on PRNG state is unchanged...
@ -8112,7 +8149,6 @@ static OOComparisonResult comparePrice(id dict1, id dict2, void * context)
}
return kZeroVector;
#endif
}