Error in a particular condition, long to explain

Forum Home Forum Home > Construct 2 Development > Bugs > Closed bugs
 Post Reply Post Reply
Author
5,530 Rep
Post Options Post Options   Quote 0plus1 Quote  Post ReplyReply Direct Link To This Post Topic: Error in a particular condition, long to explain
    Posted: 12 Apr 2012 at 9:53am
Maybe it's not the right direction, but probably @Ashley knows what we are talking about.

On iOS4 (not 5)and Android too, this plugin (inject)make the entire canvas hang completely. Xcode do not show anything (because it do not have a js debugger) instead LogCat in Eclipse fires this:

INDEX_SIZE_ERR: DOM Exception 1: Index or size was negative, or greater than the allowed value.

The incriminating line is this one: ctx.drawImage(cur_image, myx, myy, this.width, this.height);

Any idea why and how to fix it?
Back to Top

Scirra Developer
78,381 Rep
Post Options Post Options   Quote Ashley Quote  Post ReplyReply Direct Link To This Post Posted: 12 Apr 2012 at 3:30pm
Check this.width > 0 and this.height > 0. The canvas spec says to throw an exception if drawing a zero or negative size image. It can happen more often than you think since e.g. the Anchor behavior may zero size the object for one tick. C2's engine prevents draw() being called on any zero or negative sized object, but maybe if the plugin does its own draw call it can still crash.

Apart from that - if it's a bug in a third party plugin, there's not much more we can do to help.
Back to Top
5,530 Rep
Post Options Post Options   Quote 0plus1 Quote  Post ReplyReply Direct Link To This Post Posted: 13 Apr 2012 at 5:21pm
@Ashley thanks for your help. But something else is wrong here. I wrapped your code to check:

if(this.height>0&&this.width>0){
                    ctx.drawImage(cur_image,
                               myx,
                               myy,
                               this.width,
                               this.height);
               }

And it throws the same error here: this.height.
Why do you think this is happening?
Back to Top

Scirra Developer
78,381 Rep
Post Options Post Options   Quote Ashley Quote  Post ReplyReply Direct Link To This Post Posted: 13 Apr 2012 at 5:47pm
No idea I'm afraid... maybe the image itself is zero sized, but I think that would be to do with the third party plugins you're using. Or maybe you're drawing the image before its loaded event has fired.

Edited by Ashley - 13 Apr 2012 at 5:47pm
Back to Top
5,530 Rep
Post Options Post Options   Quote 0plus1 Quote  Post ReplyReply Direct Link To This Post Posted: 13 Apr 2012 at 5:54pm
It's very strange, the plugin is a behaviour that is doing this:

this.inst.cur_animation.frames[this.inst.cur_frame].texture_img.src = '';
          this.inst.cur_animation.frames[this.inst.cur_frame].texture_img.src = base64string;
          this.inst.cur_animation.frames[this.inst.cur_frame].texture_img.onload = (function (self) {
               return function(info) {
                    cr.runtime.redraw = true;
               };
          })(this);

where base64string is the url of the image. The line that throws this error is just this one: this.inst.cur_animation.frames[this.inst.cur_frame].texture_img.src = base64string; even deleting all the rest it still throws that error.

All the browser do not, only android 2.2 and iOS 4.X

It seems strange, but maybe you have an idea about the reason this might happen and how to mitigate it, is there any other way except .src to load an image inside a sprite?

Thanks

Edit: @Ashley sorry to bother you about this but you are the only one that can point me in the right direction

Edited by 0plus1 - 14 Apr 2012 at 9:08am
Back to Top

Scirra Developer
78,381 Rep
Post Options Post Options   Quote Ashley Quote  Post ReplyReply Direct Link To This Post Posted: 14 Apr 2012 at 2:08pm
What is the content of base64string? If it's a URL what URL is it and where does it point? Maybe just using a new Image() and assigning that will work, but I don't know, just a guess.

There are a few mistakes/issues with the code you pasted:
- there's no need to assign src to '' first
- onload should be set before src, otherwise there's a slim chance src could finish loading before the next line (since browsers are asynchronous), then your onload event is never fired because it's set after the event has already fired.
- however it's likely to take at least 2-3 ticks to load the image even if cached. Drawing an image before it has loaded is likely to cause an error
- cr.runtime.redraw = true does nothing, I think it was intended to write self.runtime.redraw = true.
Back to Top
5,530 Rep
Post Options Post Options   Quote 0plus1 Quote  Post ReplyReply Direct Link To This Post Posted: 14 Apr 2012 at 7:09pm
@Ashley The url point to an image. On device to emotions/xyz.png (xyz is the image name that changes everytime) for testing is set to http://u.dropbox.com.../emotions/xyz.png. The images works, this is an error specific to androdid 2.2 and ios4.x on "moderner" browsers it works without problem. I discovered that after .src the content of:

this.inst.cur_animation.frames[this.inst.cur_frame].texture_img.width (and height) are both 0. While before .src where equal to this.inst.width/height. I thought that was the problem, but even if I set:

this.inst.cur_animation.frames[this.inst.cur_frame].texture_img.width = this.inst.width;

(same for height) the error still happens (and the value is set after cheching with console.log). Tomorrow I'll try your solution.
But I think that what happens is that after .src the .width/height goes to 0 and the engine picks that for the tick it takes to set the correct value (as it's async).
Back to Top

Scirra Developer
78,381 Rep
Post Options Post Options   Quote Ashley Quote  Post ReplyReply Direct Link To This Post Posted: 14 Apr 2012 at 8:29pm
Hmm, if it doesn't work in Android 2.2 or iOS 4.x, and works in newer versions of Android or iOS, maybe they're just out of date and broken browsers. Might be best just to forget them.
Back to Top
5,297 Rep
Post Options Post Options   Quote Pode Quote  Post ReplyReply Direct Link To This Post Posted: 16 Apr 2012 at 2:01pm
@Ashley, @0plus1 : I used
Quote src = '';
because I read somewhere that for V8 (WebKit JS engine), it help the GC to catch faster the image to delete (the one referenced there before), but I can't find the reference anymore.
I have updated the plugin, and I'm going to post it in a few minutes.
One a problem that I have is that when you inject an image, you are 'loading' it (regarding the way the browser deal with it). And before loading it, you don't know its width/height.
I added some code to specify the width/height of the Sprite container (not the underlying IMGElement width/height), because I can't manage to force the browser to update the image when I set those.
With the new build, @0plus1, can you test and say if you still have the problem (I have tested it on FF 11, Chrome 16+, Opera 11+ and iOS5.1). I don't have any device with iOS < to 5 now, so I can't test it on that, neither on Androïd.
See you in the other thread .
Back to Top
5,530 Rep
Post Options Post Options   Quote 0plus1 Quote  Post ReplyReply Direct Link To This Post Posted: 18 Apr 2012 at 9:58am
@Ashley
Thanks, with your help I made this plugin: http://www.scirra.com/forum/topic51261_post323173.html#323173 it now works perfectly.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down