Tuesday 25 October 2011

Reading binary data in C#

A few weeks ago I was trying to read binary data (e.g. a file) for a client application (to test a server application) and I struggled, there was no easy way of reading a file into a byte array, that I could think of.

A little bit of googling and I found this, which works pretty well, but it turns out that there is an inbuilt method into the framework: BinaryReader, which has the advantage of using exactly two lines of code, relevant code below:

   1 BinaryReader br = new BinaryReader(File.Open(@"c:\searchterms.txt",FileMode.Open));
   2 
   3 byte[] dgram = br.ReadBytes((int)br.BaseStream.Length);


I can now send the dgram array to my server application :)

Saturday 15 October 2011

2-D Simple Elastic collision using the XNA framework

Lately I've been having a look at XNA and I think it's really good or at least it's a very good way of getting started in game design. It's Microsoft doing what Microsoft does best, i.e. make life simpler for developers. I grabbed a sample to get me started and decided to have a look at a very crude of Brownian motion simulation or in layman's terms, a lot of balls randomly colliding with each other.

I decided to tackle elastic collisions first and ignored rotations, so this is really as simple as it gets in 2D. I won't go into details of the physics and I know that I could've used inbuilt XNA framework methods to do same operations that I do here manually (dot product, vector modulus), but it's good to have them written long hand, for portability to other languages.

Without further ado here's the code. Note that Ball is a class that defines a position (Vector2), velocity (Vector2) and mass (float). 

   1 private void EllasticCollisionPhysics(Ball ball1, Ball ball2)
   2 {
   3     //find normal vector
   4     Vector2 normal = new Vector2(ball2.Position.X - ball1.Position.X, ball2.Position.Y - ball1.Position.Y);
   5 
   6     //find normal vector's modulus, i.e. length
   7     float normalmod = (float)Math.Sqrt(Math.Pow(normal.X, 2) + Math.Pow(normal.Y, 2));
   8 
   9     //find unitnormal vector
  10     Vector2 unitnormal = new Vector2((ball2.Position.X - ball1.Position.X) / normalmod, (ball2.Position.Y - ball1.Position.Y) / normalmod);
  11 
  12     //find tangent vector
  13     Vector2 unittan = new Vector2(-1 * unitnormal.Y, unitnormal.X);
  14 
  15     //first ball normal speed before collision
  16     float inormalspeedb = unitnormal.X * ball1.Velocity.X + unitnormal.Y * ball1.Velocity.Y;
  17     
  18     //first ball tangential speed 
  19     float itanspeed = unittan.X * ball1.Velocity.X + unittan.Y * ball1.Velocity.Y;
  20 
  21     //second ball normal speed before collision
  22     float ynormalspeedb = unitnormal.X * ball2.Velocity.X + unitnormal.Y * ball2.Velocity.Y;
  23    
  24     //second ball tangential speed
  25     float ytanspeed = unittan.X * ball2.Velocity.X + unittan.Y * ball2.Velocity.Y;
  26 
  27     //tangential speeds don't change whereas normal speeds do
  28 
  29     //Calculate normal speeds after the collision
  30     float inormalspeeda = (inormalspeedb * (ball1.mass - ball2.mass) + 2 * ball2.mass * ynormalspeedb) / (ball1.mass + ball2.mass);
  31     float ynormalspeeda = (ynormalspeedb * (ball2.mass - ball1.mass) + 2 * ball1.mass * inormalspeedb) / (ball1.mass + ball2.mass);
  32     
  33     //Calculate first ball Velocity vector components (tangential and normal)
  34     Vector2 inormala = new Vector2(unitnormal.X * inormalspeeda, unitnormal.Y * inormalspeeda);
  35     Vector2 itana = new Vector2(unittan.X * itanspeed, unittan.Y * itanspeed);
  36     
  37     //Calculate second ball Velocity vector components (tangential and normal)
  38     Vector2 ynormala = new Vector2(unitnormal.X * ynormalspeeda, unitnormal.Y * ynormalspeeda);
  39     Vector2 ytana = new Vector2(unittan.X * ytanspeed, unittan.Y * ytanspeed);
  40     
  41     //Add Vector components to each balls' Velocity
  42     ball1.Velocity = Vector2.Add(inormala, itana);
  43     ball2.Velocity = Vector2.Add(ynormala, ytana);
  44 }

Wednesday 12 October 2011

Validation? We don't need no validation, part 2

Following on from my last post, I decided to give validation in WPF a go, with the added limitation that I could only use .NET 3.0 as we have a customer that has an n-1 policy and thus we are stuck with .NET 3.0 with this customer, but I digress. The application has a few textboxes and their content needs to be validated. There are two types of validation needed:
  • Time
  • Integer
For the first one, a Regular Expression will be used and for the second one, type checking will be used, in other words, any non-integer value will trigger a validation error. A class called, Parameters, that implements the INotifyPropertyChanged, is used to hold all the textbox values. This is the class definition:

   1 using System;
   2 using System.Collections.Generic;
   3 using System.Text;
   4 using System.ComponentModel;
   5 using System.Windows.Controls;
   6 using System.Globalization;
   7 using System.Text.RegularExpressions;
   8 
   9 namespace ConfigurationTool
  10 {
  11     public class Parameters : INotifyPropertyChanged 
  12     {
  13         public event PropertyChangedEventHandler PropertyChanged;
  14 
  15         string starttime;
  16         int retryinterval;
  17         int callretention;
  18         int nofservers;
  19         int threadsperserver;
  20 
  21         public Parameters() { }
  22 
  23         public string startTime          
  24         {
  25             get { return starttime; }
  26             set
  27             {
  28                starttime = value;
  29                 OnPropertyChanged("startTime");
  30             }
  31         }
  32 
  33         public int retryInterval
  34         {
  35             get { return retryinterval; }
  36             set
  37             {
  38                 retryinterval = value;
  39                 OnPropertyChanged("retryInterval");
  40             }
  41         }
  42 
  43         public int callRetention
  44         {
  45             get { return callretention; }
  46             set
  47             {
  48                 callretention= value;
  49                 OnPropertyChanged("callRetention");
  50             }
  51         }
  52 
  53         public int nofServers
  54         {
  55             get { return nofservers; }
  56             set
  57             {
  58                 nofservers = value;
  59                 OnPropertyChanged("nofServers");
  60             }
  61         }
  62 
  63         public int threadsperServers
  64         {
  65             get { return threadsperserver; }
  66             set
  67             {
  68                 threadsperserver = value;
  69                 OnPropertyChanged("threadsperServers");
  70             }
  71         }
  72       
  73 
  74         protected void OnPropertyChanged(string name)
  75         {
  76 
  77             PropertyChangedEventHandler handler = PropertyChanged;
  78 
  79             if (handler != null)
  80             {
  81 
  82                 handler(this, new PropertyChangedEventArgs(name));
  83 
  84             }
  85 
  86         }      
  87 
  88 
  89     }
  90 
  91 }

Note that starttime is a string, I guess TimeSpan object could have used to perhaps used type checking but I've just thought about it now, while writing this up.

In order to do the regex validation, the following class is used (thanks to stackoverflow).

   1 using System;
   2 using System.Collections.Generic;
   3 using System.Text;
   4 using System.Windows.Controls;
   5 using System.Globalization;
   6 using System.Text.RegularExpressions;
   7 
   8 namespace ConfigurationTool
   9 {
  10     class RegexValidator : ValidationRule
  11     {
  12          string pattern;
  13          string errormessage;
  14          Regex regex;
  15          
  16         public string Pattern
  17         {
  18             get { return pattern; }
  19             set
  20             {
  21                 pattern = value;
  22                 regex = new Regex(pattern, RegexOptions.IgnoreCase);
  23             }
  24         }
  25 
  26         public string errorMessage
  27         {
  28             get { return errormessage; }
  29             set
  30             {
  31                 errormessage= value;                
  32             }
  33         }
  34 
  35         public RegexValidator()
  36         {
  37 
  38         }
  39 
  40         public override ValidationResult Validate(object value, CultureInfo cultureInfo)
  41         {           
  42             try
  43             {
  44                 if (regex != null)
  45                 {
  46                     if (!regex.IsMatch(value.ToString()))
  47                     {
  48                         throw new FormatException();
  49                     }
  50                     else
  51                     {
  52                         return ValidationResult.ValidResult;
  53                     } 
  54                 }
  55 
  56                 return new ValidationResult(false, errorMessage);
  57             }
  58             catch (FormatException)
  59             {
  60                 return new ValidationResult(false, errorMessage);
  61             }
  62 
  63         }
  64     }
  65 }

Using this class any regular expression can be validated. All that is required is to hook it up in the xaml to a property and it will be validated.  At any rate, below is the (edited) xaml for this application, with an example of using regular expression validation:

   1 <Window x:Class="ConfigurationTool.MainWindow"
   2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   4         xmlns:sys="clr-namespace:System;assembly=mscorlib"
   5         xmlns:u="clr-namespace:ConfigurationTool"
   6         Title="Configuration Tool" Height="465" Width="565" Icon="/ConfigurationTool;component/Images/maint.ico">
   7 
   8  <Window.Resources>
   9      <u:Parameters x:Key="Pams"/>
  10  </Window.Resources>
  11  
  12  <Grid>
  13     <TextBox Height="23" HorizontalAlignment="Left" Margin="371,72,0,0" Name="RunningTimetextBox" VerticalAlignment="Top" Width="144">
  14         <TextBox.Text>
  15             <Binding Path="startTime" UpdateSourceTrigger="PropertyChanged" Source="{StaticResource Pams}">
  16                 <Binding.ValidationRules>
  17                     <u:RegexValidator Pattern="^([0-1][0-9]|2[0-3]):[0-5][0-9]$" errorMessage="Enter a Valid Time"/>
  18                 </Binding.ValidationRules>
  19             </Binding>
  20         </TextBox.Text>
  21     </TextBox>
  22     <Label Content="Retry Interval (in minutes)" Height="28" HorizontalAlignment="Left" Margin="26,102,0,0" Name="label4" VerticalAlignment="Top" />
  23     <TextBox Height="23" HorizontalAlignment="Left" Margin="371,101,0,0" Name="RetryIntervaltextBox" VerticalAlignment="Top" Width="144" >
  24         <TextBox.Text>
  25             <Binding Path="retryInterval" UpdateSourceTrigger="PropertyChanged" Source="{StaticResource Pams}">
  26                 <Binding.ValidationRules>
  27                     <ExceptionValidationRule/>
  28                 </Binding.ValidationRules>
  29             </Binding>
  30         </TextBox.Text>            
  31     </TextBox>
  32   </Grid>
  33 </Window>

Things to note with the xaml are:
  • Windows resources defines the parameters class
  • This class is hooked up to all textboxes via Source attribute
  • The regex validation class is also hooked up to any textbox as needed.
We can compare the above with a sample code used to validate a textbox in a winforms application:

   1 private void RunningTimetextBox_Validating(object sender, CancelEventArgs e)
   2 {
   3     try
   4     {    //Ensure that the Start time is valid
   5         if (!RunningTimetextBox.Text.Trim().Equals(string.Empty))
   6         {
   7             if (!Regex.IsMatch(RunningTimetextBox.Text.Trim(), Constants.timeRegex))
   8             {
   9                 e.Cancel = true;
  10 
  11                 MessageBox.Show(Constants.errValMsg, "Error", MessageBoxButtons.OK);
  12             } 
  13         }
  14 
  15     }
  16     catch (Exception ex)
  17     {
  18         MessageBox.Show(string.Format(Constants.errMsg, ex.ToString()), "Error", MessageBoxButtons.OK);
  19     }
  20 
  21 }
   
The code is from a similar application and while not perfect it takes about one minute to write, yes it might not be as pretty as WPF, but prettification is hardly at the top of the list for most enterprise applications. It's a nice to have not a killer feature.

Saturday 1 October 2011

Validation? We don't need no validation.

I decided to give WPF a go last week, after all, it's only been out for five years. I wrote a small app that writes to the configuration file of a windows service. This app ensures that the fields are validated and also that the app.config file is well formed (we've had a few instances were an web.config file has been edited manually and the values placed after the configuration closing tags) or at least that was the idea.

Anyway, in the old days of winforms apps, in order to validate a textbox all one had to do was implement the Validating event. If it passed validation, the program would continue otherwise the event would be cancelled and focus stayed with the same textbox.

Imagine my surprise when the validating event wasn't there for a WPF textbox. I thought that it must be called something else, i.e. there would be an event that would have similar functionality, but alas there isn't. It is possible to use the previewtextinput event to prevent text being input, e.g. letters in a numerical only field, but there are limitations to this approach, as it only validates one character.

This should be another, why Microsoft why post? There are a few solutions but they involve writing quite a bit of code, which is fine, but it seems like a step backwards to me.