1
\$\begingroup\$

so following situation. I have a project which is structured something like this.

Game1 -> GameManager -> Module (multiple instances)

During runtime units are being spawned in each instance of the Module class. Those Units require spritesheets for animation. Let us say each unit has a "Move", "Attack" and "Die" state, each using a individual spritesheet. This makes three Texutre2D instances per unit and with 5 different units this adds up to 15 different Texture files. Those are being passed to the unit's constructor on creation.

As I am loading those textures in Game1's LoadContent method I have to pass them the entire way to the Module class which then uses those textures to instaciate units.

Game1.LoadContent(15x textures) -> GameManager(15x textures) -> Module(15x textures) -> Unit(3x textures)

Imo this has several disadvantages:

  1. As far as I can judge all those 15 textures are being held in memory of the Module classes the entire time. I would like to avoid that.

  2. Also passing 15 textures through the project's entire structure makes the classes unreadable and ugly.

  3. I've got the overall feeling that this is not the way things should be done here.

In order to avoid problem #2 I created a class, its only purpose is to hold all textures that are needed in Module.cs. I called the class AnimationCollection. It holds Texture2D variables and the according getters and setters. So now my Project looks like this.

Game1.LoadContent(new AnimationCollection(15x textures)) -> GameManager(AnimationCollection) -> Module(AnimationCollection) -> Unit(AnimationCollection)

While this does seem to solve problem #2 the other problems remain. Are there other options on how to handle this problem? I could think of something like loading all content in the Module Class itself, but I never saw this before. I always load my stuff in Game1.LoadContent().

Any ideas, suggestions or expert knowledge is highly appreciated.

Thanks in advance!

\$\endgroup\$
  • \$\begingroup\$ This is most likely decision what is lesser evil - Global static object(/singleton) or repetitive dependency injection? \$\endgroup\$ – wondra Jan 29 '15 at 11:53
2
\$\begingroup\$

It is possible to just pass the Content Manager to your modules, and have them load their own textures/data. Its also tidier, as the Module is responsible for loading its own textures, and doesn't have to depend on its resources being loaded elsewhere.
I do something similar - my data objects have a string specifying a texture/model, and my rendering code uses that string to load the corresponding texture/model via the ContentManager when an object is being drawn. Essentially, my rendering class uses the textures/models, so its responsible for loading them. The data objects just tell it what ones to load.

Also, Texture2D is a class, which means its passed by reference by default. Only the ContentManager actually holds the Texture2D itself, and your modules hold a pointer which refers to the memory location the Texture2D has been loaded into. So despite having 15 pointers across your unit classes, there is only one instance of each texture through your program (unless you have 2 identical textures which different filenames loaded individually). The ContentManager also caches all content files it loads, so trying to load an already loaded file returns the one it loaded earlier.
Sadly, there is no way to remove individual textures from the ContentManager - you unload all content, or none.

The above summarized & answering your questions:

  1. The ContentManager loads all your textures into memory, your modules just have a pointer which references the loaded texture. There isn't duplicates unless you load 2 identical but differently named files.
  2. Yep. Its easier to just have your modules load there own textures, not to mention its tidier and your modules don't have to rely on something else loading its textures - it has control when it comes to loading.
  3. Yep. What you current have is not the best way to do it in my opinion. You can do it what way, but I feel there are better ways. In the end it boils down to what you're comfortable using, and what you feel is best.
\$\endgroup\$
  • \$\begingroup\$ This means that having like 100 units on screen which all use the same animation would not be a performance issue due to memory. As long as all animations have their origin in a single Context.Load<Texture2D>() call? \$\endgroup\$ – チーズパン Jan 29 '15 at 11:17
  • 1
    \$\begingroup\$ Not necessarily. You could have multiple Context.Load<Texture2D>() calls across your code loading the same file. The first one called would load the Texture2D and give you a reference to it, all subsequent ones would return the reference to the loaded file in memory. Your 100 units would just all reference the same 15 textures, regardless of how many times you call Content.Load<Texture2D>() \$\endgroup\$ – Seta Jan 29 '15 at 17:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.