Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

How do I recreate a Destroy method?

Asked by 8 years ago

Heres the idea I'm using modulescripts to create objects

I want to call the Destroy method to destroy that object; all its properties, tied Instances, references, and Objects that were required from the modulescript. I want to leave NO DATA BEHIND

I was thinking of doing something like:

    function stuff:Destroy()
        for i, v in pairs(getfenv()) do
            if v:IsA("Instance") then
                v:Destroy();
            else 
                v = nil
                i = nil
            end
        end
    end

but alas, the function does not produce the desired effect.

Please help me achieve complete destruction

0
Try using :remove() instead. TheDeadlyPanther 2460 — 8y
0
Can I ask what that will accomplish? randomsmileyface 375 — 8y

1 answer

Log in to vote
1
Answered by 8 years ago

Most of the time you don't need to recreate a Destroy function - lua's garbage collection will take care of it: whenever something no longer has a reference to it, it will eventually get garbage collected (often within a few seconds). ex:

local t = {}
t = nil
--At this point, the table still (probably) exists in memory [I believe lua can garbage collect while your code runs - even if your code doesn't yield - so it's technically not a guarantee, but it's very probable)
wait(3)
--At this point, the table is likely garbage collected since nothing refers to it

This works regardless of what information is contained within t. In fact, lua can handle circular references, too:

local t1 = {}
local t2 = {t1}
t1[1] = t2
t1 = nil
t2 = nil
--As you can see, we've created two tables that refer to each other. As before, they're still in memory.
wait(3)
--Despite the two tables referencing each other, lua knows that nothing else refers to them, so it garbage collects both

However, memory leaks are still possible. The easiest one is this scenario:

  • You create a Part, let's call it P.
  • Another script listens to P's Changed event (I believe it will need to connect it to a function that uses P, or else this example won't work)
  • You destroy all references to P (but don't call P:Destroy())

P thus cannot be garbage collected, even though you don't need it anymore.

Thus, you will need a custom Destroy function for some of your classes. Here's what you do:

  1. Create a Destroy function in the class
  2. For each thing that class initializes, clean it up if needed:
    • Call :Destroy() on any created instances (and any custom classes that also have a :Destroy function)
    • Call :disconnect() on any custom events (or :Destroy() on BindableEvents/etc)
    • Release any custom resources that need to keep track of how many references there are to it (ex if you have an object that is distributed to multiple coroutines/scripts and needs to destroy itself only after all those scripts are done with it. In that case, you can't just call :Destroy(), since other scripts may be using it. Instead, you need to keep track of the number of references, and only when that number reaches 0 does the object call Destroy on itself).
  • You do not need to clean up basic values (numbers, tables, strings, Vector3s, etc).
  • If you have nothing to destroy, there's no need for a :Destroy() function, but you might want one for consistency

If the ModuleScript contains a table of values, you might want to create/call some sort of "ClearData" function that erases the table (ex in another one of your questions you had a Deck of cards. If that ModuleScript actually contained a list of Decks in existence, you might want to clear that list (in preparation for a new round/game) so that those decks can be garbage collected, allowing you to make new ones).

0
Do you have any idea as to how I could iterate through every variable in a given function within the modulescript? I'm calling getfenv but I randomsmileyface 375 — 8y
Ad

Answer this question