Saturday 29 August 2009

Scene graphs? Yuch!

So one of my friends has been nagging me for some time to start on the graphics library I have been planing on writing for a few months now. Always had other work I needed to do first. But now I'm all done with that, and I can finally start on it.

I was thinking about how the scene system would work, and how different behaver would be added to different entities (ok, that's more an overall engine design point, rather than graphics, but meh), and I can't for the life of me figure out why so many people try to do this through inheritance. It's like the idea of inheritance has been so ingrained in people as A Good Thing, that it's heresy to do anything else.

But it makes things so hard. Imagine, say, you have a DrawableEntity class. From this you inherit a NpcUnit class. Now you want to add some AI. As you probably want all NPCs to have some AI, you could stick that in between Drawable and Npc. Alright so far.

Now lets say you have a door, which you make inherit off DrawableEntity.
One of the characters in your game is a talking door. It has the characteristics of a door, and it has AI. What do you do now? You could have Door inherit from AIUnit instead, but now all doors have AI..

The solution is to use composition. Have an Entity class, which contains a collection of EntityComponents, each of which represents a piece of functionality which you want to add to the entity.

As I was searching the net for what other people had done with this, I stumbled upon a post from Nick Gravelyn, in which he talks about such a system. Except that in his implementation, any components which have properties which return another EntityComponent type, his entity will automatically hook it up with an instance of that type if it has one available in its components collection.

I loved his implementation, and decided that I would use that, but with one addition.

As I was thinking about how my graphics library would handle the scene graph at the time, and how so much of a bad idea scene graphs are, I thought I would modify Nicks entity system so that it could fully operate as a scene graph replacement.

All that needed adding was the idea of each EntiyComponent type defining a manager to manage its instances. For example, when a PositionComponent is added to an Entity, the entity will stick the component into a manager dedicated to managing PositionComponents. This manager could implement a tree to show parent/child spacial relationships (like a swords' position being relative to the players' hand). On the other hand, a StaticDrawableComponent would register itself with a manager which places it into an octree, for efficient visibility determination.

And there you go, we are no longer trying to stuff many entirely different relationships into the same, messed up convoluted, tree.

Sunday 23 August 2009

ParallelTasks, Multithreading on Xbox

I think I'll start off by releasing a project I've been working on the past few weeks.

I'm sure you have all by now had a look at the new Parallel Extensions (ParallelFX) coming with .net4.0 and VS2010. At its core, it's a multi threaded work scheduler, in a similar vein to the ThreadPool, however extended with a rich API and much better scaling as the number of cores is increased.

I would have loved to simply use this library on all my projects, but unfortuneately it does not seem that they will release this for the Compact Framework on the Xbox360. So no multi-threaded Xna games :(. Even if they do port it, their system creates many many allocations, which can be catastrophic with the CF non generational garbage collector.

Fortunately, I love writing parallel code, so I had a go at writing my own (albeit cut down) version of it.
I'm going to upload it along with all the source code, and I can only hope if anyone else decides to work on a similar project in the future, they may learn something here.

I had a few requirements:

  1. Must support task parallelism.  The user must be able to tell the system to go off and do a unit of work, and come back later to check that it has been done.
  2. Must support data parallelism. I wanted the user to be able to do loops where each iteration may occur in parallel with others, so that they could do very fine grained parallelism where potentially every piece of data could be executed on another thread.
  3. Must compile on the Compact Framework. The whole point of this is so I can use it on the Xbox. This turned out to present many problems, as there are quite a few synchronisation primitives missing, such as Monitor.Pulse..
  4. Must cause minimal heap allocations. It's no good if each task scheduled allocates new objects. The xbox does not have a generational garbage collector, and allocating while the game is running can cause terrible framerate hickups each time the GC kicks in.

The scheduler works around executing IWork items as fast as it can across all available cores. In return for scheduling an item, you get given a Task struct. This struct will contain methods for waiting for a task to complete, as well as properties to check on the status of a task. New heap allocations are not made for each work scheduled.

You can schedule tasks from the static factory methods in the Parallel class, a la ParallelFX. There are methods to start new IWork items, as well as overloads which accept delegates, and a couple methods for executing loops in parallel.


// schedule a new task to do the work Foo
var task = Parallel.Start(Foo);

// Loop over a collection and do some processing on each item, in parallel
Parallel.For(0, items.Count, item => item.Bar());

// Wait on the task, so we can continue knowing that it has finished from this point on
task.Wait();


Here are the xna game library projects. I might a bit about how some of it works in future posts. Hope it's useful to someone.

Hello!

Well, this is new to me. Never done anything like a blog before. *pokes arround the blog settings page*.. gotta love settings pages, the more the better I say!

Going to be posting about any projects I'm working on, hopefully if anyone else tries to do something similar again, they can find some nice hints here.

Now, I just need to learn how to write.