Line data Source code
1 0 : /*
2 :
3 : OOJSSoundSource.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 "OOJSSound.h"
26 : #import "OOJSVector.h"
27 : #import "OOJavaScriptEngine.h"
28 : #import "OOSound.h"
29 : #import "ResourceManager.h"
30 :
31 :
32 0 : static JSObject *sSoundSourcePrototype;
33 :
34 :
35 : static JSBool SoundSourceGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value);
36 : static JSBool SoundSourceSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value);
37 : static JSBool SoundSourceConstruct(JSContext *context, uintN argc, jsval *vp);
38 :
39 : // Methods
40 : static JSBool SoundSourcePlay(JSContext *context, uintN argc, jsval *vp);
41 : static JSBool SoundSourceStop(JSContext *context, uintN argc, jsval *vp);
42 : static JSBool SoundSourcePlayOrRepeat(JSContext *context, uintN argc, jsval *vp);
43 :
44 :
45 0 : static JSClass sSoundSourceClass =
46 : {
47 : "SoundSource",
48 : JSCLASS_HAS_PRIVATE,
49 :
50 : JS_PropertyStub, // addProperty
51 : JS_PropertyStub, // delProperty
52 : SoundSourceGetProperty, // getProperty
53 : SoundSourceSetProperty, // setProperty
54 : JS_EnumerateStub, // enumerate
55 : JS_ResolveStub, // resolve
56 : JS_ConvertStub, // convert
57 : OOJSObjectWrapperFinalize, // finalize
58 : JSCLASS_NO_OPTIONAL_MEMBERS
59 : };
60 :
61 :
62 0 : enum
63 : {
64 : // Property IDs
65 : kSoundSource_sound,
66 : kSoundSource_isPlaying,
67 : kSoundSource_loop,
68 : kSoundSource_position,
69 : kSoundSource_positional,
70 : kSoundSource_repeatCount,
71 : kSoundSource_volume
72 : };
73 :
74 :
75 0 : static JSPropertySpec sSoundSourceProperties[] =
76 : {
77 : // JS name ID flags
78 : { "isPlaying", kSoundSource_isPlaying, OOJS_PROP_READONLY_CB },
79 : { "loop", kSoundSource_loop, OOJS_PROP_READWRITE_CB },
80 : { "position", kSoundSource_position, OOJS_PROP_READWRITE_CB },
81 : { "positional", kSoundSource_positional, OOJS_PROP_READWRITE_CB },
82 : { "repeatCount", kSoundSource_repeatCount, OOJS_PROP_READWRITE_CB },
83 : { "sound", kSoundSource_sound, OOJS_PROP_READWRITE_CB },
84 : { "volume", kSoundSource_volume, OOJS_PROP_READWRITE_CB },
85 : { 0 }
86 : };
87 :
88 :
89 0 : static JSFunctionSpec sSoundSourceMethods[] =
90 : {
91 : // JS name Function min args
92 : { "toString", OOJSObjectWrapperToString, 0, },
93 : { "play", SoundSourcePlay, 0, },
94 : { "playOrRepeat", SoundSourcePlayOrRepeat, 0, },
95 : // playSound is defined in oolite-global-prefix.js.
96 : { "stop", SoundSourceStop, 0, },
97 : { 0 }
98 : };
99 :
100 :
101 : DEFINE_JS_OBJECT_GETTER(JSSoundSourceGetSoundSource, &sSoundSourceClass, sSoundSourcePrototype, OOSoundSource)
102 :
103 :
104 : // *** Public ***
105 :
106 0 : void InitOOJSSoundSource(JSContext *context, JSObject *global)
107 : {
108 : sSoundSourcePrototype = JS_InitClass(context, global, NULL, &sSoundSourceClass, SoundSourceConstruct, 0, sSoundSourceProperties, sSoundSourceMethods, NULL, NULL);
109 : OOJSRegisterObjectConverter(&sSoundSourceClass, OOJSBasicPrivateObjectConverter);
110 : }
111 :
112 :
113 0 : static JSBool SoundSourceConstruct(JSContext *context, uintN argc, jsval *vp)
114 : {
115 : OOJS_NATIVE_ENTER(context)
116 :
117 : if (EXPECT_NOT(!JS_IsConstructing(context, vp)))
118 : {
119 : OOJSReportError(context, @"SoundSource() cannot be called as a function, it must be used as a constructor (as in new SoundSource()).");
120 : return NO;
121 : }
122 :
123 : OOJS_RETURN_OBJECT([[[OOSoundSource alloc] init] autorelease]);
124 :
125 : OOJS_NATIVE_EXIT
126 : }
127 :
128 :
129 : // *** Implementation stuff ***
130 :
131 0 : static JSBool SoundSourceGetProperty(JSContext *context, JSObject *this, jsid propID, jsval *value)
132 : {
133 : if (!JSID_IS_INT(propID)) return YES;
134 :
135 : OOJS_NATIVE_ENTER(context)
136 :
137 : OOSoundSource *soundSource = nil;
138 :
139 : if (!JSSoundSourceGetSoundSource(context, this, &soundSource)) return NO;
140 :
141 : switch (JSID_TO_INT(propID))
142 : {
143 : case kSoundSource_sound:
144 : *value = OOJSValueFromNativeObject(context, [soundSource sound]);
145 : return YES;
146 :
147 : case kSoundSource_isPlaying:
148 : *value = OOJSValueFromBOOL([soundSource isPlaying]);
149 : return YES;
150 :
151 : case kSoundSource_loop:
152 : *value = OOJSValueFromBOOL([soundSource loop]);
153 : return YES;
154 :
155 : case kSoundSource_repeatCount:
156 : *value = INT_TO_JSVAL([soundSource repeatCount]);
157 : return YES;
158 :
159 : case kSoundSource_position:
160 : return VectorToJSValue(context, [soundSource position], value);
161 :
162 : case kSoundSource_positional:
163 : *value = OOJSValueFromBOOL([soundSource positional]);
164 : return YES;
165 :
166 : case kSoundSource_volume:
167 : return JS_NewNumberValue(context, [soundSource gain], value);
168 :
169 :
170 : default:
171 : OOJSReportBadPropertySelector(context, this, propID, sSoundSourceProperties);
172 : return NO;
173 : }
174 :
175 : OOJS_NATIVE_EXIT
176 : }
177 :
178 :
179 0 : static JSBool SoundSourceSetProperty(JSContext *context, JSObject *this, jsid propID, JSBool strict, jsval *value)
180 : {
181 : if (!JSID_IS_INT(propID)) return YES;
182 :
183 : OOJS_NATIVE_ENTER(context)
184 :
185 : OOSoundSource *soundSource = nil;
186 : int32 iValue;
187 : JSBool bValue;
188 : Vector vValue;
189 : double fValue;
190 :
191 : if (!JSSoundSourceGetSoundSource(context, this, &soundSource)) return NO;
192 :
193 : switch (JSID_TO_INT(propID))
194 : {
195 : case kSoundSource_sound:
196 : [soundSource setSound:SoundFromJSValue(context, *value)];
197 : return YES;
198 : break;
199 :
200 : case kSoundSource_loop:
201 : if (JS_ValueToBoolean(context, *value, &bValue))
202 : {
203 : [soundSource setLoop:bValue];
204 : return YES;
205 : }
206 : break;
207 :
208 : case kSoundSource_repeatCount:
209 : if (JS_ValueToInt32(context, *value, &iValue))
210 : {
211 : if (iValue > 100) iValue = 100;
212 : if (100 < 1) iValue = 1;
213 : [soundSource setRepeatCount:iValue];
214 : return YES;
215 : }
216 : break;
217 :
218 :
219 : case kSoundSource_position:
220 : if (JSValueToVector(context, *value, &vValue))
221 : {
222 : [soundSource setPosition:vValue];
223 : return YES;
224 : }
225 : break;
226 :
227 : case kSoundSource_positional:
228 : if (JS_ValueToBoolean(context, *value, &bValue))
229 : {
230 : [soundSource setPositional:bValue];
231 : return YES;
232 : }
233 : break;
234 :
235 : case kSoundSource_volume:
236 : if (JS_ValueToNumber(context, *value, &fValue))
237 : {
238 : fValue = OOClamp_0_max_d(fValue, 1);
239 : [soundSource setGain:fValue];
240 : return YES;
241 : }
242 : break;
243 :
244 : default:
245 : OOJSReportBadPropertySelector(context, this, propID, sSoundSourceProperties);
246 : return NO;
247 : }
248 :
249 : OOJSReportBadPropertyValue(context, this, propID, sSoundSourceProperties, *value);
250 : return NO;
251 :
252 : OOJS_NATIVE_EXIT
253 : }
254 :
255 :
256 : // *** Methods ***
257 :
258 : // play([count : Number])
259 0 : static JSBool SoundSourcePlay(JSContext *context, uintN argc, jsval *vp)
260 : {
261 : OOJS_NATIVE_ENTER(context)
262 :
263 : OOSoundSource *thisv = nil;
264 : int32 count = 0;
265 :
266 : if (EXPECT_NOT(!JSSoundSourceGetSoundSource(context, OOJS_THIS, &thisv))) return NO;
267 : if (argc > 0 && !JSVAL_IS_VOID(OOJS_ARGV[0]) && !JS_ValueToInt32(context, OOJS_ARGV[0], &count))
268 : {
269 : OOJSReportBadArguments(context, @"SoundSource", @"play", 1, OOJS_ARGV, nil, @"integer count or no argument");
270 : return NO;
271 : }
272 :
273 : if (count > 0)
274 : {
275 : if (count > 100) count = 100;
276 : [thisv setRepeatCount:count];
277 : }
278 :
279 : OOJS_BEGIN_FULL_NATIVE(context)
280 : [thisv play];
281 : OOJS_END_FULL_NATIVE
282 :
283 : OOJS_RETURN_VOID;
284 :
285 : OOJS_NATIVE_EXIT
286 : }
287 :
288 :
289 : // stop()
290 0 : static JSBool SoundSourceStop(JSContext *context, uintN argc, jsval *vp)
291 : {
292 : OOJS_NATIVE_ENTER(context)
293 :
294 : OOSoundSource *thisv = nil;
295 :
296 : if (EXPECT_NOT(!JSSoundSourceGetSoundSource(context, OOJS_THIS, &thisv))) return NO;
297 :
298 : OOJS_BEGIN_FULL_NATIVE(context)
299 : [thisv stop];
300 : OOJS_END_FULL_NATIVE
301 :
302 : OOJS_RETURN_VOID;
303 :
304 : OOJS_NATIVE_EXIT
305 : }
306 :
307 :
308 : // playOrRepeat()
309 0 : static JSBool SoundSourcePlayOrRepeat(JSContext *context, uintN argc, jsval *vp)
310 : {
311 : OOJS_NATIVE_ENTER(context)
312 :
313 : OOSoundSource *thisv = nil;
314 :
315 : if (EXPECT_NOT(!JSSoundSourceGetSoundSource(context, OOJS_THIS, &thisv))) return NO;
316 :
317 : OOJS_BEGIN_FULL_NATIVE(context)
318 : [thisv playOrRepeat];
319 : OOJS_END_FULL_NATIVE
320 :
321 : OOJS_RETURN_VOID;
322 :
323 : OOJS_NATIVE_EXIT
324 : }
325 :
326 :
327 : @implementation OOSoundSource (OOJavaScriptExtentions)
328 :
329 0 : - (jsval) oo_jsValueInContext:(JSContext *)context
330 : {
331 : JSObject *jsSelf = NULL;
332 : jsval result = JSVAL_NULL;
333 :
334 : jsSelf = JS_NewObject(context, &sSoundSourceClass, sSoundSourcePrototype, NULL);
335 : if (jsSelf != NULL)
336 : {
337 : if (!JS_SetPrivate(context, jsSelf, [self retain])) jsSelf = NULL;
338 : }
339 : if (jsSelf != NULL) result = OBJECT_TO_JSVAL(jsSelf);
340 :
341 : return result;
342 : }
343 :
344 :
345 0 : - (NSString *) oo_jsClassName
346 : {
347 : return @"SoundSource";
348 : }
349 :
350 : @end
|