Cleaned up some invalid JS attributes. Fixed JS namespace pollution with call() and inspect(), and renamed call() to callObjC(). Mission variable names may no longer begin with underscores. Script names may no longer begin or end with underscores or whitespace. The missionVariables object may now be enumerated with for-in.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3636 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
b775065f76
commit
3c88ad59f5
@ -491,11 +491,10 @@ 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 inspect()
|
||||
Entity.inspect = function inspect()
|
||||
{
|
||||
debugConsole.inspectEntity(this);
|
||||
}
|
||||
|
||||
|
||||
// Add call() method to all entities (calls an Objective-C method directly), now only available with debug OXP to avoid abuse.
|
||||
Object.getPrototypeOf(Entity).call = debugConsole.__callObjCMethod;
|
||||
debugConsole.__setUpCallObjC(Object.prototype);
|
||||
|
@ -71,6 +71,7 @@ static JSBool ConsoleClearConsole(JSContext *context, JSObject *this, uintN argc
|
||||
static JSBool ConsoleScriptStack(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool ConsoleInspectEntity(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool ConsoleCallObjCMethod(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool ConsoleSetUpCallObjC(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool ConsoleIsExecutableJavaScript(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool ConsoleDisplayMessagesInClass(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool ConsoleSetDisplayMessagesInClass(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
@ -93,7 +94,7 @@ static JSBool PerformProfiling(JSContext *context, NSString *nominalFunction, ui
|
||||
static JSClass sConsoleClass =
|
||||
{
|
||||
"Console",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_IS_ANONYMOUS,
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
|
||||
JS_PropertyStub, // addProperty
|
||||
JS_PropertyStub, // delProperty
|
||||
@ -178,7 +179,7 @@ static JSFunctionSpec sConsoleMethods[] =
|
||||
{ "clearConsole", ConsoleClearConsole, 0 },
|
||||
{ "scriptStack", ConsoleScriptStack, 0 },
|
||||
{ "inspectEntity", ConsoleInspectEntity, 1 },
|
||||
{ "__callObjCMethod", ConsoleCallObjCMethod, 1 },
|
||||
{ "__setUpCallObjC", ConsoleSetUpCallObjC, 1, JSPROP_READONLY },
|
||||
{ "isExecutableJavaScript", ConsoleIsExecutableJavaScript, 2 },
|
||||
{ "displayMessagesInClass", ConsoleDisplayMessagesInClass, 1 },
|
||||
{ "setDisplayMessagesInClass", ConsoleSetDisplayMessagesInClass, 2 },
|
||||
@ -667,7 +668,7 @@ static JSBool ConsoleInspectEntity(JSContext *context, JSObject *this, uintN arg
|
||||
}
|
||||
|
||||
|
||||
// function __callObjCMethod(selector : String [, ...]) : Object
|
||||
// function callObjC(selector : String [, ...]) : Object
|
||||
static JSBool ConsoleCallObjCMethod(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
|
||||
{
|
||||
OOJS_NATIVE_ENTER(context)
|
||||
@ -691,6 +692,25 @@ static JSBool ConsoleCallObjCMethod(JSContext *context, JSObject *this, uintN ar
|
||||
}
|
||||
|
||||
|
||||
// function __setUpCallObjC(object) -- object is expected to be Object.prototye.
|
||||
static JSBool ConsoleSetUpCallObjC(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
|
||||
{
|
||||
OOJS_NATIVE_ENTER(context)
|
||||
|
||||
if (EXPECT_NOT(!JSVAL_IS_OBJECT(argv[0])))
|
||||
{
|
||||
OOReportJSBadArguments(context, @"Console", @"__setUpCallObjC", argc, argv, nil, @"Object.prototype");
|
||||
return NO;
|
||||
}
|
||||
|
||||
JSObject *obj = JSVAL_TO_OBJECT(argv[0]);
|
||||
JS_DefineFunction(context, obj, "callObjC", ConsoleCallObjCMethod, 1, JSPROP_PERMANENT | JSPROP_READONLY);
|
||||
return YES;
|
||||
|
||||
OOJS_NATIVE_EXIT
|
||||
}
|
||||
|
||||
|
||||
// function isExecutableJavaScript(this : Object, string : String) : Boolean
|
||||
static JSBool ConsoleIsExecutableJavaScript(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
|
||||
{
|
||||
|
@ -291,6 +291,8 @@ static JSBool MissionRunScreen(JSContext *context, JSObject *this, uintN argc, j
|
||||
return NO;
|
||||
}
|
||||
|
||||
OOJSPauseTimeLimiter();
|
||||
|
||||
if (function != JSVAL_NULL)
|
||||
{
|
||||
sCallbackScript = [[[OOJSScript currentlyRunningScript] weakRefUnderlyingObject] retain];
|
||||
@ -358,6 +360,8 @@ static JSBool MissionRunScreen(JSContext *context, JSObject *this, uintN argc, j
|
||||
[player setMissionTitle:nil];
|
||||
[player setMissionMusic:nil];
|
||||
|
||||
OOJSResumeTimeLimiter();
|
||||
|
||||
*outResult = JSVAL_TRUE;
|
||||
return YES;
|
||||
|
||||
|
@ -34,34 +34,47 @@ MA 02110-1301, USA.
|
||||
|
||||
static NSString *KeyForName(JSContext *context, jsval name)
|
||||
{
|
||||
return [@"mission_" stringByAppendingString:[NSString stringWithJavaScriptValue:name inContext:context]];
|
||||
NSCParameterAssert(JSVAL_IS_STRING(name));
|
||||
|
||||
NSString *key = [NSString stringWithJavaScriptString:JSVAL_TO_STRING(name)];
|
||||
if ([key hasPrefix:@"_"]) return nil;
|
||||
return [@"mission_" stringByAppendingString:key];
|
||||
}
|
||||
|
||||
|
||||
static JSBool MissionVariablesDeleteProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue);
|
||||
static JSBool MissionVariablesGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue);
|
||||
static JSBool MissionVariablesSetProperty(JSContext *context, JSObject *this, jsval name, jsval *value);
|
||||
static JSBool MissionVariablesEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, jsval *statep, jsid *idp);
|
||||
|
||||
|
||||
static JSClass sMissionVariablesClass =
|
||||
static JSExtendedClass sMissionVariablesClass =
|
||||
{
|
||||
{
|
||||
"MissionVariables",
|
||||
JSCLASS_IS_ANONYMOUS,
|
||||
JSCLASS_NEW_ENUMERATE | JSCLASS_IS_EXTENDED,
|
||||
|
||||
JS_PropertyStub,
|
||||
MissionVariablesDeleteProperty,
|
||||
MissionVariablesGetProperty,
|
||||
MissionVariablesSetProperty,
|
||||
JS_EnumerateStub,
|
||||
(JSEnumerateOp)MissionVariablesEnumerate,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
JS_FinalizeStub
|
||||
},
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
JSCLASS_NO_RESERVED_MEMBERS
|
||||
};
|
||||
|
||||
|
||||
void InitOOJSMissionVariables(JSContext *context, JSObject *global)
|
||||
{
|
||||
JS_DefineObject(context, global, "missionVariables", &sMissionVariablesClass, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
JS_DefineObject(context, global, "missionVariables", &sMissionVariablesClass.base, NULL, JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
}
|
||||
|
||||
|
||||
@ -91,6 +104,8 @@ static JSBool MissionVariablesGetProperty(JSContext *context, JSObject *this, js
|
||||
if (JSVAL_IS_STRING(name))
|
||||
{
|
||||
NSString *key = KeyForName(context, name);
|
||||
if (key == nil) return YES;
|
||||
|
||||
id value = [player missionVariableForKey:key];
|
||||
|
||||
*outValue = JSVAL_VOID;
|
||||
@ -142,3 +157,52 @@ static JSBool MissionVariablesSetProperty(JSContext *context, JSObject *this, js
|
||||
|
||||
OOJS_NATIVE_EXIT
|
||||
}
|
||||
|
||||
|
||||
static JSBool MissionVariablesEnumerate(JSContext *context, JSObject *object, JSIterateOp enumOp, jsval *state, jsid *idp)
|
||||
{
|
||||
OOJS_NATIVE_ENTER(context)
|
||||
|
||||
NSEnumerator *mvarEnumerator = JSVAL_TO_PRIVATE(*state);
|
||||
|
||||
switch (enumOp)
|
||||
{
|
||||
case JSENUMERATE_INIT:
|
||||
{
|
||||
// -allKeys implicitly makes a copy, which is good since the enumerating code might mutate.
|
||||
NSArray *mvars = [[[PlayerEntity sharedPlayer] missionVariables] allKeys];
|
||||
mvarEnumerator = [[mvars objectEnumerator] retain];
|
||||
*state = PRIVATE_TO_JSVAL(mvarEnumerator);
|
||||
if (idp != NULL)
|
||||
{
|
||||
*idp = INT_TO_JSVAL([mvars count]);
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
{
|
||||
id next = [mvarEnumerator nextObject];
|
||||
if (next != nil)
|
||||
{
|
||||
NSCAssert1([next hasPrefix:@"mission_"] || next == nil, @"Mission variable key without \"mission_\" prefix: %@.", next);
|
||||
next = [next substringFromIndex:8];
|
||||
|
||||
jsval val = [next javaScriptValueInContext:context];
|
||||
return JS_ValueToId(context, val, idp);
|
||||
}
|
||||
// else:
|
||||
*state = JSVAL_NULL;
|
||||
// Fall through.
|
||||
}
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
{
|
||||
[mvarEnumerator release];
|
||||
if (idp != NULL) return JS_ValueToId(context, JSVAL_VOID, idp);
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
OOJS_NATIVE_EXIT
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ static NSData *CompiledScriptData(JSContext *context, JSScript *script);
|
||||
static JSScript *ScriptWithCompiledData(JSContext *context, NSData *data);
|
||||
#endif
|
||||
|
||||
static NSString *StrippedName(NSString *string);
|
||||
|
||||
|
||||
static JSClass sScriptClass =
|
||||
{
|
||||
@ -202,7 +204,7 @@ static JSFunctionSpec sScriptMethods[] =
|
||||
{
|
||||
// Get display attributes from script
|
||||
DESTROY(name);
|
||||
name = [[[self propertyNamed:@"name"] description] copy];
|
||||
name = [StrippedName([[self propertyNamed:@"name"] description]) copy];
|
||||
if (name == nil)
|
||||
{
|
||||
name = [[self scriptNameFromPath:path] retain];
|
||||
@ -582,7 +584,7 @@ static JSFunctionSpec sScriptMethods[] =
|
||||
|
||||
if (0 == [theName length]) theName = path;
|
||||
|
||||
return [theName stringByAppendingString:@".anon-script"];
|
||||
return StrippedName([theName stringByAppendingString:@".anon-script"]);
|
||||
}
|
||||
|
||||
@end
|
||||
@ -708,3 +710,12 @@ static JSScript *ScriptWithCompiledData(JSContext *context, NSData *data)
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static NSString *StrippedName(NSString *string)
|
||||
{
|
||||
static NSCharacterSet *invalidSet = nil;
|
||||
if (invalidSet == nil) invalidSet = [[NSCharacterSet characterSetWithCharactersInString:@"_ \t\n\r\v"] retain];
|
||||
|
||||
return [string stringByTrimmingCharactersInSet:invalidSet];
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ static JSExtendedClass sSystemInfoClass =
|
||||
{
|
||||
{
|
||||
"SystemInfo",
|
||||
JSCLASS_IS_ANONYMOUS | JSCLASS_HAS_PRIVATE | JSCLASS_IS_EXTENDED,
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_IS_EXTENDED,
|
||||
|
||||
JS_PropertyStub,
|
||||
SystemInfoDeleteProperty,
|
||||
|
@ -38,7 +38,7 @@ static JSBool GetWorldScriptNames(JSContext *context, JSObject *this, jsval name
|
||||
static JSClass sWorldScriptsClass =
|
||||
{
|
||||
"WorldScripts",
|
||||
JSCLASS_IS_ANONYMOUS,
|
||||
0,
|
||||
|
||||
JS_PropertyStub,
|
||||
JS_PropertyStub,
|
||||
|
Loading…
x
Reference in New Issue
Block a user