Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not able to retrieve a function layer by name using v5.4 #18

Closed
BillyRayPreachersSon opened this issue Jun 9, 2012 · 3 comments
Closed

Comments

@BillyRayPreachersSon
Copy link

Hi,

I've just tested some of my code against v5.4, and found that it's no longer possible to retrieve a function layer by its name as you can with non-function layers. This is possible with v5.3.1.

Take the following scenario:

var MyObj = {
    canvas: $('<canvas />'),

    addLayer: function() {
        this.canvas.addLayer(this.drawLines);
    },

    drawLines: function lines(ctx) {
        console.log('MyObj.drawLines is being called');
        console.log('"this" context = ', this);
    }
}

Under v5.3.1, here's what I got:

MyObj.addLayer()
    'MyObj.drawLines is being called'
    "this" context = <canvas>​

MyObj.canvas.getLayer('lines')
    function lines(ctx) { console.log(...) }

MyObj.canvas.getLayers()
    [function lines(ctx) { console.log(...) }]  

Under v5.4, here's what I get:

MyObj.addLayer()

MyObj.canvas.drawLayers()               // this is no longer automatic, but I've included it to give a fair comparison
    'MyObj.drawLines is being called'
    "this" context = <canvas>​
    [<canvas>​]   

MyObj.canvas.getLayer('lines')
    undefined

MyObj.canvas.getLayers()
    [function (Y){return W.call(this,Y)}]

While on the subject of function layers, would it be possible to add a facility to provide a context for "this" when adding the layer? At present, "this" refers to the canvas - which is fine in some cases. However, it would be nice to be able to override this without having to restort to code like this:

var MyObj2 = {
    canvas: $('<canvas />'),

    addLayer: function() {
        var boundLinesFunc = $.proxy(this.drawLines, this);
        this.canvas.addLayer(function lines(ctx) { boundLinesFunc(ctx) });
    },

    drawLines: function lines(ctx) {
        console.log('MyObj2.drawLines is being called');
        console.log('"this" context = ', this);
    }
}

The reason for the named local function in the call to this.canvas.addLayer() is because $.proxy doesn't keep the function name. I could probably use .call() or .apply() here, but I think it would make code flow much easier if the context could be set when the layer was added.

Thanks!

Dan

@caleb531
Copy link
Owner

caleb531 commented Jun 9, 2012

I recently changed the v5.4b code to fix a bug. To ensure layers can be
drawn across multiple canvases, I have to clone the layer first. I used to
do this using the Function constructor, but that destroyed the function's
access to closure variables. Therefore, I wrapped the function in a closure
to fix this.

Frankly, I don't see any real need to override the context. At this point,
I'm more interested in trying to fix what you've just described.

-Caleb

On Sat, Jun 9, 2012 at 7:50 AM, BillyRayPreachersSon <
reply@reply.github.com

wrote:

Hi,

I've just tested some of my code against v5.4, and found that it's no
longer possible to retrieve a function layer by its name as you can with
non-function layers. This is possible with v5.3.1.

Take the following scenario:

var MyObj = {
       canvas: $('<canvas />'),

       addLayer: function() {
               this.canvas.addLayer(this.drawLines);
       },

       drawLines: function lines(ctx) {
               console.log('MyObj.drawLines is being called');
               console.log('"this" context = ', this);
       }
}

Under v5.3.1, here's what I got:

MyObj.addLayer()
       'MyObj.drawLines is being called'
       "this" context = <canvas>

MyObj.canvas.getLayer('lines')
       function lines(ctx) { console.log(...) }

MyObj.canvas.getLayers()
       [function lines(ctx) { console.log(...) }]

Under v5.4, here's what I get:

MyObj.addLayer()

MyObj.canvas.drawLayers()                               // this is no
longer automatic, but I've included it to give a fair comparison
       'MyObj.drawLines is being called'
       "this" context = <canvas>
       [<canvas>​]

MyObj.canvas.getLayer('lines')
       undefined

MyObj.canvas.getLayers()
       [function (Y){return W.call(this,Y)}]

While on the subject of function layers, would it be possible to add a
facility to provide a context for "this" when adding the layer? At present,
"this" refers to the canvas - which is fine in some cases. However, it
would be nice to be able to override this without having to restort to code
like this:

var MyObj2 = {
       canvas: $('<canvas />'),

       addLayer: function() {
               var boundLinesFunc = $.proxy(this.drawLines, this);
               this.canvas.addLayer(function lines(ctx) {
boundLinesFunc(ctx) });
       },

       drawLines: function lines(ctx) {
               console.log('MyObj2.drawLines is being called');
               console.log('"this" context = ', this);
       }
}

The reason for the named local function in the call to
this.canvas.addLayer() is because $.proxy doesn't keep the function name. I
could probably use .call() or .apply() here, but I think it would make code
flow much easier if the context could be set when the layer was added.

Thanks!

Dan


Reply to this email directly or view it on GitHub:
#18

@caleb531
Copy link
Owner

Just wanted to let you know:

I added the ability to name function layers in v5.4. You can do so simply by naming the function expression you pass to it. For example,

$("canvas").addLayer(function myLayerName() {
// Do something here
});

For more flexibility, you can also pass an object instead, with the function as the object's 'fn' property:

$("canvas").addLayer({
name: "myLayerName",
fn: function() {
// Do something here
}
});

I hope that helps.
-Caleb

@BillyRayPreachersSon
Copy link
Author

Great - thanks :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants