Resetting boogared vec2 metatable [ANSWERED]

So, I did something stupid to vec2’s metatable while trying to extend the class. It seems messed up in all the projects and quitting Codify doesn’t help. Is there a way to restore it to its factory state without losing all my projects?

Thanks,

-Steve

That shouldn’t be possible, but I’ll definitely look into it. I’ll try to subclass and see what happens.

Can you try completely quit Codea? That is go to the home screen, double-tap the home button, hold down on the Codea icon and then tap the little red close button to kill the process.

vec2 doesn’t use the class() mechanism for its methods, as it is entirely implemented in C. So I don’t think it can be subclassed. But the Lua interpreter is reset every time you hit run, so it shouldn’t be causing long term issues outside of your project.

Keep in mind - vec2 is buggy right now - a fix is incoming. But if you think you messed it up because you’re getting some incorrect results - you might just be seeing the bugs.

I did try to completely quit (double tap home, tap and hold app until shakey, tap x), but this did not help.

With some embarrassment, I can give you more details about what I did, if that will help…

I obtained the vec2 meta table using getmetatable(vec2()). Then I stored the __index() function in a global and replaced it with my own implementation that calls the original one under some circumstances. While this initially seemed reasonable to me, in hind sight, I think it was not: every time I ran, I think I was nesting another hooked version of __index(). At this point, I’m unable to remove my __index() and restore yours, and my version is doing something stupid.

Bortels…

I did notice that angleBetween() doesn’t always work right, but that is not my problem, now.

It’s odd because the Lua interpreter is completely re-initialized every run. Have you tried restarting your iPad?

Very odd. If you could share your project (iExplorer) that would be great.

OK… The code is just a minor modification to the Gravity example. What I was trying to do, may not work, but in the process of experimenting, I now have an ‘xy’ permanently ‘in’ vec2 everywhere.

vec2_mt = getmetatable(vec2())
oldVec2__index = vec2_mt.__index
function vec2_mt:__index(key)
    if key == 'xy' then
        return self.x, self.y
    else
        return oldVec2__index(self, key)
    end
end

GravityX = 0
GravityY = 0 -- we are just using this for the watch()

-- Use this function to perform your initial setup
function setup()
    print("An example that shows how to use the Gravity vector")
    watch("GravityX")
    watch("GravityY")
    
    print(vec2(4.2,5.3).xy)
end

-- This function gets called once every frame
function draw()
    GravityX = Gravity.x -- a bit not nice
    GravityY = Gravity.y
    
    background(127, 127, 127, 255)
    
    stroke(255, 255, 255, 255)
    strokeWidth(15)
    
    lineCapMode(ROUND)
    
    pushMatrix()
    
    translate(WIDTH/2, HEIGHT/2)
        
    grav = vec2(Gravity.x, Gravity.y) * 300
    
    --print(grav)
    
    line(0, 0, grav.xy)
    
    -- Arrowhead
    down = vec2(0,-1)
    orient = down:angleBetween(grav)
    
    pushMatrix()
    resetMatrix()
    
    translate(WIDTH/2,HEIGHT/2)
    translate(grav.xy)
    rotate(math.deg(orient))
    
    line(0, 0, -20, 25)
    line(0, 0,  20, 25)
    popMatrix()
    -- End Arrowhead
    
    popMatrix()
end

I tried your code and it did not affect any other example projects.

You might need to run my code a couple times. Every time it runs, I think it might ‘nest’ another __index(). Now try placing:

print(vec2(4.2,5.3).xy)

into the setup() of some other project. You’ll see that it will run there, even though it was created in the other project.

print(vec2(4.2,5.3).xy)

Will always print “4.2”

This is because Codea is lazy when checking in the C code for vec2’s __index. It just checks the first character of the key. So you can actually write anything there:

print(vec2(4.2,5.3).xp)

Will also print “4.2”

I can make it check the entire string. But you can be assured there are no permanent alterations to vec2 from running your code.

Thanks… Sorry to have sent you on this wild goose chase.

So my attempt at introducing some a new key into vec2 by hooking __index() never really worked. I was fooled into thinking it was kind of working when I saw the x, but I couldn’t see why I never saw the x, y multiple result

Sorry about that! I actually thought I disabled getmetatable() but from your code, it seems to exist.

vec2 is a userdata type in Lua, it has a metatable. I think there could be a way to get your code working, will look into it.

Actually your code works just fine. Your overload of “xy” is actually being called in your example, print() is only printing the first argument.

If you make the “xy” lookup return the string “test” then the print will print “test” correctly.

Edit: I don’t believe Lua “unpacks” arguments when you return multiple items and attempt to use them as parameters in another function. When you use grav.xy as a parameter, it is the same as passing grav.x.

Edit 2: I’m incorrect, Lua does pass multiple returns off as multiple parameters. Unsure why Codea functions are not doing this.

I think print \will\ output all the results of a function, each result interpreted as a separate argument. Something else is going wrong here.

Following is what I hoped to do, but I’ve instead written a global function xy(v) that returns the xy components in a multiple result. I can use it in print and to replace separate x y parameter pairs in any function (there are many examples in the code). The following code works fine; it just all went south when I tried to streamline the usage by instead implementing it in an extension to vec2.

function xy(v)
    return v.x, v.y
end

GravityX = 0
GravityY = 0 -- we are just using this for the watch()

-- Use this function to perform your initial setup
function setup()
    print("An example that shows how to use the Gravity vector")
    watch("GravityX")
    watch("GravityY")
 
    print(xy(vec2(4.2,3.5)))
end

-- This function gets called once every frame
function draw()
    GravityX, GravityY = xy(Gravity) -- a bit not nice
    
    background(127, 127, 127, 255)
    stroke(255, 255, 255, 255)
    strokeWidth(15)
    lineCapMode(ROUND)
    
    pushMatrix()
    translate(WIDTH/2, HEIGHT/2)
    grav = vec2(xy(Gravity)) * 300
    --print(grav)
    line(0, 0, xy(grav))
    
    -- Arrowhead
    pushMatrix()
    resetMatrix()
    translate(WIDTH/2,HEIGHT/2)
    translate(xy(grav))
    rotate(math.deg(math.pi - math.atan2(xy(grav))))
 
    line(0, 0, -20, 25)
    line(0, 0,  20, 25)
    popMatrix()
    -- End Arrowhead
    
    popMatrix()
end 

Anyway, this has all become more a topic for a Lua language board rather than a Codea issue anymore. Thanks for your help and time.