FreeWRL / FreeX3D 4.3.0
jsVRMLClasses.c
1/*
2
3
4???
5
6*/
7
8/****************************************************************************
9 This file is part of the FreeWRL/FreeX3D Distribution.
10
11 Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12
13 FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14 it under the terms of the GNU Lesser Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25****************************************************************************/
26
27
28#include <config.h>
29#if !defined(JS_SMCPP)
30#include <system.h>
31//#if !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK))
32#ifdef JAVASCRIPT_SM
33#include <system_threads.h>
34#include <display.h>
35#include <internal.h>
36
37#include <libFreeWRL.h>
38
39
40#include "../vrml_parser/Structs.h"
41#include "../main/headers.h"
42#include "../vrml_parser/CParseGeneral.h"
43#include "../main/Snapshot.h"
44#include "../scenegraph/Collision.h"
45#include "../scenegraph/quaternion.h"
46#include "../scenegraph/Viewer.h"
47#include "../input/SensInterps.h"
48#include "../x3d_parser/Bindable.h"
49
50#include "JScript.h"
51#include "CScripts.h"
52#include "jsUtils.h"
53#include "jsNative.h"
54#include "jsVRMLClasses.h"
55
56
57/********************************************************/
58/* */
59/* first part - standard helper functions */
60/* */
61/********************************************************/
62
63void _get4f(double *ret, double *mat, int row);
64void _set4f(double len, double *mat, int row);
65
66/* for keeping track of the ECMA values */
67#define ECMAValueTableSize 300
68/* for keeping track of the ECMA values */
69struct ECMAValueStruct {
70 jsval JS_address;
71 JSContext *context;
72 int valueChanged;
73 char *name;
74};
75
76//struct ECMAValueStruct ECMAValues[ECMAValueTableSize];
77//int maxECMAVal = 0;
78
79typedef struct pjsVRMLClasses{
80 struct ECMAValueStruct ECMAValues[ECMAValueTableSize];
81 int maxECMAVal;// = 0;
82}* ppjsVRMLClasses;
83void *jsVRMLClasses_constructor(){
84 void *v = MALLOCV(sizeof(struct pjsVRMLClasses));
85 memset(v,0,sizeof(struct pjsVRMLClasses));
86 return v;
87}
88void jsVRMLClasses_init(struct tjsVRMLClasses *t){
89 //public
90 //private
91 t->prv = jsVRMLClasses_constructor();
92 {
93 ppjsVRMLClasses p = (ppjsVRMLClasses)t->prv;
94 //p->ECMAValues[ECMAValueTableSize];
95 p->maxECMAVal = 0;
96 }
97}
98// ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
99/*
100 * VRML Node types as JS classes:
101 */
102
103
104
105JSClass SFColorClass = {
106 "SFColor",
107 JSCLASS_HAS_PRIVATE,
108 JS_PropertyStub,
109 JS_PropertyStub,
110 SFColorGetProperty,
111 SFColorSetProperty,
112 JS_EnumerateStub,
113 JS_ResolveStub,
114 JS_ConvertStub,
115 JS_MY_Finalize
116};
117
118JSPropertySpec (SFColorProperties)[] = {
119 {"r", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
120 {"g", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
121 {"b", 2, JSPROP_SHARED | JSPROP_ENUMERATE},
122 {0}
123};
124
125
126
127JSFunctionSpec (SFColorFunctions)[] = {
128 {"getHSV", SFColorGetHSV, 0},
129 {"setHSV", SFColorSetHSV, 0},
130 {"toString", SFColorToString, 0},
131 {"assign", SFColorAssign, 0},
132 {0}
133};
134
135
136
137JSClass SFColorRGBAClass = {
138 "SFColorRGBA",
139 JSCLASS_HAS_PRIVATE,
140 JS_PropertyStub,
141 JS_PropertyStub,
142 SFColorRGBAGetProperty,
143 SFColorRGBASetProperty,
144 JS_EnumerateStub,
145 JS_ResolveStub,
146 JS_ConvertStub,
147 JS_MY_Finalize
148};
149
150JSPropertySpec (SFColorRGBAProperties)[] = {
151 {"r", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
152 {"g", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
153 {"b", 2, JSPROP_SHARED | JSPROP_ENUMERATE},
154 {"a", 3, JSPROP_SHARED | JSPROP_ENUMERATE},
155 {0}
156};
157
158JSFunctionSpec (SFColorRGBAFunctions)[] = {
159 {"getHSV", SFColorRGBAGetHSV, 0},
160 {"setHSV", SFColorRGBASetHSV, 0},
161 {"toString", SFColorRGBAToString, 0},
162 {"assign", SFColorRGBAAssign, 0},
163 {0}
164};
165
166
167
168JSClass SFImageClass = {
169 "SFImage",
170 JSCLASS_HAS_PRIVATE,
171 JS_PropertyStub,
172 JS_PropertyStub,
173 SFImageGetProperty,
174 SFImageSetProperty,
175 JS_EnumerateStub,
176 JS_ResolveStub,
177 JS_ConvertStub,
178 JS_MY_Finalize
179};
180
181JSPropertySpec (SFImageProperties)[] = {
182 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
183 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
184 {"comp", 2, JSPROP_SHARED | JSPROP_ENUMERATE},
185 {"array", 3, JSPROP_SHARED | JSPROP_ENUMERATE},
186 {0}
187};
188
189JSFunctionSpec (SFImageFunctions)[] = {
190 {"toString", SFImageToString, 0},
191 {"assign", SFImageAssign, 0},
192 {0}
193};
194
195
196
197JSClass SFNodeClass = {
198 "SFNode",
199 JSCLASS_HAS_PRIVATE,
200 JS_PropertyStub,
201 JS_PropertyStub,
202 SFNodeGetProperty,
203 SFNodeSetProperty,
204 JS_EnumerateStub,
205 JS_ResolveStub,
206 JS_ConvertStub,
207 SFNodeFinalize /* note, this is different, as it contains a string to get rid of */
208};
209
210JSPropertySpec (SFNodeProperties)[] = {
211 {0}
212};
213
214/*
215struct JSFunctionSpec {
216 const char *name;
217 JSNative call;
218 uint16 nargs;
219 uint16 flags;
220};
221*/
222
223
224// JS_FS("js_function", jjjs_function, 1, 0, 0),
225JSFunctionSpec (SFNodeFunctions)[] = {
226#ifdef NEWCLASSES
227 {"getNodeName", SFNodeGetNodeName, 0},
228 {"getNodeType", SFNodeGetNodeType, 0},
229 {"getFieldDefinitions",SFNodeGetFieldDefs, 0},
230 {"toVRMLString",SFNodeToVRMLString, 0},
231 {"toXMLString", SFNodeToXMLString, 0},
232#endif
233 JS_FS("equals", SFNodeEquals, 1,0),
234 JS_FS("toString", SFNodeToString, 0, 0),
235 JS_FS("valueOf", SFNodeValueOf, 0, 0),
236 {"assign", SFNodeAssign, 0, 0},
237 JS_FS_END
238};
239
240
241
242JSClass SFRotationClass = {
243 "SFRotation",
244 JSCLASS_HAS_PRIVATE,
245 JS_PropertyStub,
246 JS_PropertyStub,
247 SFRotationGetProperty,
248 SFRotationSetProperty,
249 JS_EnumerateStub,
250 JS_ResolveStub,
251 JS_ConvertStub,
252 JS_MY_Finalize
253};
254
255JSPropertySpec (SFRotationProperties)[] = {
256 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
257 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
258 {"z", 2, JSPROP_SHARED | JSPROP_ENUMERATE},
259 {"angle",3, JSPROP_SHARED | JSPROP_ENUMERATE},
260 {0}
261};
262
263JSFunctionSpec (SFRotationFunctions)[] = {
264 {"getAxis", SFRotationGetAxis, 0},
265 {"inverse", SFRotationInverse, 0},
266 {"multiply", SFRotationMultiply, 0},
267 {"multVec", SFRotationMultVec, 0},
268 {"multiVec", SFRotationMultVec, 0},
269 {"setAxis", SFRotationSetAxis, 0},
270 {"slerp", SFRotationSlerp, 0},
271 {"toString", SFRotationToString, 0},
272 {"assign", SFRotationAssign, 0},
273 {0}
274};
275
276
277
278JSClass SFVec2fClass = {
279 "SFVec2f",
280 JSCLASS_HAS_PRIVATE,
281 JS_PropertyStub,
282 JS_PropertyStub,
283 SFVec2fGetProperty,
284 SFVec2fSetProperty,
285 JS_EnumerateStub,
286 JS_ResolveStub,
287 JS_ConvertStub,
288 JS_MY_Finalize
289};
290
291JSPropertySpec (SFVec2fProperties)[] = {
292 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
293 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
294 {0}
295};
296
297JSFunctionSpec (SFVec2fFunctions)[] = {
298 {"add", SFVec2fAdd, 0},
299 {"divide", SFVec2fDivide, 0},
300 {"dot", SFVec2fDot, 0},
301 {"length", SFVec2fLength, 0},
302 {"multiply", SFVec2fMultiply, 0},
303 {"normalize", SFVec2fNormalize, 0},
304 {"subtract", SFVec2fSubtract, 0},
305 {"toString", SFVec2fToString, 0},
306 {"assign", SFVec2fAssign, 0},
307 {0}
308};
309
310#ifdef NEWCLASSES
311JSClass SFVec2dClass = {
312 "SFVec2d",
313 JSCLASS_HAS_PRIVATE,
314 JS_PropertyStub,
315 JS_PropertyStub,
316 SFVec2dGetProperty,
317 SFVec2dSetProperty,
318 JS_EnumerateStub,
319 JS_ResolveStub,
320 JS_ConvertStub,
321 JS_MY_Finalize
322};
323
324JSPropertySpec (SFVec2dProperties)[] = {
325 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
326 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
327 {0}
328};
329
330JSFunctionSpec (SFVec2dFunctions)[] = {
331 {"add", SFVec2dAdd, 0},
332 {"divide", SFVec2dDivide, 0},
333 {"dot", SFVec2dDot, 0},
334 {"length", SFVec2dLength, 0},
335 {"multiply", SFVec2dMultiply, 0},
336 {"normalize", SFVec2dNormalize, 0},
337 {"subtract", SFVec2dSubtract, 0},
338 {"toString", SFVec2dToString, 0},
339 {"assign", SFVec2dAssign, 0},
340 {0}
341};
342
343#endif /* NEWCLASSES */
344
345JSClass SFVec4fClass = {
346 "SFVec4f",
347 JSCLASS_HAS_PRIVATE,
348 JS_PropertyStub,
349 JS_PropertyStub,
350 SFVec4fGetProperty,
351 SFVec4fSetProperty,
352 JS_EnumerateStub,
353 JS_ResolveStub,
354 JS_ConvertStub,
355 JS_MY_Finalize
356};
357
358JSPropertySpec (SFVec4fProperties)[] = {
359 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
360 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
361 {"z", 2, JSPROP_SHARED | JSPROP_ENUMERATE},
362 {"w", 3, JSPROP_SHARED | JSPROP_ENUMERATE},
363 {0}
364};
365
366JSFunctionSpec (SFVec4fFunctions)[] = {
367 /* do not know what functions to use here */
368 {"toString", SFVec4fToString, 0},
369 {"assign", SFVec4fAssign, 0},
370 {0}
371};
372
373
374JSClass SFVec4dClass = {
375 "SFVec4d",
376 JSCLASS_HAS_PRIVATE,
377 JS_PropertyStub,
378 JS_PropertyStub,
379 SFVec4dGetProperty,
380 SFVec4dSetProperty,
381 JS_EnumerateStub,
382 JS_ResolveStub,
383 JS_ConvertStub,
384 JS_MY_Finalize
385};
386
387JSPropertySpec (SFVec4dProperties)[] = {
388 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
389 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
390 {"z", 2, JSPROP_SHARED | JSPROP_ENUMERATE},
391 {"w", 3, JSPROP_SHARED | JSPROP_ENUMERATE},
392 {0}
393};
394
395JSFunctionSpec (SFVec4dFunctions)[] = {
396 /* do not know what functions to use here */
397 {"toString", SFVec4dToString, 0},
398 {"assign", SFVec4dAssign, 0},
399 {0}
400};
401
402
403
404
405JSClass SFVec3fClass = {
406 "SFVec3f",
407 JSCLASS_HAS_PRIVATE, //JSPROP_SHARED | JSPROP_ENUMERATE
408 JS_PropertyStub,
409 JS_PropertyStub,
410 SFVec3fGetProperty, // 185 this is (JSPropertyOp*)
411 SFVec3fSetProperty, // 185 this should be (JSStrictPropertyOp*)
412 JS_EnumerateStub,
413 JS_ResolveStub,
414 JS_ConvertStub,
415 JS_MY_Finalize
416};
417// 90% down page shows a bit of getter/setter
418// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_Cookbook
419//JSPropertySpec (SFVec3fProperties)[] = {
420// {"x", 0, JSPROP_ENUMERATE, NULL, NULL }, //| JSPROP_PERMANENT
421// {"y", 1, JSPROP_ENUMERATE, NULL, NULL },
422// {"z", 2, JSPROP_ENUMERATE, NULL, NULL },
423// {0}
424//};
425// we seem to need the SHARED in order to set ie translation.x = -3,
426// otherwise it creates a new orphan js property .x unrelated to the C sfvec3f.c[0] property
427JSPropertySpec (SFVec3fProperties)[] = {
428 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE, NULL, NULL }, //| JSPROP_PERMANENT
429 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE, NULL, NULL },
430 {"z", 2, JSPROP_SHARED | JSPROP_ENUMERATE, NULL, NULL },
431 {0}
432};
433
434JSFunctionSpec (SFVec3fFunctions)[] = {
435 {"add", SFVec3fAdd, 0},
436 {"cross", SFVec3fCross, 0},
437 {"divide", SFVec3fDivide, 0},
438 {"dot", SFVec3fDot, 0},
439 {"length", SFVec3fLength, 0},
440 {"multiply", SFVec3fMultiply, 0},
441 {"negate", SFVec3fNegate, 0},
442 {"normalize", SFVec3fNormalize, 0},
443 {"subtract", SFVec3fSubtract, 0},
444 {"toString", SFVec3fToString, 0},
445 {"assign", SFVec3fAssign, 0},
446 {0}
447};
448
449
450JSClass SFVec3dClass = {
451 "SFVec3d",
452 JSCLASS_HAS_PRIVATE,
453 JS_PropertyStub,
454 JS_PropertyStub,
455 SFVec3dGetProperty,
456 SFVec3dSetProperty,
457 JS_EnumerateStub,
458 JS_ResolveStub,
459 JS_ConvertStub,
460 JS_MY_Finalize
461};
462
463JSPropertySpec (SFVec3dProperties)[] = {
464 {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE},
465 {"y", 1, JSPROP_SHARED | JSPROP_ENUMERATE},
466 {"z", 2, JSPROP_SHARED | JSPROP_ENUMERATE},
467 {0}
468};
469
470JSFunctionSpec (SFVec3dFunctions)[] = {
471 {"add", SFVec3dAdd, 0},
472 {"cross", SFVec3dCross, 0},
473 {"divide", SFVec3dDivide, 0},
474 {"dot", SFVec3dDot, 0},
475 {"length", SFVec3dLength, 0},
476 {"multiply", SFVec3dMultiply, 0},
477 {"negate", SFVec3dNegate, 0},
478 {"normalize", SFVec3dNormalize, 0},
479 {"subtract", SFVec3dSubtract, 0},
480 {"toString", SFVec3dToString, 0},
481 {"assign", SFVec3dAssign, 0},
482 {0}
483};
484
485JSClass MFColorClass = {
486 "MFColor",
487 JSCLASS_HAS_PRIVATE,
488 MFColorAddProperty,
489 JS_PropertyStub,
490 MFColorGetProperty,
491 MFColorSetProperty,
492 JS_EnumerateStub,
493 JS_ResolveStub,
494 JS_ConvertStub,
495 JS_MY_Finalize
496};
497
498JSFunctionSpec (MFColorFunctions)[] = {
499 {"toString", MFColorToString, 0},
500 {"assign", MFColorAssign, 0},
501 {0}
502};
503
504
505
506JSClass MFFloatClass = {
507 "MFFloat",
508 JSCLASS_HAS_PRIVATE, // | JSPROP_SHARED | JSPROP_ENUMERATE,
509 MFFloatAddProperty,
510 JS_PropertyStub,
511 MFFloatGetProperty,
512 MFFloatSetProperty,
513 JS_EnumerateStub,
514 JS_ResolveStub,
515 JS_ConvertStub,
516 JS_MY_Finalize
517};
518
519JSFunctionSpec (MFFloatFunctions)[] = {
520 {"toString", MFFloatToString, 0},
521 {"assign", MFFloatAssign, 0},
522 {0}
523};
524
525
526
527JSClass MFInt32Class = {
528 "MFInt32",
529 JSCLASS_HAS_PRIVATE,
530 MFInt32AddProperty,
531 JS_PropertyStub,
532 MFInt32GetProperty,
533 MFInt32SetProperty,
534 JS_EnumerateStub,
535 JS_ResolveStub,
536 JS_ConvertStub,
537 JS_MY_Finalize
538};
539
540JSFunctionSpec (MFInt32Functions)[] = {
541 {"toString", MFInt32ToString, 0},
542 {"assign", MFInt32Assign, 0},
543 {0}
544};
545
546#ifdef NEWCLASSES
547JSClass MFBoolClass = {
548 "MFBool",
549 JSCLASS_HAS_PRIVATE,
550 MFBoolAddProperty,
551 JS_PropertyStub,
552 MFBoolGetProperty,
553 MFBoolSetProperty,
554 JS_EnumerateStub,
555 JS_ResolveStub,
556 JS_ConvertStub,
557 JS_MY_Finalize
558};
559
560JSFunctionSpec (MFBoolFunctions)[] = {
561 {"toString", MFBoolToString, 0},
562 {"assign", MFBoolAssign, 0},
563 {0}
564};
565
566
567JSClass MFDoubleClass = {
568 "MFDouble",
569 JSCLASS_HAS_PRIVATE,
570 MFDoubleAddProperty,
571 JS_PropertyStub,
572 MFDoubleGetProperty,
573 MFDoubleSetProperty,
574 JS_EnumerateStub,
575 JS_ResolveStub,
576 JS_ConvertStub,
577 JS_MY_Finalize
578};
579
580JSFunctionSpec (MFDoubleFunctions)[] = {
581 {"toString", MFDoubleToString, 0},
582 {"assign", MFDoubleAssign, 0},
583 {0}
584};
585
586
587
588JSClass MFImageClass = {
589 "MFImage",
590 JSCLASS_HAS_PRIVATE,
591 MFImageAddProperty,
592 JS_PropertyStub,
593 MFImageGetProperty,
594 MFImageSetProperty,
595 JS_EnumerateStub,
596 JS_ResolveStub,
597 JS_ConvertStub,
598 JS_MY_Finalize
599};
600
601JSFunctionSpec (MFImageFunctions)[] = {
602 {"toString", MFImageToString, 0},
603 {"assign", MFImageAssign, 0},
604 {0}
605};
606
607
608JSClass MFVec2dClass = {
609 "MFVec2d",
610 JSCLASS_HAS_PRIVATE,
611 MFVec2dAddProperty,
612 JS_PropertyStub,
613 MFVec2dGetProperty,
614 MFVec2dSetProperty,
615 JS_EnumerateStub,
616 JS_ResolveStub,
617 JS_ConvertStub,
618 JS_MY_Finalize
619};
620
621JSFunctionSpec (MFVec2dFunctions)[] = {
622 {"toString", MFVec2dToString, 0},
623 {"assign", MFVec2dAssign, 0},
624 {0}
625};
626
627JSClass MFVec3dClass = {
628 "MFVec3d",
629 JSCLASS_HAS_PRIVATE,
630 MFVec3dAddProperty,
631 JS_PropertyStub,
632 MFVec3dGetProperty,
633 MFVec3dSetProperty,
634 JS_EnumerateStub,
635 JS_ResolveStub,
636 JS_ConvertStub,
637 JS_MY_Finalize
638};
639
640JSFunctionSpec (MFVec3dFunctions)[] = {
641 {"toString", MFVec3dToString, 0},
642 {"assign", MFVec3dAssign, 0},
643 {0}
644};
645
646#endif /* NEWCLASSES */
647
648JSClass MFNodeClass = {
649 "MFNode",
650 JSCLASS_HAS_PRIVATE,
651 MFNodeAddProperty,
652 JS_PropertyStub,
653 MFNodeGetProperty,
654 MFNodeSetProperty,
655 JS_EnumerateStub,
656 JS_ResolveStub,
657 JS_ConvertStub,
658 JS_MY_Finalize
659};
660
661JSFunctionSpec (MFNodeFunctions)[] = {
662 {"toString", MFNodeToString, 0},
663 {"assign", MFNodeAssign, 0},
664 {0}
665};
666
667
668
669JSClass MFRotationClass = {
670 "MFRotation",
671 JSCLASS_HAS_PRIVATE,
672 MFRotationAddProperty,
673 JS_PropertyStub,
674 MFRotationGetProperty,
675 MFRotationSetProperty,
676 JS_EnumerateStub,
677 JS_ResolveStub,
678 JS_ConvertStub,
679 JS_MY_Finalize
680};
681
682JSFunctionSpec (MFRotationFunctions)[] = {
683 {"toString", MFRotationToString, 0},
684 {"assign", MFRotationAssign, 0},
685 {0}
686};
687
688
689
690/* this one is not static. */
691JSClass MFStringClass = {
692 "MFString",
693 JSCLASS_HAS_PRIVATE,
694 MFStringAddProperty,
695 MFStringDeleteProperty, /* JS_PropertyStub, */
696 MFStringGetProperty,
697 MFStringSetProperty,
698 MFStringEnumerateProperty, /* JS_EnumerateStub, */
699 MFStringResolveProperty, /* JS_ResolveStub, */
700 MFStringConvertProperty, /* JS_ConvertStub, */
701 JS_MY_Finalize
702};
703
704JSFunctionSpec (MFStringFunctions)[] = {
705 {"toString", MFStringToString, 0},
706 {"assign", MFStringAssign, 0},
707 {0}
708};
709
710
711
712JSClass MFTimeClass = {
713 "MFTime",
714 JSCLASS_HAS_PRIVATE,
715 MFTimeAddProperty,
716 JS_PropertyStub,
717 MFTimeGetProperty,
718 MFTimeSetProperty,
719 JS_EnumerateStub,
720 JS_ResolveStub,
721 JS_ConvertStub,
722 JS_MY_Finalize
723};
724
725JSPropertySpec (MFTimeProperties)[] = {
726 {0}
727};
728
729JSFunctionSpec (MFTimeFunctions)[] = {
730 {"toString", MFTimeToString, 0},
731 {"assign", MFTimeAssign, 0},
732 {0}
733};
734
735
736
737JSClass MFVec2fClass = {
738 "MFVec2f",
739 JSCLASS_HAS_PRIVATE,
740 MFVec2fAddProperty,
741 JS_PropertyStub,
742 MFVec2fGetProperty,
743 MFVec2fSetProperty,
744 JS_EnumerateStub,
745 JS_ResolveStub,
746 JS_ConvertStub,
747 JS_MY_Finalize
748};
749
750JSFunctionSpec (MFVec2fFunctions)[] = {
751 {"toString", MFVec2fToString, 0},
752 {"assign", MFVec2fAssign, 0},
753 {0}
754};
755
756
757
758JSClass MFVec3fClass = {
759 "MFVec3f",
760 JSCLASS_HAS_PRIVATE,
761 MFVec3fAddProperty,
762 JS_PropertyStub,
763 MFVec3fGetProperty,
764 MFVec3fSetProperty,
765 JS_EnumerateStub,
766 JS_ResolveStub,
767 JS_ConvertStub,
768 JS_MY_Finalize
769};
770
771JSFunctionSpec (MFVec3fFunctions)[] = {
772 {"toString", MFVec3fToString, 0},
773 {"assign", MFVec3fAssign, 0},
774 {0}
775};
776
777JSObject *proto_VrmlMatrix;
778
779JSClass VrmlMatrixClass = {
780 "VrmlMatrix",
781 JSCLASS_HAS_PRIVATE,
782 VrmlMatrixAddProperty,
783 JS_PropertyStub,
784 VrmlMatrixGetProperty,
785 VrmlMatrixSetProperty,
786 JS_EnumerateStub,
787 JS_ResolveStub,
788 JS_ConvertStub,
789 JS_MY_Finalize
790};
791
792JSFunctionSpec (VrmlMatrixFunctions)[] = {
793 {"setTransform", VrmlMatrixsetTransform, 0},
794 {"getTransform", VrmlMatrixgetTransform, 0},
795 {"inverse", VrmlMatrixinverse, 0},
796 {"transpose", VrmlMatrixtranspose, 0},
797 {"multLeft", VrmlMatrixmultLeft, 0},
798 {"multRight", VrmlMatrixmultRight, 0},
799 {"multVecMatrix", VrmlMatrixmultVecMatrix, 0},
800 {"multMatrixVec", VrmlMatrixmultMatrixVec, 0},
801 {"toString", VrmlMatrixToString, 0},
802 {"assign", VrmlMatrixAssign, 0},
803 {0}
804};
805
806
807#ifdef NEWCLASSES
808
809JSObject *proto_X3DMatrix3;
810
811JSClass X3DMatrix3Class = {
812 "X3DMatrix3",
813 JSCLASS_HAS_PRIVATE,
814 X3DMatrix3AddProperty,
815 JS_PropertyStub,
816 X3DMatrix3GetProperty,
817 X3DMatrix3SetProperty,
818 JS_EnumerateStub,
819 JS_ResolveStub,
820 JS_ConvertStub,
821 JS_MY_Finalize
822};
823
824JSFunctionSpec (X3DMatrix3Functions)[] = {
825 {"getTransform", X3DMatrix3getTransform, 0},
826 {"setTransform", X3DMatrix3setTransform, 0},
827 {"inverse", X3DMatrix3inverse, 0},
828 {"transpose", X3DMatrix3transpose, 0},
829 {"multLeft", X3DMatrix3multLeft, 0},
830 {"multRight", X3DMatrix3multRight, 0},
831 {"multVecMatrix", X3DMatrix3multVecMatrix, 0},
832 {"multMatrixVec", X3DMatrix3multMatrixVec, 0},
833 {"toString", X3DMatrix3ToString, 0},
834 {"assign", X3DMatrix3Assign, 0},
835 {0}
836};
837
838
839JSObject *proto_X3DMatrix4;
840
841JSClass X3DMatrix4Class = {
842 "X3DMatrix4",
843 JSCLASS_HAS_PRIVATE,
844 X3DMatrix4AddProperty,
845 JS_PropertyStub,
846 X3DMatrix4GetProperty,
847 X3DMatrix4SetProperty,
848 JS_EnumerateStub,
849 JS_ResolveStub,
850 JS_ConvertStub,
851 JS_MY_Finalize
852};
853
854JSFunctionSpec (X3DMatrix4Functions)[] = {
855 {"toString", X3DMatrix4ToString, 0},
856 {"assign", X3DMatrix4Assign, 0},
857 {"getTransform", X3DMatrix4getTransform, 0},
858 {"setTransform", X3DMatrix4setTransform, 0},
859 {"inverse", X3DMatrix4inverse, 0},
860 {"transpose", X3DMatrix4transpose, 0},
861 {"multLeft", X3DMatrix4multLeft, 0},
862 {"multRight", X3DMatrix4multRight, 0},
863 {"multVecMatrix", X3DMatrix4multVecMatrix, 0},
864 {"multMatrixVec", X3DMatrix4multMatrixVec, 0},
865 {0}
866};
867
868#endif /* NEWCLASSES */
869
870//#define MFFloatProperties NULL
871//#define MFInt32Properties NULL
872//#define MFColorProperties NULL
873//#define MFVec2fProperties NULL
874//#define MFVec3fProperties NULL
875//#define MFRotationProperties NULL
876//#define MFNodeProperties NULL
877//#define MFStringProperties NULL
878//#define VrmlMatrixProperties NULL
879
880
881struct JSLoadPropElement {
882 JSClass *class;
883 void *constr;
884 void *Functions;
885 void *Properties;
886 char *id;
887};
888
889
890struct JSLoadPropElement (JSLoadProps) [] = {
891#ifdef NEWCLASSES
892 { &MFVec2dClass, MFVec2dConstr, &MFVec2dFunctions, &MFVec2dProperties, "MFVec2dClass"},
893 { &MFVec3dClass, MFVec3dConstr, &MFVec3dFunctions, &MFVec3dProperties, "MFVec3dClass"},
894 { &SFVec2dClass, SFVec2dConstr, &SFVec2dFunctions, &SFVec2dProperties, "SFVec2dClass"},
895 { &MFBoolClass, MFBoolConstr, &MFBoolFunctions, &MFBoolProperties, "MFBoolClass"},
896 { &MFDoubleClass, MFDoubleConstr, &MFDoubleFunctions, &MFDoubleProperties, "MFDoubleClass"},
897 { &MFImageClass, MFImageConstr, &MFImageFunctions, &MFImageProperties, "MFImageClass"},
898 { &X3DMatrix3Class, X3DMatrix3Constr, &X3DMatrix3Functions, &X3DMatrix3Properties, "X3DMatrix3Class"},
899 { &X4DMatrix4Class, X4DMatrix4Constr, &X4DMatrix4Functions, &X4DMatrix4Properties, "X4DMatrix4Class"},
900#endif /* NEWCLASSES */
901
902 { &SFColorClass, SFColorConstr, &SFColorFunctions, &SFColorProperties, "SFColorClass"},
903 { &SFVec2fClass, SFVec2fConstr, &SFVec2fFunctions, &SFVec2fProperties, "SFVec2fClass"},
904 { &SFColorRGBAClass, SFColorRGBAConstr, &SFColorRGBAFunctions, &SFColorRGBAProperties, "SFColorRGBAClass"},
905 { &SFVec3fClass, SFVec3fConstr, &SFVec3fFunctions, &SFVec3fProperties, "SFVec3fClass"},
906 { &SFVec3dClass, SFVec3dConstr, &SFVec3dFunctions, &SFVec3dProperties, "SFVec3dClass"},
907 { &SFRotationClass, SFRotationConstr, &SFRotationFunctions, &SFRotationProperties, "SFRotationClass"},
908 { &SFNodeClass, SFNodeConstr, &SFNodeFunctions, &SFNodeProperties, "SFNodeClass"},
909 { &MFFloatClass, MFFloatConstr, &MFFloatFunctions, NULL, "MFFloatClass"},
910 { &MFTimeClass, MFTimeConstr, &MFTimeFunctions, &MFTimeProperties, "MFTimeClass"},
911 { &MFInt32Class, MFInt32Constr, &MFInt32Functions, NULL, "MFInt32Class"},
912 { &MFColorClass, MFColorConstr, &MFColorFunctions, NULL, "MFColorClass"},
913 { &MFVec2fClass, MFVec2fConstr, &MFVec2fFunctions, NULL, "MFVec2fClass"},
914
915 { &MFVec3fClass, MFVec3fConstr, &MFVec3fFunctions, NULL, "MFVec3fClass"},
916
917 { &SFVec4fClass, SFVec4fConstr, &SFVec4fFunctions, &SFVec4fProperties, "SFVec4fClass"},
918 { &SFVec4dClass, SFVec4dConstr, &SFVec4dFunctions, &SFVec4dProperties, "SFVec4dClass"},
919
920 { &MFRotationClass, MFRotationConstr, &MFRotationFunctions, NULL, "MFRotationClass"},
921 { &MFNodeClass, MFNodeConstr, &MFNodeFunctions, NULL, "MFNodeClass"},
922 { &SFImageClass, SFImageConstr, &SFImageFunctions, &SFImageProperties, "SFImageClass"},
923/* { &MFColorRGBAClass, MFColorRGBAConstr, &MFColorRGBAFunctions, &MFColorRGBAProperties, "MFColorRGBAClass"},*/
924 { &MFStringClass, MFStringConstr, &MFStringFunctions, NULL, "MFStringClass"},
925 { &VrmlMatrixClass, VrmlMatrixConstr, &VrmlMatrixFunctions, NULL, "VrmlMatrixClass"},
926 {0}
927};
928
929
930
931/* return the string representation of this class */
932const char *classToString(JSClass *myClass) {
933
934 int i;
935 i = 0;
936
937 /* printf ("class to string starting\n"); */
938
939 /* ok - this is an object, lets find out what class it is */
940 while (JSLoadProps[i].class != NULL) {
941 if (JSLoadProps[i].class == myClass) {
942 /* printf ("found it! it is a %s\n",JSLoadProps[i].id); */
943 return JSLoadProps[i].id;
944 }
945 i++;
946 }
947 return "class unknown";
948}
949
950/* try and print what an element is in case of error */
951void printJSNodeType (JSContext *context, JSObject *myobj) {
952 int i;
953 i=0;
954
955 #ifdef JSVRMLCLASSESVERBOSE
956 printf ("printJSNodeType, obj pointer is %p\n",myobj);
957 #endif
958
959 /* ok - this is an object, lets find out what class it is */
960 while (JSLoadProps[i].class != NULL) {
961 if (JS_InstanceOf(context, myobj, JSLoadProps[i].class, NULL)) {
962 printf ("'%s'\n",JSLoadProps[i].id);
963 return;
964 }
965 i++;
966 }
967 printf ("'unknown class'\n");
968}
969
970/* do a simple copy; from, to, and count */
971JSBool _simplecopyElements (JSContext *cx,
972 JSObject *fromObj,
973 JSObject *toObj,
974 int count,
975 int type) {
976 int i;
977 jsval val;
978 double dd;
979 int ii;
980
981
982 #ifdef JSVRMLCLASSESVERBOSE
983 printf ("simpleCopyElements, count %d\n",count);
984 #endif
985
986 for (i = 0; i < count; i++) {
987 if (!JS_GetElement(cx, fromObj, (jsint) i, &val)) {
988 printf( "failed in get %d index %d.\n",type, i);
989 return JS_FALSE;
990 }
991 /* ensure that the types are ok */
992 if ((type == FIELDTYPE_SFFloat) || (type == FIELDTYPE_SFTime)) {
993 /* if we expect a double, and we have an INT... */
994 if (JSVAL_IS_INT(val)) {
995 ii = JSVAL_TO_INT(val);
996 dd = (double) ii;
997 /* printf ("integer is %d doulbe %lf\n",ii,dd); */
998 if (JS_NewNumberValue(cx,dd,&val) == JS_FALSE) {
999 printf( "JS_NewNumberValue failed for %f in simplecopyelements.\n",dd);
1000 return JS_FALSE;
1001 }
1002 }
1003 }
1004
1005 /*
1006 if (JSVAL_IS_OBJECT(val)) printf ("sc, element %d is an OBJECT\n",i);
1007 if (JSVAL_IS_STRING(val)) printf ("sc, element %d is an STRING\n",i);
1008 if (JSVAL_IS_NUMBER(val)) printf ("sc, element %d is an NUMBER\n",i);
1009 if (JSVAL_IS_DOUBLE(val)) printf ("sc, element %d is an DOUBLE\n",i);
1010 if (JSVAL_IS_INT(val)) printf ("sc, element %d is an INT\n",i);
1011 */
1012
1013 if (!JS_SetElement(cx, toObj, (jsint) i, &val)) {
1014 printf( "failed in set %d index %d.\n", type, i);
1015 return JS_FALSE;
1016 }
1017 }
1018 return JS_TRUE;
1019}
1020
1021
1022/* make a standard assignment for MF variables */
1023JSBool _standardMFAssign(JSContext *cx,
1024 JSObject *obj,
1025 uintN argc,
1026 jsval *argv,
1027 jsval *rval,
1028 JSClass *myClass,
1029 int type) {
1030
1031 JSObject *_from_obj;
1032 jsval val;
1033 int32 len;
1034 SFImageNative *ptr;
1035#if JS_VERSION < 185
1036 char *_id_str;
1037#else
1038 JSString *_id_jsstr;
1039#endif
1040
1041 if (!JS_InstanceOf(cx, obj, myClass, argv)) {
1042 printf("JS_InstanceOf failed for fieldType %s.\n",stringFieldtypeType(type));
1043 return JS_FALSE;
1044 }
1045
1046#if JS_VERSION < 185
1047 if (!JS_ConvertArguments(cx, argc, argv, "o s", &_from_obj, &_id_str)) {
1048#else
1049 if (!JS_ConvertArguments(cx, argc, argv, "oS", &_from_obj, &_id_jsstr)) {
1050#endif
1051 printf("JS_ConvertArguments failed in %s.\n",stringFieldtypeType(type));
1052 return JS_FALSE;
1053 }
1054
1055
1056 if (!JS_InstanceOf(cx, _from_obj, myClass, argv)) {
1057 printf("JS_InstanceOf failed for fieldType %s.\n",stringFieldtypeType(type));
1058 return JS_FALSE;
1059 }
1060 if (!JS_GetProperty(cx, _from_obj, MF_LENGTH_FIELD, &val)) {
1061 printf("JS_GetProperty failed for \"%s\" in %s.\n",MF_LENGTH_FIELD,stringFieldtypeType(type));
1062 return JS_FALSE;
1063 }
1064
1065 if (!JS_SetProperty(cx, obj, MF_LENGTH_FIELD, &val)) {
1066 printf("JS_SetProperty failed for \"%s\" in %s\n",MF_LENGTH_FIELD,stringFieldtypeType(type));
1067 return JS_FALSE;
1068 }
1069
1070 len = JSVAL_TO_INT(val);
1071
1072 #ifdef JSVRMLCLASSESVERBOSE
1073#if JS_VERSION >= 185
1074 _id_str = JS_EncodeString(cx,_id_jsstr);
1075#endif
1076 printf("StandardMFAssign %s: obj = %p, id = \"%s\", from = %p, len = %d\n",stringFieldtypeType(type),
1077 obj, _id_str, _from_obj, len);
1078#if JS_VERSION >= 185
1079 JS_free(cx,_id_str);
1080#endif
1081 #endif
1082
1083 /* copyElements */
1084 *rval = OBJECT_TO_JSVAL(obj);
1085
1086 /* SF* values that use this routine - check if we need to set valueChanged in private area */
1087
1088 if (type == FIELDTYPE_SFImage) {
1089 if ((ptr = (SFImageNative *)JS_GetPrivateFw(cx, obj)) == NULL) {
1090 printf( "JS_GetPrivate failed in standard MF assign.\n");
1091 return JS_FALSE;
1092 }
1093 ptr->valueChanged = 1;
1094 }
1095
1096 return _simplecopyElements(cx, _from_obj, obj, len,type);
1097}
1098void X3D_SF_TO_JS_B(JSContext *cx, void *Data, unsigned datalen, int dataType, int *valueChanged, jsval *newval);
1099/* standardized GetProperty for MF's */
1100JSBool
1101_standardMFGetProperty(JSContext *cx,
1102 JSObject *obj,
1103#if JS_VERSION < 185
1104 jsval id,
1105#else
1106 jsid iid,
1107#endif
1108 jsval *vp,
1109 char *makeNewElement,
1110 int type) {
1111
1112 int32 _length, _index;
1113 jsval _length_val;
1114
1115 /* in case we need to run makeNewElement*/
1116 int newElemenLen;
1117 jsval newEle;
1118#if JS_VERSION >= 185
1119 jsval id;
1120 //printf("in _standardMFGetProperty\n ");
1121 if (!JS_IdToValue(cx,iid,&id)) {
1122 //printf( "JS_IdToValue failed\n");
1123 return JS_FALSE;
1124 }
1125#endif
1126
1127 #ifdef JSVRMLCLASSESVERBOSE
1128 printf ("_standardMFGetProperty starting for type %d\n",type);
1129 printJSNodeType (cx,obj);
1130 #endif
1131
1132 if(SM_method() == 2){
1133 AnyNative *ptr;
1134 union anyVrml *any;
1135 int sfsize, sftype;
1136 if ((ptr = (AnyNative *)JS_GetPrivateFw(cx,obj)) == NULL) {
1137 printf( "JS_GetPrivate failed in standardMFGetterProperty\n");
1138 return JS_FALSE;
1139 }
1140 sftype = type2SF(ptr->type);
1141 sfsize = sizeofSForMF(sftype);
1142
1143 if (JSVAL_IS_INT(id)) {
1144 char *mf_p;
1145 int mf_n;
1146 int newlength;
1147 int index = JSVAL_TO_INT(id);
1148 if(index < 0) return JS_FALSE;
1149
1150 //>> allow resize by mf[10000] = 0.0;
1151 newlength = index + 1;
1152 mf_n = ptr->v->mfbool.n;
1153 mf_p = (char *)ptr->v->mfbool.p;
1154 if(newlength > mf_n ) {
1155 // in the setter, normally we realloc
1156 if(mf_p == NULL){
1157 mf_p = malloc(sfsize*upper_power_of_two(newlength));
1158 memset(mf_p,0,sfsize*upper_power_of_two(newlength));
1159 }else{
1160 int k;
1161 mf_p = realloc(mf_p,sizeof(int) + sfsize*upper_power_of_two(newlength));
1162 for(k=mf_n;k<newlength;k++)
1163 memset(mf_p + (size_t)sfsize*k,0,sfsize);
1164 }
1165 ptr->v->mfbool.n = newlength;
1166 }
1167 ptr->v->mfbool.p = (int*)mf_p;
1168 //<< allow resize by mf[10000] = 0.0;
1169
1170 any = (union anyVrml*)(mf_p + (index * sfsize));
1171 switch(type2SF(ptr->type)){
1172 case FIELDTYPE_SFBool:
1173 case FIELDTYPE_SFFloat:
1174 case FIELDTYPE_SFTime:
1175 case FIELDTYPE_SFDouble:
1176 case FIELDTYPE_SFInt32:
1177 X3D_ECMA_TO_JS(cx, any,sfsize,sftype,vp);
1178 break;
1179 case FIELDTYPE_SFString:
1180 if(any->sfstring == NULL){
1181 any->sfstring = (struct Uni_String*)malloc(sizeof(struct Uni_String));
1182 memset(any->sfstring,0,sizeof(struct Uni_String));
1183 }
1184 X3D_ECMA_TO_JS(cx, any,sfsize,sftype,vp);
1185 break;
1186 case FIELDTYPE_SFColor:
1187 case FIELDTYPE_SFVec2f:
1188 case FIELDTYPE_SFVec3f:
1189 case FIELDTYPE_SFVec3d:
1190 case FIELDTYPE_SFRotation:
1191 X3D_SF_TO_JS_B(cx, any,sfsize, sftype, ptr->valueChanged, vp);
1192 break;
1193 case FIELDTYPE_SFNode:
1194 X3D_SF_TO_JS_BNode(cx, any,sfsize, sftype, ptr->valueChanged, vp);
1195 break;
1196 default: printf ("invalid type in standardMFGetProperty method 2\n"); return JS_FALSE;
1197 }
1198 return JS_TRUE;
1199 }else if(JSVAL_IS_STRING(id)){
1200 JSString *_idStr;
1201 char *_id_c;
1202
1203 _idStr = JS_ValueToString(cx, id);
1204 if(_idStr){
1205#if JS_VERSION < 185
1206 _id_c = JS_GetStringBytes(_idStr);
1207#else
1208 _id_c = JS_EncodeString(cx,_idStr);
1209#endif
1210 if (strcmp ("length",_id_c) == 0) {
1211 //create js int
1212 //assign length to it
1213 // length = ptr->v->mfbool.n;
1214 int mf_n;
1215 jsval retval;
1216
1217 mf_n = ptr->v->mfbool.n;
1218 retval = INT_TO_JSVAL(mf_n);
1219 *vp = retval;
1220 return JS_TRUE;
1221
1222 }
1223 }
1224 }
1225 }else{
1226 if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &_length_val)) {
1227 printf( "JS_GetProperty failed for \"%s\" in %d.\n",MF_LENGTH_FIELD,type);
1228 return JS_FALSE;
1229 }
1230
1231 _length = JSVAL_TO_INT(_length_val);
1232 #ifdef JSVRMLCLASSESVERBOSE
1233 printf ("standarg get property, len %d\n",_length);
1234 #endif
1235
1236 if (JSVAL_IS_INT(id)) {
1237 _index = JSVAL_TO_INT(id);
1238 #ifdef JSVRMLCLASSESVERBOSE
1239 printf ("standard get property, index requested %d length is %d\n",_index,_length);
1240 #endif
1241
1242 if (_index >= _length) {
1243 #ifdef JSVRMLCLASSESVERBOSE
1244 printf ("\n\nconstructing new object\n");
1245 #endif
1246 /* we were making this with C calls, but it would fail with a*/
1247 /* segfault; so, now, we run a script to do it.*/
1248
1249
1250 newElemenLen = (int)strlen(makeNewElement);
1251
1252 if (!JS_EvaluateScript(cx, obj, makeNewElement, newElemenLen,
1253 FNAME_STUB, LINENO_STUB, &newEle)) {
1254 ConsoleMessage ("standardMFGetProperty: JS_EvaluateScript failed for %s", makeNewElement);
1255 return JS_FALSE;
1256 }
1257
1258 /* error? newEle is already a jsval
1259 *vp = OBJECT_TO_JSVAL(newEle); */
1260 *vp = newEle;
1261
1262 #ifdef JSVRMLCLASSESVERBOSE
1263 printf ("defining element %d now... is %d %#x\n",_index,(int)*vp,(unsigned int)*vp);
1264 #endif
1265
1266 if (!JS_DefineElement(cx, obj, (jsint) _index, *vp,
1267 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_STUB8,
1268 JSPROP_ENUMERATE)) {
1269 printf( "JS_DefineElement failed in %d.\n",type);
1270 return JS_FALSE;
1271 }
1272
1273 if (!doMFSetProperty(cx,obj,
1274 #if JS_VERSION < 185
1275 id,
1276 #else
1277 iid,
1278 #endif
1279 vp,type)) {
1280 printf ("wow, cant assign property\n");
1281 }
1282 }
1283 #ifdef JSVRMLCLASSESVERBOSE
1284 printf ("object might already have this index\n");
1285 #endif
1286 if (!JS_LookupElement(cx, obj, _index, vp)) {
1287 printf( "JS_LookupElement failed in %d.\n",type);
1288 return JS_FALSE;
1289 }
1290 if (JSVAL_IS_NULL(*vp)) {
1291 printf( "warning: %d: obj = %p, jsval = %d does not exist!\n",type,
1292 obj, (int) _index);
1293 return JS_TRUE;
1294 }
1295 } else if (JSVAL_IS_STRING(id)) {
1296 #ifdef JSVRMLCLASSESVERBOSE
1297 JSString *_str;
1298 char * asciiStr;
1299
1300 printf ("HAVE STRING HERE!\n");
1301 _str = JS_ValueToString(cx, id);
1302 #if JS_VERSION < 185
1303 asciiStr = JS_GetStringBytes(_str);
1304 #else
1305 asciiStr = JS_EncodeString(cx,_str);
1306 #endif
1307 printf ("we have as a parameter :%s:\n",asciiStr);
1308 #if JS_VERSION >= 185
1309 JS_free(cx,asciiStr);
1310 #endif
1311 #endif
1312
1313 }
1314 } //SM_method == 2
1315 #ifdef JSVRMLCLASSESVERBOSE
1316 printf ("_standardMFGetProperty finishing; element is %u\n",(unsigned int)*vp);
1317 #endif
1318
1319 return JS_TRUE;
1320}
1321/*
1322 "SFFloat",
1323 "SFRotation",
1324 "SFVec3f",
1325 "SFBool",
1326 "SFInt32",
1327 "SFNode",
1328 "SFColor",
1329 "SFColorRGBA",
1330 "SFTime",
1331 "SFString",
1332 "SFVec2f",
1333 "SFImage",
1334 "SFVec3d",
1335 "SFDouble",
1336 "SFMatrix3f",
1337 "SFMatrix3d",
1338 "SFMatrix4f",
1339 "SFMatrix4d",
1340 "SFVec2d",
1341 "SFVec4f",
1342 "SFVec4d",
1343 "FreeWRLThread",
1344*/
1345char *mf2str(int type, union anyVrml *ptr);
1346char *sf2str(int sftype, union anyVrml *any){
1347 //caller must free / gc the return string
1348 int i;
1349 char strbuf[100];
1350 char *str = NULL;
1351 switch(sftype){
1352 case FIELDTYPE_SFBool:
1353 if(any->sfbool) str = strdup("true");
1354 else str = strdup("false");
1355 break;
1356 case FIELDTYPE_SFInt32:
1357 sprintf(strbuf,"%d",any->sfint32);
1358 str = strdup(strbuf);
1359 break;
1360 case FIELDTYPE_SFFloat:
1361 sprintf(strbuf,"%g",any->sffloat);
1362 str = strdup(strbuf);
1363 break;
1364 case FIELDTYPE_SFDouble:
1365 case FIELDTYPE_SFTime:
1366 sprintf(strbuf,"%g",any->sfdouble);
1367 str = strdup(strbuf);
1368 break;
1369 case FIELDTYPE_SFString:{
1370 str = malloc(strlen(any->sfstring->strptr)+3);
1371 strcpy(str,"\"");
1372 str = strcat(str,any->sfstring->strptr);
1373 str = strcat(str,"\"");
1374 }
1375 break;
1376 case FIELDTYPE_SFVec2f:
1377 {
1378 sprintf(strbuf,"%f %f",any->sfvec2f.c[0],any->sfvec2f.c[1]);
1379 str = strdup(strbuf);
1380 break;
1381 }
1382 case FIELDTYPE_SFVec2d:
1383 {
1384 sprintf(strbuf,"%g %g",any->sfvec2d.c[0],any->sfvec2d.c[1]);
1385 str = strdup(strbuf);
1386 break;
1387 }
1388 case FIELDTYPE_SFVec3f:
1389 case FIELDTYPE_SFColor:
1390 {
1391 sprintf(strbuf,"%f %f %f",any->sfvec3f.c[0],any->sfvec3f.c[1],any->sfvec3f.c[2]);
1392 str = strdup(strbuf);
1393 break;
1394 }
1395 case FIELDTYPE_SFVec3d:
1396 {
1397 sprintf(strbuf,"%g %g %g",any->sfvec3d.c[0],any->sfvec3d.c[1],any->sfvec3d.c[2]);
1398 str = strdup(strbuf);
1399 break;
1400 }
1401 case FIELDTYPE_SFColorRGBA:
1402 case FIELDTYPE_SFRotation:
1403 case FIELDTYPE_SFVec4f:
1404 {
1405 sprintf(strbuf,"%f %f %f %f",any->sfvec4f.c[0],any->sfvec4f.c[1],any->sfvec4f.c[2],any->sfvec4f.c[3]);
1406 str = strdup(strbuf);
1407 break;
1408 }
1409 case FIELDTYPE_SFVec4d:
1410 {
1411 sprintf(strbuf,"%g %g %g %g",any->sfvec4d.c[0],any->sfvec4d.c[1],any->sfvec4d.c[2],any->sfvec4d.c[3]);
1412 str = strdup(strbuf);
1413 break;
1414 }
1415 case FIELDTYPE_SFNode:
1416 sprintf(strbuf,"%zx",any->sfnode);
1417 str = strdup(strbuf);
1418 break;
1419 case FIELDTYPE_SFImage:
1420 str = mf2str(FIELDTYPE_MFInt32,any);
1421 break;
1422 case FIELDTYPE_SFMatrix3f:
1423 case FIELDTYPE_SFMatrix3d:
1424 case FIELDTYPE_SFMatrix4f:
1425 case FIELDTYPE_SFMatrix4d:
1426 return NULL;
1427 break;
1428 default: break;
1429 }
1430 return str;
1431}
1432char *mf2str(int type, union anyVrml *ptr){
1433 int len, elen, sftype, i;
1434 char *p, *str = NULL;
1435 static int showType = 0;
1436
1437 len = strlen("[ ");
1438 if(showType) len += strlen(FIELDTYPES[type]);
1439 str = malloc(len +1);
1440 str[0] = 0;
1441 if(showType) strcat(str,FIELDTYPES[type]);
1442 str = strcat(str,"[ ");
1443 //sftype = mf2sf(fwt->itype);
1444 sftype = type2SF(type);
1445 p = (char *)ptr->mfbool.p;
1446 elen = sizeofSF(sftype);
1447 for(i=0;i<ptr->mfbool.n;i++)
1448 {
1449 char * sf = sf2str(sftype,(union anyVrml*)p);
1450 str = realloc(str,strlen(str)+strlen(sf)+2);
1451 str = strcat(str,sf);
1452 str = strcat(str," ");
1453 free(sf);
1454 p = p + elen;
1455 }
1456 str[strlen(str)-1] = ']';
1457 return str;
1458}
1459
1460JSBool doMFToString(JSContext *cx, JSObject *obj, const char *className, jsval *rval)
1461{
1462 if(SM_method() == 2){
1463 AnyNative *ptr;
1464 union anyVrml *any;
1465 char *str;
1466 JSString *_str;
1467 if((ptr = (AnyNative*)JS_GetPrivateFw(cx,obj)) == NULL){
1468 printf("in doMFToString - not a Native\n");
1469 return JS_FALSE;
1470 }
1471 any = ptr->v;
1472 str = mf2str(ptr->type,any);
1473 _str = JS_NewStringCopyZ(cx,str);
1474 *rval = STRING_TO_JSVAL(_str);
1475
1476 return JS_TRUE;
1477 }
1478 JSString *_str, *_tmpStr;
1479 jsval _v;
1480 char *_buff, *_tmp_valStr, *_tmp_buff;
1481 const char *_empty_array = "[]";
1482 int len = 0, i;
1483 size_t buff_size = 0, tmp_valStr_len = 0, tmp_buff_len = 0;
1484 JSBool isString = JS_FALSE;
1485 JSBool isImage = JS_FALSE;
1486#if JS_VERSION >= 185
1487 JSBool encodedTmpValstr = JS_FALSE;
1488#endif
1489
1490 if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &_v)) {
1491 printf( "JS_GetProperty failed for \"%s\" in doMFToString for %s.\n",
1492 MF_LENGTH_FIELD,className);
1493 return JS_FALSE;
1494 }
1495 len = JSVAL_TO_INT(_v);
1496
1497 #ifdef JSVRMLCLASSESVERBOSE
1498 printf ("doMFToString, obj %p len %d\n",obj, len);
1499 printJSNodeType (cx,obj);
1500 #endif
1501
1502 if (len == 0) {
1503 _str = JS_NewStringCopyZ(cx, _empty_array);
1504 *rval = STRING_TO_JSVAL(_str);
1505 #ifdef JSVRMLCLASSESVERBOSE
1506 printf ("doMFToString, len is zero, returning JS_TRUE, and %d\n",(int)*rval);
1507 #endif
1508 return JS_TRUE;
1509 }
1510
1511 if (!strcmp(className, "MFString")) {
1512 isString = JS_TRUE;
1513 }
1514 if (!strcmp(className, "SFImage")) {
1515 isImage = JS_TRUE;
1516 #ifdef JSVRMLCLASSESVERBOSE
1517 printf ("doMFToString - doing an image\n");
1518 #endif
1519 }
1520
1521 buff_size = LARGESTRING;
1522 _buff = MALLOC(char *, buff_size * sizeof(char));
1523 memset(_buff, 0, buff_size);
1524
1525 for (i = 0; i < len; i++) {
1526 if (!JS_GetElement(cx, obj, i, &_v)) {
1527 printf("warning, no element %d of %d in doMFToString for a type of %s.\n",
1528 i, len,className);
1529 _tmp_valStr = "NULL";
1530 } else {
1531
1532 #ifdef JSVRMLCLASSESVERBOSE
1533 if (JSVAL_IS_NUMBER(_v)) printf ("is a number\n");
1534 if (JSVAL_IS_INT(_v)) printf ("is an integer\n");
1535 if (JSVAL_IS_DOUBLE(_v)) printf ("is an double\n");
1536 #endif
1537
1538 _tmpStr = JS_ValueToString(cx, _v);
1539 if (_tmpStr==NULL) {
1540 _tmp_valStr = "NULL";
1541 } else {
1542#if JS_VERSION < 185
1543 _tmp_valStr = JS_GetStringBytes(_tmpStr);
1544#else
1545 _tmp_valStr = JS_EncodeString(cx,_tmpStr);
1546 encodedTmpValstr = JS_TRUE;
1547#endif
1548 }
1549 }
1550
1551 #ifdef JSVRMLCLASSESVERBOSE
1552 printf ("doMFToString, element %d is %#x, string %s\n",i,(unsigned int)_v,_tmp_valStr);
1553
1554 #endif
1555 tmp_valStr_len = strlen(_tmp_valStr) + 1;
1556 tmp_buff_len = strlen(_buff);
1557
1558 if ((buff_size - (tmp_buff_len + 1)) < (tmp_valStr_len + 1)) {
1559 buff_size += LARGESTRING;
1560 if ((_buff =
1561 (char *)
1562 JS_realloc(cx, _buff, buff_size * sizeof(char *)))
1563 == NULL) {
1564 printf( "JS_realloc failed for %d in doMFToString for %s.\n", i, className);
1565#if JS_VERSION >= 185
1566 if (encodedTmpValstr == JS_TRUE) JS_free(cx,_tmp_valStr);
1567#endif
1568 return JS_FALSE;
1569 }
1570 }
1571
1572 if (len == 1) {
1573 if (isString) {
1574 sprintf(_buff, "[ \"%.*s\" ]", (int) tmp_valStr_len, _tmp_valStr);
1575 } else {
1576 sprintf(_buff, "[ %.*s ]", (int) tmp_valStr_len, _tmp_valStr);
1577 }
1578#if JS_VERSION >= 185
1579 if (encodedTmpValstr == JS_TRUE) {
1580 JS_free(cx,_tmp_valStr);
1581 encodedTmpValstr = JS_FALSE;
1582 }
1583#endif
1584 break;
1585 }
1586
1587 _tmp_buff = MALLOC(char *, (tmp_buff_len + 1) * sizeof(char));
1588 memset(_tmp_buff, 0, tmp_buff_len + 1);
1589 memmove(_tmp_buff, _buff, tmp_buff_len);
1590 memset(_buff, 0, buff_size);
1591
1592 if (i == 0 && len > 1) {
1593 if (isString) {
1594 sprintf(_buff, "[ \"%.*s\"",
1595 (int) tmp_valStr_len, _tmp_valStr);
1596 } else {
1597 sprintf(_buff, "[ %.*s", (int) tmp_valStr_len, _tmp_valStr);
1598 }
1599 } else if (i == (len - 1)) {
1600 if (isString) {
1601 sprintf(_buff, "%.*s, \"%.*s\" ]",
1602 (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1603 } else {
1604 sprintf(_buff, "%.*s, %.*s ]",
1605 (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1606 }
1607 } else {
1608 if (isString) {
1609 sprintf(_buff, "%.*s, \"%.*s\"",
1610 (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1611 } else {
1612 sprintf(_buff, "%.*s, %.*s",
1613 (int) tmp_buff_len, _tmp_buff, (int) tmp_valStr_len, _tmp_valStr);
1614 }
1615 }
1616
1617 FREE_IF_NZ (_tmp_buff);
1618#if JS_VERSION >= 185
1619 if (encodedTmpValstr == JS_TRUE) {
1620 JS_free(cx,_tmp_valStr);
1621 encodedTmpValstr = JS_FALSE;
1622 }
1623#endif
1624 }
1625
1626 /* PixelTextures are stored in Javascript as MFInt32s but in FreeWRL/Perl as an ascii string.
1627 we have to remove some characters to make it into a valid VRML image string */
1628 if (isImage) {
1629 for (i=0; i<(int)strlen(_buff); i++) {
1630 if (_buff[i] == ',') _buff[i]=' ';
1631 if (_buff[i] == ']') _buff[i]=' ';
1632 if (_buff[i] == '[') _buff[i]=' ';
1633 }
1634 }
1635 /* printf ("domfstring, buff %s\n",_buff);*/
1636 _str = JS_NewStringCopyZ(cx, _buff);
1637 *rval = STRING_TO_JSVAL(_str);
1638
1639 FREE_IF_NZ (_buff);
1640 return JS_TRUE;
1641}
1642
1643JSBool
1644#if JS_VERSION < 185
1645doMFAddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, char *name) {
1646#else
1647doMFAddProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp, char *name) {
1648#endif
1649 JSString *str;
1650 jsval v;
1651 char *p;
1652 int len, ind;
1653#if JS_VERSION >= 185
1654 jsval id;
1655 if (!JS_IdToValue(cx,iid,&id)) {
1656 printf("\tdoMFAddProperty:%s JS_IdToValue failed\n",name);
1657 return JS_FALSE;
1658 }
1659#endif
1660 len = 0;
1661 //ind = JSVAL_TO_INT(id);
1662
1663 #ifdef JSVRMLCLASSESVERBOSE
1664 printf("\tdoMFAddProperty:%s id %d (%d) NodeType: ",name,(int)id,ind);
1665 printJSNodeType(cx,obj);
1666 #endif
1667
1668 str = JS_ValueToString(cx, id);
1669#if JS_VERSION < 185
1670 p = JS_GetStringBytes(str);
1671#else
1672 p = JS_EncodeString(cx,str);
1673#endif
1674 #ifdef JSVRMLCLASSESVERBOSE
1675 printf("\tid string %s\n ",p);
1676 #endif
1677
1678 if (!strcmp(p, MF_LENGTH_FIELD) ||
1679 !strcmp(p, "MF_ECMA_has_changed") ||
1680 !strcmp(p, "_parentField") ||
1681 !strcmp(p, "toString") ||
1682 !strcmp(p, "setTransform") ||
1683 !strcmp(p, "assign") ||
1684 !strcmp(p, "inverse") ||
1685 !strcmp(p, "transpose") ||
1686 !strcmp(p, "multLeft") ||
1687 !strcmp(p, "multRight") ||
1688 !strcmp(p, "multVecMatrix") ||
1689 !strcmp(p, "multMatrixVec") ||
1690 !strcmp(p, "constructor") ||
1691 !strcmp(p, "getTransform")) {
1692 #ifdef JSVRMLCLASSESVERBOSE
1693 printf("property \"%s\" is one of the standard properties. Do nothing.\n", p);
1694 #endif
1695#if JS_VERSION >= 185
1696 JS_free(cx,p);
1697#endif
1698 return JS_TRUE;
1699 }
1700
1701 #ifdef JSVRMLCLASSESVERBOSE
1702 printf("\tdoMFAddProperty:%s id %d NodeType: ",name,(int)id);
1703 printJSNodeType(cx,obj);
1704 printf("\tdoMFAddProperty:%s id %d string %s ",name,(int)id,p);
1705 #endif
1706#if JS_VERSION >= 185
1707 JS_free(cx,p);
1708#endif
1709
1710 if (!JSVAL_IS_INT(id)){
1711 printf( "JSVAL_IS_INT failed for id in doMFAddProperty.\n");
1712 return JS_FALSE;
1713 }
1714 if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &v)) {
1715 printf( "JS_GetProperty failed for \"%s\" in doMFAddProperty.\n",MF_LENGTH_FIELD);
1716 return JS_FALSE;
1717 }
1718 ind = JSVAL_TO_INT(id);
1719
1720 len = JSVAL_TO_INT(v);
1721 if (ind >= len) {
1722 len = ind + 1;
1723
1724 #ifdef JSVRMLCLASSESVERBOSE
1725 printf ("doMFAddProperty, len %d ind %d\n",len,ind);
1726 #endif
1727
1728 v = INT_TO_JSVAL(len);
1729 if (!JS_SetProperty(cx, obj, MF_LENGTH_FIELD, &v)) {
1730 printf( "JS_SetProperty failed for \"%s\" in doMFAddProperty.\n",MF_LENGTH_FIELD);
1731 return JS_FALSE;
1732 }
1733 }
1734
1735 #ifdef JSVRMLCLASSESVERBOSE
1736 printf("index = %d, length = %d\n", ind, len);
1737 #endif
1738
1739 return JS_TRUE;
1740}
1741
1742void JS_ECMA_TO_X3D(JSContext *cx, void *Data, unsigned datalen, int dataType, jsval *newval);
1743void JS_SF_TO_X3D(JSContext *cx, void *Data, unsigned datalen, int dataType, jsval *newval);
1744void JS_SF_TO_X3D_B(JSContext *cx, void *Data, int dataType, int *valueChanged, jsval *newval);
1745
1746JSBool
1747#if JS_VERSION < 185
1748doMFSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, int type) {
1749#else
1750doMFSetProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp, int type) {
1751#endif
1752 JSString *_sstr;
1753 jsval myv;
1754 int i;
1755 double dd;
1756
1757 int ii;
1758
1759 JSObject *par;
1760 JSObject *me;
1761 jsval pf;
1762 jsval nf;
1763 char * _cc;
1764 jsid oid;
1765#if JS_VERSION >= 185
1766 jsval id;
1767 if (!JS_IdToValue(cx,iid,&id)) {
1768 printf("doMFSetProperty, JS_IdToValue failed.\n");
1769 return JS_FALSE;
1770 }
1771#endif
1772 if(SM_method() == 2){
1773 AnyNative *ptr;
1774 union anyVrml* any;
1775 int sftype, sfsize;
1776 int *valueChanged;
1777
1778 if ((ptr = (AnyNative *)JS_GetPrivateFw(cx,obj)) == NULL) {
1779 printf( "JS_GetPrivate failed in standardMFGetterProperty\n");
1780 return JS_FALSE;
1781 }
1782 valueChanged = ptr->valueChanged;
1783 sftype = type2SF(ptr->type);
1784 sfsize = sizeofSForMF(sftype);
1785
1786 if (JSVAL_IS_INT(id)) {
1787 // [index] property
1788 char *mf_p;
1789 int mf_n, iupper;
1790 int newlength;
1791 int index = JSVAL_TO_INT(id);
1792 if(index < 0) return JS_FALSE;
1793
1794 newlength = index + 1;
1795 mf_n = ptr->v->mfbool.n;
1796 mf_p = (char *)ptr->v->mfbool.p;
1797 iupper = upper_power_of_two(newlength);
1798 if(newlength > mf_n ) {
1799 // in the setter, normally we realloc
1800 if(mf_p == NULL){
1801 mf_p = malloc(sfsize*iupper);
1802 memset(mf_p,0,(size_t)sfsize*iupper);
1803 }else{
1804 int k;
1805 mf_p = realloc(mf_p,(size_t)sfsize*iupper);
1806 memset(mf_p + (size_t)sfsize*mf_n,0,(size_t)(iupper - mf_n)*sfsize);
1807 }
1808 ptr->v->mfbool.n = newlength;
1809 }
1810 ptr->v->mfbool.p = (int*)mf_p;
1811 any = (union anyVrml*)(mf_p + (index * sfsize));
1812 switch(type2SF(ptr->type)){
1813 case FIELDTYPE_SFBool:
1814 case FIELDTYPE_SFFloat:
1815 case FIELDTYPE_SFTime:
1816 case FIELDTYPE_SFDouble:
1817 case FIELDTYPE_SFInt32:
1818 case FIELDTYPE_SFString:
1819 //X3D_ECMA_TO_JS(cx, any,sfsize,sftype,vp);
1820 JS_ECMA_TO_X3D(cx, any, sfsize,sftype,vp);
1821 if(valueChanged)
1822 (*valueChanged)++;
1823
1824 break;
1825 case FIELDTYPE_SFColor:
1826 case FIELDTYPE_SFVec2f:
1827 case FIELDTYPE_SFVec3f:
1828 case FIELDTYPE_SFVec3d:
1829 case FIELDTYPE_SFRotation:
1830 JS_SF_TO_X3D_B(cx, any, sftype, valueChanged, vp);
1831 //JS_SF_TO_X3D(cx, any, sfsize, sftype, ptr->valueChanged, vp);
1832 break;
1833 case FIELDTYPE_SFNode:
1834 JS_SF_TO_X3D_BNode(cx, any, sftype, valueChanged, vp);
1835 break;
1836 default: printf ("invalid type in standardMFGetProperty method 2\n"); return JS_FALSE;
1837 }
1838 return JS_TRUE;
1839 }else if(JSVAL_IS_STRING(id)){
1840 JSString *_idStr;
1841 char *_id_c;
1842
1843 _idStr = JS_ValueToString(cx, id);
1844#if JS_VERSION < 185
1845 _ id_c = JS_GetStringBytes(_idStr);
1846#else
1847 _id_c = JS_EncodeString(cx,_idStr);
1848#endif
1849 if (strcmp ("length",_id_c) == 0) {
1850 //create js int
1851 //assign length to it
1852 // length = ptr->v->mfbool.n;
1853 if(JSVAL_IS_INT(*vp)){
1854 char *mf_p;
1855 int mf_n, iupper;
1856 int newlength = JSVAL_TO_INT(*vp);
1857
1858 mf_n = ptr->v->mfbool.n;
1859 mf_p = (char *)ptr->v->mfbool.p;
1860 iupper = upper_power_of_two(newlength);
1861 if(newlength > mf_n ) {
1862 // in the setter, normally we realloc
1863 if(mf_p == NULL){
1864 mf_p = malloc(sfsize*iupper);
1865 memset(mf_p,0,(size_t)sfsize*iupper);
1866 }else{
1867 int k;
1868 mf_p = realloc(mf_p,(size_t)sfsize*iupper);
1869 memset(mf_p + (size_t)sfsize*mf_n,0,(size_t)(iupper - mf_n)*sfsize);
1870 }
1871 }
1872 ptr->v->mfbool.n = newlength;
1873 ptr->v->mfbool.p = (int*)mf_p;
1874 if(valueChanged)
1875 (*valueChanged)++;
1876 return JS_TRUE;
1877 }
1878 }
1879 } // if else JSVAL_IS
1880 return JS_FALSE;
1881 }else{ //SM_method == 2
1882 #ifdef JSVRMLCLASSESVERBOSE
1883 JSString *_str;
1884 char * _c;
1885 printf ("doMFSetProperty, for object %p, vp %u\n", obj,(unsigned int)*vp);
1886 _str = JS_ValueToString(cx, id);
1887#if JS_VERSION < 185
1888 _c = JS_GetStringBytes(_str);
1889#else
1890 _c = JS_EncodeString(cx,_str);
1891#endif
1892 printf ("id is %s\n",_c);
1893
1894 _sstr = JS_ValueToString(cx, *vp);
1895 printf ("looking up value for %d %#x object %p\n",(int)*vp,(unsigned int)*vp,obj);
1896#if JS_VERSION < 185
1897 _cc = JS_GetStringBytes(_sstr);
1898#else
1899 _cc = JS_EncodeString(cx,_sstr);
1900#endif
1901 printf("\tdoMFSetProperty:%d: obj = %p, id = %s, vp = %s\n",type,
1902 obj, _c, _cc);
1903 if (JSVAL_IS_OBJECT(*vp)) { printf ("doMFSet, vp is an OBJECT\n"); }
1904 if (JSVAL_IS_PRIMITIVE(*vp)) { printf ("doMFSet, vp is an PRIMITIVE\n"); }
1905
1906 printf ("parent is a "); printJSNodeType(cx,obj);
1907 /* printf ("jsval is is a "); printJSNodeType(cx,*vp); */
1908#if JS_VERSION >= 185
1909 JS_free(cx,_c);
1910 JS_free(cx,_cc);
1911#endif
1912 #endif
1913
1914 /* should this value be checked for possible conversions */
1915 if (type == FIELDTYPE_MFInt32) {
1916 #ifdef JSVRMLCLASSESVERBOSE
1917 printf ("doMFSetProperty, this should be an int \n");
1918 #endif
1919
1920 if (!JSVAL_IS_INT(*vp)) {
1921 #ifdef JSVRMLCLASSESVERBOSE
1922 printf ("is NOT an int\n");
1923 #endif
1924
1925 if (!JS_ValueToInt32(cx, *vp, &i)) {
1926 _sstr = JS_ValueToString(cx, *vp);
1927#if JS_VERSION < 185
1928 _cc = JS_GetStringBytes(_sstr);
1929#else
1930 _cc = JS_EncodeString(cx,_sstr);
1931#endif
1932 printf ("can not convert %s to an integer in doMFAddProperty for type %d\n",_cc,type);
1933#if JS_VERSION >= 185
1934 JS_free(cx,_cc);
1935#endif
1936 return JS_FALSE;
1937 }
1938
1939 *vp = INT_TO_JSVAL(i);
1940 }
1941 } else if ((type == FIELDTYPE_MFFloat) || (type == FIELDTYPE_MFTime)) {
1942 #ifdef JSVRMLCLASSESVERBOSE
1943 printf ("doMFSetProperty - ensure that this is a DOUBLE ");
1944 _sstr = JS_ValueToString(cx, *vp);
1945#if JS_VERSION < 185
1946 _cc = JS_GetStringBytes(_sstr);
1947#else
1948 _cc = JS_EncodeString(cx,_sstr);
1949#endif
1950 printf ("value is %s \n",_cc);
1951#if JS_VERSION >= 185
1952 JS_free(cx,_cc);
1953#endif
1954 #endif
1955
1956 if (JSVAL_IS_INT(*vp)) {
1957 ii = JSVAL_TO_INT(*vp);
1958 dd = (double) ii;
1959 /* printf ("integer is %d doulbe %lf\n",ii,dd); */
1960 if (JS_NewNumberValue(cx,dd,vp) == JS_FALSE) {
1961 printf( "JS_NewNumberValue failed for %f in simplecopyelements.\n",dd);
1962 return JS_FALSE;
1963 }
1964 }
1965 }
1966
1967 #ifdef JSVRMLCLASSESVERBOSE
1968 printf ("setting changed flag on %p\n",obj);
1969 #endif
1970
1971 /* is this an MF ECMA type that uses the MF_ECMA_has_changed flag? */
1972 switch (type) {
1973 case FIELDTYPE_MFInt32:
1974 case FIELDTYPE_MFBool:
1975 case FIELDTYPE_MFTime:
1976 case FIELDTYPE_MFFloat:
1977 case FIELDTYPE_MFString: {
1978 SET_MF_ECMA_HAS_CHANGED
1979 break;
1980 }
1981 default: {}
1982 }
1983
1984
1985 if (JSVAL_IS_INT(id)) {
1986 /* save this element into the parent at index */
1987
1988 #ifdef JSVRMLCLASSESVERBOSE
1989 printf ("saving element %d\n",JSVAL_TO_INT(id));
1990 #endif
1991
1992 if (!JS_DefineElement(cx, obj, JSVAL_TO_INT(id), *vp,
1993 JS_GET_PROPERTY_STUB, JS_SET_PROPERTY_CHECK,
1994 JSPROP_ENUMERATE)) {
1995 printf( "JS_DefineElement failed in doMFSetProperty.\n");
1996 return JS_FALSE;
1997 }
1998
1999 /* has the length changed? */
2000 if (!JS_GetProperty(cx, obj, MF_LENGTH_FIELD, &myv)) {
2001 printf("JS_GetProperty failed for \"%s\" in doMFSetProperty.\n", MF_LENGTH_FIELD);
2002 return JS_FALSE;
2003 }
2004
2005 #ifdef JSVRMLCLASSESVERBOSE
2006 printf ("object %p old length %d, possibly new length is going to be %d\n",obj,JSVAL_TO_INT(myv), JSVAL_TO_INT(id)+1);
2007 #endif
2008
2009 if (JSVAL_TO_INT(myv) < (JSVAL_TO_INT(id)+1)) {
2010 printf ("new length is %d\n",JSVAL_TO_INT(id)+1);
2011 myv = INT_TO_JSVAL(JSVAL_TO_INT(id)+1);
2012 if (!JS_SetProperty(cx, obj, MF_LENGTH_FIELD, &myv)) {
2013 printf("JS_SetProperty failed for \"%s\" in doMFSetProperty.\n", MF_LENGTH_FIELD);
2014 return JS_FALSE;
2015 }
2016 }
2017 }
2018
2019 #ifdef JSVRMLCLASSESVERBOSE
2020 printf ("doMFSetProperty, lets see if we have an SFNode somewhere up the chain...\n");
2021 #endif
2022
2023 /* ok - if we are setting an MF* field by a thing like myField[10] = new String(); the
2024 set method does not really get called. So, we go up the parental chain until we get
2025 either no parent, or a SFNode. If we get a SFNode, we call the "save this" function
2026 so that the X3D scene graph gets the updated array value. To make a long story short,
2027 here's the call to find the parent for the above. */
2028
2029 me = obj;
2030 par = JS_GetParentFw(cx, me);
2031 while (par != NULL) {
2032 #ifdef JSVRMLCLASSESVERBOSE
2033 printf ("for obj %p: ",me);
2034 printJSNodeType(cx,me);
2035 printf ("... parent %p\n",par);
2036 printJSNodeType(cx,par);
2037 #endif
2038
2039 if (JS_InstanceOf (cx, par, &SFNodeClass, NULL)) {
2040 #ifdef JSVRMLCLASSESVERBOSE
2041 printf (" the parent IS AN SFNODE - it is %p\n",par);
2042 #endif
2043
2044
2045 if (!JS_GetProperty(cx, obj, "_parentField", &pf)) {
2046 printf ("doMFSetProperty, can not get parent field from this object\n");
2047 return JS_FALSE;
2048 }
2049
2050 nf = OBJECT_TO_JSVAL(me);
2051
2052 #ifdef JSVRMLCLASSESVERBOSE
2053 #if JS_VERSION < 185
2054 printf ("parentField is %u \"%s\"\n", (unsigned int)pf, JS_GetStringBytes(JSVAL_TO_STRING(pf)));
2055 #else
2056 _cc = JS_EncodeString(cx,JSVAL_TO_STRING(pf));
2057 printf ("parentField is %u \"%s\"\n", (unsigned int)pf, _cc);
2058 JS_free(cx,_cc);
2059 #endif
2060 #endif
2061
2062 if (!JS_ValueToId(cx,pf,&oid)) {
2063 printf("doMFSetProperty: JS_ValueToId failed.\n");
2064 return JS_FALSE;
2065 }
2066 #if JS_VERSION == 186
2067 {
2068 JSHandleObject hobj;
2069 JSHandleId hiid;
2070 JSMutableHandleValue hvp;
2071 hobj._ = &par;
2072 hiid._ = &oid;
2073 hvp._ = &nf;
2074 setSFNodeField(cx,hobj,hiid,JS_FALSE,hvp);
2075 }
2076 #else
2077
2078 if (!setSFNodeField (cx, par, oid,
2079#if JS_VERSION >= 185
2080 JS_FALSE,
2081#endif
2082 &nf)) {
2083 printf ("could not set field of SFNode\n");
2084 }
2085 #endif
2086
2087 }
2088 me = par;
2089 par = JS_GetParentFw(cx, me);
2090 }
2091 return JS_TRUE;
2092
2093 }//SM_method == 2
2094}
2095
2096JSBool
2097doMFStringUnquote(JSContext *cx, jsval *vp)
2098{
2099 JSString *_str, *_vpStr;
2100 char *_buff, *_tmp_vpStr;
2101 size_t _buff_len;
2102 unsigned int i, j = 0;
2103
2104 _str = JS_ValueToString(cx, *vp);
2105#if JS_VERSION < 185
2106 _buff = JS_GetStringBytes(_str);
2107#else
2108 _buff = JS_EncodeString(cx,_str);
2109#endif
2110 _buff_len = strlen(_buff) + 1;
2111
2112 #ifdef JSVRMLCLASSESVERBOSE
2113 printf("doMFStringUnquote: vp = \"%s\"\n", _buff);
2114 #endif
2115
2116 if (memchr(_buff, '"', _buff_len) != NULL) {
2117 _tmp_vpStr = MALLOC(char *, _buff_len * sizeof(char));
2118
2119 memset(_tmp_vpStr, 0, _buff_len);
2120
2121 for (i = 0; i <= (_buff_len-1); i++) {
2122 if (_buff[i] != '"' ||
2123 (i > 0 && _buff[i - 1] == '\\')) {
2124 _tmp_vpStr[j++] = _buff[i];
2125 }
2126 }
2127 #ifdef JSVRMLCLASSESVERBOSE
2128 printf ("new unquoted string %s\n",_tmp_vpStr);
2129 #endif
2130
2131 _vpStr = JS_NewStringCopyZ(cx, _tmp_vpStr);
2132 *vp = STRING_TO_JSVAL(_vpStr);
2133
2134 FREE_IF_NZ (_tmp_vpStr);
2135 }
2136#if JS_VERSION >= 185
2137 JS_free(cx,_buff);
2138#endif
2139
2140 return JS_TRUE;
2141}
2142
2143
2144JSBool
2145#if JS_VERSION < 185
2146globalResolve(JSContext *cx, JSObject *obj, jsval id){
2147#elif JS_VERSION == 185
2148globalResolve(JSContext *cx, JSObject *obj, jsid id){
2149#else
2150globalResolve(JSContext *cx, JSHandleObject hobj, JSHandleId hiid){
2151 JSObject *obj = *hobj._;
2152 jsid id = *hiid._;
2153#endif
2154 UNUSED(cx);
2155 UNUSED(obj);
2156 UNUSED(id);
2157 return JS_TRUE;
2158}
2159
2160
2161/* load the FreeWRL extra classes */
2162JSBool loadVrmlClasses(JSContext *context, JSObject *globalObj) {
2163 jsval v;
2164 int i;
2165
2166 JSObject *myProto;
2167
2168 i=0;
2169 while (JSLoadProps[i].class != NULL) {
2170 #ifdef JSVRMLCLASSESVERBOSE
2171 printf ("loading %s\n",JSLoadProps[i].id);
2172 #endif
2173
2174 /* v = 0; */
2175 if (( myProto = JS_InitClass(context, globalObj, NULL, JSLoadProps[i].class,
2176 JSLoadProps[i].constr, INIT_ARGC, JSLoadProps[i].Properties,
2177 JSLoadProps[i].Functions, NULL, NULL)) == NULL) {
2178 printf("JS_InitClass for %s failed in loadVrmlClasses.\n",JSLoadProps[i].id);
2179 return JS_FALSE;
2180 }
2181 v = OBJECT_TO_JSVAL(myProto);
2182 if (!JS_SetProperty(context, globalObj, JSLoadProps[i].id, &v)) {
2183 printf("JS_SetProperty for %s failed in loadVrmlClasses.\n",JSLoadProps[i].id);
2184 return JS_FALSE;
2185 }
2186
2187 i++;
2188 }
2189 return JS_TRUE;
2190}
2191
2192/* go through and see if the setECMA routine touched this name */
2193int findNameInECMATable(JSContext *context, char *toFind) {
2194 int i;
2195 ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
2196 #ifdef JSVRMLCLASSESVERBOSE
2197 printf ("findNameInECMATable, looking for %s context %p\n",toFind,context);
2198 #endif
2199
2200 i=0;
2201 while (i < p->maxECMAVal) {
2202 #ifdef JSVRMLCLASSESVERBOSE
2203 printf (" %d: %s==%s cx %p==%p\n",i,p->ECMAValues[i].name,toFind,p->ECMAValues[i].context,context);
2204 #endif
2205
2206
2207 if ((p->ECMAValues[i].context == context) && (strcmp(p->ECMAValues[i].name,toFind)==0)) {
2208 #ifdef JSVRMLCLASSESVERBOSE
2209 printf ("fineInECMATable: found value at %d\n",i);
2210 #endif
2211 return p->ECMAValues[i].valueChanged;
2212 }
2213 i++;
2214 }
2215
2216 /* did not find this one, add it */
2217 #ifdef JSVRMLCLASSESVERBOSE
2218 printf ("findInECMATable - did not find %s\n",toFind);
2219 #endif
2220
2221 return FALSE;
2222}
2223
2224/* go through the ECMA table, and reset the valueChanged flag. */
2225void resetNameInECMATable(JSContext *context, char *toFind) {
2226 int i;
2227 ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
2228 #ifdef JSVRMLCLASSESVERBOSE
2229 printf ("findNameInECMATable, looking for %s\n",toFind);
2230 #endif
2231
2232 i=0;
2233 while (i < p->maxECMAVal) {
2234 #ifdef JSVRMLCLASSESVERBOSE
2235 printf (" %d: %s==%s cx %p==%p\n",i,p->ECMAValues[i].name,toFind,p->ECMAValues[i].context,context);
2236 #endif
2237
2238
2239 if ((p->ECMAValues[i].context == context) && (strcmp(p->ECMAValues[i].name,toFind)==0)) {
2240 #ifdef JSVRMLCLASSESVERBOSE
2241 printf ("fineInECMATable: found value at %d\n",i);
2242 #endif
2243 p->ECMAValues[i].valueChanged = FALSE;
2244 return;
2245 }
2246 i++;
2247 }
2248}
2249
2250
2251
2252
2253/* set the valueChanged flag - add a new entry to the table if required */
2254void setInECMATable(JSContext *context, char *toFind) {
2255 int i;
2256 ppjsVRMLClasses p = (ppjsVRMLClasses)gglobal()->jsVRMLClasses.prv;
2257 #ifdef JSVRMLCLASSESVERBOSE
2258 printf ("setInECMATable, looking for %s\n",toFind);
2259 #endif
2260
2261 i=0;
2262 while (i < p->maxECMAVal) {
2263 #ifdef JSVRMLCLASSESVERBOSE
2264 printf (" %d: %s==%s cx %p==%p\n",i,p->ECMAValues[i].name,toFind,p->ECMAValues[i].context,context);
2265 #endif
2266
2267
2268 if ((p->ECMAValues[i].context == context) && (strcmp(p->ECMAValues[i].name,toFind)==0)) {
2269 #ifdef JSVRMLCLASSESVERBOSE
2270 printf ("setInECMATable: found value at %d\n",i);
2271 #endif
2272 p->ECMAValues[i].valueChanged = TRUE;
2273 return;
2274 }
2275 i++;
2276 }
2277
2278 /* did not find this one, add it */
2279 #ifdef JSVRMLCLASSESVERBOSE
2280 printf ("setInECMATable - new entry at %d for %s\n",p->maxECMAVal, toFind);
2281 #endif
2282
2283 p->maxECMAVal ++;
2284 if (p->maxECMAVal == ECMAValueTableSize) {
2285 ConsoleMessage ("problem in setInECMATable for scripting\n");
2286 p->maxECMAVal = ECMAValueTableSize - 10;
2287 }
2288#if JS_VERSION < 185
2289 /* Dangerous code, taking a string and casting it directly -- why does this happen? */
2290 p->ECMAValues[p->maxECMAVal-1].JS_address = (jsval) toFind;
2291#else
2292 /* since this seems to never be used anyways .. */
2293 p->ECMAValues[p->maxECMAVal-1].JS_address = INT_TO_JSVAL(0); //JSVAL_ZERO;
2294#endif
2295 p->ECMAValues[p->maxECMAVal-1].valueChanged = TRUE;
2296 p->ECMAValues[p->maxECMAVal-1].name = STRDUP(toFind);
2297 p->ECMAValues[p->maxECMAVal-1].context = context;
2298}
2299
2300
2301/*
2302int getFieldFromScript(struct Shader_Script * sp, char *fieldname, int *type, int *kind, int *iifield, union anyVrml **value, int **valueChanged){
2303 //sp = (struct Shader_Script *)snode->__scriptObj;
2304 int k;
2305 struct ScriptFieldDecl *sfield;
2306 struct Vector *sfields;
2307 struct FieldDecl *fdecl;
2308 struct CRjsnameStruct *JSparamnames = getJSparamnames();
2309
2310
2311 sfields = sp->fields;
2312 for(k=0;k<sfields->n;k++)
2313 {
2314 char *fieldName;
2315 sfield = vector_get(struct ScriptFieldDecl *,sfields,k);
2316 //if(sfield->ASCIIvalue) printf("Ascii value=%s\n",sfield->ASCIIvalue);
2317 fdecl = sfield->fieldDecl;
2318 fieldName = fieldDecl_getShaderScriptName(fdecl);
2319 if(!strcmp(fieldName,fieldname)){
2320 *type = fdecl->fieldType;
2321 *kind = fdecl->PKWmode;
2322 *value = &(sfield->value);
2323 *valueChanged = &(sfield->valueChanged);
2324 *iifield = k;
2325 return 1;
2326 }
2327 }
2328 return 0;
2329}
2330*/
2331
2332void X3D_ECMA_TO_JS(JSContext *cx, void *Data, int datalen, int dataType, jsval *newval);
2333void X3D_MF_TO_JS(JSContext *cx, JSObject *obj, void *Data, int dataType, jsval *newval, char *fieldName);
2334void X3D_MF_TO_JS_B(JSContext *cx, void *Data, int dataType, int *valueChanged, jsval *newval);
2335void X3D_SF_TO_JS(JSContext *cx, JSObject *obj, void *Data, unsigned datalen, int dataType, jsval *newval);
2336void X3D_SF_TO_JS_B(JSContext *cx, void *Data, unsigned datalen, int dataType, int *valueChanged, jsval *newval);
2337
2338JSBool
2339#if JS_VERSION < 185
2340getECMANative(JSContext *cx, JSObject *obj, jsval id, jsval *vp){
2341#elif JS_VERSION == 185
2342getECMANative(JSContext *cx, JSObject *obj, jsid iid, jsval *vp){
2343#else
2344getECMANative(JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSMutableHandleValue hvp){
2345 JSObject *obj = *hobj._;
2346 jsid iid = *hiid._;
2347 jsval *vp = hvp._;
2348#endif
2349 if(SM_method() == 2){
2350
2351 //printf("in getECMANative\n");
2352 //#ifdef JSVRMLCLASSESVERBOSE
2353 JSString *_idStr, *_vpStr;
2354 char *_id_c, *fieldname, *_vp_c;
2355
2356#if JS_VERSION >= 185
2357 jsval id;
2358 if (!JS_IdToValue(cx,iid,&id)) {
2359 printf("getECMANative: JS_IdToValue failed -- returning JS_TRUE anyways\n");
2360 }
2361#endif
2362
2363 _idStr = JS_ValueToString(cx, id);
2364// _vpStr = JS_ValueToString(cx, *vp);
2365#if JS_VERSION < 185
2366 _id_c = JS_GetStringBytes(_idStr);
2367 _vp_c = JS_GetStringBytes(_vpStr);
2368#else
2369 _id_c = JS_EncodeString(cx,_idStr);
2370// _vp_c = JS_EncodeString(cx,_vpStr);
2371#endif
2372 //printf("getECMANative: obj = %p, id = \"%s\", vp = %s\n",
2373 // obj, _id_c, _vp_c);
2374 //printf("getECMANative: obj = %p, id = \"%s\"\n", obj, _id_c);
2375
2376 //printf ("what is vp? \n");
2377 //if (JSVAL_IS_OBJECT(*vp)) {
2378 // printf ("is OBJECT\n");
2379 // if (JSVAL_IS_OBJECT(vp[1])) printf ("vp1 is OBJECT\n");
2380 // if (JSVAL_IS_STRING(vp[1])) {
2381 // printf ("vp1 is STRING\n");
2382 // JSString * jstr = JS_ValueToString(cx, vp[1]);
2383 // char * cstr = JS_EncodeString(cx,jstr);
2384 // printf("vp1 str=|%s|\n",cstr);
2385 // }
2386 // if (JSVAL_IS_INT(vp[1])) printf ("vp1 is INT %d\n",JSVAL_TO_INT(*vp));
2387 // if (JSVAL_IS_DOUBLE(vp[1])) printf ("vp1 is DOUBLE\n");
2388 //}
2389 //if (JSVAL_IS_STRING(*vp)) printf ("is STRING\n");
2390 //if (JSVAL_IS_INT(*vp)) printf ("is INT %d\n",JSVAL_TO_INT(*vp));
2391 //if (JSVAL_IS_DOUBLE(*vp)) printf ("is DOUBLE\n");
2392 fieldname = _id_c;
2393 //inputOnly field will have a prefix on the var name
2394 // for avoiding javascript namespace clash with eventIn function
2395 //(inputOutput renames the function to set_<fieldname> and leaves fieldname)
2396 if(!strncmp(fieldname,"__eventIn_Value_",strlen("__eventIn_Value_")))
2397 fieldname = &fieldname[strlen("__eventIn_Value_")];
2398 //printf("getNative short fieldname %s\n",fieldname);
2399 {
2400 int type, kind, iifield, ifound, sfsize, sftype;
2401 union anyVrml *value;
2402 int *valueChanged;
2403 struct Shader_Script *script;
2404 // = sm_get_script();
2405 script = JS_GetPrivateFw(cx,obj);
2406
2407 valueChanged = NULL;
2408 value = NULL;
2409 ifound = getFieldFromScript(script,fieldname,&type,&kind,&iifield,&value,&valueChanged);
2410 if(ifound){
2411 sftype = type2SF(type);
2412 sfsize = sizeofSForMF(sftype);
2413 //similar to SFNodeGetProperty
2414 //printf("getECMANative found field %s in script type %d kind %d index %d vC %d \n",fieldname,type,kind,iifield,*valueChanged);
2415 //set up a return value
2416 switch (type) {
2417 case FIELDTYPE_SFBool:
2418 case FIELDTYPE_SFFloat:
2419 case FIELDTYPE_SFTime:
2420 case FIELDTYPE_SFDouble:
2421 case FIELDTYPE_SFInt32:
2422 case FIELDTYPE_SFString:
2423 X3D_ECMA_TO_JS(cx, value,sfsize,type,vp);
2424 break;
2425 case FIELDTYPE_SFColor:
2426 case FIELDTYPE_SFNode:
2427 case FIELDTYPE_SFVec2f:
2428 case FIELDTYPE_SFVec3f:
2429 case FIELDTYPE_SFVec3d:
2430 case FIELDTYPE_SFRotation:
2431 //void X3D_SF_TO_JS_B(JSContext *cx, void *Data, unsigned datalen, int dataType, int *valueChanged, jsval *newval)
2432 X3D_SF_TO_JS_B(cx, value,sfsize, type, valueChanged, vp);
2433 break;
2434 case FIELDTYPE_MFColor:
2435 case FIELDTYPE_MFVec3f:
2436 case FIELDTYPE_MFVec2f:
2437 case FIELDTYPE_MFFloat:
2438 case FIELDTYPE_MFTime:
2439 case FIELDTYPE_MFInt32:
2440 case FIELDTYPE_MFString:
2441 case FIELDTYPE_MFNode:
2442 case FIELDTYPE_MFRotation:
2443 case FIELDTYPE_SFImage:
2444 //static void X3D_MF_TO_JS(JSContext *cx, void *Data, int dataType, jsval *newval, char *fieldName) {
2445 X3D_MF_TO_JS_B(cx, value, type, valueChanged, vp);
2446 break;
2447 default: printf ("unhandled type FIELDTYPE_ %d in getSFNodeField\n", type) ;
2448 return JS_FALSE;
2449 }
2450 }else{
2451 printf("getECMANative didn't find field %s in script\n",fieldname);
2452 }
2453 }
2454
2455
2456#if JS_VERSION >= 185
2457 JS_free(cx,_id_c);
2458 //JS_free(cx,_vp_c);
2459#endif
2460 //#endif
2461 } //if SM_method() == 2
2462 return JS_TRUE;
2463}
2464
2465
2466JSBool
2467#if JS_VERSION < 185
2468setECMANative(JSContext *cx, JSObject *obj, jsval id, jsval *vp){
2469#elif JS_VERSION == 185
2470setECMANative(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp){
2471#else
2472setECMANative(JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
2473 JSObject *obj = *hobj._;
2474 jsid iid = *hiid._;
2475 jsval *vp = hvp._;
2476#endif
2477 JSString *_idStr;
2478 JSString *_vpStr, *_newVpStr;
2479 JSBool ret = JS_TRUE;
2480 char *_id_c, *fieldname;
2481
2482 char *_vp_c, *_new_vp_c;
2483 size_t len = 0;
2484#if JS_VERSION >= 185
2485 jsval id;
2486 if (!JS_IdToValue(cx,iid,&id)) {
2487 printf( "JS_IdToValue failed\n");
2488 return JS_FALSE;
2489 }
2490#endif
2491
2492 _idStr = JS_ValueToString(cx, id);
2493#if JS_VERSION < 185
2494 _id_c = JS_GetStringBytes(_idStr);
2495#else
2496 _id_c = JS_EncodeString(cx,_idStr);
2497#endif
2498 fieldname = _id_c;
2499 //inputOnly field will have a prefix on the var name
2500 // for avoiding javascript namespace clash with eventIn function
2501 //(inputOutput renames the function to set_<fieldname> and leaves fieldname)
2502 if(!strncmp(fieldname,"__eventIn_Value_",strlen("__eventIn_Value_")))
2503 fieldname = &fieldname[strlen("__eventIn_Value_")];
2504 if(SM_method() == 2){
2505 int type, kind, iifield, *valueChanged, ifound;
2506 union anyVrml *value;
2507 valueChanged = NULL;
2508 value = NULL;
2509 struct Shader_Script *script;
2510 // = sm_get_script();
2511 script = JS_GetPrivateFw(cx,obj);
2512
2513 ifound = getFieldFromScript(script,fieldname,&type,&kind,&iifield,&value,&valueChanged);
2514 if(ifound){
2515 //its a script field
2516 //but in setECMANative obj == global.
2517 //And global has no one single private (it could - we could put scriptcontrol)
2518 //printf("set found field %s in script type %d kind %d index %d \n",fieldname,type,kind,iifield);
2519 //type of incoming RHS
2520 //setField_fromJavascript (X3D_NODE(ptr->handle), _id_c, _val_c, FALSE);
2521 //printf("in setECMANative RHS ");
2522 //if (JSVAL_IS_OBJECT(*vp)) printf ("is OBJECT\n");
2523 //if (JSVAL_IS_STRING(*vp)) printf ("is STRING\n");
2524 //if (JSVAL_IS_INT(*vp)) printf ("is INT\n");
2525 //if (JSVAL_IS_DOUBLE(*vp)) printf ("is DOUBLE\n");
2526
2527 //in js, null is an object
2528 if (JSVAL_IS_NULL(*vp)){
2529 if(type == FIELDTYPE_SFNode)
2530 value->sfnode = NULL;
2531 if(valueChanged)
2532 (*valueChanged) ++;
2533 }else if (JSVAL_IS_OBJECT(*vp)) {
2534 AnyNative *rhs;
2535 if ((rhs = (AnyNative *)JS_GetPrivateFw(cx, JSVAL_TO_OBJECT(*vp))) == NULL) {
2536 //printf("in setECMANative, RHS was NOT native type \n");
2537 }else{
2538 //printf("in setECMANative, RHS was native type \n");
2539 //can do an assign here
2540 //printf("lhstype = %d rhstype= %d\n",type,rhs->type);
2541 if(type == rhs->type){
2542 if(valueChanged)
2543 (*valueChanged) ++;
2544 //shallow assumes the top has already been malloced (just base part of MF needed)
2545 //use this if you need to malloc anyvrml: int sizeofSForMF(int itype)
2546 shallow_copy_field(rhs->type,rhs->v,value);
2547 }
2548 }
2549
2550 } else {
2551 //printf("in setECMANative, RHS was a scalar type \n");
2552 if(isSFType(type)){
2553 int sfsize = sizeofSForMF(type);
2554
2555 switch(type2SF(type)){
2556 case FIELDTYPE_SFBool:
2557 case FIELDTYPE_SFFloat:
2558 case FIELDTYPE_SFTime:
2559 case FIELDTYPE_SFDouble:
2560 case FIELDTYPE_SFInt32:
2561 case FIELDTYPE_SFString:
2562 //X3D_ECMA_TO_JS(cx, any,sfsize,sftype,vp);
2563 JS_ECMA_TO_X3D(cx, value, sfsize,type,vp);
2564 //printf("setECMANative after converting, sffloat value=%f\n",value->sffloat);
2565 if(valueChanged)
2566 (*valueChanged) ++;
2567 break;
2568 default:
2569 break;
2570 }
2571 }
2572 }
2573
2574
2575 }else{
2576 printf("set didn't find field %s in script\n",fieldname);
2577 }
2578 } else {
2579 /* "register" this ECMA value for routing changed flag stuff */
2580 setInECMATable(cx, _id_c);
2581
2582 if (JSVAL_IS_STRING(*vp)) {
2583 _vpStr = JS_ValueToString(cx, *vp);
2584#if JS_VERSION < 185
2585 _vp_c = JS_GetStringBytes(_vpStr);
2586#else
2587 _vp_c = JS_EncodeString(cx,_vpStr);
2588#endif
2589
2590 len = strlen(_vp_c);
2591
2592
2593 /* len + 3 for '\0' and "..." */
2594 _new_vp_c = MALLOC(char *, (len + 3) * sizeof(char));
2595 /* JAS - do NOT prepend/append double quotes to this string*/
2596 /* JAS - only for the null terminator*/
2597 /* JAS len += 3;*/
2598 len += 1;
2599
2600 memset(_new_vp_c, 0, len);
2601 /* JAS sprintf(_new_vp_c, "\"%.*s\"", len, _vp_c);*/
2602 sprintf(_new_vp_c, "%.*s", (int) len, _vp_c);
2603 _newVpStr = JS_NewStringCopyZ(cx, _new_vp_c);
2604 *vp = STRING_TO_JSVAL(_newVpStr);
2605
2606 #ifdef JSVRMLCLASSESVERBOSE
2607 printf("setECMANative: have string obj = %p, id = \"%s\", vp = %s\n",
2608 obj, _id_c, _new_vp_c);
2609 #endif
2610 FREE_IF_NZ (_new_vp_c);
2611#if JS_VERSION >= 185
2612 JS_free(cx,_vp_c);
2613#endif
2614 } else {
2615 #ifdef JSVRMLCLASSESVERBOSE
2616 _vpStr = JS_ValueToString(cx, *vp);
2617#if JS_VERSION < 185
2618 _vp_c = JS_GetStringBytes(_vpStr);
2619#else
2620 _vp_c = JS_EncodeString(cx,_vpStr);
2621#endif
2622 printf("setECMANative: obj = %p, id = \"%s\", vp = %s\n",
2623 obj, _id_c, _vp_c);
2624#if JS_VERSION >= 185
2625 JS_free(cx,_vp_c);
2626#endif
2627 #endif
2628 }
2629 } //if SM_Mehod == 2
2630#if JS_VERSION >= 185
2631 JS_free(cx,_id_c);
2632#endif
2633 return ret;
2634}
2635
2636/* used mostly for debugging */
2637JSBool
2638#if JS_VERSION < 185
2639getAssignProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp){
2640#elif JS_VERSION == 185
2641getAssignProperty(JSContext *cx, JSObject *obj, jsid iid, jsval *vp){
2642#else
2643getAssignProperty(JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSMutableHandleValue hvp){
2644 JSObject *obj = *hobj._;
2645 jsid iid = *hiid._;
2646 jsval *vp = hvp._;
2647#endif
2648
2649 //printf("in getAssignProperty\n");
2650 #ifdef JSVRMLCLASSESVERBOSE
2651 JSString *_idStr, *_vpStr;
2652 char *_id_c, *_vp_c;
2653
2654#if JS_VERSION >= 185
2655 jsval id;
2656 if (!JS_IdToValue(cx,iid,&id)) {
2657 printf("getAssignProperty: JS_IdToValue failed -- returning JS_TRUE anyways\n");
2658 }
2659#endif
2660
2661 _idStr = JS_ValueToString(cx, id);
2662 _vpStr = JS_ValueToString(cx, *vp);
2663#if JS_VERSION < 185
2664 _id_c = JS_GetStringBytes(_idStr);
2665 _vp_c = JS_GetStringBytes(_vpStr);
2666#else
2667 _id_c = JS_EncodeString(cx,_idStr);
2668 _vp_c = JS_EncodeString(cx,_vpStr);
2669#endif
2670 printf("getAssignProperty: obj = %p, id = \"%s\", vp = %s\n",
2671 obj, _id_c, _vp_c);
2672 printf ("what is vp? \n");
2673 if (JSVAL_IS_OBJECT(*vp)) printf ("is OBJECT\n");
2674 if (JSVAL_IS_STRING(*vp)) printf ("is STRING\n");
2675 if (JSVAL_IS_INT(*vp)) printf ("is INT\n");
2676 if (JSVAL_IS_DOUBLE(*vp)) printf ("is DOUBLE\n");
2677
2678#if JS_VERSION >= 185
2679 JS_free(cx,_id_c);
2680 JS_free(cx,_vp_c);
2681#endif
2682 #endif
2683 return JS_TRUE;
2684}
2685
2686
2687/* a kind of hack to replace the use of JSPROP_ASSIGNHACK */
2688JSBool
2689#if JS_VERSION < 185
2690setAssignProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp){
2691#elif JS_VERSION == 185
2692setAssignProperty(JSContext *cx, JSObject *obj, jsid iid, JSBool strict, jsval *vp){
2693#else
2694setAssignProperty(JSContext *cx, JSHandleObject hobj, JSHandleId hiid, JSBool strict, JSMutableHandleValue hvp){
2695 JSObject *obj = *hobj._;
2696 jsid iid = *hiid._;
2697 jsval *vp = hvp._;
2698#endif
2699 JSObject *_o;
2700 JSString *_str;
2701 const uintN _argc = 2;
2702#ifdef _MSC_VER
2703 jsval newVal, initVal, _argv[2]; /* win32 complains cant allocate array of size 0 */
2704#else
2705 jsval newVal, initVal, _argv[_argc];
2706#endif
2707 char *_id_c;
2708#if JS_VERSION >= 185
2709 jsval id;
2710 //printf("in setAssignProperty\n");
2711
2712 if (!JS_IdToValue(cx,iid,&id)) {
2713 printf("setAssignProperty: JS_IdToValue failed.\n");
2714 return JS_FALSE;
2715 }
2716#endif
2717
2718 if (JSVAL_IS_STRING(id)) {
2719 if (!JS_ConvertValue(cx, *vp, JSTYPE_OBJECT, &newVal)) {
2720 printf( "JS_ConvertValue failed in setAssignProperty.\n");
2721 return JS_FALSE;
2722 }
2723
2724 _str = JSVAL_TO_STRING(id);
2725#if JS_VERSION < 185
2726 _id_c = JS_GetStringBytes(_str);
2727#else
2728 _id_c = JS_EncodeString(cx,_str);
2729#endif
2730 if (!JS_GetProperty(cx, obj, _id_c, &initVal)) {
2731 printf( "JS_GetProperty failed in setAssignProperty.\n");
2732#if JS_VERSION >= 185
2733 JS_free(cx,_id_c);
2734#endif
2735 return JS_FALSE;
2736 }
2737 #ifdef JSVRMLCLASSESVERBOSE
2738 printf("setAssignProperty: obj = %p, id = \"%s\", from = %d, to = %d\n",
2739 obj, _id_c, (int)newVal, (int)initVal);
2740
2741 if (JSVAL_IS_OBJECT(initVal)) printf ("initVal is an OBJECT\n");
2742 if (JSVAL_IS_STRING(initVal)) printf ("initVal is an STRING\n");
2743 if (JSVAL_IS_NUMBER(initVal)) printf ("initVal is an NUMBER\n");
2744 if (JSVAL_IS_DOUBLE(initVal)) printf ("initVal is an DOUBLE\n");
2745 if (JSVAL_IS_INT(initVal)) printf ("initVal is an INT\n");
2746
2747 if (JSVAL_IS_OBJECT(newVal)) printf ("newVal is an OBJECT\n");
2748 if (JSVAL_IS_STRING(newVal)) printf ("newVal is an STRING\n");
2749 if (JSVAL_IS_NUMBER(newVal)) printf ("newVal is an NUMBER\n");
2750 if (JSVAL_IS_DOUBLE(newVal)) printf ("newVal is an DOUBLE\n");
2751 if (JSVAL_IS_INT(newVal)) printf ("newVal is an INT\n");
2752
2753 if (JSVAL_IS_OBJECT(id)) printf ("id is an OBJECT\n");
2754 if (JSVAL_IS_STRING(id)) printf ("id is an STRING\n");
2755 if (JSVAL_IS_NUMBER(id)) printf ("id is an NUMBER\n");
2756 if (JSVAL_IS_DOUBLE(id)) printf ("id is an DOUBLE\n");
2757 if (JSVAL_IS_INT(id)) printf ("id is an INT\n");
2758
2759#if JS_VERSION < 185
2760 printf ("id is %s\n",JS_GetStringBytes(JS_ValueToString(cx,id)));
2761 printf ("initVal is %s\n",JS_GetStringBytes(JS_ValueToString(cx,initVal)));
2762 printf ("newVal is %s\n",JS_GetStringBytes(JS_ValueToString(cx,newVal)));
2763#else
2764 printf ("id is %s\n",JS_EncodeString(cx,JS_ValueToString(cx,id)));
2765 printf ("initVal is %s\n",JS_EncodeString(cx,JS_ValueToString(cx,initVal)));
2766 printf ("newVal is %s\n",JS_EncodeString(cx,JS_ValueToString(cx,newVal)));
2767#endif
2768 #endif
2769#if JS_VERSION >= 185
2770 JS_free(cx,_id_c);
2771#endif
2772
2773
2774 _o = JSVAL_TO_OBJECT(initVal);
2775
2776 #ifdef xxJSVRMLCLASSESVERBOSE
2777 printf ("in setAssignProperty, o is %u type ",_o);
2778 printJSNodeType(cx,_o);
2779 printf ("\n");
2780 #endif
2781
2782 _argv[0] = newVal;
2783 _argv[1] = id;
2784
2785 if (!JS_CallFunctionName(cx, _o, "assign", _argc, _argv, vp)) {
2786 printf( "JS_CallFunctionName failed in setAssignProperty.\n");
2787 return JS_FALSE;
2788 }
2789 } else {
2790 #ifdef JSVRMLCLASSESVERBOSE
2791 _str = JS_ValueToString(cx, id);
2792#if JS_VERSION < 185
2793 _id_c = JS_GetStringBytes(_str);
2794#else
2795 _id_c = JS_EncodeString(cx,_str);
2796#endif
2797 printf("setAssignProperty: obj = %p, id = \"%s\"\n",
2798 obj, _id_c);
2799#if JS_VERSION >= 185
2800 JS_free(cx,_id_c);
2801#endif
2802 #endif
2803 }
2804
2805 return JS_TRUE;
2806}
2807
2808#endif /* !(defined(JAVASCRIPT_STUB) || defined(JAVASCRIPT_DUK) */
2809#endif