Line data Source code
1 0 : /*
2 :
3 : OOJSManifest.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 "OOJSManifest.h"
26 : #import "OOJavaScriptEngine.h"
27 : #import "PlayerEntity.h"
28 : #import "PlayerEntityScriptMethods.h"
29 : #import "PlayerEntityContracts.h"
30 : #import "Universe.h"
31 : #import "OOJSPlayer.h"
32 : #import "OOJSPlayerShip.h"
33 : #import "OOIsNumberLiteral.h"
34 :
35 :
36 0 : static JSObject *sManifestPrototype;
37 0 : static JSObject *sManifestObject;
38 :
39 : static JSBool ManifestComment(JSContext *context, uintN argc, jsval *vp);
40 : static JSBool ManifestSetComment(JSContext *context, uintN argc, jsval *vp);
41 : static JSBool ManifestShortComment(JSContext *context, uintN argc, jsval *vp);
42 : static JSBool ManifestSetShortComment(JSContext *context, uintN argc, jsval *vp);
43 :
44 :
45 : static JSBool ManifestDeleteProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
46 : static JSBool ManifestGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
47 : static JSBool ManifestSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value);
48 :
49 :
50 0 : static JSClass sManifestClass =
51 : {
52 : "Manifest",
53 : JSCLASS_HAS_PRIVATE,
54 :
55 : JS_PropertyStub,
56 : ManifestDeleteProperty,
57 : ManifestGetProperty,
58 : ManifestSetProperty,
59 : JS_EnumerateStub,
60 : JS_ResolveStub,
61 : JS_ConvertStub,
62 : OOJSObjectWrapperFinalize,
63 : JSCLASS_NO_OPTIONAL_MEMBERS
64 : };
65 :
66 :
67 0 : enum
68 : {
69 : kManifest_list // manifest list, array of commodities: name, unit, quantity, displayName - read-only
70 : };
71 :
72 :
73 0 : static JSPropertySpec sManifestProperties[] =
74 : {
75 : // JS name ID flags
76 : { "list", kManifest_list, OOJS_PROP_READONLY_CB },
77 : { 0 }
78 : };
79 :
80 :
81 0 : static JSFunctionSpec sManifestMethods[] =
82 : {
83 : // JS name Function min args
84 : { "shortComment", ManifestShortComment, 1 },
85 : { "setShortComment", ManifestSetShortComment, 2 },
86 : { "comment", ManifestComment, 1 },
87 : { "setComment", ManifestSetComment, 2 },
88 : { 0 }
89 : };
90 :
91 :
92 : // Helper class wrapped by JS Manifest objects
93 0 : @interface OOManifest: NSObject
94 : @end
95 :
96 :
97 : @implementation OOManifest
98 :
99 0 : - (void) dealloc
100 : {
101 : [super dealloc];
102 : }
103 :
104 :
105 0 : - (NSString *) oo_jsClassName
106 : {
107 : return @"Manifest";
108 : }
109 :
110 :
111 0 : - (jsval) oo_jsValueInContext:(JSContext *)context
112 : {
113 : JSObject *jsSelf = NULL;
114 : jsval result = JSVAL_NULL;
115 :
116 : jsSelf = JS_NewObject(context, &sManifestClass, sManifestPrototype, NULL);
117 : if (jsSelf != NULL)
118 : {
119 : if (!JS_SetPrivate(context, jsSelf, [self retain])) jsSelf = NULL;
120 : }
121 : if (jsSelf != NULL) result = OBJECT_TO_JSVAL(jsSelf);
122 :
123 : return result;
124 : }
125 :
126 : @end
127 :
128 :
129 0 : void InitOOJSManifest(JSContext *context, JSObject *global)
130 : {
131 : sManifestPrototype = JS_InitClass(context, global, NULL, &sManifestClass, OOJSUnconstructableConstruct, 0, sManifestProperties, sManifestMethods, NULL, NULL);
132 : OOJSRegisterObjectConverter(&sManifestClass, OOJSBasicPrivateObjectConverter);
133 :
134 : // Create manifest object as a property of the player.ship object.
135 : sManifestObject = JS_DefineObject(context, JSPlayerShipObject(), "manifest", &sManifestClass, sManifestPrototype, OOJS_PROP_READONLY);
136 : JS_SetPrivate(context, sManifestObject, NULL);
137 :
138 : // Also define manifest object as a property of the global object.
139 : // Wait, what? Why? Oh well, too late now. Deprecate for EMMSTRAN? -- Ahruman 2011-02-10
140 : JS_DefineObject(context, global, "manifest", &sManifestClass, sManifestPrototype, OOJS_PROP_READONLY);
141 :
142 : }
143 :
144 :
145 0 : static JSBool ManifestDeleteProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
146 : {
147 : jsval v = JSVAL_VOID;
148 : return ManifestSetProperty(context, this, propID, NO, &v);
149 : }
150 :
151 :
152 0 : static JSBool ManifestGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
153 : {
154 : OOJS_NATIVE_ENTER(context)
155 :
156 : id result = nil;
157 : PlayerEntity *entity = OOPlayerForScripting();
158 :
159 : if (JSID_IS_INT(propID))
160 : {
161 : switch (JSID_TO_INT(propID))
162 : {
163 : case kManifest_list:
164 : result = [entity cargoListForScripting];
165 : break;
166 :
167 : default:
168 : OOJSReportBadPropertySelector(context, this, propID, sManifestProperties);
169 : return NO;
170 : }
171 : }
172 : else if (JSID_IS_STRING(propID))
173 : {
174 : /* 'list' property is hard-coded
175 : * others map to the commodity keys in trade-goods.plist
176 : * compatible-ish with 1.80 and earlier except that
177 : * alienItems and similar aliases don't work */
178 : NSString *key = OOStringFromJSString(context, JSID_TO_STRING(propID));
179 : if ([[UNIVERSE commodities] goodDefined:key])
180 : {
181 : *value = INT_TO_JSVAL([entity cargoQuantityForType:key]);
182 : return YES;
183 : }
184 : else
185 : {
186 : return YES;
187 : }
188 : }
189 :
190 : *value = OOJSValueFromNativeObject(context, result);
191 : return YES;
192 :
193 : OOJS_NATIVE_EXIT
194 : }
195 :
196 :
197 0 : static JSBool ManifestSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
198 : {
199 : OOJS_NATIVE_ENTER(context)
200 :
201 : PlayerEntity *entity = OOPlayerForScripting();
202 : int32 iValue;
203 :
204 : if (JSID_IS_STRING(propID))
205 : {
206 : NSString *key = OOStringFromJSString(context, JSID_TO_STRING(propID));
207 :
208 : OOMassUnit unit = [[UNIVERSE commodityMarket] massUnitForGood:key];
209 : // we can always change gold, platinum & gem-stones quantities, even with special cargo
210 : if (unit == UNITS_TONS && [entity specialCargo])
211 : {
212 : OOJSReportWarning(context, @"PlayerShip.manifest['foo'] - cannot modify cargo tonnage when Special Cargo is in use.");
213 : return YES;
214 : }
215 :
216 : if (JS_ValueToInt32(context, *value, &iValue))
217 : {
218 : if (iValue < 0) iValue = 0;
219 : [entity setCargoQuantityForType:key amount:iValue];
220 : }
221 : else
222 : {
223 : OOJSReportBadPropertyValue(context, this, propID, sManifestProperties, *value);
224 : }
225 : }
226 : return YES;
227 :
228 : OOJS_NATIVE_EXIT
229 : }
230 :
231 :
232 0 : static JSBool ManifestComment(JSContext *context, uintN argc, jsval *vp)
233 : {
234 : OOJS_NATIVE_ENTER(context)
235 :
236 : OOCommodityType good = nil;
237 : NSString * information = nil;
238 :
239 : if (argc > 0)
240 : {
241 : good = OOStringFromJSValue(context, OOJS_ARGV[0]);
242 : }
243 : if (good == nil)
244 : {
245 : OOJSReportBadArguments(context, @"Manifest", @"comment", MIN(argc, 1U), OOJS_ARGV, nil, @"good");
246 : return NO;
247 : }
248 :
249 : information = [[PLAYER shipCommodityData] commentForGood:good];
250 :
251 : OOJS_RETURN_OBJECT(information);
252 :
253 : OOJS_NATIVE_EXIT
254 : }
255 :
256 :
257 0 : static JSBool ManifestSetComment(JSContext *context, uintN argc, jsval *vp)
258 : {
259 : OOJS_NATIVE_ENTER(context)
260 :
261 : BOOL OK;
262 : OOCommodityType good = nil;
263 : NSString * information = nil;
264 :
265 : if (argc > 1)
266 : {
267 : good = OOStringFromJSValue(context, OOJS_ARGV[0]);
268 : information = OOStringFromJSValue(context, OOJS_ARGV[1]);
269 : }
270 : if (good == nil || information == nil)
271 : {
272 : OOJSReportBadArguments(context, @"Manifest", @"setComment", MIN(argc, 2U), OOJS_ARGV, nil, @"good and information text");
273 : return NO;
274 : }
275 :
276 : OK = [[PLAYER shipCommodityData] setComment:information forGood:good];
277 :
278 : OOJS_RETURN_BOOL(OK);
279 :
280 : OOJS_NATIVE_EXIT
281 : }
282 :
283 :
284 0 : static JSBool ManifestShortComment(JSContext *context, uintN argc, jsval *vp)
285 : {
286 : OOJS_NATIVE_ENTER(context)
287 :
288 : OOCommodityType good = nil;
289 : NSString * information = nil;
290 :
291 : if (argc > 0)
292 : {
293 : good = OOStringFromJSValue(context, OOJS_ARGV[0]);
294 : }
295 : if (good == nil)
296 : {
297 : OOJSReportBadArguments(context, @"Manifest", @"shortComment", MIN(argc, 1U), OOJS_ARGV, nil, @"good");
298 : return NO;
299 : }
300 :
301 : information = [[PLAYER shipCommodityData] shortCommentForGood:good];
302 :
303 : OOJS_RETURN_OBJECT(information);
304 :
305 : OOJS_NATIVE_EXIT
306 : }
307 :
308 :
309 0 : static JSBool ManifestSetShortComment(JSContext *context, uintN argc, jsval *vp)
310 : {
311 : OOJS_NATIVE_ENTER(context)
312 :
313 : BOOL OK;
314 : OOCommodityType good = nil;
315 : NSString * information = nil;
316 :
317 : if (argc > 1)
318 : {
319 : good = OOStringFromJSValue(context, OOJS_ARGV[0]);
320 : information = OOStringFromJSValue(context, OOJS_ARGV[1]);
321 : }
322 : if (good == nil || information == nil)
323 : {
324 : OOJSReportBadArguments(context, @"Manifest", @"setShortComment", MIN(argc, 2U), OOJS_ARGV, nil, @"good and information text");
325 : return NO;
326 : }
327 :
328 : OK = [[PLAYER shipCommodityData] setShortComment:information forGood:good];
329 :
330 : OOJS_RETURN_BOOL(OK);
331 :
332 : OOJS_NATIVE_EXIT
333 : }
|