Hi all, this is a question for the more experienced script programmers.

Hi all, this is a question for the more experienced script programmers. I was looking at ways to optimize my code and I found that it would be handy if I could assign custom fields to item objects, because then I would be able to store calculated values on the item and if be able to use them in functions to which I would only have to pass the item as argument and not also the calculated value. Actually I wouldn’t even have to pass the items as an argument to the functions because I could make the function run on the item.

After some searching I found this: http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript

I implemented this in a small example script:

dummy = LL.getCurrentDesktop().addShortcut(“dummy”,new Intent(),0,0);

// OLD WAY

/*

function displayCenter(it, center){

it.setLabel(center[0]+”,”+center[1]);

}

function moveToCenter(it, center){

it.setPosition(center[0], center[1]);

}

function center(item){

var r=item.getRotation()*Math.PI/180;

var sin=Math.abs(Math.sin(r));

var cos=Math.abs(Math.cos(r));

var w=item.getWidth()*item.getScaleX();

var h=item.getHeight()*item.getScaleY();

return[item.getPositionX()+(w*cos+h*sin)*0.5,item.getPositionY()+(h*cos+w*sin)*0.5];

}

var center = center(dummy);

displayCenter(dummy, center);

moveToCenter(dummy, center);

*/

//NEW WAY:

myItem = function(){

this.getCenter = function(){

if(this.center==null){

alert(“test”)

var r=this.getRotation()*Math.PI/180;

var sin=Math.abs(Math.sin(r));

var cos=Math.abs(Math.cos(r));

var w=this.getWidth()*this.getScaleX();

var h=this.getHeight()*this.getScaleY();

var center = [this.getPositionX()+(w*cos+h*sin)*0.5,this.getPositionY()+(h*cos+w*sin)*0.5]

this.center = center;

}

return this.center;

};

this.displayCenter = function(){

this.setLabel(this.getCenter()[0]+”, “+this.getCenter()[1]);

};

this.moveToCenter = function(){

this.setPosition(this.getCenter()[0], this.getCenter()[1]);

};

};

myItem.prototype = dummy;

myDummy = new myItem();

myDummy.displayCenter();

myDummy.moveToCenter();

myDummy.setSize(288, myDummy.getHeight()) //ALSO STILL WORKS BOTH WORK ON SAME OBJECT DESPITE THAT I DIDN’T DEFINE A getPositionX() IN myItem 😀

As you can see this enables me to do what I explained herebove, but I haven’t seen anyone do it before, so I am wondering if there is anything bad happening here or I actually found something cool and useful.

Please tell me what you think in the comments.

Thanks for reading 🙂

cdfa

http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript
]]>

10 Commentsto Hi all, this is a question for the more experienced script programmers.

  1. Anonymous says:

    < ![CDATA[

    I don’t think something really bad happens here. However you are abusing the prototype here. A prototype should be set once and used for all instances, however you’d have to set the prototype again every time you want to create a myItem from another item.



    If you want to extend an item I would go this way:



    function extendItem(item){


        item.displayCenter = function(){…}


        item.moveToCenter = function(){…}


        …


    }



    extendItem(dummy);


    dummy.displayCenter();




    However I think that isn’t necessary at all and your old way is equally good.

    ]]>

  2. Anonymous says:

    < ![CDATA[

    Have you actually tested your way of extending the item? I’m asking because when i read it I already was thinking it wouldn’t work because just as I’m not able to set custom fields to the “real” item object I also can’t seam to add any functions to it. This is the code I tested it with:



    dummy = LL.getCurrentDesktop().addShortcut(“dummy”,new Intent(),0,0);



    function extendItem(item){


    item.testFunction = function(){


    alert(“test”);


    }


    }



    extendItem(dummy);


    dummy.testFunction();



    Am I doing something stupidly wrong or is it actually not working?



    As for my approach:


    I already suspected that setting the prototype for each item isn’t really the way it should be done, but I don’t know a way of extending the real item class instead of an instance of it. I you do know one, please let me know :).

    ]]>

  3. Anonymous says:

    < ![CDATA[

    I haven’t tested it, I just assumed it would work. It might actually fail because item is not a javascript object, but rather a java object. Maybe Rhino does not allow such operations on java objects.

    ]]>

  4. Anonymous says:

    < ![CDATA[

    Personally, when I want a way to store data from items that I’m going to use only on the current script, an object with the data saved as keys is how I do it.



    var data={}



    data[item.getId()] = “whatever you want”





    alert(data[item.getId()] )







    Also, if you want to store those values you can instead use tags. (I think you will prefer this)


    http://www.pierrox.net/android/applications/lightning_launcher/script/reference/net/pierrox/lightning_launcher/script/api/Item.html#setTag(java.lang.String,%20java.lang.String)

    ]]>

  5. Anonymous says:

    < ![CDATA[

    Hmm, you’re right that storing values with tags would be a lot more straight forward. That takes away the only real pro of my new way apart from that I think calling the function on the object instead of passing the object to the function looks better in my opinion, but isn’t really more efficient. Though I think straightforwardness is more important than looks, so I think i’ll go with your method for now.


    Thanks for helping 🙂


    Regards cdfa

    ]]>

  6. Anonymous says:

    < ![CDATA[

    Just as addition: Lightnings built-in tags are already very efficient, maybe even equal to direct storing.


    And: If your script doesn’t run in the positionchanged (and maybe resumed) event you don’t have to care about performance anyway.

    ]]>

  7. Anonymous says:

    < ![CDATA[

    Aha. What about the item touch event?

    ]]>

  8. Anonymous says:

    < ![CDATA[

    Colin de Roos


    In this case I’d say it depends what you’re doing. Executing once – no problem. Executing 5 times – no problem. Executing in a loop with unknown durability (e.g. over all items) – problem.

    ]]>

  9. Anonymous says:

    < ![CDATA[

    Ah, okay. I didn’t really know for what and how i was going to use it, just trying out the concept. Thanks for your help 🙂

    ]]>

  10. Anonymous says:

    < ![CDATA[

    So for General use here is the general rule: For optimization you only care for an action if


    a) the action is run very often (loop, positionchanged)


    b) the action runs long in relation to how long the overall task runs or should run. (A background task can run long, so even actions taking several seconds don’t matter, but an icon click should resolve instantly [instantly is normally seen as below 500ms])

    ]]>

Leave a Reply

Your email address will not be published. Required fields are marked *