Line data Source code
1 0 : /* 2 : 3 : EntityOOJavaScriptExtensions.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 : 26 : #import "EntityOOJavaScriptExtensions.h" 27 : #import "OOJSEntity.h" 28 : #import "OOJSShip.h" 29 : #import "OOJSStation.h" 30 : #import "StationEntity.h" 31 : #import "OOJSDock.h" 32 : #import "DockEntity.h" 33 : #import "OOPlanetEntity.h" 34 : #import "OOVisualEffectEntity.h" 35 : #import "OOJSVisualEffect.h" 36 : #import "WormholeEntity.h" 37 : #import "OOJSWormhole.h" 38 : 39 : 40 : @implementation Entity (OOJavaScriptExtensions) 41 : 42 : - (BOOL) isVisibleToScripts 43 : { 44 : return NO; 45 : } 46 : 47 : 48 : - (NSString *) oo_jsClassName 49 : { 50 : return @"Entity"; 51 : } 52 : 53 : 54 0 : - (jsval) oo_jsValueInContext:(JSContext *)context 55 : { 56 : JSClass *class = NULL; 57 : JSObject *prototype = NULL; 58 : jsval result = JSVAL_NULL; 59 : 60 : if (_jsSelf == NULL && [self isVisibleToScripts]) 61 : { 62 : // Create JS object 63 : [self getJSClass:&class andPrototype:&prototype]; 64 : 65 : _jsSelf = JS_NewObject(context, class, prototype, NULL); 66 : if (_jsSelf != NULL) 67 : { 68 : if (!JS_SetPrivate(context, _jsSelf, OOConsumeReference([self weakRetain]))) _jsSelf = NULL; 69 : } 70 : 71 : if (_jsSelf != NULL) 72 : { 73 : OOJSAddGCObjectRoot(context, &_jsSelf, "Entity jsSelf"); 74 : [[NSNotificationCenter defaultCenter] addObserver:self 75 : selector:@selector(deleteJSSelf) 76 : name:kOOJavaScriptEngineWillResetNotification 77 : object:[OOJavaScriptEngine sharedEngine]]; 78 : } 79 : } 80 : 81 : if (_jsSelf != NULL) result = OBJECT_TO_JSVAL(_jsSelf); 82 : 83 : return result; 84 : // Analyzer: object leaked. [Expected, object is retained by JS object.] 85 : } 86 : 87 : 88 : - (void) getJSClass:(JSClass **)outClass andPrototype:(JSObject **)outPrototype 89 : { 90 : *outClass = JSEntityClass(); 91 : *outPrototype = JSEntityPrototype(); 92 : } 93 : 94 : 95 : - (void) deleteJSSelf 96 : { 97 : if (_jsSelf != NULL) 98 : { 99 : _jsSelf = NULL; 100 : JSContext *context = OOJSAcquireContext(); 101 : JS_RemoveObjectRoot(context, &_jsSelf); 102 : OOJSRelinquishContext(context); 103 : 104 : [[NSNotificationCenter defaultCenter] removeObserver:self 105 : name:kOOJavaScriptEngineWillResetNotification 106 : object:[OOJavaScriptEngine sharedEngine]]; 107 : } 108 : } 109 : 110 : @end 111 : 112 : 113 : @implementation ShipEntity (OOJavaScriptExtensions) 114 : 115 0 : - (BOOL) isVisibleToScripts 116 : { 117 : return YES; 118 : } 119 : 120 : 121 0 : - (void) getJSClass:(JSClass **)outClass andPrototype:(JSObject **)outPrototype 122 : { 123 : *outClass = JSShipClass(); 124 : *outPrototype = JSShipPrototype(); 125 : } 126 : 127 : 128 0 : - (NSString *) oo_jsClassName 129 : { 130 : return @"Ship"; 131 : } 132 : 133 : 134 : - (NSArray *) subEntitiesForScript 135 : { 136 : return [[self shipSubEntityEnumerator] allObjects]; 137 : } 138 : 139 : 140 : - (void) setTargetForScript:(ShipEntity *)target 141 : { 142 : ShipEntity *me = self; 143 : 144 : // Ensure coherence by not fiddling with subentities. 145 : while ([me isSubEntity]) 146 : { 147 : if (me == [me owner] || [me owner] == nil) break; 148 : me = (ShipEntity *)[me owner]; 149 : } 150 : while ([target isSubEntity]) 151 : { 152 : if (target == [target owner] || [target owner] == nil) break; 153 : target = (ShipEntity *)[target owner]; 154 : } 155 : if (![me isKindOfClass:[ShipEntity class]]) return; 156 : if (target != nil) 157 : { 158 : [me addTarget:target]; 159 : } 160 : else [me removeTarget:[me primaryTarget]]; 161 : } 162 : 163 : @end 164 :