2

I have JSON config like:

{ shape:[ 'SphereGeometry', [7, 16, 16] ] }

and try to load model like:

new THREE[shape[0]].apply( this, shape[1] )

As you can see "new" and "apply" are not an option here. Does anyone know a trick or a tip how I can solve my problem here?

Thank you in advance.

Ju-v
  • 362
  • 3
  • 15

3 Answers3

0

The solution is based on Use of .apply() with 'new' operator. Is this possible?

JSON config

{ shape: 'SphereGeometry', properties: [ null, 7, 16, 16 ] }

and creating an new object:

new (Function.prototype.bind.apply( THREE[object.shape], object.properties ))
Community
  • 1
  • 1
Ju-v
  • 362
  • 3
  • 15
0

Using .apply() and new together in general is not a pretty process but here's how it goes:

function dynamicShape() {
    return THREE[shape[0]].apply(this, shape[1]);
}
dynamicShape.prototype = THREE[shape[0]].prototype;

var sphere = new dynamicShape();

This should work. Here's a fiddle using some sample code to render: http://jsfiddle.net/jcc6zbtn/

Eric Hannum
  • 382
  • 2
  • 6
  • 16
0

Here's one way of doing it, using a reviver function. The advantage is that the parsing process directly takes care of instantiating the correct object types, rather than doing it in two steps.

var shapes = { 'Rectangle': Rectangle }, //same as THREE in your code
    shapeJson = '{ "shape": ["Rectangle", [2, 4]] }',
    shape = shapeFromJson(shapeJson);

console.log(shape);

function instanciate(ctor, args) {
    var instance = Object.create(ctor.prototype);
    ctor.apply(instance, args);
    return instance;
}

function createShape(shape, args) {
    return instanciate(shapes[shape], args);
}

function shapeFromJson(json) {
    return JSON.parse(json, function (key, val) {
        return key? val : createShape(val.shape[0], val.shape[1]);
    });
}

function Rectangle(height, width) {
    this.height = height;
    this.width = width;
}
plalx
  • 42,889
  • 6
  • 74
  • 90