RETAINED bug

. @Simeon, I think there is a bug with RETAINED mode. Here is a program that shows the bug. If I drag my finger around the screen to draw a continuous line, sometimes gaps show in the lines. I thought that the touch was being interrupted so I added print statements in the BEGAN and ENDED if statements. But I show only one BEGAN and ENDED, so the touch isn’t the problem. I think that one of the 3 screens that are being drawn on isn’t always being copied forward, causing the gaps.


backingMode(RETAINED)

function setup()
    x1=0
end

function touched(t)
    if t.state==BEGAN then
        print("BEGAN")
        x=t.x
        y=t.y
    elseif t.state==MOVING then
        x1=x
        y1=y
        x=t.x
        y=t.y
    elseif t.state==ENDED then
        print("ENDED")
        x1=0
    end
end

function draw()
    strokeWidth(2)
    if x1>0 then
        line(x1,y1,x,y)
    end
end

.@dave1707 after some more testing it seems like it is due to touched(t) being called multiple times in a single frame. At least, if I move the line drawing directly into the touched function it stops the gaps for me:

backingMode(RETAINED)
 
function setup()
    x1=0
end
 
function touched(t)
    if t.state==BEGAN then
        print("BEGAN")
        x=t.x
        y=t.y
    elseif t.state==MOVING then
        x1=x
        y1=y
        x=t.x
        y=t.y    
        drawLine()
    elseif t.state==ENDED then
        print("ENDED")
        x1=0
    end
end

function draw()
end
 
function drawLine()
    strokeWidth(2)
    if x1>0 then
        line(x1,y1,x,y)
    end
end

```


Edit: Better version below

. @Simeon, Here is another version I tried. I draw red and white alternating dots at .01 second intervals. I expected to see a skip in the color pattern where there was a gap, but there wasn’t any skip. But I did notice that the gap appears at around every 23, 24, or 25 dots. I’m wondering if the draw and touch routines are interfering with each other every .25 seconds and the draw routine is being delayed causing the gap ??? I have some other ideas I’m going to try, I like coding mysteries.


backingMode(RETAINED)
displayMode(FULLSCREEN)

function setup()
    x=0
    a=0
end

function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        x=t.x
        y=t.y
    end
end

function draw()
    if ElapsedTime-a>.01 and x>0 then
        fill(255)
        a=ElapsedTime
        count = not count
        if count then
            fill(255,0,0)
        end
        ellipse(x,y,8)
    end
end

Here is a slightly re-architected version that does not dispatch drawing commands in touched. Instead it queues line segments to be drawn in a global segmentsToDraw table, which is drawn (if necessary) and cleared each time draw is called.

backingMode(RETAINED)
 
function setup()
    segmentsToDraw = {}
end
 
function touched(t)
    if t.state==BEGAN then
        print("BEGAN")
        table.insert( segmentsToDraw, vec2(t.x,t.y) )
    elseif t.state==MOVING then
        table.insert( segmentsToDraw, vec2(t.x,t.y) )
    elseif t.state==ENDED then
        print("ENDED")
        segmentsToDraw = {}
    end
end

function draw()
    strokeWidth(2)
    
    if #segmentsToDraw > 1 then
        local prevPoint = segmentsToDraw[1]
        for i = 2, #segmentsToDraw do
            local p = segmentsToDraw[i]
            
            line( prevPoint.x, prevPoint.y, p.x, p.y )
            
            prevPoint = p
        end        
        
        segmentsToDraw = {prevPoint}
    end
end

I would recommend this version over the above due to it not calling drawing commands in touched.

. @Simeon. Here is another version. I create a table of the x,y positions as I move my finger. When I’m done and lift my finger, I then draw the dots from the table. I still see the gaps, but not every time. I’m not sure what this proves, but are the touched and draw functions interfering with each other as suggested above.

EDIT: If I remove backingMode and add backgroung(40,40,50) to draw, I get it to happen but not as often.


backingMode(RETAINED)
displayMode(FULLSCREEN)

function setup()
    tab={}
    done=false
end

function touched(t)
    if t.state==BEGAN or t.state==MOVING then
        table.insert(tab,vec2(t.x,t.y))
    end
    if t.state==ENDED then
        done=true
    end
end

function draw()
    if done then
        fill(255)
        for z=1,#tab do
            ellipse(tab[z].x,tab[z].y,8)
        end
        done=false
    end    
end

.@Simeon. I can’t eliminate any more than this. It still happens with this code.


displayMode(FULLSCREEN)
backingMode(RETAINED)

function draw()
    fill(255)
    ellipse(CurrentTouch.x,CurrentTouch.y,8)
end

.@dave1707 my solutions above seemed to resolve the issue for me — did they not work for you?

This isn’t a bug, just that touched() can be called at any time — even multiple times before draw() is called.

I’m not sure what I’m looking for with your last example. The ellipses will appear at arbitrary intervals depending on the speed of the device and the rate at which your finger moves. What should I be looking for there?

. @Simeon. I’ve been writing different programs to try and understand what I’m seeing or what’s happening. If I use the above program and drag my finger in a steady speed and continuous sine wave motion across the screen, I see a larger gap every 23 to 25 dots. I know the speed affects the distance between the dots, but the gap is very noticeable when you compare the distance between the other dots around it. I’m not after a work around, I’m just trying to see if I can figure out why the gap is showing up. Does anyone else see the gaps. I’m using an ipad1.

.@dave1707 yes, that behaviour is because touched() can be called multiple times before draw() is called. That is, touched() can run at a higher rate (or lower rate) than draw().

To visualise every touch event you have to queue your touches and then draw them in draw(). What you are doing is only drawing the state of CurrentTouch in draw — CurrentTouch may have been updated two or three times since the last draw() function, but you won’t know it (unless you monitor touched()) and it will only appear as a larger gap between ellipses.

. @Simeon. I hate to keep bugging you on this, but in the program just above the last one, I create a table entry for every MOVING touch event and then in the ENDED if statement I set “done” to true and draw the points from the table. I have the program set to not draw anything until touch has ENDED, so draw doesn’t get involved. So if you draw the invisible sine wave across the screen and then lift your finger, I’ll draw the dots in the table and the gaps still show every 23 to 25 dots. That makes me think that something is interfering with the touch routine or that a touch event is happening faster than the touched function can handle it and one gets skipped every now and then. Can a touch event get skipped if something else is happening and that’s what causes the gaps that I see. I can’t get it to happen every time unless I’m going a the correct speed.