I'm trying to build a button that displays a loading circle and loads some data in a C# application.
I have a boolean value called Loading
that tracks the state of the current data that is being loaded.
I have a delegate called LoadHandler
that returns a boolean value based on whether the loading is complete or not, I also have an event that can be subscribed to in a separate class that takes the LoadHandler
signature and handles the actual loading.
I have a private Load()
function that gets called when an event handler for input is called in the base class, this is called on a new Thread
.
Here's the code for the LoadEntry
class (Keep in mind this is just a button that displays a loading circle when hit, and delegates loading to a separate class)
public class LoadingEntry : ButtonEntry
{
private readonly object objLock = new object();
/// <summary>
/// The loading circle texutre
/// </summary>
Texture2D loadingReticle;
/// <summary>
/// Tracks the rotation of the loading reticle.
/// </summary>
float loadingRotation;
/// <summary>
/// Tells whether we are loading or not
/// </summary>
public bool Loading { get; private set; }
public LoadingEntry(string buttonText)
: base(buttonText)
{
}
/// <summary>
/// Handler that will return true when loading information is complete
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <returns>True if loading is complete</returns>
public delegate bool LoadHandler(object sender, EventArgs e);
/// <summary>
/// The LoadHandler event that should be subscribed to in a menu class
/// </summary>
public event LoadHandler onLoad;
private void Load()
{
if (onLoad != null)
{
lock (objLock)
{
Loading = true;
while (true)
{
Loading = onLoad(this, EventArgs.Empty);
if (!Loading)
break;
}
}
}
}
protected internal override void OnSelectEntry(PlayerIndex playerIndex)
{
Thread t = new Thread(new ThreadStart(Load));
t.Start();
base.OnSelectEntry(playerIndex);
}
public override void Draw(MenuScreen screen, bool isSelected, GameTime gameTime, bool fade)
{
if (Loading)
{
loadingReticle = screen.ScreenManager.LoadingReticle;
Vector2 origin = new Vector2(loadingReticle.Width / 2, loadingReticle.Height / 2);
loadingRotation += 0.01f;
screen.ScreenManager.SpriteBatch.Draw(loadingReticle, position, null, Color.White, loadingRotation, origin, 1f, SpriteEffects.None, 1f);
}
else base.Draw(screen, isSelected, gameTime, fade);
}
The base class ButtonEntry
shouldn't be important.
And here's what is subscribed to onLoad
in another class: (just for practice, this is where actual loading code would go)
int sampleTics = 0;
bool sampleLoad_onLoad(object sender, System.EventArgs e)
{
sampleTics++;
if (sampleTics < 1000)
return true;
return false;
}
My question is am I using mulit-threading properly? The code doesn't even display the circle, I haven't done much testing yet because i'm going to bed. Is the lock necessary in this situation? Is there a better way to do this that i'm not seeing?