Jump to content

BJS source code study


Vousk-prod.
 Share

Recommended Posts

Hi smart devs community,

 

Pretty yound padawan in javascript, I'm learning essentially by reading source code and trying to understand what everything is about, and why it's written that way (with the help of internet ressources and forums, of course).

 

Sometimes javascript is really disturbing, and very often I'm not sure to understand every subtleties.

For instance inside a namespace, why using

var foo = function() { ... };

instead of

function foo() { ... }

Is it because with the first one you ensure that your function in not global but restricted to the scope of the namespace ?

And then, if this function won't never be called outside this file nor outside the scope of this namespace, is MYNAMESPACE.foo = foo; required ?

... javascript is not always easy to get humm...

 

But my true question is this one: there is something in the babylon.engine.js file I do not manage to understand at all, could someone explain me what this is about.

var EngineCapabilities = (function () {    function EngineCapabilities() {    }    return EngineCapabilities;})();BABYLON.EngineCapabilities = EngineCapabilities;

IEF, closures, etc, are javascript concepts I globally understand while reading javascript courses, but here, in real situation, arrff I'm going out of my mind reading this particular piece of code :lol: ... (globally the other parts of the babylon.engine.js file are quite clear to me)

Link to comment
Share on other sites

Hello,

We're following the best practices explained in the book written by Douglas Crockford "JavaScript, the good parts". You should read this book first then.

Also, I often recommend to newbies to have a look to TypeScript playground and review the modules & classes samples that could help also understanding our code.

Have a good reading!

David

Link to comment
Share on other sites

Thanks for your answer. I will have a look at this book.

 

I understand quite well the namespace and "class" javascript mechanisms (thanks to BJS code study, by the way). Also I'm fine with IEF, closures, prototype, accessors concepts.

All of these are clear to me :

var MYNAMESPACE ;(function (MYNAMESPACE) {        Object.defineProperty(MYNAMESPACE , "VERSION", {        value: "1.4.1",        enumerable: true, configurable: false, writable : false    });    Object.defineProperty(MYNAMESPACE , "debugMode", {        get: function() {            return MYNAMESPACE._debugMode;        },        set: function(value) {            MYNAMESPACE._debugMode = value;        },        enumerable: true, configurable: false    });     MYNAMESPACE._debugMode = 2;    var MyClass = (function () {           function MyClass(id) {            this.identifier = id;            this.param = "hehe";            ...        }        MyClass.prototype.foo = function() {            ...        };        return MyClass;    })();    MYNAMESPACE.MyClass = MyClass;...})(MYNAMESPACE || (MYNAMESPACE = {}));

In fact I can understand pretty well the whole babylon.engine.js file (in terms of js concepts), except the particular piece of code quoted in my previous post.

Too much empty functions inside functions, inside functions, returning itself, etc... :D

Link to comment
Share on other sites

The piece of code you quoted is actually the definition for a new class called 'EngineCapabilities'.

This : 

function EngineCapabilities() {}

is an empty constructor (creating an empty object).

And that's all ! 

 

The point to do this is to define an object EngineCapabilities which will describe the engine features. You can see in the class Engine that a new EngineCapabilities is created, and several attributes are added to this object : 

this._caps = new EngineCapabilities();this._caps.maxTexturesImageUnits = this._gl.getParameter(this._gl.MAX_TEXTURE_IMAGE_UNITS);this._caps.maxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);this._caps.maxCubemapTextureSize = this._gl.getParameter(this._gl.MAX_CUBE_MAP_TEXTURE_SIZE);

Why not add these attributes directly in the class definition ?

=>This class is creating by the typescript compilation, and as there is no default values for this attribute, nothing is done in the constructor by the compilator.

 

Hope that helps :)

Link to comment
Share on other sites

Of course !! OK !!

That helps a lot, I perfectly get it now, that was exactly what I was asking for.

Many thanks Temechon !!

 

It's funny because I use this kind of class definition in my code (I even wrote this in my pseudo code example above), but here I didn't realise that

function EngineCapabilities() {}

is no more than an empty constructor, certainly because until now I always had something to declare in my constructors.

 

You make my day, thank you. These 6 lines of code can no longuer mock me now :P

Link to comment
Share on other sites

Just an FYI.  In coming release of the blender exporter I am doing, I am generating a .babylon, and both a .js & .ts.  To avoid name conflicts, both script files will be self contained modules.  The .js will be in the format:

var blender_file_name = (function(){. . .}());

 

You would refer to it in your .html, for example, as "blender_file_name.initScene(scene);"  

 

The only thing that I have not done exactly the same as typescript to generate javascript, is use the variable "foo"  for the internal collection of public stuff returned.  This duplication of the same internally nested names as the external name drives me crazy and is very hard for someone new to know which one is which.  Could also have used "ret" instead.  Here is an outline of a test output (version checking only shown once, but done on all entry points):

"use strict";var __extends = this.__extends || function (d,  {    for (var p in  if (b.hasOwnProperty(p)) d[p] = b[p];    function __() { this.constructor = d; }    __.prototype = b.prototype;    d.prototype = new __();};var blender_file_name = (function(){    var foo = {};    foo.initScene = function(scene){        if (typeof(BABYLON.Engine.Version) === "undefined" || Number(BABYLON.Engine.Version.substr(0, 4)) < 1.13) throw "Babylon version too old";        scene.autoClear = true;        scene.clearColor    = new BABYLON.Color3(0,0,0);        scene.ambientColor  = new BABYLON.Color3(0,0,0);        scene.gravity = new BABYLON.Vector3(0,-9.81,0);        foo.defineCameras  (scene);        foo.defineLights   (scene);        foo.defineMaterials(scene);        foo.defineSkeletons(scene);        new foo.ParentMesh("ParentMesh", scene);        foo.defineShadowGen(scene);    };    foo.defineCameras = function(scene){        . . .    };    foo.defineLights = function(scene){        . . .    };    var matLoaded = false;    foo.defineMaterials = function(scene){        if (matLoaded) return;        . . .        foo.defineMultiMaterials(scene);        matLoaded = true;    };    foo.ParentMesh = (function (_super) {        __extends(ParentMesh, _super);        function ParentMesh(name, scene){            _super.call(this, name, scene);            foo.defineMaterials(scene); //embedded version check            this.Kiddie = foo.child_Kiddie(scene, this);            . . .        }        return Gus;    })(BABYLON.Mesh); // or BABYLON.Automaton if shapekeys found    foo.child_Kiddie = function(scene, parent){        var ret = new BABYLON.Mesh("Kiddie_" + parent.name, scene);        ret.parent = parent;        . . .        return ret;    }    foo.defineMultiMaterials = function(scene){        . . .    };    foo.defineShadowGen = function(scene){        . . .    };    var bonesLoaded = false;    foo.defineSkeletons = function(scene){        if (bonesLoaded) return;        . . .        bonesLoaded = true;    };    return foo;}());
Link to comment
Share on other sites

No, InitScene(), defineCameras(), etc. are the Java equiv to static methods. 

 

The Meshes or Automatons that have no parent are generated as sub-classes (JS does not have sub-classes, but lets say they do).  If you call them directly (similar to sceneLoader.importMesh()), you would do it with a "new": 

 

     var myMesh1 = new blender_file_name.ParentMesh("MeshID", scene);

 

Meshes with a parent are not really intended to be called directly, but if you did:

     var zzz = blender_file_name.child_Kiddie(scene, someOtherParent);

 

There is no need for a "new" here as the returned object of the call is the result of a "new".

 

While the .ts is mainly for sub-classing for a commercial code base, you should be able to doing it from the .js as well:

    MySub = (function (_super) {        __extends(MySub, _super);        function MySub(name, scene){            _super.call(this, name, scene);            . . .        }        return MySub;    })(blender_file_name.ParentMesh); 

BTW,  I have not tested the .ts code, but I think I am going to put in a pull request tomorrow anyway.  The Automaton classes will come later, but I have everything I will need in the output files.  I am currently guessing on how to represent shape key groups in the .babylon, and I have 2 other tests to do, but I am close.

Link to comment
Share on other sites

(BTW, what happened to your avatar picture Temechon ?)

--

Where is your new tutorial, Temechon, I searched for it but with no luck...

 

I updated my profile picture, maybe you cannot see it. I have the same problem with a lot of users here in this forum and in the phaser forum.

 

My new tutorial is not finished yet, but I can already tell you that it will be about extending BABYLON.Mesh and the actions system (ActionManager, triggers, conditions...) You can subscribe to the newsletter to receive an email when it will be live (I hope this week)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...