Set a global variable within a .jslib file?

I would like to to store a value within a .jslib file:

Assets/Plugins/WebGL/MyPlugin.jslib
mergeInto(LibraryManager.library, {
var a = 123;
  Setvar: function (val) {
    a = val;
  },
  Getvar: function () {
    return a;
  },
});

and set/get it with separate functions. Is that possible?
Or by creating a DOM element with assigned value?

2 Likes

would this work?

mergeInto(LibraryManager.library, {
  Setvar: function (val) {
    this.a = val;
  },
  Getvar: function () {
    return this.a;
  },
});

just make sure to initialize Setvar before calling Getvar.

5 Likes

Incredibly simple.
And works.
Thank you.

I should also mention that with this technique, the variable is visible to all other libraries (jslib’s). If you need library specific variables, you may want to do this instead:

var LibraryMyPlugin = {
   $MyData: {
       myVar: 123,
   },

   Setvar: function (val) {
       MyData.myVar = val;
   },
   Getvar: function () {
       return MyData.myVar;
   },
};

autoAddDeps(LibraryMyPlugin, '$MyData');
mergeInto(LibraryManager.library, LibraryMyPlugin);
10 Likes

Please help, somethinhg must be wrong with the below code.
I wanted this.gameObject to store the global value here.
But SendMessage returns undefined instead of this.gameObject
Does anyone know how to fix?

I found a workaround by storing the value as the dom Element attribute, but there must be some more straightforwand way.

var JSFunctions =
{
    InitUpload: function () {
        this.gameObject = "gmo";
     
        var input = document.createElement("input");
        input.type = "file";
        input.id = "inFile";
        input.style = "display:none";
         
        input.onchange = function (event) {
            if(event.target.files.length>0)
            {
                var tmppath = URL.createObjectURL(event.target.files[0]);
                var filename = event.target.files[0].name;
                alert(getg.getgo);
                if(check.checkExtention(filename)) SendMessage(this.gameObject, "_GetTexture", tmppath + "&" + filename);
            }
            else
            {
                SendMessage(this.gameObject, "_GetTexture", "");
            };
            window.focus();
        }
        var dropbox = document.body;     
        dropbox.appendChild(input);
         
    },
 
    OpenFileDialog: function (gmo){
        this.gameObject = Pointer_stringify(gmo);

        var fileElem = document.getElementById("inFile");
        fileElem.click();
    },
 
    $check: {
        checkExtention: function(fname)
        {
            var extentions = ["jpg", "JPG", "png", "PNG"];
            ext = fname.split(".")[1];
            if(extentions.indexOf(ext) > -1){
                //alert("true");
                return true;
                }else{
                alert("only .jpg and .png files allowed");
                return false; 
            }
        },
    },

};

autoAddDeps(JSFunctions, '$check');
mergeInto(LibraryManager.library, JSFunctions);

Hi, recently i am developing a webapp, and i want my variables to have like getters and setters, then i saw this thread, used this technique “$MyData: {}” for storing variables, at first it is great! so i adapt this technique to my plugin, and then i tried to make another plugin with same technique, with same name, but different properties, and when i tested it, there is a undefined error popping out on my browser, i read the code many times and yeah, i know there is no mispell in my plugins, and then i suspect that the “$MyData” of the other plugin is being accessed by the new plugin, not the “$MyData” of itself, so i have done a test and confirmed that “$MyData” of the other plugin is being accessed.
I think with this technique, it is still not possible to hide your variables to other jslibs.

And also i think it might be the way to access variables of other jslibs.

Heres the sample :

JSLIB 1 :

var Var_1 =
{
$Private_Container_but_its_Not_1:
{
Private_Variable_1: “Var 1 Private Variable”,
Private_Method_but_its_Not_1: function()
{
alert(“Var 1 Private Method”);
},
},
Public_Method: function()
{
alert(Private_Container_but_its_Not_2.Private_Variable_2);
Private_Container_but_its_Not_2.Private_Method_but_its_Not_2();
},
};
autoAddDeps(Var_1, ‘Private_Container_but_its_Not_2’);
mergeInto(LibraryManager.library, Var_1);

JSLIB 2 :

var Var_2 =
{
$Private_Container_but_its_Not_2:
{
Private_Variable_2: “Var 2 Private Variable”,
Private_Method_but_its_Not_2: function()
{
alert(“Var 2 Private Method”);
},
},
Public_Method: function()
{
alert(Private_Container_but_its_Not_1.Private_Variable_1);
Private_Container_but_its_Not_1.Private_Method_but_its_Not_1();
},
};
autoAddDeps(Var_2, ‘Private_Container_but_its_Not_1’);
mergeInto(LibraryManager.library, Var_2);

My Unity version is 2018.2.7f1
Test this one out, i hope it helps!.

1 Like

I had this exact same experience. I had two .jslib files that both define $Shared as a storage place for “static” variables within the jslib. But one appears to be overwriting the other so I keep getting “undefined” exception from one of the jslibs.

I believe the trick is to rename the $Shared to be unique for each .jslib file to prevent them from accidentally overwriting each other. For example, if use $Shared0 for one .jslib and $Shared1 for the other .jslib, then the problem goes away. (I recommend using the name of the .jslib file in the $Shared variable name to guarantee uniqueness.)

Of course, this doesn’t help with access control since one .jslib seems to be able to access the $Shared of another .jslib, but like with all access control, we’ll have to live with “don’t do it” until Unity fixes it. :slight_smile:

How do you call Setvar from within another function in the same mergeInto scope?
Whenever I try a call to Setvar, I just get Setvar is undefined

When the function is compiled, it is converted by adding an ‘_’ (underscore) to the beginning of the function name.
So I think you can call it like this:

_Setvar(val);
3 Likes