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