WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   Emptying a Table (https://www.wowinterface.com/forums/showthread.php?t=17637)

kerrang 08-10-08 06:30 AM

Emptying a Table
 
Here's a challenge for you

Fred = {}
Fred['barney'] = {}
Fred['barney']['wilma'] = "Flintstone"
Fred = nil
Fred = {}
Fred['barney'] = {}

What does Fred['barney']['wilma'] now contain

Clue: It's not nil, "" nor does it not exist :)

How does one actually empty a table then?

Slakah 08-10-08 07:33 AM

Quote:

Originally Posted by kerrang (Post 98499)
Here's a challenge for you

Fred = {}
Fred['barney'] = {}
Fred['barney']['wilma'] = "Flintstone"
Fred = nil
Fred = {}
Fred['barney'] = {}

What does Fred['barney']['wilma'] now contain

Clue: It's not nil, "" nor does it not exist :)

How does one actually empty a table then?

Code:

Fred = {}
Fred['barney'] = {}
print(Fred['barney'])
Fred['barney']['wilma'] = "Flintstone"
Fred = nil
Fred = {}
Fred['barney'] = {}
print(Fred['barney'])
print(Fred['barney']['wilma'])

outputs
Code:

table: 0036B180
table: 0036B290
nil


LBXZero 08-10-08 07:57 AM

I believe it should be nil unless you have a local variable in a block using the same name. Then for that block it will fool you.

If Fred is a global, you can also setglobal("Fred",nil).

kerrang 08-10-08 08:09 AM

In my case, Fred is declared at the highest level within my addon - it's actually a 'savedvariable' too.

After

Fred = {}
Fred['barney'] = {}
print(Fred['barney'])
Fred['barney']['wilma'] = "Flintstone"
Fred = nil
Fred = {}
Fred['barney'] = {}
print(Fred['barney']['wilma'])

results in "Flintstone"

I've actually changed

Fred = nil

to

for val = pairs(Fred) do
for val2 in pairs(Fred[val]) do
Fred[val][val2] = nil
end
end
Fred = nil

and that resets it...

Something related to the way SavedVariables work perhaps?

kerrang 08-15-08 05:26 PM

I've come across a second instance where emptying a table isn't actually emptying it - in that recreating a key which existed before will bring back values previous held for that key...

This time it's not a savedvariable but it is defined at the highest level of the addon's scope.

I can only assume this is a bug in the Blizzard lua implementation?

The statement

mytable = {}

SHOULD clear EVERYTHING in the existing table should it not?

LBXZero 08-16-08 08:41 AM

If I understand what you are saying, try this for cleaning the table. Create a dummy variable with a new blank table and set your global variable to that blank table.

Code:


local blanktable = {};
setglobal("fred",blanktable);

I am just thinking this up, so I really have not tried it nor can immediately comfirm if it will run.

arkayenro 08-21-08 09:08 PM

Quote:

Originally Posted by kerrang (Post 99079)
mytable = {}

SHOULD clear EVERYTHING in the existing table should it not?

clear the table? no. youre assigning a new empty table to that variable and throwing the old one onto the lua garbage heap, it still exists in memory but it shouldnt be allocated to your variable any more.

how it's getting reassigned to your variable is weird, but its got to be in your code somewhere.

are you using any savedvaraible libraries? like acedb or similar? or is this from no library code?

Iriel 08-21-08 10:25 PM

Your problem is almost certainly that you're doing all those operations BEFORE the saved variables are loaded, and the game then simply restores the old value of the table.

kerrang 08-22-08 05:49 AM

It's nothing to do with savedvariables - I've seen a similar issue in 2 addons and the table is only a 'savedvariable' in one of those addons so...

It's not behaviour before VARIABLES_LOADED either - this is something you can see after you've been playing for HOURS :)

Furthermore - 2 users have reported bugs which could ONLY be caused by a table not being completely emptied - so it's not just me :) The addon in question resets it's table VERY often - and yet we see 'weirdness' which goes away after a "/console reloadui" and the ONLY thing that would do is 'properly' clear the tables.

I think the issue is with tables WITHIN tables - and it may be down to my ignorance of how this should work of course.

It's not an easy bug to reproduce - there seems to be a specific set of circumstances (most likely related to being in/out of combat) but what I seem to be seeing is

fred['a'] = {}
fred ['a']['a'] = 1
fred ['a']['b'] = 1
fred ['a']['c'] = 1
fred = {}
fred['a'] = {}
fred ['a']['a'] = 1

At this point fred ['a']['b'] == 1

If, instead of using fred = {} I do something like

for v in pairs(fred) do
fred[v] = {}
end

I never see the issue - so that's what my addons do to clear tables right now. If I ever went to a 3rd level of 'nesting' I guess I'd have to reset both levels - and so on...

kerrang 08-22-08 05:53 AM

Quote:

Originally Posted by arkayenro (Post 99761)
are you using any savedvaraible libraries? like acedb or similar? or is this from no library code?

No libraries whatsoever...

Duugu 08-22-08 12:06 PM

imho this is about weak tables and/or the garbage collection.

Please read http://www.lua.org/pil/17.html and http://www.lua.org/manual/5.1/manual.html#2.10.

[edit]
Could you please state which mod we're talking about?

kerrang 08-25-08 08:16 AM

I saw this whilst developing both O.B.I. and O-Wheely! addons.

At one point I was creating and clearing tables quite frequently - however this being bad in terms of memory usage I've rewritten both addons NOT to do this now - so I don't have a working example...

A question, however...

If you write code which triggers on ON_UPDATE and takes a LONG time to run - can another ON_UPDATE event trigger before the first one is complete?

At one point I had some code scraping tooltips inefficiently and it was taking maybe .2sec to complete - which is a LONG time - could that code have been executed 'on top of itself'?

Akryn 08-25-08 08:39 AM

Quote:

Originally Posted by kerrang (Post 100090)
If you write code which triggers on ON_UPDATE and takes a LONG time to run - can another ON_UPDATE event trigger before the first one is complete

No, the UI is single-threaded. As long as your OnUpdate code is running, no other UI code will run and no video frames will be drawn because the game waits for the UI to be ready before it draws each frame. If you create an infinite loop, for example, you'll completely freeze the game.

Duugu 08-25-08 11:07 AM

A while ago I made a simple mod to show this behavior.
http://www.scherbenweltkorps.de/systemtest.zip

The first slider controls a simple loop that is done on every OnUpdate:
Code:

        for x = 1, [slidervalue], 1 do
        end

The second slider creates a table if the slider's value changed:
Code:

        local value = getglobal("SystemTestMainSlider2"):GetValue()
        local size = table.getn(DummyTable)
        if size ~= value then
                DummyTable = {}
                local xt = _G.collectgarbage("count")
                for x = 1, value, 1 do
                        table.insert(DummyTable, {"Test","Test","Test","Test","Test","Test","Test","Test","Test","Test","Test"})
                end
        end
        collectgarbage("collect")

It's a nice tool to lower your fps too. ;D

[edit]
This mod was originally to show that the client's performance isn't affected by the mod's memory usage but only by the mod's activity.

kerrang 08-26-08 02:29 PM

Quote:

Originally Posted by Duugu (Post 100107)
This mod was originally to show that the client's performance isn't affected by the mod's memory usage but only by the mod's activity.

That's quite interesting in itself...

With O.B.I., I'd got myself into a position where I had 2 mechanisms for updating ActionButtons.

One method was entirely event-based and used minimal CPU - but it reset (e.g. discarded) tables a LOT (hence he original issue here) and so it's memory usage was constantly climbing (until GC lowered it and it started again). This approach had some issues with the way some actionbar addons worked which were going to be hard to solve too.

The approach I've switched to now is more cpu intensive BUT it's very memory-efficient in that it uses no more memory once initially loaded. It also uses less CPU when you're in-combat which I think is where it matters most ;)

What you're saying tho is that I've made my addon worse in performance terms?? :)

Duugu 08-27-08 06:10 AM

Quote:

Originally Posted by kerrang (Post 100247)
What you're saying tho is that I've made my addon worse in performance terms?? :)

Nope, not really. :)

It's not about how much memory is used. It's about when or where the memory is allocated.

There are basically no performance losses due to high memory usage only. But there WILL be performance losses due to the memory allocating process itself (creating new tables) and there will be a noticeable "lag" on every garbage collection. (depending on how much memory is allocated)

So you could use a lot of memory. But never allocate new memory (create tables) within OnUpdate. (Sounds as you already discovered that. *g*)

The way you're doing it is the only practical way. (re-using tables instead of creating new tables).


All times are GMT -6. The time now is 12:37 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI