Code structuring - intermediate help needed

Hi all,

I’ve run into a problem with recursive modules (meaning: module A requires module B, and module B requires module A, which results in a Lua error).

Here’s my situation. I have two modules:

  • gameEngine.lua

  • touchController.lua

The module called " gameEngine.lua" contains my game logic, and requires the module “touchController.lua” to start listening for touches. Now, when a touch gesture is recognised by " touchController.lua" , it needs to call a function that resides in “gameEngine.lua”. Unfortunately I can’t require “gameEngine.lua” inside “touchController.lua” because that creates a recursion loop.

How could I fix this? For the sake of my needs I would like to add that I’m generalising the example a bit here, so just suggesting “Why don’t you add listen for the touches inside gameEngine.lua?” won’t help me: I have the same situation regarding a couple of other modules. For example: “gameEngine.lua” also requires “enemy.lua” to creates instances of my enemies. Same issue here: when my enemies collide with something I want to call a function inside “gameEngine.lua” - and likewise I could include the code for enemies inside “gameEngine.lua” but in the end that sort of solution sort of defeats the purpose of modularising your code.

For what it’s worth, make “gameEngine.lua” global works well, naturally, but feels wrong.

Any insight here? Thanks!

Your solution that you warn against (because of simplification) is in fact, in simple terms, the only solution. The problem you face is the same problem of coders since time (of coding) began. A better way to understand your solution, and therefore your problem, is just to describe in a different way. Let me explain…

You want two (or more) units of code to reference each other. While it is not impossible for that to happen (double-linked lists do this, for example) what you are trying to force is where the code execution dives deeper into itself at each iteration (in your case, a user’s touch on the interface) and this will eventually cause an infinite loop, stack overflow and, finally, memory exceptions (if the stack overflow doesn’t kill it first.)

The solution is, as you’ve already mentioned, to use listeners. The confusion comes by how to set them up, not by their linkages.

So, and this will be somewhat general because you’ve not provided any code, lets say that module A, B, C and D all refer to each other. That’s impossible. But it can be done. Fortunately, module A is - in your case - the main.lua code, so we’re safe here.

Modules B, C and D all get loaded by module A with require statements. One approach is, in module A, to call a function which let’s you register the other modules with each module. So, first load them all, then tell each one about the others. This works, but it’s not elegant because you can still end up creating infinite loops, stack overflows and the like.

The better solution is, in simple terms, to have each module listen to some object in the system, let’s say Runtime, for some event. You can also use scene objects or any display object, like display groups, for example.

So, if object B needs to listen for events fired for object C, and D listens for events fired by objects A and B, they can. They are not attaching function calls to another object; They are simply listening for events being fired - it doesn’t matter what they are being fired by. This is a change in perception by how the system is setup, not by the relationships between objects. Part of this is “de-coupling.”

Now, take this a step further and look at the system objects or demo samples in the Corona folder. You can see that the widget library has objects which receive touch events, for example. They don’t care what needs to be told that the touch event occurred and that some function somewhere needs to be called - they simply provide a mechanism to let another object attach a callback function or fire an event themselves and let whatever else in the system listen for that event.

The key to understanding the architectural problem here is to think, “What if each thing in my application did not rely on anything else? What if every single user interface object and game/app object existed in a world of it’s own and did not - must not - rely on any other object?”

Start from that point and you’ll realise two major things: First, you’ve probably got a lot of re-writing/structuring to do and, second, that you have just realised how to simplify the architecture and make a lot of your code re-usable (because it won’t be innately tied to other pieces of code.)

Hit me back if you need anything clarifying, but before you do I highly recommend that you post some boiled down sample code - that in itself (boiling) might lead to some useful realisations, too.

Hi.

I mentioned an idea which I use, in this thread: two modules require each other

In any situation where I couldn’t cleanly restructure it, my needs were asymmetric: side A needs side B’s stuff right away; for side B it isn’t so urgent, but it’s still convenient to get everything ready. This is probably not generally true, of course.

hi Horace and StarCrunch, thank you for your excellent response and excellent response time! :slight_smile:

HoraceBury, are you referring to “custom events” as described here:

https://coronalabs.com/blog/2012/06/26/how-to-use-custom-events-in-corona/

I was wondering about that, but for some reason I thought I could only add these to displayObjects. Can I add them to any variable, table or instance of an object?

If so then yes, that does fix my problem and empowers my code tremendously, I might think! So in essence, if I am no mistaken, then I can just have my touchController dispatch an event, and have my gameEngine listen for it? That would be very cool - although I would then really like a better understanding of how the timing of events etc… fits into the frame-loop…

My second thought: maybe I should just make gameEngine.lua global :smiley:

Yes

Don’t make it global.

Awesome! Thanks! Both your long and your short answers are helping me out immensely!!!

Busy checking this a we speak. As I vaguely remembered it turns out this only works with displayObjects or Runtime, so unfortunately not with custom classes or instances.

So, one more question, Horace: am I correct in assuming that I just use the Runtime as the mediator?

It does work in my case: my touchController fires an event to the Runtime, which listens for this event and can, in turn, instruct my gameEngine to do something. Too bad this doesn’t work for classes directly!

Often you can use the Runtime, maybe use the scene object. But if you have an interface object created by a function, other things in your scene can listen to it for user input events (or the result of them, anyway.)

Thanks for the info, HoraceBury! This is awesome stuff to be honest. I spent some time playing around with this yesterday evening and fixed my troubles pretty quickly.

I don’t use composer or director so the scene object is of little use to me, but most of my classes contain a main displayObject so I guess I can hook some stuff to this displayObject as far as events go, and then have it call a function in its super.

Tres cool!

Your solution that you warn against (because of simplification) is in fact, in simple terms, the only solution. The problem you face is the same problem of coders since time (of coding) began. A better way to understand your solution, and therefore your problem, is just to describe in a different way. Let me explain…

You want two (or more) units of code to reference each other. While it is not impossible for that to happen (double-linked lists do this, for example) what you are trying to force is where the code execution dives deeper into itself at each iteration (in your case, a user’s touch on the interface) and this will eventually cause an infinite loop, stack overflow and, finally, memory exceptions (if the stack overflow doesn’t kill it first.)

The solution is, as you’ve already mentioned, to use listeners. The confusion comes by how to set them up, not by their linkages.

So, and this will be somewhat general because you’ve not provided any code, lets say that module A, B, C and D all refer to each other. That’s impossible. But it can be done. Fortunately, module A is - in your case - the main.lua code, so we’re safe here.

Modules B, C and D all get loaded by module A with require statements. One approach is, in module A, to call a function which let’s you register the other modules with each module. So, first load them all, then tell each one about the others. This works, but it’s not elegant because you can still end up creating infinite loops, stack overflows and the like.

The better solution is, in simple terms, to have each module listen to some object in the system, let’s say Runtime, for some event. You can also use scene objects or any display object, like display groups, for example.

So, if object B needs to listen for events fired for object C, and D listens for events fired by objects A and B, they can. They are not attaching function calls to another object; They are simply listening for events being fired - it doesn’t matter what they are being fired by. This is a change in perception by how the system is setup, not by the relationships between objects. Part of this is “de-coupling.”

Now, take this a step further and look at the system objects or demo samples in the Corona folder. You can see that the widget library has objects which receive touch events, for example. They don’t care what needs to be told that the touch event occurred and that some function somewhere needs to be called - they simply provide a mechanism to let another object attach a callback function or fire an event themselves and let whatever else in the system listen for that event.

The key to understanding the architectural problem here is to think, “What if each thing in my application did not rely on anything else? What if every single user interface object and game/app object existed in a world of it’s own and did not - must not - rely on any other object?”

Start from that point and you’ll realise two major things: First, you’ve probably got a lot of re-writing/structuring to do and, second, that you have just realised how to simplify the architecture and make a lot of your code re-usable (because it won’t be innately tied to other pieces of code.)

Hit me back if you need anything clarifying, but before you do I highly recommend that you post some boiled down sample code - that in itself (boiling) might lead to some useful realisations, too.

Hi.

I mentioned an idea which I use, in this thread: two modules require each other

In any situation where I couldn’t cleanly restructure it, my needs were asymmetric: side A needs side B’s stuff right away; for side B it isn’t so urgent, but it’s still convenient to get everything ready. This is probably not generally true, of course.

hi Horace and StarCrunch, thank you for your excellent response and excellent response time! :slight_smile:

HoraceBury, are you referring to “custom events” as described here:

https://coronalabs.com/blog/2012/06/26/how-to-use-custom-events-in-corona/

I was wondering about that, but for some reason I thought I could only add these to displayObjects. Can I add them to any variable, table or instance of an object?

If so then yes, that does fix my problem and empowers my code tremendously, I might think! So in essence, if I am no mistaken, then I can just have my touchController dispatch an event, and have my gameEngine listen for it? That would be very cool - although I would then really like a better understanding of how the timing of events etc… fits into the frame-loop…

My second thought: maybe I should just make gameEngine.lua global :smiley:

Yes

Don’t make it global.

Awesome! Thanks! Both your long and your short answers are helping me out immensely!!!

Busy checking this a we speak. As I vaguely remembered it turns out this only works with displayObjects or Runtime, so unfortunately not with custom classes or instances.

So, one more question, Horace: am I correct in assuming that I just use the Runtime as the mediator?

It does work in my case: my touchController fires an event to the Runtime, which listens for this event and can, in turn, instruct my gameEngine to do something. Too bad this doesn’t work for classes directly!

Often you can use the Runtime, maybe use the scene object. But if you have an interface object created by a function, other things in your scene can listen to it for user input events (or the result of them, anyway.)