Problem with button class

For some reason, when I use this, the buttons occasionally freeze,seemingly randomly, and I’ve no clue why.

QuadButton = class()

function QuadButton:init(x,y,size,d1,d2,d3,d4,c1,c2,c3,c4)
    local s=size/2
    local w=5
    local q=s/w
    self.m1=mesh()
    self.m5=mesh()
    self.m2=mesh()
    self.m6=mesh()
    self.m3=mesh()
    self.m7=mesh()
    self.m4=mesh()
    self.m8=mesh()
    self.m1.vertices={vec2(x,y),vec2(x-s,y),vec2(x,y-s),vec2(x-s-q,y-s-q),vec2(x-s,y),vec2(x,y-s)}
    self.h1 = vec4(x-s,x,y-s,y)
    self.m5:addRect(x-s/2,y-s/2,s,s)
    self.m2.vertices={vec2(x,y),vec2(x-s,y),vec2(x,y+s),vec2(x-s-q,y+s+q),vec2(x-s,y),vec2(x,y+s)}
    self.h2 = vec4(x-s,x,y,y+s)
    self.m6:addRect(x-s/2,y+s/2,s,s)
    self.m3.vertices={vec2(x,y),vec2(x+s,y),vec2(x,y+s),vec2(x+s+q,y+s+q),vec2(x+s,y),vec2(x,y+s)}
    self.h3 = vec4(x,x+s,y,y+s)
    self.m7:addRect(x+s/2,y+s/2,s,s)
    self.m4.vertices={vec2(x,y),vec2(x+s,y),vec2(x,y-s),vec2(x+s+q,y-s-q),vec2(x+s,y),vec2(x,y-s)}
    self.h4 = vec4(x,x+s,y-s,y)
    self.m8:addRect(x+s/2,y-s/2,s,s)
    self.m1:setColors(color(155,155,155,255))
    self.m2:setColors(color(155,155,155,255))
    self.m3:setColors(color(155,155,155,255))
    self.m4:setColors(color(155,155,155,255))
    self.img1 = readImage("Cargo Bot:Condition Red")
    self.m5.texture = self.img1
    self.img2 = readImage("Cargo Bot:Condition Yellow")
    self.m6.texture = self.img2
    self.img3 = readImage("Cargo Bot:Condition Green")
    self.m7.texture = self.img3
    self.img4 = readImage("Cargo Bot:Condition Blue")
    self.m8.texture = self.img4
    self.t1,self.t2,self.t3,self.t4=nil,nil,nil,nil
    self.d1,self.d2,self.d3,self.d4=d1 or 1,d2 or 1,d3 or 1,d4 or 1
    self.c1,self.c2,self.c3,self.c4=
    c1 or function() end,c2 or function() end,c3 or function() end,c4 or function() end
    zgfqbrtyzzzzx = self
end

function QuadButton:draw()
    pushStyle()
    self.m1:draw()
    self.m2:draw()
    self.m3:draw()
    self.m4:draw()
    self.m5:draw()
    self.m6:draw()
    self.m7:draw()
    self.m8:draw()
    rectMode(CORNERS)
    fill(0, 0, 0, 126)
    if self.t1 then
        rect(self.h1.x,self.h1.z,self.h1.y,self.h1.w)
    end
    if self.t2 then
        rect(self.h2.x,self.h2.z,self.h2.y,self.h2.w)
    end
    if self.t3 then
        rect(self.h3.x,self.h3.z,self.h3.y,self.h3.w)
    end
    if self.t4 then
        rect(self.h4.x,self.h4.z,self.h4.y,self.h4.w)
    end
    popStyle()
end

function QuadButton:touched(t)
    if t.state == BEGAN then
        if self:test(t,self.h1) and not self.t1 then
            self.t1 = t
            return
        end
        if self:test(t,self.h2) and not self.t2 then
            self.t2 = t
            return
        end
        if self:test(t,self.h3) and not self.t3 then
            self.t3 = t
            return
        end
        if self:test(t,self.h4) and not self.t4 then
            self.t4 = t
            return
        end
    end
    if t.state == ENDED then
        if self.t1 and self.t1.id == t.id then
            --self.t1 = nil
            self.m1:setColors(255,0,0)
            self.c1()
            tween.delay(self.d1,function() zgfqbrtyzzzzx.t1 = nil; zgfqbrtyzzzzx.m1:setColors(color(155)) end)
            self.a=true
            return
        end   
        if self.t2 and self.t2.id == t.id then
            --self.t2 = nil
            self.m2:setColors(255,0,0)
            self.c2()
            tween.delay(self.d2,function() zgfqbrtyzzzzx.t2 = nil; zgfqbrtyzzzzx.m2:setColors(color(155)) end)
            self.b=true
            return
        end   
        if self.t3 and self.t3.id == t.id then
            --self.t3 = nil
            self.m3:setColors(255,0,0)
            self.c3()
            tween.delay(self.d3,function() zgfqbrtyzzzzx.t3 = nil; zgfqbrtyzzzzx.m3:setColors(color(155)) end)
            self.c=true
            return
        end 
        if self.t4 and self.t4.id == t.id then
            --self.t4 = nil
            self.m4:setColors(255,0,0)
            self.c4()
            tween.delay(self.d4,function() zgfqbrtyzzzzx.t4 = nil; zgfqbrtyzzzzx.m4:setColors(color(155)) end)
            self.d=true
            return
        end
    end
end

function QuadButton:collectData(resetOutputs)
    local t = {self.a,self.b,self.c,self.d}
    if resetOutputs then
        self.a,self.b,self.c,self.d = false,false,false,false
        
    end
    return t
end

function QuadButton:test(t,zeta)
    if t.x >= zeta.x and t.x <= zeta.y and
    t.y >= zeta.z and t.y <= zeta.w then
        return true
    else
        return false
    end
end

I do not know where the error is, and I’ve gone over it multiple times

Bug. Replace

    self.h4 = vec4(x,x+s,y,y-s)

by

    self.h4 = vec4(x,x+s,y-s,y)

PS: you should comment your code!

Wow, such a simple bug, thanks a million! I checked over all that a billion times and could have swore it was right
Yeah, it’s a habit I [REALLY] need to adopt but I generally don’t share my code, and so there’s usually no need for others to understand it

Edited original post, new question, please help :frowning:

When your touch ends, you’re checking t.id but I don’t see anyplace where you’re saving it.

I’m storing the touch itself in self.t1, so the id should be the same, and is stored in the touch itself.

@Monkeyman32123 OK, I see that now. I was just searching for t.id and didn’t see where you were saving t. Will keep looking.

@Monkeyman32123 The problem is the touch ID is being duplicated. I’m not sure how Codea creates the id, but sometimes it creates duplicates. See the print statements that I added in the touched function below. Try your code with them and touch each button once fast and sometimes you’ll see duplicate id’s.


function QuadButton:touched(t)
    if t.state == BEGAN then
        if self:test(t,self.h1) and not self.t1 then
            self.t1 = t
            print("1a",t.id)     -- print
            return
        end
        if self:test(t,self.h2) and not self.t2 then
            self.t2 = t
            print("2a",t.id)    -- print
            return
        end
        if self:test(t,self.h3) and not self.t3 then
            self.t3 = t
            print("3a",t.id)    -- print
            return
        end
        if self:test(t,self.h4) and not self.t4 then
            self.t4 = t
            print("4a",t.id)    -- print
            return
        end
    end

Hm, well, that makes sense. If that is the case, however, why does it freeze? Additionally, what fixes it?

@Monkeyman32123 What do you mean by freeze. Are you saying because the buttons don’t go back to their original color or do you mean the code freezes. If it because the buttons don’t go back to their original color, then remove the 4 “return” statements in the “if t.state == ENDED then” section of code. If you mean the code freezes, I don’t know because I don’t see that happening.