How can I find references to a given physics body?

@UberGoober If you update the info everyplace you add a body to a table, then whenever you print the info, you’ll know where that body was added. If you know where it was added then maybe you can figure out what’s happening. If you have bodies without info, then they’re being added someplace you don’t update the info. As far as I know, bodies don’t just appear unless they’re created.

‘Every place you add a body to a table’ is a lot of places. That’s why I was looking for a global table tweak.

@UberGoober Then you better get started or you’re never going to figure out what your problem is.

Aw but @dave1707 , avoiding brute force is also an interesting problem to solve. :slight_smile:

Ok here’s a metatable that stores tables in a tablesWithBodies table if:

  • they ever have a body added to them
  • those bodies have a “shortName” property

    bodiesDetecter = {}
    bodiesDetecter.tablesWithBodies = {}
    bodiesDetecter.__newindex = function(tableUsed, index, newValue)
        rawset(tableUsed, index, newValue)
        if newValue.shortName ~= nil then
            print("table storing bodies added to bodiesDetecter")
            if rawget(bodiesDetecter.tablesWithBodies, tableUsed) == nil then
                rawset(bodiesDetecter.tablesWithBodies, tableUsed, debug.traceback())
                rawset(bodiesDetecter.tablesWithBodies, 
                    #bodiesDetecter.tablesWithBodies + 1, tableUsed)
            end
        end
    end
    bodiesDetecter.__index = function(tableUsed, index)
        return rawget(tableUsed, index)
    end
  

Here it is in action:


    tableHas, tableHas2 = {}, {}
    setmetatable(tableHas, bodiesDetecter)
    setmetatable(tableHas2, bodiesDetecter)
    body1 = physics.body(CIRCLE, 20)
    body1.shortName = "body1"
    body2 = physics.body(CIRCLE, 20)
    body2.shortName = "body2"
    tableHas[1] = body1
    table.insert(tableHas2, body2)
    print(tableHas, tableHas2)
    for k, v in pairs(bodiesDetecter.tablesWithBodies) do
        print("found ", k, v)
    end

So that seems to work, now I just have to assign that metatable to every table as soon as it’s created, which should be possible with the _G variable.

I tried this, though, and it doesn’t work:


    bodiesDetecterAssigner = {}
    bodiesDetecterAssigner.__newindex = function(tableUsed, index, newValue)
        rawset(tableUsed, index, newValue)
        if type(newValue) == "table" then
            print("assigning bodiesDetecter to table")
            setmetatable(newValue, bodiesDetecter)
        end
    end
    bodiesDetecterAssigner.__index = function(tableUsed, index)
        return rawget(tableUsed, index)
    end
    setmetatable(_G, bodiesDetecterAssigner)

…any idea what I’m doing wrong?

You would have to overwrite the table.insert function which is pretty simple to just declare it

table.insert = function ()
  —do your stuff
end

I don’t think that would cover direct assignments such as

thisTable.circle = physics.body(CIRCLE, 10)

…would it?

No it won’t you’re right, for that you would need to modify the built in table metatable which I think can only be done from the C level in the Codea source