Entities

An entity is the base component (function and data) of all xGraph solutions. An entity is a single JavaScript function that is instantiated with the xGraph core. An entity must be encapsulated in a module to be run in an xGraph system. An entity is generated using an entity definition. If the entity is generated when the module is generated, the entity’s definition is found in the module’s "schema.json" file. If the entity is generated dynamically by another entity in the module, the entity definition is found in the entity that called the generation.

Entity Definition

Below is an example of an entity definition.

"HelloWorld2": {
    "Entity": "HelloWorld2.js",
    "SomePar": "SomeValue"
}

The entity definition starts by declaring the entity file with the "Entity" key. After the entity file is listed, you can add any number of entity parameters as key-value pairs.

The "Entity" key defines the JavaScript file that has the entities function.

The "SomePar" key is an example of a parameter that will be passed to the entity as a key, value pair. This parameter can be accessed in the context of the entity by accessing this.Par.SomePar. Any number of parameters can be added here.

JavaScript Function

An entity is represented by a single JavaScript class or function in a single JavaScript file.

The most simple way to create a JavaScript entity is with a JavaScript class. xGraph can interpret a JavaScript file with a single JavaScript class as an entity.

Additionally, an entity can be a self-executing function that returns a dispatch table. xGraph can interpret a JavaScript file with a single JavaScript self-executing function as an entity. To use a self-executing function as an entity, the function must return the entities dispatch table. This is an object containing the entity’s commands.

   var dispatch = {
        Start: Start,
        Pong:Pong
   };

If the self-executing function contains a JavaScript class, you can return the class prototype as the dispatch table.

return {
	dispatch: LayoutManager.prototype
}

Commands

Most of the entities code consists of command functions. Both types of entity will have a number of functions, called xGraph commands. These functions accept two arguments: the command object, com, and a callback function, fun. Each function must be called by an xGraph command.

Start and Setup are commands that xGraph can send to modules on instantiation. These functions can be included in the module’s apex entity but are not required. Then when they are sent to a module, Setup and Start commands are received by the module’s apex entity.

To tell a module how it should handle the Setup and Start commands, you must include the "$Setup" and "$Start" keys in the entity definition of the module’s apex entity, pointing to the function that should respond to the command.

{
	"Apex": {
		"$Setup": "Setup",
		"$Start": "Start",
		"Entity": "HelloWorld.js",
		"Friend": "#OtherEntity"
	},
	"OtherEntity": {
		"$Start": "Start",
		"Entity": "HelloWorld2.js"
	}
}

Here is an example of a simple Setup command.

   function Setup(com,fun) {
        console.log("--HelloWorld/Setup");

        // Nothing happens here, continue on...

        if(this.Par.SomePar) {
            console.log("There is a parameter SomePar valued: " + this.Par.SomePar);
        }

        if (fun){
            fun(null, com);
        }
    }

Finally, here is an example of a simple, yet complete, entity.

//# sourceURL=Ping
(
    /**
     * The Ping entity communicates with the Pong entities.
     * Starting with the Ping module, the Start() function calls Pong.
     * Encapsulating module is defined in the PingPong system config file.
     * @param {pid} this.Par.Pong   The Pid of the Pong entity.
     */
function Ping() {

    /*
        Define all commands. This will be returned so that the xGraph core knows what
        commands the entity can accept.
    */
    var dispatch = {
        Start: Start,
        Pong:Pong
    };


    //-------------------------------------------------------Start
    /**
     * The Start command sets up a setTimeout function that will send the first "Ping" command
     * to the entity referenced in this.Par.Pong.
     *
     * @param {object} com  The command object.
     * @callback fun
     */
    function Start(com,fun) {
        console.log("--Ping/Start");

        // Launch the ball by sending the first Ping a command to Pong
        // This command does not need any information back, so it is sent
        //  without a callback
        this.send({"Cmd":"Ping"}, this.Par.Pong);


        if (fun){
            fun(null, com);
        }
    }

    //-------------------------------------------------------Pong
    /**
     * The Pong command is sent from the Pong entity, Pong.js. When Pong is received,
     * this module prints "Pong" in the console, then sends a 'Ping' command to the
     * module referenced in this.Par.Pong.
     * @param {object} com  The command object.
     * @callback fun
     */
    function Pong(com, fun){
        console.log("          |      Pong");
        // some useful variables
        let that = this;
        let Par = this.Par;

        // Wait one second before sending Ping command back.
        // This prevents stack overflow due to infinent loop.
        setTimeout(sendCommand, 1000);

        function sendCommand() {
            // Send Ping command to the Pong Module. Like before, this command does not need
            //      any information back, so it is sent without a callback
            // Here you will see we have used the 'that' variable to retain the
            //      parent functions context.
            that.send({"Cmd": "Ping"}, Par.Pong);
        }

        // call the Callback
        if (fun){
            fun(null, com);
        }
    }

    // return the dispatch, the commands that this entity can receive.
    return {
        dispatch: dispatch
    };
})();