LCOV - code coverage report
Current view: top level - Core/Scripting - OOJSMissionVariables.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 9 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOJSMissionVariables.h
       4             : 
       5             : JavaScript mission variables object.
       6             : 
       7             : 
       8             : Oolite
       9             : Copyright (C) 2004-2013 Giles C Williams and contributors
      10             : 
      11             : This program is free software; you can redistribute it and/or
      12             : modify it under the terms of the GNU General Public License
      13             : as published by the Free Software Foundation; either version 2
      14             : of the License, or (at your option) any later version.
      15             : 
      16             : This program is distributed in the hope that it will be useful,
      17             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             : GNU General Public License for more details.
      20             : 
      21             : You should have received a copy of the GNU General Public License
      22             : along with this program; if not, write to the Free Software
      23             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      24             : MA 02110-1301, USA.
      25             : 
      26             : */
      27             : 
      28             : #import "OOJSMissionVariables.h"
      29             : #import "OOJavaScriptEngine.h"
      30             : #import "OOIsNumberLiteral.h"
      31             : 
      32             : #import "OOJSPlayer.h"
      33             : 
      34             : 
      35           0 : static NSString *KeyForPropertyID(JSContext *context, jsid propID)
      36             : {
      37             :         NSCParameterAssert(JSID_IS_STRING(propID));
      38             :         
      39             :         NSString *key = OOStringFromJSString(context, JSID_TO_STRING(propID));
      40             :         if ([key hasPrefix:@"_"])  return nil;
      41             :         return [@"mission_" stringByAppendingString:key];
      42             : }
      43             : 
      44             : 
      45             : static JSBool MissionVariablesDeleteProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
      46             : static JSBool MissionVariablesGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
      47             : static JSBool MissionVariablesSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value);
      48             : static JSBool MissionVariablesEnumerate(JSContext *context, JSObject *object, JSIterateOp enumOp, jsval *state, jsid *idp);
      49             : 
      50             : #ifndef NDEBUG
      51             : static id MissionVariablesConverter(JSContext *context, JSObject *object);
      52             : #endif
      53             : 
      54             : 
      55           0 : static JSClass sMissionVariablesClass =
      56             : {
      57             :         "MissionVariables",
      58             :         JSCLASS_NEW_ENUMERATE,
      59             :         
      60             :         JS_PropertyStub,
      61             :         MissionVariablesDeleteProperty,
      62             :         MissionVariablesGetProperty,
      63             :         MissionVariablesSetProperty,
      64             :         (JSEnumerateOp)MissionVariablesEnumerate,
      65             :         JS_ResolveStub,
      66             :         JS_ConvertStub,
      67             :         JS_FinalizeStub
      68             : };
      69             : 
      70             : 
      71           0 : void InitOOJSMissionVariables(JSContext *context, JSObject *global)
      72             : {
      73             :         JS_DefineObject(context, global, "missionVariables", &sMissionVariablesClass, NULL, OOJS_PROP_READONLY);
      74             :         
      75             : #ifndef NDEBUG
      76             :         // Allow callObjC() on missionVariables to call methods on the mission variables dictionary.
      77             :         OOJSRegisterObjectConverter(&sMissionVariablesClass, MissionVariablesConverter);
      78             : #endif
      79             : }
      80             : 
      81             : 
      82             : #ifndef NDEBUG
      83           0 : static id MissionVariablesConverter(JSContext *context, JSObject *object)
      84             : {
      85             :         return [PLAYER missionVariables];
      86             : }
      87             : #endif
      88             : 
      89             : 
      90           0 : static JSBool MissionVariablesDeleteProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
      91             : {
      92             :         OOJS_NATIVE_ENTER(context)
      93             :         
      94             :         PlayerEntity                            *player = OOPlayerForScripting();
      95             :         
      96             :         if (JSID_IS_STRING(propID))
      97             :         {
      98             :                 NSString *key = KeyForPropertyID(context, propID);
      99             :                 [player setMissionVariable:nil forKey:key];
     100             :         }
     101             :         return YES;
     102             :         
     103             :         OOJS_NATIVE_EXIT
     104             : }
     105             : 
     106             : 
     107           0 : static JSBool MissionVariablesGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
     108             : {
     109             :         OOJS_NATIVE_ENTER(context)
     110             :         
     111             :         PlayerEntity                            *player = OOPlayerForScripting();
     112             :         
     113             :         if (JSID_IS_STRING(propID))
     114             :         {
     115             :                 NSString *key = KeyForPropertyID(context, propID);
     116             :                 if (key == nil)  return YES;
     117             :                 
     118             :                 id mvar = [player missionVariableForKey:key];
     119             :                 
     120             :                 if ([mvar isKindOfClass:[NSString class]])      // Currently there should only be strings, but we may want to change this.
     121             :                 {
     122             :                         if (OOIsNumberLiteral(mvar, YES))
     123             :                         {
     124             :                                 return JS_NewNumberValue(context, [mvar doubleValue], value);
     125             :                         }
     126             :                 }
     127             :                 
     128             :                 *value = OOJSValueFromNativeObject(context, mvar);
     129             :         }
     130             :         return YES;
     131             :         
     132             :         OOJS_NATIVE_EXIT
     133             : }
     134             : 
     135             : 
     136           0 : static JSBool MissionVariablesSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
     137             : {
     138             :         OOJS_NATIVE_ENTER(context)
     139             :         
     140             :         PlayerEntity                            *player = OOPlayerForScripting();
     141             :         
     142             :         if (JSID_IS_STRING(propID))
     143             :         {
     144             :                 NSString *key = KeyForPropertyID(context, propID);
     145             :                 if (key == nil)
     146             :                 {
     147             :                         OOJSReportError(context, @"Invalid mission variable name \"%@\".", [OOStringFromJSID(propID) escapedForJavaScriptLiteral]);
     148             :                         return NO;
     149             :                 }
     150             :                 
     151             :                 NSString *objValue = OOStringFromJSValue(context, *value);
     152             :                 
     153             :                 if ([objValue isKindOfClass:[NSNull class]])  objValue = nil;
     154             :                 [player setMissionVariable:objValue forKey:key];
     155             :         }
     156             :         return YES;
     157             :         
     158             :         OOJS_NATIVE_EXIT
     159             : }
     160             : 
     161             : 
     162           0 : static JSBool MissionVariablesEnumerate(JSContext *context, JSObject *object, JSIterateOp enumOp, jsval *state, jsid *idp)
     163             : {
     164             :         OOJS_NATIVE_ENTER(context)
     165             :         
     166             :         NSEnumerator *enumerator = nil;
     167             :         
     168             :         switch (enumOp)
     169             :         {
     170             :                 case JSENUMERATE_INIT:
     171             :                 case JSENUMERATE_INIT_ALL:      // For ES5 Object.getOwnPropertyNames(). Since we have no non-enumerable properties, this is the same as _INIT.
     172             :                 {
     173             :                         // -allKeys implicitly makes a copy, which is good since the enumerating code might mutate.
     174             :                         NSArray *mvars = [[PLAYER missionVariables] allKeys];
     175             :                         enumerator = [[mvars objectEnumerator] retain];
     176             :                         *state = PRIVATE_TO_JSVAL(enumerator);
     177             :                         
     178             :                         NSUInteger count = [mvars count];
     179             :                         assert(count <= INT32_MAX);
     180             :                         if (idp != NULL)  *idp = INT_TO_JSID((uint32_t)count);
     181             :                         return YES;
     182             :                 }
     183             :                 
     184             :                 case JSENUMERATE_NEXT:
     185             :                 {
     186             :                         enumerator = JSVAL_TO_PRIVATE(*state);
     187             :                         for (;;)
     188             :                         {
     189             :                                 NSString *next = [enumerator nextObject];
     190             :                                 if (next == nil)  break;
     191             :                                 if (![next hasPrefix:@"mission_"])  continue; // Skip mission instructions, which aren't visible through missionVariables.
     192             :                                 
     193             :                                 next = [next substringFromIndex:8];             // Cut off "mission_".
     194             :                                 
     195             :                                 jsval val = [next oo_jsValueInContext:context];
     196             :                                 return JS_ValueToId(context, val, idp);
     197             :                         }
     198             :                         
     199             :                         // If we got here, we've hit the end of the enumerator.
     200             :                         *state = JSVAL_NULL;
     201             :                         // Fall through.
     202             :                 }
     203             :                 
     204             :                 case JSENUMERATE_DESTROY:
     205             :                 {
     206             :                         if (enumerator == nil && JSVAL_IS_DOUBLE(*state))
     207             :                         {
     208             :                                 enumerator = JSVAL_TO_PRIVATE(*state);
     209             :                         }
     210             :                         [enumerator release];
     211             :                         
     212             :                         if (idp != NULL)  *idp = JSID_VOID;
     213             :                         return YES;
     214             :                 }
     215             :         }
     216             :         
     217             :         OOJS_NATIVE_EXIT
     218             : }

Generated by: LCOV version 1.14