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

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOJSEntity.m
       4             : 
       5             : Oolite
       6             : Copyright (C) 2004-2013 Giles C Williams and contributors
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #import "OOJSEntity.h"
      26             : #import "OOJSVector.h"
      27             : #import "OOJSQuaternion.h"
      28             : #import "OOJavaScriptEngine.h"
      29             : #import "OOConstToJSString.h"
      30             : #import "EntityOOJavaScriptExtensions.h"
      31             : #import "OOJSCall.h"
      32             : 
      33             : #import "OOJSPlayer.h"
      34             : #import "PlayerEntity.h"
      35             : #import "ShipEntity.h"
      36             : 
      37             : 
      38           0 : JSObject                *gOOEntityJSPrototype;
      39             : 
      40             : 
      41             : static JSBool EntityGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
      42             : static JSBool EntitySetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value);
      43             : #ifndef NDEBUG
      44             : static JSBool EntityDumpState(JSContext *context, uintN argc, jsval *vp);
      45             : #endif
      46             : 
      47             : 
      48           0 : JSClass gOOEntityJSClass =
      49             : {
      50             :         "Entity",
      51             :         JSCLASS_HAS_PRIVATE,
      52             :         
      53             :         JS_PropertyStub,                // addProperty
      54             :         JS_PropertyStub,                // delProperty
      55             :         EntityGetProperty,              // getProperty
      56             :         EntitySetProperty,              // setProperty
      57             :         JS_EnumerateStub,               // enumerate
      58             :         JS_ResolveStub,                 // resolve
      59             :         JS_ConvertStub,                 // convert
      60             :         OOJSObjectWrapperFinalize,// finalize
      61             :         JSCLASS_NO_OPTIONAL_MEMBERS
      62             : };
      63             : 
      64             : 
      65           0 : enum
      66             : {
      67             :         // Property IDs
      68             :         kEntity_collisionRadius,        // collision radius, double, read-only.
      69             :         kEntity_distanceTravelled,      // distance travelled, double, read-only.
      70             :         kEntity_energy,                         // energy, double, read-write.
      71             :         kEntity_heading,                        // heading, vector, read-only (like orientation but ignoring twist angle)
      72             :         kEntity_mass,                           // mass, double, read-only
      73             :         kEntity_maxEnergy,                      // maxEnergy, double, read-only.
      74             :         kEntity_orientation,            // orientation, quaternion, read/write
      75             :         kEntity_owner,                          // owner, Entity, read-only. (Parent ship for subentities, station for defense ships, launching ship for missiles etc)
      76             :         kEntity_position,                       // position in system space, Vector, read/write
      77             :         kEntity_scanClass,                      // scan class, string, read-only
      78             :         kEntity_spawnTime,                      // spawn time, double, read-only.
      79             :         kEntity_status,                         // entity status, string, read-only
      80             :         kEntity_isPlanet,                       // is planet, boolean, read-only.
      81             :         kEntity_isPlayer,                       // is player, boolean, read-only.
      82             :         kEntity_isShip,                         // is ship, boolean, read-only.
      83             :         kEntity_isStation,                      // is station, boolean, read-only.
      84             :         kEntity_isDock,                         // is dock, boolean, read-only.
      85             :         kEntity_isSubEntity,            // is subentity, boolean, read-only.
      86             :         kEntity_isSun,                          // is sun, boolean, read-only.
      87             :         kEntity_isSunlit,           // is sunlit, boolean, read-only.
      88             :         kEntity_isValid,                        // is not stale, boolean, read-only.
      89             :         kEntity_isInSpace,                      // is in space, boolean, read-only.
      90             :         kEntity_isVisible,                      // is within drawing distance, boolean, read-only.
      91             :         kEntity_isVisualEffect,         // is visual effect, boolean, read-only.
      92             :         kEntity_isWormhole,             // is visual effect, boolean, read-only.
      93             : };
      94             : 
      95             : 
      96           0 : static JSPropertySpec sEntityProperties[] =
      97             : {
      98             :         // JS name                                      ID                                                      flags
      99             :         { "collisionRadius",          kEntity_collisionRadius,        OOJS_PROP_READONLY_CB },
     100             :         { "distanceTravelled",                kEntity_distanceTravelled,      OOJS_PROP_READONLY_CB },
     101             :         { "energy",                                   kEntity_energy,                         OOJS_PROP_READWRITE_CB },
     102             :         { "heading",                          kEntity_heading,                        OOJS_PROP_READONLY_CB },
     103             :         { "mass",                                     kEntity_mass,                           OOJS_PROP_READONLY_CB },
     104             :         { "maxEnergy",                                kEntity_maxEnergy,                      OOJS_PROP_READWRITE_CB },
     105             :         { "orientation",                      kEntity_orientation,            OOJS_PROP_READWRITE_CB },
     106             :         { "owner",                                    kEntity_owner,                          OOJS_PROP_READONLY_CB },
     107             :         { "position",                         kEntity_position,                       OOJS_PROP_READWRITE_CB },
     108             :         { "scanClass",                                kEntity_scanClass,                      OOJS_PROP_READWRITE_CB },
     109             :         { "spawnTime",                                kEntity_spawnTime,                      OOJS_PROP_READONLY_CB },
     110             :         { "status",                                   kEntity_status,                         OOJS_PROP_READONLY_CB },
     111             :         { "isPlanet",                         kEntity_isPlanet,                       OOJS_PROP_READONLY_CB },
     112             :         { "isPlayer",                         kEntity_isPlayer,                       OOJS_PROP_READONLY_CB },
     113             :         { "isShip",                                   kEntity_isShip,                         OOJS_PROP_READONLY_CB },
     114             :         { "isDock",                                   kEntity_isDock,                         OOJS_PROP_READONLY_CB },
     115             :         { "isStation",                                kEntity_isStation,                      OOJS_PROP_READONLY_CB },
     116             :         { "isSubEntity",                      kEntity_isSubEntity,            OOJS_PROP_READONLY_CB },
     117             :         { "isSun",                                    kEntity_isSun,                          OOJS_PROP_READONLY_CB },
     118             :         { "isSunlit",               kEntity_isSunlit,           OOJS_PROP_READONLY_CB },
     119             :         { "isValid",                          kEntity_isValid,                        OOJS_PROP_READONLY_CB },
     120             :         { "isInSpace",                                kEntity_isInSpace,                      OOJS_PROP_READONLY_CB },
     121             :         { "isVisible",                                kEntity_isVisible,                      OOJS_PROP_READONLY_CB },
     122             :         { "isVisualEffect",                   kEntity_isVisualEffect,         OOJS_PROP_READONLY_CB },
     123             :         { "isWormhole",                       kEntity_isWormhole,             OOJS_PROP_READONLY_CB },
     124             :         { 0 }
     125             : };
     126             : 
     127             : 
     128           0 : static JSFunctionSpec sEntityMethods[] =
     129             : {
     130             :         // JS name                                      Function                                        min args
     131             :         { "toString",                         OOJSObjectWrapperToString,      0 },
     132             : #ifndef NDEBUG
     133             :         { "dumpState",                                EntityDumpState,                        0 },
     134             : #endif
     135             :         { 0 }
     136             : };
     137             : 
     138             : 
     139           0 : void InitOOJSEntity(JSContext *context, JSObject *global)
     140             : {
     141             :         gOOEntityJSPrototype = JS_InitClass(context, global, NULL, &gOOEntityJSClass, OOJSUnconstructableConstruct, 0, sEntityProperties, sEntityMethods, NULL, NULL);
     142             :         OOJSRegisterObjectConverter(&gOOEntityJSClass, OOJSBasicPrivateObjectConverter);
     143             : }
     144             : 
     145             : 
     146           0 : BOOL JSValueToEntity(JSContext *context, jsval value, Entity **outEntity)
     147             : {
     148             :         if (JSVAL_IS_OBJECT(value))
     149             :         {
     150             :                 return OOJSEntityGetEntity(context, JSVAL_TO_OBJECT(value), outEntity);
     151             :         }
     152             :         
     153             :         return NO;
     154             : }
     155             : 
     156             : 
     157           0 : BOOL EntityFromArgumentList(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv, Entity **outEntity, uintN *outConsumed)
     158             : {
     159             :         OOJS_PROFILE_ENTER
     160             :         
     161             :         // Sanity checks.
     162             :         if (outConsumed != NULL)  *outConsumed = 0;
     163             :         if (EXPECT_NOT(argc == 0 || argv == NULL || outEntity == NULL))
     164             :         {
     165             :                 OOLogGenericParameterError();
     166             :                 return NO;
     167             :         }
     168             :         
     169             :         // Get value, if possible.
     170             :         if (EXPECT_NOT(!JSValueToEntity(context, argv[0], outEntity)))
     171             :         {
     172             :                 // Failed; report bad parameters, if given a class and function.
     173             :                 if (scriptClass != nil && function != nil)
     174             :                 {
     175             :                         OOJSReportWarning(context, @"%@.%@(): expected entity, got %@.", scriptClass, function, [NSString stringWithJavaScriptParameters:argv count:1 inContext:context]);
     176             :                         return NO;
     177             :                 }
     178             :         }
     179             :         
     180             :         // Success.
     181             :         if (outConsumed != NULL)  *outConsumed = 1;
     182             :         return YES;
     183             :         
     184             :         OOJS_PROFILE_EXIT
     185             : }
     186             : 
     187             : 
     188           0 : static JSBool EntityGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
     189             : {
     190             :         if (!JSID_IS_INT(propID))  return YES;
     191             :         
     192             :         OOJS_NATIVE_ENTER(context)
     193             :         
     194             :         Entity                                          *entity = nil;
     195             :         id                                                      result = nil;
     196             :         
     197             :         if (EXPECT_NOT(!OOJSEntityGetEntity(context, this, &entity))) return NO;
     198             :         if (OOIsStaleEntity(entity))
     199             :         { 
     200             :                 if (JSID_TO_INT(propID) == kEntity_isValid)  *value = JSVAL_FALSE;
     201             :                 else  { *value = JSVAL_VOID; }
     202             :                 return YES;
     203             :         }
     204             :         
     205             :         switch (JSID_TO_INT(propID))
     206             :         {
     207             :                 case kEntity_collisionRadius:
     208             :                         return JS_NewNumberValue(context, [entity collisionRadius], value);
     209             :         
     210             :                 case kEntity_position:
     211             :                         return HPVectorToJSValue(context, [entity position], value);
     212             :                 
     213             :                 case kEntity_orientation:
     214             :                         return QuaternionToJSValue(context, [entity normalOrientation], value);
     215             :                 
     216             :                 case kEntity_heading:
     217             :                         return VectorToJSValue(context, vector_forward_from_quaternion([entity normalOrientation]), value);
     218             :                 
     219             :                 case kEntity_status:
     220             :                         *value = OOJSValueFromEntityStatus(context, [entity status]);
     221             :                         return YES;
     222             :                 
     223             :                 case kEntity_scanClass:
     224             :                         *value = OOJSValueFromScanClass(context, [entity scanClass]);
     225             :                         return YES;
     226             :                 
     227             :                 case kEntity_mass:
     228             :                         return JS_NewNumberValue(context, [entity mass], value);
     229             :                 
     230             :                 case kEntity_owner:
     231             :                         result = [entity owner];
     232             :                         if (result == entity)  result = nil;
     233             :                         break;
     234             :                 
     235             :                 case kEntity_energy:
     236             :                         return JS_NewNumberValue(context, [entity energy], value);
     237             :                 
     238             :                 case kEntity_maxEnergy:
     239             :                         return JS_NewNumberValue(context, [entity maxEnergy], value);
     240             :                 
     241             :                 case kEntity_isValid:
     242             :                         *value = [entity status] == STATUS_DEAD ? JSVAL_FALSE : JSVAL_TRUE;
     243             :                         return YES;
     244             : 
     245             :                 case kEntity_isInSpace:
     246             :                         *value = OOJSValueFromBOOL([entity isInSpace]);
     247             :                         return YES;
     248             :                 
     249             :                 case kEntity_isShip:
     250             :                         *value = OOJSValueFromBOOL([entity isShip]);
     251             :                         return YES;
     252             :                 
     253             :                 case kEntity_isStation:
     254             :                         *value = OOJSValueFromBOOL([entity isStation]);
     255             :                         return YES;
     256             : 
     257             :                 case kEntity_isDock:
     258             :                         *value = OOJSValueFromBOOL([entity isDock]);
     259             :                         return YES;
     260             :                         
     261             :                 case kEntity_isSubEntity:
     262             :                         *value = OOJSValueFromBOOL([entity isSubEntity]);
     263             :                         return YES;
     264             :                 
     265             :                 case kEntity_isPlayer:
     266             :                         *value = OOJSValueFromBOOL([entity isPlayer]);
     267             :                         return YES;
     268             :                         
     269             :                 case kEntity_isPlanet:
     270             :                         *value = OOJSValueFromBOOL([entity isPlanet]);
     271             :                         return YES;
     272             :                         
     273             :                 case kEntity_isSun:
     274             :                         *value = OOJSValueFromBOOL([entity isSun]);
     275             :                         return YES;
     276             :                 
     277             :                 case kEntity_isSunlit:
     278             :                         *value = OOJSValueFromBOOL([entity isSunlit]);
     279             :                         return YES;
     280             :                         
     281             :                 case kEntity_isVisible:
     282             :                         *value = OOJSValueFromBOOL([entity isVisible]);
     283             :                         return YES;
     284             : 
     285             :                 case kEntity_isVisualEffect:
     286             :                         *value = OOJSValueFromBOOL([entity isVisualEffect]);
     287             :                         return YES;
     288             : 
     289             :                 case kEntity_isWormhole:
     290             :                         *value = OOJSValueFromBOOL([entity isWormhole]);
     291             :                         return YES;
     292             :                         
     293             :                 case kEntity_distanceTravelled:
     294             :                         return JS_NewNumberValue(context, [entity distanceTravelled], value);
     295             :                 
     296             :                 case kEntity_spawnTime:
     297             :                         return JS_NewNumberValue(context, [entity spawnTime], value);
     298             :                 
     299             :                 default:
     300             :                         OOJSReportBadPropertySelector(context, this, propID, sEntityProperties);
     301             :         }
     302             :         
     303             :         *value = OOJSValueFromNativeObject(context, result);
     304             :         return YES;
     305             :         
     306             :         OOJS_NATIVE_EXIT
     307             : }
     308             : 
     309             : 
     310           0 : static JSBool EntitySetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
     311             : {
     312             :         if (!JSID_IS_INT(propID))  return YES;
     313             :         
     314             :         OOJS_NATIVE_ENTER(context)
     315             :         
     316             :         Entity                          *entity = nil;
     317             :         double                          fValue;
     318             :         HPVector                                hpvValue;
     319             :         Quaternion                      qValue;
     320             :         
     321             :         if (EXPECT_NOT(!OOJSEntityGetEntity(context, this, &entity)))  return NO;
     322             :         if (OOIsStaleEntity(entity))  return YES;
     323             :         
     324             :         switch (JSID_TO_INT(propID))
     325             :         {
     326             :                 case kEntity_position:
     327             :                         if (JSValueToHPVector(context, *value, &hpvValue))
     328             :                         {
     329             :                                 [entity setPosition:hpvValue];
     330             :                                 if ([entity isShip])
     331             :                                 {
     332             :                                         [(ShipEntity *)entity resetExhaustPlumes];
     333             :                                         [(ShipEntity *)entity forceAegisCheck];
     334             :                                 }
     335             :                                 return YES;
     336             :                         }
     337             :                         break;
     338             :                         
     339             :                 case kEntity_orientation:
     340             :                         if (JSValueToQuaternion(context, *value, &qValue))
     341             :                         {
     342             :                                 [entity setNormalOrientation:qValue];
     343             :                                 return YES;
     344             :                         }
     345             :                         break;
     346             :                         
     347             :                 case kEntity_energy:
     348             :                         if (JS_ValueToNumber(context, *value, &fValue))
     349             :                         {
     350             :                                 fValue = OOClamp_0_max_d(fValue, [entity maxEnergy]);
     351             :                                 [entity setEnergy:fValue];
     352             :                                 return YES;
     353             :                         }
     354             :                         break;
     355             : 
     356             :                 case kEntity_maxEnergy:
     357             :                         if (JS_ValueToNumber(context, *value, &fValue))
     358             :                         {
     359             :                                 if (fValue <= 0.0)
     360             :                                 {
     361             :                                         OOJSReportError(context, @"entity.maxEnergy must be positive.");
     362             :                                         return NO;
     363             :                                 }
     364             :                                 [entity setMaxEnergy:fValue];
     365             :                                 return YES;
     366             :                         }
     367             :                         break;
     368             : 
     369             : 
     370             :                 case kEntity_scanClass:
     371             :                         if ([entity isShip] && ![entity isPlayer])
     372             :                         {
     373             :                                 OOScanClass newClass = OOScanClassFromJSValue(context, *value);
     374             :                                 if (newClass == CLASS_NOT_SET || newClass == CLASS_NO_DRAW || newClass == CLASS_TARGET || newClass == CLASS_WORMHOLE || newClass == CLASS_PLAYER || newClass == CLASS_VISUAL_EFFECT)
     375             :                                 {
     376             :                                         OOJSReportError(context, @"entity.scanClass cannot be set to that value.");
     377             :                                         return NO;
     378             :                                 }
     379             :                                 [entity setScanClass:newClass];
     380             :                                 return YES;
     381             :                         }
     382             :                         else
     383             :                         {
     384             :                                 OOJSReportError(context, @"entity.scanClass is read-only except on NPC ships.");
     385             :                                 return NO;
     386             :                         }
     387             :                 default:
     388             :                         OOJSReportBadPropertySelector(context, this, propID, sEntityProperties);
     389             :                         return NO;
     390             :         }
     391             :         
     392             :         OOJSReportBadPropertyValue(context, this, propID, sEntityProperties, *value);
     393             :         return NO;
     394             :         
     395             :         OOJS_NATIVE_EXIT
     396             : }
     397             : 
     398             : 
     399             : #ifndef NDEBUG
     400           0 : static JSBool EntityDumpState(JSContext *context, uintN argc, jsval *vp)
     401             : {
     402             :         OOJS_PROFILE_ENTER
     403             :         
     404             :         Entity *thisEnt = nil;
     405             :         OOJSEntityGetEntity(context, OOJS_THIS, &thisEnt);
     406             :         [thisEnt dumpState];
     407             :         
     408             :         OOJS_RETURN_VOID;
     409             :         
     410             :         OOJS_PROFILE_EXIT       
     411             : }
     412             : #endif

Generated by: LCOV version 1.14