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

          Line data    Source code
       1           0 : /*
       2             : 
       3             : OOJSCall.h
       4             : 
       5             : Basic JavaScript-to-ObjC bridge implementation.
       6             : 
       7             : Oolite
       8             : Copyright (C) 2004-2013 Giles C Williams and contributors
       9             : 
      10             : This program is free software; you can redistribute it and/or
      11             : modify it under the terms of the GNU General Public License
      12             : as published by the Free Software Foundation; either version 2
      13             : of the License, or (at your option) any later version.
      14             : 
      15             : This program is distributed in the hope that it will be useful,
      16             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             : GNU General Public License for more details.
      19             : 
      20             : You should have received a copy of the GNU General Public License
      21             : along with this program; if not, write to the Free Software
      22             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      23             : MA 02110-1301, USA.
      24             : 
      25             : */
      26             : 
      27             : #ifndef NDEBUG
      28             : 
      29             : 
      30             : #import "OOJSCall.h"
      31             : #import "OOJavaScriptEngine.h"
      32             : 
      33             : #import "OOFunctionAttributes.h"
      34             : #import "ShipEntity.h"
      35             : #import "OOCollectionExtractors.h"
      36             : #import "OOShaderUniformMethodType.h"
      37             : #import "OOJSVector.h"
      38             : #import "OOJSQuaternion.h"
      39             : 
      40             : 
      41           0 : typedef enum
      42             : {
      43             :         kMethodTypeInvalid                              = kOOShaderUniformTypeInvalid,
      44             :         
      45             :         kMethodTypeCharVoid                             = kOOShaderUniformTypeChar,
      46             :         kMethodTypeUnsignedCharVoid             = kOOShaderUniformTypeUnsignedChar,
      47             :         kMethodTypeShortVoid                    = kOOShaderUniformTypeShort,
      48             :         kMethodTypeUnsignedShortVoid    = kOOShaderUniformTypeUnsignedShort,
      49             :         kMethodTypeIntVoid                              = kOOShaderUniformTypeInt,
      50             :         kMethodTypeUnsignedIntVoid              = kOOShaderUniformTypeUnsignedInt,
      51             :         kMethodTypeLongVoid                             = kOOShaderUniformTypeLong,
      52             :         kMethodTypeUnsignedLongVoid             = kOOShaderUniformTypeUnsignedLong,
      53             :         kMethodTypeFloatVoid                    = kOOShaderUniformTypeFloat,
      54             :         kMethodTypeDoubleVoid                   = kOOShaderUniformTypeDouble,
      55             :         kMethodTypeVectorVoid                   = kOOShaderUniformTypeVector,
      56             :         kMethodTypeQuaternionVoid               = kOOShaderUniformTypeQuaternion,
      57             :         kMethodTypeMatrixVoid                   = kOOShaderUniformTypeMatrix,
      58             :         kMethodTypePointVoid                    = kOOShaderUniformTypePoint,
      59             :         
      60             :         kMethodTypeObjectVoid                   = kOOShaderUniformTypeObject,
      61             :         kMethodTypeObjectObject,
      62             :         kMethodTypeVoidVoid,
      63             :         kMethodTypeVoidObject
      64             : } MethodType;
      65             : 
      66             : 
      67             : static MethodType GetMethodType(id object, SEL selector);
      68           0 : OOINLINE BOOL MethodExpectsParameter(MethodType type)   { return type == kMethodTypeVoidObject || type == kMethodTypeObjectObject; }
      69             : 
      70             : 
      71           0 : BOOL OOJSCallObjCObjectMethod(JSContext *context, id object, NSString *oo_jsClassName, uintN argc, jsval *argv, jsval *outResult)
      72             : {
      73             :         OOJS_PROFILE_ENTER
      74             :         
      75             :         NSString                                *selectorString = nil;
      76             :         SEL                                             selector = NULL;
      77             :         NSString                                *paramString = nil;
      78             :         MethodType                              type;
      79             :         BOOL                                    haveParameter = NO,
      80             :                                                         error = NO;
      81             :         id                                              result = nil;
      82             :         
      83             :         if (argc == 0)
      84             :         {
      85             :                 OOJSReportError(context, @"%@.callObjC(): no selector specified.", oo_jsClassName);
      86             :                 return NO;
      87             :         }
      88             :         
      89             :         if ([object isKindOfClass:[ShipEntity class]])
      90             :         {
      91             :                 [PLAYER setScriptTarget:object];
      92             :         }
      93             :         
      94             :         selectorString = OOStringFromJSValue(context, argv[0]);
      95             :         
      96             :         // Join all parameters together with spaces.
      97             :         if (1 < argc && [selectorString hasSuffix:@":"])
      98             :         {
      99             :                 haveParameter = YES;
     100             :                 paramString = [NSString concatenationOfStringsFromJavaScriptValues:argv + 1 count:argc - 1 separator:@" " inContext:context];
     101             :         }
     102             :         
     103             :         selector = NSSelectorFromString(selectorString);
     104             :         
     105             :         if ([object respondsToSelector:selector])
     106             :         {
     107             :                 // Validate signature.
     108             :                 type = GetMethodType(object, selector);
     109             :                 
     110             :                 if (MethodExpectsParameter(type) && !haveParameter)
     111             :                 {
     112             :                         OOJSReportError(context, @"%@.callObjC(): method %@ requires a parameter.", oo_jsClassName, selectorString);
     113             :                         error = YES;
     114             :                 }
     115             :                 else
     116             :                 {
     117             :                         IMP method = [object methodForSelector:selector];
     118             :                         switch (type)
     119             :                         {
     120             :                                 case kMethodTypeVoidObject:
     121             :                                         [object performSelector:selector withObject:paramString];
     122             :                                         break;
     123             :                                         
     124             :                                 case kMethodTypeObjectObject:
     125             :                                         result = [object performSelector:selector withObject:paramString];
     126             :                                         break;
     127             :                                         
     128             :                                 case kMethodTypeObjectVoid:
     129             :                                         result = [object performSelector:selector];
     130             :                                         if ([selectorString hasSuffix:@"_bool"])  result = [NSNumber numberWithBool:OOBooleanFromObject(result, NO)];
     131             :                                         break;
     132             :                                         
     133             :                                 case kMethodTypeVoidVoid:
     134             :                                         [object performSelector:selector];
     135             :                                         break;
     136             :                                         
     137             :                                 case kMethodTypeCharVoid:
     138             :                                 case kMethodTypeUnsignedCharVoid:
     139             :                                 case kMethodTypeShortVoid:
     140             :                                 case kMethodTypeUnsignedShortVoid:
     141             :                                 case kMethodTypeIntVoid:
     142             :                                 case kMethodTypeUnsignedIntVoid:
     143             :                                 case kMethodTypeLongVoid:
     144             :                                         result = [NSNumber numberWithLongLong:OOCallIntegerMethod(object, selector, method, (OOShaderUniformType)type)];
     145             :                                         break;
     146             :                                         
     147             :                                 case kMethodTypeUnsignedLongVoid:
     148             :                                         result = [NSNumber numberWithUnsignedLongLong:OOCallIntegerMethod(object, selector, method, (OOShaderUniformType)type)];
     149             :                                         break;
     150             :                                         
     151             :                                 case kMethodTypeFloatVoid:
     152             :                                 case kMethodTypeDoubleVoid:
     153             :                                         result = [NSNumber numberWithDouble:OOCallFloatMethod(object, selector, method, (OOShaderUniformType)type)];
     154             :                                         break;
     155             :                                         
     156             :                                 case kMethodTypeVectorVoid:
     157             :                                 {
     158             :                                         Vector v = ((VectorReturnMsgSend)method)(object, selector);
     159             :                                         *outResult = OBJECT_TO_JSVAL(JSVectorWithVector(context, v));
     160             :                                         break;
     161             :                                 }
     162             :                                         
     163             :                                 case kMethodTypeQuaternionVoid:
     164             :                                 {
     165             :                                         Quaternion q = ((QuaternionReturnMsgSend)method)(object, selector);
     166             :                                         *outResult = OBJECT_TO_JSVAL(JSQuaternionWithQuaternion(context, q));
     167             :                                         break;
     168             :                                 }
     169             :                                         
     170             :                                 case kMethodTypeMatrixVoid:
     171             :                                 case kMethodTypePointVoid:
     172             :                                 case kMethodTypeInvalid:
     173             :                                         OOJSReportError(context, @"%@.callObjC(): method %@ cannot be called from JavaScript.", oo_jsClassName, selectorString);
     174             :                                         error = YES;
     175             :                                         break;
     176             :                         }
     177             :                         if (result != nil)
     178             :                         {
     179             :                                 *outResult = [result oo_jsValueInContext:context];
     180             :                         }
     181             :                 }
     182             :         }
     183             :         else
     184             :         {
     185             :                 OOJSReportError(context, @"%@.callObjC(): %@ does not respond to method %@.", oo_jsClassName, [object shortDescription], selectorString);
     186             :                 error = YES;
     187             :         }
     188             :         
     189             :         return !error;
     190             :         
     191             :         OOJS_PROFILE_EXIT
     192             : }
     193             : 
     194             : 
     195             : // Template class providing method signature strings for the four signatures we support.
     196           0 : @interface OOJSCallMethodSignatureTemplateClass: NSObject
     197             : 
     198           0 : - (void)voidVoidMethod;
     199           0 : - (void)voidObjectMethod:(id)object;
     200           0 : - (id)objectObjectMethod:(id)object;
     201             : 
     202             : @end
     203             : 
     204             : 
     205           0 : static BOOL SignatureMatch(NSMethodSignature *sig, SEL selector)
     206             : {
     207             :         NSMethodSignature               *template = nil;
     208             :         
     209             :         template = [OOJSCallMethodSignatureTemplateClass instanceMethodSignatureForSelector:selector];
     210             :         return [sig isEqual:template];
     211             : }
     212             : 
     213             : 
     214           0 : static MethodType GetMethodType(id object, SEL selector)
     215             : {
     216             :         NSMethodSignature *sig = [object methodSignatureForSelector:selector];
     217             :         
     218             :         if (SignatureMatch(sig, @selector(voidVoidMethod)))  return kMethodTypeVoidVoid;
     219             :         if (SignatureMatch(sig, @selector(voidObjectMethod:)))  return kMethodTypeVoidObject;
     220             :         if (SignatureMatch(sig, @selector(objectObjectMethod:)))  return kMethodTypeObjectObject;
     221             :         
     222             :         MethodType type = (MethodType)OOShaderUniformTypeFromMethodSignature(sig);
     223             :         if (type != kMethodTypeInvalid)  return type;
     224             :         
     225             :         return kMethodTypeInvalid;
     226             : }
     227             : 
     228             : 
     229             : @implementation OOJSCallMethodSignatureTemplateClass: NSObject
     230             : 
     231             : - (void)voidVoidMethod {}
     232             : 
     233             : 
     234             : - (void)voidObjectMethod:(id)object {}
     235             : 
     236             : 
     237             : - (id)objectObjectMethod:(id)object { return nil; }
     238             : 
     239             : @end
     240             : 
     241             : #endif

Generated by: LCOV version 1.14