WEBLOGS :: Tucan Entertainment Developers Team

EXCELSIOR Projects

Core Library
Network Library
Toolset
Prelude
Stand-alone Server
TE GAME Engine
TE GFX Engine
TE SFX Engine
TE 3D Tools
Testapplication
TE GFX Engine is using

as its Renderer.

Bugzilla

Bugzilla-Database

GIT/SVN

GIT-Access
SVN-Access

RSS

Weblogs

Bloggers


Downloads

Primary Server
Secondary Server

Media

Screenshots

Support our Team

Archive

Weblogs (last 365 days)

Weblogs (RSS)

Weblogs (old)




Server Uptime:

February 02

Duncan Mac Leod: Threading Part 2 (**special**): CoRoutines, Microthreading and beyond...

Hi there, fellow Readers!

Today we'll continue our Threading series with a **special** blog-post. It's more about threading techniques apart from standard .NET Framework 'real' Threads.

I also don't want to handle code-examples, I want to talk about several techniques I am currently evaluating here at Tucan Entertainment, which may be implemented into our EXCELSIOR GameEngine in the future.

If you know the Unity3D Engine, you may know their (C# based) scripting technique 'Coroutines & Yield'. A very interesting concept. As I discovered these features for the very first time, I wondered WHY the statement is called 'yield' and how this magically works 'under the hood'. Of course, this kind of technique is very interesting for the ambitious Game-Developer ;-), so it would be great to get my fingers on such a piece of code...

Yesterday, I found the answer, looking on a IMHO very promising technique, called Iterator-based Microthreading. This technique, which is intended to run on a single(!!) Thread, embedded in our current multi-threaded environment (multiple task-oriented work-queues with schedulers, communicating across Threads via an intelligent Messaging-System) would be the icing on the cake :-D ! I am sure, we 'll implement it in the future, cause there are so many possibilities of usage, which will improve our Engine.

In addition, we are also currently evaluating Microsoft's new Parallel Extensions for the new upcoming .NET 4.0 Framework, which may also used by our Engine in the future, replacing / optimizing / supplementing some of our current techniques. I love the process of abandoning code in favor of new techniques coming available. Indeed, I hate it, really! It reminds me on our old EXCELSIOR Toolset, which we had rewritten from scratch five times :-( !

Another interesting approach are Mono's Continuations, which are so closely tied to the Runtime, that they are only available on Mono (Continuations won't run on MS .NET Framework).

I will refer to this Blog-Post later this year, when we have made decisions on our Final Engine-Design. As for now, I will leave it up to you, making the right conclusions, which technique(s) to use or to combine. Please mail me your thoughts if you'd like.

Posted at 8:37 PM

Duncan Mac Leod: Dragon Age: Origins - DLC Return to Ostagar


Here we are - back at Ostagar...
 
It's nice to have this DLC-AddOn to shorten the time till DA:O Awakenings is available (around 03/22/10).
 
Just bought it for Euro 3,49 (thx to the weak Dollar!)... - will play it through next weekend!

Posted at 3:11 PM

January 21

Duncan Mac Leod: Threading Part 1: CheckForIllegalCrossThreadCalls = false;

It's always funny on the Web. If it comes to Multi-Threading, there are sooo many wrong articles on the Net. Myths, rumors and wild guess can be found everywhere. I will write some blog-posts over the year, which will look behind the scenes and reveal some valuable information regarding Multi-Threading...

Don't get me wrong: I won't teach you how to write proper Multi-Threaded Applications! I'll only talk about 'borderline cases' and try to destroy some myths ;-) !

Today, we'll talk about using CheckForIllegalCrossThreadCalls = false;

Developing a Multi-Threaded Game-Engine and a Toolset for developing Games under .NET / C# is pure fun - believe me! Especially, if you want to use a C++ based Render-Engine, which should run (render) on its own Thread, but render (its output) to a managed Windows Form (or managed Control), which runs on the UI-Thread.

Just search on the Net for Multi-Threading + UI-Thread and you'll get some interesting articles as a result. Nearly every article speaks about: 'Never use a Control from a thread other than the UI-Thread (startup-thread).' - of course, it's not clever trying to use Controls from outside the UI-Thread as they ARE NOT THREAD-SAFE! Absolutely true!

(Managed) Windows Forms / Controls are single-threaded by Design, so you 'should' never access them from a Thread other they were created on (UI-Thread). 'Should' - I 've used 'should'!

I recommend to read Daniel Appleman's Book: Moving to VB .NET: Strategies, Concepts, and Code. Okay, it's 'old' and about VB.NET (not C# ;-) !), but it features an interesting chapter about .NET and Threading. These were the days (back in 2001) when the .NET Framework had been in its Beta-Test. And these were also the days of the Visual Basic coders, mainly developing Business Applications, which were easier and faster to develop using Visual Basic than C++. The VB coders could do nearly everything: accessing the WinAPI, using the MTS (huh! what's that? Microsoft Transaction Server ;-) ! ...or should I say COM+ Server? ...or better Application Server, for the younger ones among us?), etc.
But one big thing had been missing - the use of Multi-Threading! So, most of the former VB Coders eagerly awaited the release of the .NET Framework, to be able to write multi-threaded applications with VB.NET.
Mr. Appleman advises in his book to be very careful with threads and to not consider Multi-Threading as an all-purpose 'weapon' doing concurrent things (tasks) easily. You should really read it! IMHO, his 'warnings' were addressed to the 'normal' average VB Coder and were made to prevent them from using threads without the necessary understanding of what's really going on (under the hood).

Back to topic! Using the WinAPI (i.e. with C++) there are NO restrictions accessing Forms / Controls from different threads! And: using the 'old' .NET Framework 1.x, there is no such thing called 'CheckForIllegalCrossThreadCalls'! WTH has this been introduced in .NET 2.0?

I assume for the same reasons as Mr. Appleman has written his chapter. To prevent the 'normal' Coder from doing dangerous things w/o having the necessary knowledge!

But I don't want you to leave w/o providing you with the 'right' knowledge of how to write Responsive UIs with Multiple Threads by Ian Griffiths. A very helpful article and you should learn from it! As for me, I would design my UIs a 'little bit different' than shown in the article ;-) ... - but, it's really okay for Business Applications!

On to CheckForIllegalCrossThreadCalls = false;

You can and SHOULD use it! REALLY! But ONLY if you KNOW WHAT YOU ARE DOING and ONLY in scenarios WHERE IT SEES FIT! Forget the warnings about it and that MS has only put this in for debugging purposes.

In my personal example (rendering on a Control from a different thread) it's SAFE to use, cause I know (can make sure) that the Control is not accessed from the UI-Thread, ONLY from my Rendering-Thread!

I use it in the Constructor of my Control (not Form! - ...as I only want this control to be excluded from the checks!), like:

public Render3D_Panel()
{
   CheckForIllegalCrossThreadCalls = false;
}

It's a static property.

If you think I am wrong or had gone mad ;-), just write me a mail...

Posted at 2:45 AM

January 20

Duncan Mac Leod: How to draw your Controls - smooth and flicker free...

Hello friends!

This year I will post more nice how-to's - today I want to talk about drawing on Controls. I often see really bad made custom controls which flickers and don't show a smooth behavior.

Normally when a Control is rendered, 2(!!) Events are fired in order: OnPaintBackground, OnPaint

First we should disable OnPaintBackground completely:

protected override void OnPaintBackground (System.Windows.Forms.PaintEventArgs pevent)
{
   //do nothing
}

Now we need to set the correct Window Styles (should be done in the Constructor of the Control):

this.SetStyle(ControlStyles.DoubleBuffer |
             ControlStyles.AllPaintingInWmPaint |
             ControlStyles.UserPaint |
             ControlStyles.Opaque, true);

If you set no Styles, your Control does the following 'under the hood':

this.OnPaintBackground();
this.OnPaint();

If you are going to use Double Buffering on, it looks like this:

this.OnPaintBackground();
this.BeginUpdate();
this.OnPaint();
this.EndUpdate();

But if you turn on the AllPaintingInWmPaint style, we 'll get our desired result:

this.BeginUpdate();
this.OnPaint();
this.EndUpdate();

Keep in mind: If you are going to use AllPaintingInWmPaint, you will get a System.ArgumentException from System.Drawing.dll from time to time, which tells you that you 've used an Invalid Parameter. Obviously a Bug! You can avoid it by NOT disposing your Graphics objects; use private class members instead, like:

private System.Drawing.Font drawFont = new System.Drawing.Font("Tahoma", 9, FontStyle.Bold);
private System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.FromArgb(162, 173, 201));
private System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat();

[...]

private void Render3D_Panel_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.DrawString("Test-Text", this.drawFont, this.drawBrush, 30.0F, 30.0F, this.drawFormat);
}

If you have any questions, just mail me ;-)

Posted at 11:45 PM


 Tucan Entertainment's 'WEBLOGS' is based on 'Monologue' by the Mono-Project.   Disclaimer