1
/* -*- Mode: JavaScript; coding: utf-8; tab-width: 3; indent-tabs-mode: tab; c-basic-offset: 3 -*-
2
*******************************************************************************
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6
* Copyright create3000, Scheffelstraße 31a, Leipzig, Germany 2011.
8
* All rights reserved. Holger Seelig <holger.seelig@yahoo.de>.
10
* The copyright notice above does not evidence any actual of intended
11
* publication of such source code, and is an unpublished work by create3000.
12
* This material contains CONFIDENTIAL INFORMATION that is the property of
15
* No permission is granted to copy, distribute, or create derivative works from
16
* the contents of this software, in whole or in part, without the prior written
17
* permission of create3000.
19
* NON-MILITARY USE ONLY
21
* All create3000 software are effectively free software with a non-military use
22
* restriction. It is free. Well commented source is provided. You may reuse the
23
* source in any way you please with the exception anything that uses it must be
24
* marked to indicate is contains 'non-military use only' components.
26
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
28
* Copyright 2015, 2016 Holger Seelig <holger.seelig@yahoo.de>.
30
* This file is part of the Cobweb Project.
32
* Cobweb is free software: you can redistribute it and/or modify it under the
33
* terms of the GNU General Public License version 3 only, as published by the
34
* Free Software Foundation.
36
* Cobweb is distributed in the hope that it will be useful, but WITHOUT ANY
37
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
38
* A PARTICULAR PURPOSE. See the GNU General Public License version 3 for more
39
* details (a copy is included in the LICENSE file that accompanied this code).
41
* You should have received a copy of the GNU General Public License version 3
42
* along with Cobweb. If not, see <http://www.gnu.org/licenses/gpl.html> for a
43
* copy of the GPLv3 License.
45
* For Silvio, Joy and Adi.
47
******************************************************************************/
52
"cobweb/Basic/FieldDefinitionArray",
54
"cobweb/Base/X3DChildObject",
55
"cobweb/Components/Core/X3DNode",
56
"cobweb/Execution/X3DExecutionContext",
57
"cobweb/Bits/X3DConstants",
58
"cobweb/InputOutput/Generator",
71
function X3DPrototypeInstance (executionContext, protoNode)
73
this .protoNode = protoNode;
74
this .fieldDefinitions = new FieldDefinitionArray (protoNode .getFieldDefinitions () .getValue () .slice ());
76
X3DNode .call (this, executionContext);
77
X3DExecutionContext .call (this, executionContext);
79
this .addType (X3DConstants .X3DPrototypeInstance);
80
this .getRootNodes () .setAccessType (X3DConstants .initializeOnly);
82
this .getScene () .addInitLoadCount (this);
84
if (protoNode .isExternProto)
85
protoNode .requestAsyncLoad (this .construct .bind (this));
91
X3DPrototypeInstance .prototype = $.extend (Object .create (X3DExecutionContext .prototype),
94
constructor: X3DPrototypeInstance,
95
create: function (executionContext)
97
return new X3DPrototypeInstance (executionContext, this .protoNode);
99
getTypeName: function ()
101
return this .protoNode .getName ();
103
getComponentName: function ()
107
getContainerField: function ()
111
construct: function ()
113
this .getScene () .removeInitLoadCount (this);
115
var proto = this .protoNode .getProtoDeclaration ();
119
// If there is a proto the externproto is completely loaded.
121
if (! this .metadata_ .getSet ())
122
this .metadata_ = proto .metadata_;
124
if (this .protoNode .isExternProto)
126
var fieldDefinitions = proto .getFieldDefinitions ();
128
for (var i = 0, length = fieldDefinitions .length; i < length; ++ i)
133
fieldDefinition = fieldDefinitions [i],
134
field = this .getField (fieldDefinition .name),
135
protoField = proto .getField (fieldDefinition .name);
137
// Continue if something is wrong.
138
if (field .getAccessType () !== protoField .getAccessType ())
141
// Continue if something is wrong.
142
if (field .getType () !== protoField .getType ())
145
// Continue if field is eventIn or eventOut.
146
if (! (field .getAccessType () & X3DConstants .initializeOnly))
149
// Is set during parse.
150
if (field .getSet ())
153
// Has IS references.
154
if (field .hasReferences ())
157
field .setValue (protoField .getValue ());
161
// Definition exists in proto but does not exist in extern proto.
162
this .addField (fieldDefinition);
169
this .setURL (proto .getURL ());
171
this .importExternProtos (proto .externprotos);
172
this .importProtos (proto .protos);
173
this .copyRootNodes (proto .rootNodes);
175
if (this .isInitialized ())
178
X3DChildObject .prototype .addEvent .call (this);
184
X3DNode .prototype .setup .call (this);
185
X3DExecutionContext .prototype .setup .call (this);
187
initialize: function ()
191
var proto = this .protoNode .getProtoDeclaration ();
195
//this .copyImportedNodes (proto);
196
this .copyRoutes (proto .routes);
199
// TODO: connect getRootNodes () to X3DChildObject .prototype .addEvent .call (this);
201
// Now initialize bases.
203
X3DNode .prototype .initialize .call (this);
204
X3DExecutionContext .prototype .initialize .call (this);
208
console .error (error .message);
211
getExtendedEventHandling: function ()
215
getInnerNode: function ()
217
var rootNodes = this .getRootNodes () .getValue ();
219
if (rootNodes .length)
221
var rootNode = rootNodes [0];
224
return rootNode .getValue () .getInnerNode ();
227
throw new Error ("Root node not available.");
229
importExternProtos: function (externprotos)
231
for (var i = 0, length = externprotos .length; i < length; ++ i)
232
this .externprotos .add (externprotos [i] .getName (), externprotos [i]);
234
importProtos: function (protos)
236
for (var i = 0, length = protos .length; i < length; ++ i)
237
this .protos .add (protos [i] .getName (), protos [i]);
239
copyRootNodes: function (rootNodes)
242
rootNodes1 = rootNodes .getValue (),
243
rootNodes2 = this .getRootNodes () .getValue ();
245
for (var i = 0, length = rootNodes1 .length; i < length; ++ i)
247
var value = rootNodes1 [i] .copy (this);
248
value .addParent (this .getRootNodes ());
249
rootNodes2 .push (value);
252
copyRoutes: function (routes)
254
for (var i = 0, length = routes .length; i < length; ++ i)
258
var route = routes [i];
260
// new Route ... addUninitializedNode ...
261
this .addRoute (this .getNamedNode (route .sourceNode .getNodeName ()),
263
this .getNamedNode (route .destinationNode .getNodeName ()),
264
route .destinationField);
268
console .log (error);
272
toXMLStream: function (stream)
274
if (Generator .IsSharedNode (this))
276
stream .string += Generator .Indent ();
277
stream .string += "<!-- NULL -->";
281
Generator .EnterScope ();
283
var name = Generator .Name (this);
287
if (Generator .ExistsNode (this))
289
stream .string += Generator .Indent ();
290
stream .string += "<ProtoInstance";
291
stream .string += " ";
292
stream .string += "name='";
293
stream .string += Generator .XMLEncode (this .getTypeName ());
294
stream .string += "'";
295
stream .string += " ";
296
stream .string += "USE='";
297
stream .string += Generator .XMLEncode (name);
298
stream .string += "'";
300
var containerField = Generator .ContainerField ();
304
if (containerField .getName () !== this .getContainerField ())
306
stream .string += " ";
307
stream .string += "containerField='";
308
stream .string += Generator .XMLEncode (containerField .getName ());
309
stream .string += "'";
313
stream .string += "/>";
315
Generator .LeaveScope ();
320
stream .string += Generator .Indent ();
321
stream .string += "<ProtoInstance";
322
stream .string += " ";
323
stream .string += "name='";
324
stream .string += Generator .XMLEncode (this .getTypeName ());
325
stream .string += "'";
329
Generator .AddNode (this);
331
stream .string += " ";
332
stream .string += "DEF='";
333
stream .string += Generator .XMLEncode (name);
334
stream .string += "'";
337
var containerField = Generator .ContainerField ();
341
if (containerField .getName () !== this .getContainerField ())
343
stream .string += " ";
344
stream .string += "containerField='";
345
stream .string += Generator .XMLEncode (containerField .getName ());
346
stream .string += "'";
351
fields = this .getChangedFields (),
352
metadata = this .metadata_;
356
metadata = this .getField ("metadata");
361
if (metadata === this .metadata_)
363
fields = fields .filter (function (value) { return value !== this .metadata_; } .bind (this));
366
if (fields .length === 0 && (metadata === this .metadata_ ? true || ! metadata .getValue () : true))
368
stream .string += "/>";
372
stream .string += ">\n";
374
Generator .IncIndent ();
376
var references = [ ];
378
for (var i = 0, length = fields .length; i < length; ++ i)
380
var field = fields [i];
382
// If the field is a inputOutput and we have as reference only inputOnly or outputOnly we must output the value
385
var mustOutputValue = false;
387
if (Generator .ExecutionContext ())
389
if (field .getAccessType () === X3DConstants .inputOutput && ! $.isEmptyObject (field .getReferences ()))
392
initializableReference = false,
393
fieldReferences = field .getReferences ();
395
for (var id in fieldReferences)
397
initializableReference |= fieldReferences [id] .isInitializable ();
400
if (! initializableReference)
401
mustOutputValue = true;
405
// If we have no execution context we are not in a proto and must not generate IS references the same is true
406
// if the node is a shared node as the node does not belong to the execution context.
408
if ($.isEmptyObject (field .getReferences ()) || ! Generator .ExecutionContext () || mustOutputValue)
411
references .push (field);
413
switch (field .getType ())
415
case X3DConstants .MFNode:
417
stream .string += Generator .Indent ();
418
stream .string += "<fieldValue";
419
stream .string += " ";
420
stream .string += "name='";
421
stream .string += Generator .XMLEncode (field .getName ());
422
stream .string += "'";
424
if (field .length === 0)
426
stream .string += "/>\n";
430
stream .string += ">\n";
432
Generator .IncIndent ();
434
field .toXMLStream (stream);
436
stream .string += "\n";
438
Generator .DecIndent ();
440
stream .string += Generator .Indent ();
441
stream .string += "</fieldValue>\n";
446
case X3DConstants .SFNode:
448
if (field .getValue () !== null)
450
stream .string += Generator .Indent ();
451
stream .string += "<fieldValue";
452
stream .string += " ";
453
stream .string += "name='";
454
stream .string += Generator .XMLEncode (field .getName ())
455
stream .string += "'";
456
stream .string += ">\n";
458
Generator .IncIndent ();
460
field .toXMLStream (stream);
462
stream .string += "\n";
464
Generator .DecIndent ();
466
stream .string += Generator .Indent ();
467
stream .string += "</fieldValue>\n";
471
// Proceed with next case.
475
stream .string += Generator .Indent ();
476
stream .string += "<fieldValue";
477
stream .string += " ";
478
stream .string += "name='";
479
stream .string += Generator .XMLEncode (field .getName ())
480
stream .string += "'";
481
stream .string += " ";
482
stream .string += "value='";
484
field .toXMLStream (stream);
486
stream .string += "'";
487
stream .string += "/>\n";
494
references .push (field);
498
if (references .length)
500
stream .string += Generator .Indent ();
501
stream .string += "<IS>";
502
stream .string += "\n";
504
Generator .IncIndent ();
506
for (var i = 0, length = references .length; i < length; ++ i)
509
field = references [i],
510
protoFields = field .getReferences ()
512
for (var id in protoFields)
514
var protoField = protoFields [id];
516
stream .string += Generator .Indent ();
517
stream .string += "<connect";
518
stream .string += " ";
519
stream .string += "nodeField='";
520
stream .string += Generator .XMLEncode (field .getName ());
521
stream .string += "'";
522
stream .string += " ";
523
stream .string += "protoField='";
524
stream .string += Generator .XMLEncode (protoField .getName ());
525
stream .string += "'";
526
stream .string += "/>\n";
530
Generator .DecIndent ();
532
stream .string += Generator .Indent ();
533
stream .string += "</IS>\n";
536
if (metadata === this .metadata_)
538
if (metadata .getValue ())
540
metadata .toXMLStream (stream);
542
stream .string += "\n";
546
Generator .DecIndent ();
548
stream .string += Generator .Indent ();
549
stream .string += "</ProtoInstance>";
552
Generator .LeaveScope ();
556
return X3DPrototypeInstance;