It keeps loaded content in a dictionary and first checks in there when loading. Additionally it will call Dispose on disposable assets when they are unloaded.
The dict is not used in a thread safe way, so be careful with that.
I’m loading almost all the content from a new thread and it works very well. The content I load in LoadContent() is the content needed to show a “loading screen”.
protected override void LoadContent()
{
// Load the rest of the assets
var thread = new Thread(LoadGame);
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
private void LoadGame()
{
// Textures
monoGameLogoSquareTexture = Content.Load<Texture2D>("monoGameLogos/SquareLogo_128px");
enemyTexture = Content.Load<Texture2D>("enemy");
inventoryTexture = Content.Load<Texture2D>("inventory");
inventorySelectedItemTexture = Content.Load<Texture2D>("inventorySelectedItem");
powerUpsBackgroundTexture = Content.Load<Texture2D>("chances/powerUpBackground");
}
I had to specify the thread.SetApartmentState(ApartmentState.STA) because I need to copy some text in the clipboard in some circumstances.
You have few items to load, so it currently works because the thread is faster than the part asking for a loaded resource, but what happens if your LoadGame() method takes 10s or more ?
I think it is missing a synching mechanism.
Something like a Manual or AutoResetEvent at the end of LoadGame() to signal the main thread it has finished its job.
@Alkher, I don’t need a synching mechanism because I’m using a screen system and I change the screen to the main menu screen at the end of LoadGame(). I’ve simulated a long time (50 seconds) load with Thread.Sleep() in the LoadGame() method and it works as expected.
And I’ve much more resources to load, sounds, songs, spriteFonts, etc. I just shown here a small piece of code to show the idea.
I think that @raizam will probably need a synching mechanism.
This makes threading in Monogame easier.
I’ve created a TaskManagerComponent, which is a regular GameComponent, this is used like this:
//In your game class
Color clearColor = Color.CornflowerBlue;
protected override void Initialize()
{
TaskManagerComponent taskManager = new TaskManagerComponent(this);
Components.Add(taskManager);
taskManager.ExecuteInBackground(() =>
{
Thread.Sleep(2000);
//ThrowIfNotInGameThread(); //this throws here
return Color.Aqua;
}).Then(task =>
{
ThrowIfNotInGameThread(); //Here we are back in the game thread, inside Update()
// 'task' is a Task Parallel Library result instance: Task<Color>
clearColor = task.Result;
});
base.Initialize();
}
He just put that there to show that the code runs in the main game thread. When the GameTasks internal task finishes it puts the ‘Then’ task in a queue in its TaskManagerComponent. When Update is called on the TaskManager (on base.Update in Game through the component stuff) it executes whatever is in that queue (on the same thread).
I don’t know where you’ve read that, but in fact… GameComponents are awesome
It encourages separating logic in small units that each have its own role, and each of these behavior can be added or removed depending on the need, hence this helps reusability.
The concept of Separation of Concerns is the key of a good architecture.
As Jjagg points out, this is just to prove that the result of the background operation is passed back to the game loop: because no exception is thrown, it passes the test. This means we are safe with synching concerns. The only thing you can do wrong here is to use instances that belong to the game thread inside ExecuteInBackground, don’t do that =)
Not sure how he got 20 votes, his points aren’t convincing, and his examples are futile. This contracdicts what’s currently happening in the software industry. The history of software architecture is quite young, the evolution could be pictured as: spaghetti -> lasagna -> ravioli
When I started my career, we were told that the lasagna architecture was the best, (N-Tier architecture)…
But in practice everyone realized the lasagna approach is not so efficient, too many layers and it was too much maintenance. Then the ravioli (Components) approach emerged, and this is AFAIK still the dominant paradigm today.
Unity is massively based on component, and it looks like it’s working well, they could build a big ecosystem, everyone is using components made by others, and everything is pluggable. I haven’t tried UE4, but I’m pretty sure it has a component-based architecture too.
So, what this guy say is not what’s happening in ‘the real world’ as he says.
@vcRobe in the stackexchange link you’ve provided, there is another answer contradicting the accepted one, which has more vote. Since you believe whoever has votes, maybe he can convince you
There is an old thread from 2007 in the Ogre forums about components: http://www.ogre3d.org/forums/viewtopic.php?t=36015. This is pretty much when the Component pattern started to be a thing, that’s an interesting read.