The code is too lengthy to post as it encompasses an entire GUI framework, so, for brevity, I'll try to summarize. I essentially separate the event thread from the rendering thread. The application requires video playback, so this setup obviously prevents the rendering side from hanging in response to lengthy events.
Texture loading, sprite creation and positioning are handled within the event thread. A collection of sprites is created to be displayed by the rendering thread. To emulate browser-style behavior, sprites are added and removed based upon desired content. The event thread creates a new collection, unknown to the rendering thread, and upon completion is assigned to an active sprite collection known to the rendering thread. Only one synchronization context is needed, so I don't believe there is anything related to thread synchronization that I've overlooked.
Image rendering is always fine; however, font rendering using the Text class results in missing characters. This behavior is not permanent and seems to manifest itself, consistently, when the application is first displayed. I've attached a screenshot of the affect. The item displayed should be '10 Years'; however, the '0' is missing.
When executing everything from a single thread, the issue is no longer present. It's definitely a threading issue, but I'm unable to fix the problem.
This is a sample for creation of display text (event thread):
protected Text CreateDisplay
( ) { Text displayText
= null; string text
= this.Item.Text; if (!string.IsNullOrEmpty(text
)) { displayText
= new Text
(text, font
); displayText
.CharacterSize = (uint)((this.Location.Height / 3
.0f
) * 2
.0f
); while ((displayText
.CharacterSize > 1) && (displayText
.GetLocalBounds( ).Width > (this.Location.Width - 40))) { displayText
.CharacterSize--; } displayText
.Color = new global
::SFML.Graphics.Color(255,
255,
255,
150); float xMid
= this.Location.X + (this.Location.Width / 2
.0f
); float xMid2
= displayText
.GetLocalBounds( ).Width / 2
.0f
; float yMid
= this.Location.Y + (this.Location.Height / 2
.0f
); float yMid2
= displayText
.CharacterSize / 1
.5f
; displayText
.Position = new Vector2f
(xMid
- xMid2, yMid
- yMid2
); } return displayText
; } And this is an example of rendering (rendering thread):
internal virtual void Paint( )
{
lock (this.PaintSynch)
{
if (this.IsLoaded)
{
if (this.BackgroundSprite != null)
{
this.ParentWindow.InternalWindow.Draw(this.BackgroundSprite);
}
if ((this.CanActivate) && (this.ActiveSprite != null) && (this.ParentWindow.ActiveControl == this))
{
this.ParentWindow.InternalWindow.Draw(this.ActiveSprite);
}
if (this.IsMouseOver && (this.OverSprite != null))
{
this.ParentWindow.InternalWindow.Draw(this.OverSprite);
}
if (this.DisplayText != null)
{
this.ParentWindow.InternalWindow.Draw(this.DisplayText);
}
}
}
}