Sign in to follow this  
venzon

Unity Question about how to achieve loose coupling

Recommended Posts

I read through this forum post about singletons: http://www.gamedev.net/community/forums/topic.asp?topic_id=449054 ... and it made me wonder if there's a simple design pattern that would allow for looser coupling than my current favored architecture: In my game engines, I usually have a GAME class that contains members of a number of sub classes. As a simple example, let's say my GAME class contains a public member of the OBJECTS class and a public member of the SOUND class. The OBJECTS class stores all of the objects in my scene and takes care of object loading, creation, etc. The SOUND class stores all of the sound buffers and sources in my game and takes care of loading, source creation, etc (multiple sound sources can have the same buffer). I want my OBJECTS to be able to talk to the SOUND class such that it can create a new sound source, configure the sound source's parameters (such as volume, buffer, etc), and store a pointer so it can update the source's position, play, stop, etc as the object moves around the scene. The way I currently have things set up, I instantiate a global GAME class in my main.cpp. In my objects.cpp, I #include "game.h" and declare "extern GAME game". When an object is created in OBJECTS::CreateObject(), I do a game.sound.NewSource() to access my sound class and get a reference to my new source. The memory for the source is managed inside the SOUND class. I'm doing this all over the place in my game engine where something needs to talk to something else (the font class needs to talk to the texture class, the objects class needs to talk to the meshes class, etc etc). I've had people advocate using singletons instead, but I disliked the idea, and the forum topic at the link above seems to confirm that they're not a good solution. I think I've got enough detail now to ask my main question: is there a better way to do this that allows looser coupling and more modularity? This has proved to be a pretty good solution, however it has a global GAME object and relies on an extern statement. I'm worried I might be making an architectural blunder without realizing it. Thoughts??

Share this post


Link to post
Share on other sites
What's wrong with just passing references to the sound/font/whatever system into the object classes so they can use them like that? You don't need a big over engineered framework, just pass things into the bits that need them as appropriate. Or is that not "sexy" enough? [rolleyes]

The obvious (and flawed) rebuttal is "but I'd need to pass the sound system everywhere!". Except that actually when you get down to it you really don't. Reliance on a global has made you and your code depend on it being used everywhere, but thats not how it should be.

However things aren't as bad as they seem. If you actually get over the initial fear and start making the changes you'll find it surprisingly easy. Even though it feels like certain objects are being used everywhere, often it's much narrower than you think. And those uses that are remaining can probably be either refactored out or are acceptable dependancies.

Share this post


Link to post
Share on other sites
I see your point. The function that would need the references passed would be, in this example, object loading. So the game would call the OBJECTS::LoadSceneFromFile(string filename) function, but it'd have to pass the SOUND class, PHYSICS class, MESHES class, TEXTURES class, etc. A bit messy, but it would be restricted to only one area. Hmm.

Share this post


Link to post
Share on other sites
Quote:
Original post by venzon
I see your point. The function that would need the references passed would be, in this example, object loading. So the game would call the OBJECTS::LoadSceneFromFile(string filename) function, but it'd have to pass the SOUND class, PHYSICS class, MESHES class, TEXTURES class, etc. A bit messy, but it would be restricted to only one area. Hmm.


First, you should get your vocabulary straight.

You don't pass classes. Unless, of course, you're using a language with reflection, such as Java or C# or (shudder) PHP, and you're passing around the type itself. In most applications, you pass around class instances. Of which there can, of course, be more than one.

So, you'd have to pass one of the SOUND class instances to that function. Which sounds pretty normal to me, since you need to specify how the scene will be able to play sounds.

Share this post


Link to post
Share on other sites
Quote:
Original post by venzon
I see your point. The function that would need the references passed would be, in this example, object loading. So the game would call the OBJECTS::LoadSceneFromFile(string filename) function, but it'd have to pass the SOUND class, PHYSICS class, MESHES class, TEXTURES class, etc. A bit messy, but it would be restricted to only one area. Hmm.

What about passing a mediating structure between these class instances, something like:


void GAME::loadSceneFromFile(string fileName);
{
SceneInfo sceneInfo = ObjectManager.getSceneInfoFromFile(fileName);

SoundManager.create ( sceneInfo.getSoundData() ); //SoundManager is an instance of SOUND
PhysicsManager.create ( sceneInfo.getPhysicsData() ); //PhysicsManager is an instance of PHYSICS
MeshManager.create ( sceneInfo.getMeshData() ); //MeshManager is an instance of MESHES
TextureManager.create ( sceneInfo.getTextureData() ); //TextureManager is an instance of TEXTURES
}

This way none of the other subsystems know about anything else other than a structure detailing what it is they're supposed to be creating.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this