I made a utility debug class in a C# game I'm working on to be able to monitor and watch values of properties. Goes like this:
public static class Monitor
{
private static List<object> monitoredObjects;
public static void Initialize()
{
monitoredObjects = new List<object>();
}
public static void Watch(object o)
{
monitoredObjects.Add(o);
}
public static void Unwatch(object o)
{
monitoredObjects.Remove(o);
}
public static void Draw(RenderWindow app)
{
//Not actual code, I actually draw this in game
foreach (object o in monitoredObjects)
Console.WriteLine(o.ToString());
}
}
public class Property
{
private object obj;
private PropertyInfo propertyInfo;
public override string ToString()
{
return propertyInfo.Name + ": " + propertyInfo.GetValue(obj, null).ToString();
}
public Property(object o, string property)
{
obj = o;
propertyInfo = o.GetType().GetProperty(property);
}
}
Now in order to monitor a property, say my game's FPS, I must do
Monitor.Watch(new Property(Game, "FPS"));
Wouldn't there be a way to somehow make this simpler to use? Ideally I'd like to be able to do
Monitor.Watch(Game.FPS);
But since we can't store pointers to value types in C#, I don't know how I would do this. Maybe using closures and lambada expressions? I was suggested this earlier but I'm not sure how to do it. Any other ways to improve this?
Thanks
Why are you not using INotifyPropertyChanged interface and just fire off the events within the Monitor class, something like this...assume your objects implement the interface...and every property in your objects raise a 'PropertyChanged' event with parameters indicating the values...in that way, it will be a fire and forget solution instead of looping through the list... as you call instantiate 'Monitor' with a 'RenderWindow' used as parameter to 'Initialize'. Also notice that 'Property' class is slightly modified to include a get accessor to return the object in question...
Hope this helps, Best regards, Tom.
Personally, what I would do is rework your Monitor class to accept a
Func<string>
as input, and return a monitoring handle that could be used to "unmonitor" the class.By doing that, you'd be able to write:
This could look something like:
You'd need to implement some interface for the handle - but this really could be anything, since it's just an object used as a hash table lookup for allowing unsubscription. You only need this to allow "Unwatch" to work, since you need to have some way to remove the delegate, which you'll probably want to define anonymously (as I did above).