Warning:
Now I am convinced that the problem is that the luatraverse script described here does not work as advertised, and does not find all references to the object. In my example, I found where the object was referencing, thereby preventing its collection, but this was not reported script.
Therefore, the basic premise of this issue is somewhat flawed.
Feedback:
I am working on improving the scripting engine in Bitfighter . I'm not sure that memory is being freed properly. Therefore, I built the test as a script below.
It prints 3 columns of userdatas. Column 1 is the user data, which I expect to not use anymore, and therefore should be destroyed by the collectgarbage function. Columns 2 and 3 are objects that I think should not be collected, because I hold them in my hands.
Problem:
The user data in column 1 never changes, so I suspect it is not going to (cols. 2 and 3 behave as expected). To clarify the situation, I am using the luatraverse script mentioned in this problem , which seems to confirm that there is only one link to obj100, which is stored in obj100. I tried to add an assignment just before running countreferences (local x = obj100), and, as expected, countreferences reported that the object was referenced twice.
Questions:
1) obj100 ? , ?
2) , luatraverse script, , Lua?
:
-- Every 2 seconds, find two objects with ids 100 and 200, and print their addrs
-- No reference is kept for object 100, so its userdata might change over time
-- Object 200 is held by objHolder, so its userdata should remain constant
-- Obj200 should remain constant over time; obj100 can vary.
-- objHolder should be constant, obviously
local ltraverse = require("luatraverse")
function printIds()
local obj100 = levelgen:findObjectById(100)
local obj200 = levelgen:findObjectById(200)
print("Obj 100:" .. tostring(obj100) .. " Obj 200:" ..
tostring(obj200) .. " Held:" .. tostring(objHolder))
print(ltraverse.countreferences(obj100))
obj100 = nil
obj200 = nil
collectgarbage()
end
function main()
-- levelgen:findObjectById is a local game command that
-- creates a userdata for an object
local obj100 = levelgen:findObjectById(100)
objHolder = levelgen:findObjectById(200) -- not local, global
assert(obj100)
assert(objHolder)
print("Column 1 can vary; 2 and 3 should be constant")
print("=============================================")
print("Obj 100:" .. tostring(obj100) .. " Obj 200:" ..
tostring(objHolder) .. " Held:" .. tostring(objHolder))
obj100 = nil
-- Run a function every 2 seconds
Timer:scheduleRepeating(printIds, 2000)
end
:
Column 1 can vary; 2 and 3 should be constant
=============================================
Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
1
Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
1
Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
1
Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
1
Obj 100:userdata: 02FC9700 Obj 200:userdata: 02FAD280 Held:userdata: 02FAD280
1
... and onward to infinity ...