LO's Sharp Devs

C# , XNA Game Development Blog. Intentionally more than only for game authors but for C# programmers in general.

Moje zdjęcie
Nazwa:
Lokalizacja: Poland

wtorek, 7 października 2008

[Coding] Debug Design

Designing basic debug channel.

Downloads:

Binaries: SharpDevs.Debug.zip

What I would like to cover first is having a standard debug routines. My intention was to have easy access to debug stream from anywhere in the code and centralized control of it's flow. Therefore I'd created that library I'm using in all other projects I'm creating. A singleton solution is obvious enough to use it for this purpose. So, therefore basic usage of the lib is just logging debug almost like using standard .Net routines:

SharpDevs.Debugging.DebugLogsSink.Instance.Log("Some debug message", SharpDevs.Debugging.ErrorSeverity.Debug);

SharpDevs.Debugging.DebugLogsSink.Instance.Log("Some debug message");


After importing SharpDevs.Debugging namespace it can be even more consistent. ErrorSeverity enumeration has several levels of seriousness (numbering from less to more serious):


  • Debug
  • Info, Info1, Info2, Info3
  • Warning
  • Error
  • Critical



I think that most of them are self explanatory, but only having several info* may raise some doubts. I intended them to setting different, not necessarily debug informations but also other messages that might be usable by central message flow to control whole application or to cover multi thread messages. Here is how debug sink is being used:

DebugLogsSink.Instance.MainLogOutput += new InvocationOfSeverityString(Instance_MainLogOutput);


And then inside Instance_MainLogOutput() method serve all coming messages. It's important that event handling is used here, so there may be set several different "readers" - each one dealing with different type of messages, for example:

private void ServeCriticalMessages(string text, ErrorSeverity severity)
{
if (severity == ErrorSeverity.Critical)
{
ShowErrorMessage(text, FormatCritical);
WriteMessageToFile(severity);
Application.Exit(); // in XNA eventually: myGame.Exit();
}
}


Such logging to file is common enough behavior that I decided this to be implemented in Sink. To start logging simply call:

DebugLogsSink.Instance.WriteDebugToFile(".\\debug.txt");


And to finish:

DebugLogsSink.Instance.FinishDebugFile();


There are several options that control how log is written:

MinimumFileWriteSeverity
- decides minimum severity of messages that will be written to the log.
InsertDebugHeader - if TRUE - header with date & time will be added on the beggining.

Such usage is quite obvious in general. But doing system that was build with several singletoned subsystems, and have expecting more that could be attached to the system as plugins, I'd decided to add some additional functionality:

All debugged objects (intentionaly singletons, but it shall also work for base classes of big trees of inheritance) shall implement IDebugLog interface:

public interface IDebugLog
{
/// <summary>
/// Returned pure debug messages
/// </summary>
event InvocationOfString LogDebugMessage;

/// <summary>
/// Returned Debug/error messages
/// </summary>
event InvocationOfSeverityString LogErrorMessage;
}


Therefeore only thing to start debugging it is to add simple line:
DebugLogsSink.Instance.AppendLogOutput(someSubsystem);

Of course that class shall implement working with these vents by implementing some OnDebugMessage() methods, but it's left for class creator on how he would deal with it.

To stop tracking subsystems simply call:

DebugLogsSink.Instance.Clear();

... that will detach all of them.

Library is free of use for noncommercial users. For commercial ones - I't easy enough to write some similar by themselves so I do not think they will come to buy it anyway :)

Komentarze (0):

Prześlij komentarz

Subskrybuj Komentarze do posta [Atom]

<< Strona główna