tags:

views:

116

answers:

4

Hey guys,

I need to display some stats, numbers, and graphs about various game objects on the screen.

(examples: camera position, field of view, frames per second, fill rate, number of objects culled, etc... )

Currently any object which wants to be graphed or displayed implements an interface along these lines:

public interface IGraphable
{
    float GraphableValue { get; set; }
}

Then that object can be sent to a graph component to be displayed. This has some obvious drawbacks like not being able to graph 2 different pieces of data which belong to the same class.

What I want is a way to pass a pointer to where the data is located or a pointer to a function which knows how to return the data instead of passing the object to the display component.

I believe that this is what delegates are for but I don't understand how to use them in this context (Actually I don't understand them very well at all). Also, is there another (smarter/better) way to do this?

Thanks!

A: 

Depending on how you're doing things, you could possibly use Reflection (attributes on accessors), although that can be relatively confusing at first too. But it's a very useful tool in your arsenal, so it's well worth spending the time on. Here is a great tutorial on how to use them:

http://www.brainbell.com/tutors/C_Sharp/Attributes.htm

But then, learning delegates is also very useful, and that does sound like a good solution. I haven't looked deeply into it, but this tutorial on the same site might be useful:

http://www.brainbell.com/tutors/C_Sharp/Delegates_and_Event_Handlers.htm

Smashery
Thanks for the link! I will look into it. However, I have heard that reflection is very slow. Is this true? (I understand that slow is a relative term)
Arriu
Yeah, I'm not sure about speeds of reflection. My guess would be that it's not as fast as just calling a method (as delegates would let you do). You probably wouldn't want to be using reflection if it's going to be called a million times a second. But I could be wrong ;-) I don't spend a heap of time using them.
Smashery
+1  A: 

Why not invert the control like this:

public interface IGraphable
{
    void BuildGraphable( IGraph g );
}

interface IGraph {
    void AddValue( double value );
}

this is a preferred option in OO anyway as it hides details of the IGraphable implementation. Additionally you can now extend IGraph for added functionality without breaking compatibility.

csharptest.net
I actually had it this way before. I changed it because every graph component can have its own update frequency (lets say 7 times per second). If the graph component were updated by the IGraphable class I would not be able to have an independent update frequency for the graph component. (for example a camera may be updated 60 times per second but the graph showing field of view (lol at graphing "field of view") may not need to be updated that often...)
Arriu
You call method 60 times a second, or ask for a property 60 times a second, there isn't a difference. One gives you the potential to collect several pieces of data, while the other returns just one.
csharptest.net
there is a difference, it wastes computation by adding or updating the value.
Arriu
A: 

I have decided to do the following:

public class GraphComponent
{
   private Func<flaot> _function;

   public GraphComponent(Func<flaot> function, ...)
   { ... }
}

This allows me to specify how the data is retrieved by writing something like this:

FPSComponent fpsc = new FPSComponent();    
GraphComponent fpsg = new GraphComponent(delegate() { return fpsc.ApproximateFPS; }, ...);
Arriu
A: 

What I want is a way to pass a pointer to where the data is located or a pointer to a function which knows how to return the data instead of passing the object to the display component.

If you don't want to add your objects to your graph component BECAUSE

This has some obvious drawbacks like not being able to graph 2 different pieces of data which belong to the same class.

Maybe a list will solve your problem ?

public interface IGraphable
{
    List<float> GraphableValues { get; }
}
Jodi