How can I have module-to-module communication without running into circular dependency?

I have two modules, a bomb module and a constructor module. When I want to destroy the object made in the constructor module, I would call object:destroyObject(). This works fine, but the variable that’s assigned the object table in the bomb module does not update as nil whenever the object is destroyed in the constructor module since it’s stored there.

This means that if I call object:destroyObject(), I could fire it again in the bomb module and it’d still go through even though the object was destroyed in the constructor module. So how can I update the object in the bomb module and also make it nil when it’s destroyed in the constructor module? I was thinking I could require the constructor module to the bomb module and make some sort of checking function, but this would cause a circular dependency error.


I was also wondering, is there any better way I can go about this as a whole? I feel like the way I’m going about it is just making unnecessary amounts of memory, but I’m not sure. I can provide my code if anyone’s interested.

And if I didn’t explain any of this well, here’s a flow chart if that helps:

I dont really understand the structure i know it has to do with managing and creating objects
but im pretty sure the problem here is table.copy you could just do newObjectTable = objectTypeTable

Without the actual code, it’s a little bit hard to fully grasp the situation you’re encountering. Where is the circular dependency on the flowchart?

In general, you should call functions on child objects (since the parent knows about the child) and fire signals to parent objects (because the child doesn’t know about the parent). To clarify, calling a function requires a reference to the owner of that function, whereas firing a signal does not require any external references. It’s up to the parent to connect and listen to the child’s signal.

In my OOP code, a parent will create the child and store the created object in a list. It connects to events on the child (e.g. exploded, etc) and when it comes time to clean up, it calls destroy on the child and then clears it from its own table to lose the reference and let the garbage collector deallocate the child’s memory.