Original Post
Hello all, I'm trying to decide what is the 'best', or 'cleanest', or 'most future-friendly' method of handling inter-module communication in my game. Currently, I've got two queues set up: one queue is for incoming network communication, and the other is for application-module communication. All queues are thread-safe. The way the engine works, when the network client thread is invoked, it begins collecting incoming packet events, and tossing them on the packet queue. The main application loop is responsible for inspecting the network queue, popping one packet event per frame, and handling it. The main application loop is also responsible for inspecting the application event queue, and handling these events as well. The network client only talks to the packet event queue. The application event queue is a singleton (gasp!) which may be invoked from any other module (graphics, sound, input, etc) in order to enable each module to create its own events. For example, when the player does pretty much anything in the game, either one of the input modules (mouse or keyboard) must work in cooperation with the graphics module (which has sub modules, the work-horse of which is the scene manager) to determine the object(s) the player wishes to interact with, then send a request via the network client (directly, no queue touching) to the server. A problem I've encountered is the difficulty of utilizing class members cross-module. In the above example, if the player clicks the mouse cursor, the engine must (a) determine the 3d coordinates in the world that the player clicked, (b) perform a raycast to determine the scene object affected, (c) send the click request to the network client as a use/examine/take/invoke command, with the object's ID. In this example, three different modules need to communicate (in order, Input, Scene, and Network). As I write this, I'm seeing different ways of handling this, and I think I need to spend more time working on my SDL flowcharts to figure out the flow of events for each command-type. In short, I'm not sure whether I should: 1) Make everything singletons, and do away with queues entirely. Involves engine overhaul. 2) Make the network client a singleton, and expose as much of each module as need be to each other module (through passing of module-object instance pointers at allocation time). Most attractive. 3) Add a 'destination' value to application events, which helps me determine what the ultimate destination of the event is. Pursue #2. Could be confusing, and sounds like it's prone to bugs. 4) Expand on my application events, such that there is no need for #3. Stick with #2. Might also involve expanding the packet event protocol, since there are events there too that are used for incoming and outgoing. 5) ???? I'd like to hear how anyone else might have gotten themselves out of such a situation. I've come to the conclusion, based on vocalization of nay-sayers, that singletons are an F-word around Gamedev. I'd appreciate to hear alternatives, if anyone needs to point out that their usage is baneful to the existence of Mankind.