Line data Source code
1 0 : /*
2 :
3 : OOJSPlanet.m
4 :
5 :
6 : Oolite
7 : Copyright (C) 2004-2013 Giles C Williams and contributors
8 :
9 : This program is free software; you can redistribute it and/or
10 : modify it under the terms of the GNU General Public License
11 : as published by the Free Software Foundation; either version 2
12 : of the License, or (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22 : MA 02110-1301, USA.
23 :
24 : */
25 :
26 : #import "OOJSPlanet.h"
27 : #import "OOJSEntity.h"
28 : #import "OOJavaScriptEngine.h"
29 : #import "OOJSQuaternion.h"
30 : #import "OOJSVector.h"
31 :
32 : #import "OOPlanetEntity.h"
33 :
34 :
35 0 : static JSObject *sPlanetPrototype;
36 :
37 :
38 : static JSBool PlanetGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
39 : static JSBool PlanetSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value);
40 :
41 :
42 0 : static JSClass sPlanetClass =
43 : {
44 : "Planet",
45 : JSCLASS_HAS_PRIVATE,
46 :
47 : JS_PropertyStub, // addProperty
48 : JS_PropertyStub, // delProperty
49 : PlanetGetProperty, // getProperty
50 : PlanetSetProperty, // setProperty
51 : JS_EnumerateStub, // enumerate
52 : JS_ResolveStub, // resolve
53 : JS_ConvertStub, // convert
54 : OOJSObjectWrapperFinalize,// finalize
55 : JSCLASS_NO_OPTIONAL_MEMBERS
56 : };
57 :
58 :
59 0 : enum
60 : {
61 : // Property IDs
62 : kPlanet_airColor, // air color, read/write
63 : kPlanet_airColorMixRatio, // air color mix ratio, float, read/write
64 : kPlanet_airDensity, // air density, float, read/write
65 : kPlanet_hasAtmosphere,
66 : kPlanet_illuminationColor, // illumination color, read/write
67 : kPlanet_isMainPlanet, // Is [UNIVERSE planet], boolean, read-only
68 : kPlanet_name, // Name of planet, string, read/write
69 : kPlanet_radius, // Radius of planet in metres, read-only
70 : kPlanet_texture, // Planet texture read / write
71 : kPlanet_orientation, // orientation, quaternion, read/write
72 : kPlanet_rotationalVelocity, // read/write
73 : kPlanet_terminatorThresholdVector,
74 : };
75 :
76 :
77 0 : static JSPropertySpec sPlanetProperties[] =
78 : {
79 : // JS name ID flags
80 : { "airColor", kPlanet_airColor, OOJS_PROP_READWRITE_CB },
81 : { "airColorMixRatio", kPlanet_airColorMixRatio, OOJS_PROP_READWRITE_CB },
82 : { "airDensity", kPlanet_airDensity, OOJS_PROP_READWRITE_CB },
83 : { "hasAtmosphere", kPlanet_hasAtmosphere, OOJS_PROP_READONLY_CB },
84 : { "illuminationColor", kPlanet_illuminationColor, OOJS_PROP_READWRITE_CB },
85 : { "isMainPlanet", kPlanet_isMainPlanet, OOJS_PROP_READONLY_CB },
86 : { "name", kPlanet_name, OOJS_PROP_READWRITE_CB },
87 : { "radius", kPlanet_radius, OOJS_PROP_READONLY_CB },
88 : { "rotationalVelocity", kPlanet_rotationalVelocity, OOJS_PROP_READWRITE_CB },
89 : { "texture", kPlanet_texture, OOJS_PROP_READWRITE_CB },
90 : { "orientation", kPlanet_orientation, OOJS_PROP_READWRITE_CB }, // Not documented since it's inherited from Entity
91 : { "terminatorThresholdVector", kPlanet_terminatorThresholdVector, OOJS_PROP_READWRITE_CB },
92 : { 0 }
93 : };
94 :
95 :
96 : DEFINE_JS_OBJECT_GETTER(JSPlanetGetPlanetEntity, &sPlanetClass, sPlanetPrototype, OOPlanetEntity)
97 :
98 :
99 0 : void InitOOJSPlanet(JSContext *context, JSObject *global)
100 : {
101 : sPlanetPrototype = JS_InitClass(context, global, JSEntityPrototype(), &sPlanetClass, OOJSUnconstructableConstruct, 0, sPlanetProperties, NULL, NULL, NULL);
102 : OOJSRegisterObjectConverter(&sPlanetClass, OOJSBasicPrivateObjectConverter);
103 : OOJSRegisterSubclass(&sPlanetClass, JSEntityClass());
104 : }
105 :
106 :
107 : @implementation OOPlanetEntity (OOJavaScriptExtensions)
108 :
109 0 : - (BOOL) isVisibleToScripts
110 : {
111 : OOStellarBodyType type = [self planetType];
112 : return type == STELLAR_TYPE_NORMAL_PLANET || type == STELLAR_TYPE_MOON;
113 : }
114 :
115 :
116 0 : - (void)getJSClass:(JSClass **)outClass andPrototype:(JSObject **)outPrototype
117 : {
118 : *outClass = &sPlanetClass;
119 : *outPrototype = sPlanetPrototype;
120 : }
121 :
122 :
123 0 : - (NSString *) oo_jsClassName
124 : {
125 : switch ([self planetType])
126 : {
127 : case STELLAR_TYPE_NORMAL_PLANET:
128 : return @"Planet";
129 : case STELLAR_TYPE_MOON:
130 : return @"Moon";
131 : default:
132 : return @"Unknown";
133 : }
134 : }
135 :
136 : @end
137 :
138 :
139 0 : static JSBool PlanetGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
140 : {
141 : if (!JSID_IS_INT(propID)) return YES;
142 :
143 : OOJS_NATIVE_ENTER(context)
144 :
145 : OOPlanetEntity *planet = nil;
146 : if (!JSPlanetGetPlanetEntity(context, this, &planet)) return NO;
147 :
148 : switch (JSID_TO_INT(propID))
149 : {
150 : case kPlanet_airColor:
151 : *value = OOJSValueFromNativeObject(context, [[planet airColor] normalizedArray]);
152 : return YES;
153 :
154 : case kPlanet_airColorMixRatio:
155 : return JS_NewNumberValue(context, [planet airColorMixRatio], value);
156 :
157 : case kPlanet_airDensity:
158 : return JS_NewNumberValue(context, [planet airDensity], value);
159 :
160 : case kPlanet_illuminationColor:
161 : *value = OOJSValueFromNativeObject(context, [[planet illuminationColor] normalizedArray]);
162 : return YES;
163 :
164 : case kPlanet_isMainPlanet:
165 : *value = OOJSValueFromBOOL(planet == (id)[UNIVERSE planet]);
166 : return YES;
167 :
168 : case kPlanet_radius:
169 : return JS_NewNumberValue(context, [planet radius], value);
170 :
171 : case kPlanet_hasAtmosphere:
172 : *value = OOJSValueFromBOOL([planet hasAtmosphere]);
173 : return YES;
174 :
175 : case kPlanet_texture:
176 : *value = OOJSValueFromNativeObject(context, [planet textureFileName]);
177 : return YES;
178 :
179 : case kPlanet_name:
180 : *value = OOJSValueFromNativeObject(context, [planet name]);
181 : return YES;
182 :
183 : case kPlanet_orientation:
184 : return QuaternionToJSValue(context, [planet normalOrientation], value);
185 :
186 : case kPlanet_rotationalVelocity:
187 : return JS_NewNumberValue(context, [planet rotationalVelocity], value);
188 :
189 : case kPlanet_terminatorThresholdVector:
190 : return VectorToJSValue(context, [planet terminatorThresholdVector], value);
191 :
192 : default:
193 : OOJSReportBadPropertySelector(context, this, propID, sPlanetProperties);
194 : return NO;
195 : }
196 :
197 : OOJS_NATIVE_EXIT
198 : }
199 :
200 :
201 0 : static JSBool PlanetSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
202 : {
203 : if (!JSID_IS_INT(propID)) return YES;
204 :
205 : OOJS_NATIVE_ENTER(context)
206 :
207 : OOPlanetEntity *planet = nil;
208 : NSString *sValue = nil;
209 : Quaternion qValue;
210 : Vector vValue;
211 : jsdouble dValue;
212 : OOColor *colorForScript = nil;
213 :
214 : if (!JSPlanetGetPlanetEntity(context, this, &planet)) return NO;
215 :
216 : switch (JSID_TO_INT(propID))
217 : {
218 : case kPlanet_airColor:
219 : colorForScript = [OOColor colorWithDescription:OOJSNativeObjectFromJSValue(context, *value)];
220 : if (colorForScript != nil || JSVAL_IS_NULL(*value))
221 : {
222 : [planet setAirColor:colorForScript];
223 : return YES;
224 : }
225 : break;
226 :
227 : case kPlanet_airColorMixRatio:
228 : if (JS_ValueToNumber(context, *value, &dValue))
229 : {
230 : [planet setAirColorMixRatio:dValue];
231 : return YES;
232 : }
233 : break;
234 :
235 : case kPlanet_airDensity:
236 : if (JS_ValueToNumber(context, *value, &dValue))
237 : {
238 : [planet setAirDensity:dValue];
239 : return YES;
240 : }
241 : break;
242 :
243 : case kPlanet_illuminationColor:
244 : colorForScript = [OOColor colorWithDescription:OOJSNativeObjectFromJSValue(context, *value)];
245 : if (colorForScript != nil || JSVAL_IS_NULL(*value))
246 : {
247 : [planet setIlluminationColor:colorForScript];
248 : return YES;
249 : }
250 : break;
251 :
252 : case kPlanet_name:
253 : sValue = OOStringFromJSValue(context, *value);
254 : [planet setName:sValue];
255 : return YES;
256 :
257 : case kPlanet_texture:
258 : {
259 : BOOL OK = NO;
260 : sValue = OOStringFromJSValue(context, *value);
261 :
262 : OOJSPauseTimeLimiter();
263 :
264 : if ([planet isKindOfClass:[OOPlanetEntity class]])
265 : {
266 : if (sValue == nil)
267 : {
268 : OOJSReportWarning(context, @"Expected texture string. Value not set.");
269 : }
270 : else
271 : {
272 : OK = YES;
273 : }
274 : }
275 :
276 : if (OK)
277 : {
278 : OK = [planet setUpPlanetFromTexture:sValue];
279 : if (!OK) OOJSReportWarning(context, @"Cannot find texture \"%@\". Value not set.", sValue);
280 : }
281 :
282 : OOJSResumeTimeLimiter();
283 :
284 : return YES; // Even if !OK, no exception was raised.
285 : }
286 :
287 : case kPlanet_orientation:
288 : if (JSValueToQuaternion(context, *value, &qValue))
289 : {
290 : quaternion_normalize(&qValue);
291 : [planet setOrientation:qValue];
292 : return YES;
293 : }
294 : break;
295 :
296 : case kPlanet_rotationalVelocity:
297 : if (JS_ValueToNumber(context, *value, &dValue))
298 : {
299 : [planet setRotationalVelocity:dValue];
300 : return YES;
301 : }
302 : break;
303 :
304 : case kPlanet_terminatorThresholdVector:
305 : if (JSValueToVector(context, *value, &vValue))
306 : {
307 : [planet setTerminatorThresholdVector:vValue];
308 : return YES;
309 : }
310 : break;
311 :
312 : default:
313 : OOJSReportBadPropertySelector(context, this, propID, sPlanetProperties);
314 : return NO;
315 : }
316 :
317 : OOJSReportBadPropertyValue(context, this, propID, sPlanetProperties, *value);
318 : return NO;
319 :
320 : OOJS_NATIVE_EXIT
321 : }
|