21 May 2013 @ 2:37 AM 

Sometimes you need to create temporary files. Usually, you can discard those temporary files by opening them in a fashion so they are deleted when they are closed. However, in some cases, you are dealing with a library or other class that is very picky about what you give it. Other times, you create an entire directory and want that directory to be deleted when you application is closed.

Whatever the case, there are several approaches to this. The first and most obvious (to me) was to try to use C#/.NET’s Disposable interface pattern. By creating a static List of those objects, we can ensure their Dispose()/Finalizers are run when the application is terminated (static variables and fields are disposed when the application is being torn down). Then the logic to delete and attempt to delete the file can be placed in the Dispose() method as needed. My implementation originally encountered problems with sharing violations- since the application, early on, may have many handles open. Primarily, this likely occurs because of the non-deterministic nature of how static objects are disposed; so if a File is opened and is in another static member, it might not have been disposed when our dispose method is called. As a result I’ve added a Delayed invoke method which, if the delete fails initially, will call itself again after a second (trying up to five times).

  1. /// <summary>
  2. ///     Rudimentary class that is instantiated with the name of a folder, and deletes that folder when the class instance is disposed.
  3. /// </summary>
  4. public class DeletionHelper : IDisposable
  5. {
  6.     //helper native methods.
  7.     private static readonly Queue<DeletionHelper> QueuedDeletions = new Queue<DeletionHelper>();
  8.     private readonly String mDeleteThis = "";
  9.     public DeletionHelper(String deletefolder)
  10.     {
  11.         mDeleteThis = deletefolder;
  12.     }
  13.     public String DeleteThis
  14.     {
  15.         get { return mDeleteThis; }
  16.     }
  17.      [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  18.     private static extern bool MoveFileEx(
  19.         string lpExistingFileName,
  20.         string lpNewFileName,
  21.         MoveFileFlags dwFlags);
  22.     public static void QueueDeletion(String FileOrDir)
  23.     {
  24.         var dh = new DeletionHelper(FileOrDir);
  25.         QueuedDeletions.Enqueue(dh);
  26.     }
  27.     ~DeletionHelper()
  28.     {
  29.         Dispose();
  30.     }
  31.     #region IDisposable Members
  32.     private int delaycount;
  33.     public void Dispose()
  34.     {
  35.         try
  36.         {
  37.             if (Directory.Exists(mDeleteThis))
  38.             {
  39.                 Debug.Print("Deleting folder:" + mDeleteThis);
  40.                 Directory.Delete(mDeleteThis, true);
  41.             }
  42.             else if (File.Exists(mDeleteThis))
  43.             {
  44.                 int AttemptCount = 0;
  45.                 try
  46.                 {
  47.                     AttemptCount++;
  48.                     Debug.Print("Deleting File:" + mDeleteThis);
  49.                     File.Delete(mDeleteThis);
  50.                 }
  51.                 catch (IOException e)
  52.                 {
  53.                     if (AttemptCount == 10)
  54.                     {
  55.                         return; //give up!
  56.                     }
  57.                     Thread.Sleep(250);
  58.                 }
  59.             }
  60.         }
  61.         catch (IOException ioe)
  62.         {
  63.             delaycount++;
  64.             if (delaycount > 5)
  65.             {
  66.                 //schedule for reboot deletion.
  67.                 ScheduleRebootDeletion();
  68.                 return;
  69.             }
  70.             DelayCall(new TimeSpan(0, 0, 0, delaycount), Dispose);
  71.         }
  72.     }
  73.  
  74.     private static void DelayInvokeThread(Object parameters)
  75.     {
  76.         var acquireparam = (Object [] ) parameters;
  77.  
  78.         var useaction = acquireparam [1]  as Action;
  79.         var waittime = (TimeSpan) acquireparam [2] ;
  80.         var startdelay = (DateTime) acquireparam [3] ;
  81.         while (DateTime.Now – startdelay < waittime)
  82.         {
  83.             Thread.Sleep(0);
  84.         }
  85.         if (useaction == null) return;
  86.         useaction();
  87.     }
  88.  
  89.     private static void DelayCall(TimeSpan waittime, Action routine)
  90.     {
  91.         var usethread = new Thread(DelayInvokeThread);
  92.         usethread.Start(new Object []  {usethread, routine, waittime, DateTime.Now});
  93.     }
  94.  
  95.     private void ScheduleRebootDeletion()
  96.     {
  97.         try
  98.         {
  99.             if (!MoveFileEx(mDeleteThis, null, MoveFileFlags.DelayUntilReboot))
  100.             {
  101.             }
  102.         }
  103.         catch (DllNotFoundException dlex)
  104.         {
  105.         }
  106.     }
  107.  
  108.     #endregion
  109.  
  110.      [Flags]
  111.     internal enum MoveFileFlags
  112.     {
  113.         None = 0,
  114.         ReplaceExisting = 1,
  115.         CopyAllowed = 2,
  116.         DelayUntilReboot = 4,
  117.         WriteThrough = 8,
  118.         CreateHardlink = 16,
  119.         FailIfNotTrackable = 32,
  120.     }
  121. }

This implementation also gives up after a few tries and then tries to schedule the file for reboot deletion. I considered a rather insane mechanic whereby the class would store a data file in the Temporary folder, then when first constructed (eg. static constructor) it can check for that file and either create and dispose a DeletionHelper for each filename stored in that data file, or add those files to the existing list for deletion when the application terminates. However, after considering it I figured such a feature might make things more complicated than necessary.

The other idea for automatic deletion would be to use the CreateFile() API with full share permissions, and pass the FILE_FLAG_DELETE_ON_CLOSE flag to it, then close that file in the Dispose method. Here is one possible implementation:

  1. public class DeletionHelperAPI : IDisposable
  2. {
  3.     private const int FILE_FLAG_DELETE_ON_CLOSE = 0×4000000;
  4.     private const int FILE_SHARE_READ = 0×1;
  5.     private const int FILE_SHARE_WRITE = 0×2;
  6.     private const int ACCESS_NONE = 0;
  7.     private const int OPEN_EXISTING = 3;
  8.     private const int FILE_SHARE_DELETE = 0×4;
  9.  
  10.     private List<DeletionHelperAPI> Subdeletors = new List<DeletionHelperAPI>();
  11.     [DllImport("kernel32.dll", CharSet = CharSet.Auto,
  12. CallingConvention = CallingConvention.StdCall,
  13. SetLastError = true)]
  14.     public static extern SafeFileHandle CreateFile(
  15.         string lpFileName,
  16.         uint dwDesiredAccess,
  17.         uint dwShareMode,
  18.         IntPtr SecurityAttributes,
  19.         uint dwCreationDisposition,
  20.         uint dwFlagsAndAttributes,
  21.         IntPtr hTemplateFile
  22.     );
  23.  
  24.     SafeFileHandle FileHandle = null;
  25.     public DeletionHelperAPI(String FileOrFolder)
  26.     {
  27.         //if it’s a folder, create subobjects.
  28.         if (Directory.Exists(FileOrFolder))
  29.         {
  30.             //create a subdeletor for each File/folder in that file-folder.
  31.             DirectoryInfo di = new DirectoryInfo(FileOrFolder);
  32.             foreach (FileSystemInfo fsi in di.GetFileSystemInfos())
  33.             {
  34.                 Subdeletors.Add(new DeletionHelperAPI(fsi.FullName));
  35.             }
  36.         }
  37.         else
  38.         {
  39.             FileHandle = CreateFile(FileOrFolder, ACCESS_NONE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, IntPtr.Zero,
  40.                 OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, IntPtr.Zero);
  41.         }
  42.  
  43.  
  44.  
  45.     }
  46.  
  47.     public void Dispose()
  48.     {
  49.         if (Subdeletors != null)
  50.         {
  51.             foreach (var iterate in Subdeletors)
  52.             {
  53.                 iterate.Dispose();
  54.             }
  55.         }
  56.         if (FileHandle != null)
  57.         {
  58.             FileHandle.Dispose();
  59.         }
  60.     }
  61. }

And so, that gives us two implementations. I currently use the first in BASeBlock for deleting the temporary files and folders that are sometimes created during start-up, particularly if it finds a Zip file (which may have additional content that it checks for). Since those extracted files may be used during the run, I use the class to make sure they are deleted when the Application exits; or at least make an effort to do so.

66 total views, 4 views today

Posted By: BC_Programming
Last Edit: 21 May 2013 @ 02:37 AM

EmailPermalinkComments (0)
Tags
Tags: , ,
Categories: .NET, C#
 09 Apr 2013 @ 10:25 AM 

I’ve already covered this topic from the perspective of why C# is better than Java, In my opinion. This time, I’ll go over the differences as even-handed as possible. This has come about primarily because I’ve been working extensively in Java, and find there are features that I like and dislike in both languages. Though I will admit I lean heavily towards C#.

First, how about a little history on them?

Java

Most, if not all, Languages and platforms have a varied and sometimes tumultuous history. The Java language and platform is definitely no exception. In it’s earliest incarnations, Oak, the purpose behind Java was to provide a platform and language to automate appliances. This is not really as far-fetched as it would seem, since most appliances do run some sort of software. If you pick a toaster off a shelf at random you have a good chance of getting something that runs some sort of executable code. The purpose was, presumably, to make this behaviour something that could be patched and changed more easily by end-users; much like how many car owners who are versed in technology will sometimes change the internal firmware to eke out better performance, one could see a person customizing their coffee maker or kettle for specific purposes.

The language, however, proved too useful for such a niche market, and eventually found it’s way onto the PC platform. It was initially met with some rather exorbinant and out of proportion enthusiasm, as Java was cited as the be all end all of all things on the web. Needless to say, that did not come to pass. Java- the language and technology- have now settled into being used for server-side development and the development of applications and games, instead. A purpose for which it is well suited, for the most part.

C#

There are some proponents- who not surprisingly are strongly biassed towards Java technologies- that claim that C# and .NET are a poor attempt by Microsoft to attempt to replicate Java. This is a rather ill-thought claim. While there is some interesting history behind C#, since it appeared relatively shortly after Sub Microsystems revoked Microsoft’s Java License, it’s very likely it was already in development anyway. Even if we go with that assumption and consider that C# is in fact Microsoft’s Java baby, it has still found itself in a very similar- but different- market.

Design Differences

One of my overriding dislikes of the Java language is mostly in the design strategy, which typically avoids the addition of language features if they can be misused. For this reason, Java does not have Operator overloading, Properties, and various similar features, under the guise that it’s easy to misuse them. In a similar vein, it lacks the ability for the programmer to create their own value types, while at the same time presenting somewhat confusing exposures for it’s own primitive types.

Java is a language designed essentially in tandem with it’s bytecode. Java source is compiled into Java Bytecode; this bytecode is an intermediate executable code that is run by a Java Virtual Machine; the Java Virtual Machine emulates a “stack-based” CPU.

C# is also designed in tandem with the CLR, it’s execution environment, but the CLR is designed with the capabilities of other languages in mind. For example, While Java uses every single feature of the Java Bytecode for Java features, C# does not actually exploit all features of the CLR and the IL bytecode that the language compiles to. What makes this interesting is that while all Java bytecode can be “decompiled” to some equivalent Java source, not all IL code can be decompiled to C#. For example, Visual Basic .NET uses a few features of the CLR that are not used in C#, such as Exception filters.

Generics

Generics are one feature that is implemented quite differently between each language. The Java approach is to make the feature something that is dealt with before the Virtual Machine runs it. What this essentially means is that, when compiling a generic class, the Java Compiler replaces all type parameters with their type restrictions (the Java docs call them “bounds”). If the type parameter is unrestricted/unbounded, then the compiler will use the Object type. The compiler will insert type casts where necessary to preserve type safety (which includes both code within the generic class as well as code that utilizes the generic class) and generate appropriate “bridge” methods between a generic base class and a class that extends from it.

C#- thanks to the CLR- has full-on support for Generic types. The ramifications for this go both ways. Whereas the Java method of Type Erasure allows your program to work successfully on older Virtual Machines as well as newer ones (because the VM is not changed) you lose out on the ability to use generics through reflection. C#, on the other hand, allows you to create a new Type based on a generic type and the types of it’s parameters, and then instantiate the applicable classes as desired. Reflection is extremely powerful in both Java and C#, but this particular ability can be very appealing for some designs. On the flip-side, however, in order to use Generics in C#, the code needs to be running on the Version 2 CLR; in fact if you compile for a later version of the CLR, the resulting compilation will not work on earlier versions. This is because the CLR development mantra is to work to add improvements to the system as a whole, while allowing legacy code to run without recompilation by allowing side by side installation.

One interesting way to compare the two platforms is with a direct demonstration and comparison of otherwise functionally equivalent segments of code. Now on e might think I would turn to the Java and C# implementations as part of my ongoing Anagrams Series , but since we will be looking at the IL and Bytecode of each, it might be ideal to go for brevity. I’ve settled on a simple program that uses a Generic structure to store 100 values, and then write them out. Here is the Java implementation:

  1. package testdisassembly;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class testdisasm {
  6.     public static void main(String []  args){
  7.         List <integer>  intlist = new ArrayList<Integer>();
  8.         for(int i=0;i<=100;i++){
  9.             intlist.add(i);
  10.         }
  11.         for(Integer iterate:intlist){
  12.             System.out.println(iterate);
  13.         }
  14.         try {
  15.             System.in.read();
  16.         } catch (IOException e) {
  17.             // TODO Auto-generated catch block
  18.             e.printStackTrace();
  19.         }
  20.     }
  21. } </integer>  

Something of note is that we need to use List rather than List because generic type parameters must be class types. This is sort of a side-effect of the way Type Erasure was implemented, since it essentially inserts appropriate casts to the proper type when the Type parameter is used. the Integer type is a boxing class that is provided by the Java Class Library, and for which the compiler has special considerations for (like the other boxing classes). The disassembled Java bytecode from this is shown below. This is from the main method, and I stripped out the extra stuff about the methods and whatnot.

  1. public <init>  ()V max stack: 1,   max locals: 1,    catch blocks: 0
  2. public static main  ([Ljava/lang/String;)V  max stack: 2,   max locals: 4,    catch blocks: 1
  3.  
  4. Bytecode of main method:
  5.  
  6. new #16 = Class java.util.ArrayList
  7. dup
  8. invokespecial #18 = Method java.util.ArrayList.<init>(()V)
  9. astore_1
  10. iconst_0
  11. istore_2
  12. goto 27
  13. aload_1
  14. iload_2
  15. invokestatic #19 = Method java.lang.Integer.valueOf((I)Ljava/lang/Integer;)
  16. invokeinterface #25 = Method java.util.List.add((Ljava/lang/Object;)Z)
  17. pop
  18. iinc 2
  19. iload_2
  20. bipush 100
  21. if_icmple 13
  22. aload_1
  23. invokeinterface #31 = Method java.util.List.iterator(()Ljava/util/Iterator;)
  24. astore_3
  25. goto 60
  26. aload_3
  27. invokeinterface #35 = Method java.util.Iterator.next(()Ljava/lang/Object;)
  28. checkcast #20 = Class java.lang.Integer
  29. astore_2
  30. getstatic #41 = Field java.lang.System.out(Ljava/io/PrintStream;)
  31. aload_2
  32. invokevirtual #47 = Method java.io.PrintStream.println((Ljava/lang/Object;)V)
  33. aload_3
  34. invokeinterface #53 = Method java.util.Iterator.hasNext(()Z)
  35. ifne 43
  36. getstatic #57 = Field java.lang.System.in(Ljava/io/InputStream;)
  37. invokevirtual #61 = Method java.io.InputStream.read(()I)
  38. pop
  39. goto 84
  40. astore_2
  41. aload_2
  42. invokevirtual #67 = Method java.io.IOException.printStackTrace(()V)
  43. return

Edit: Fixed the markup issue. you would think the &ltpre&gt tag would prevent other tags from being identified within, but apparently WordPress still helpfully tries to auto-complete tags when you save a post...
Some take-aways from this. We can see Type Erasure in action starting at the first invokespecial line, which invokes the constructor. The constructor is of java.util.ArrayList. But this lacks any Generic context. As we can see in the future calls, many of the references to and from the List are cast to an Object when being passed and cast to an Integer when being retrieved. This shows Type Erasure in action.

Moving on to C#:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace testdissasmbly
  7. {
  8.     class Program
  9.     {
  10.         static void Main(string []  args)
  11.         {
  12.             var testlist = new List<int>();
  13.             testlist.AddRange(Enumerable.Range(0, 100));
  14.             foreach (var iterate in testlist)
  15.             {
  16.                 Console.WriteLine(iterate);
  17.             }
  18.             Console.ReadKey();
  19.         }
  20.     }
  21. }

This one is a lot shorter than the Java version because I've used as many language and framework features as I thought I could get away with. To say the resulting IL dissassembly was verbose in comparison would be an understatement:

  1. .method private hidebysig static void  Main(string []  args) cil managed
  2. {
  3.   .entrypoint
  4.   // Code size       75 (0x4b)
  5.   .maxstack  3
  6.   .locals init ( [0]  class  [mscorlib] System.Collections.Generic.List`1<int32> testlist,
  7.             [1]  int32 iterate,
  8.             [2]  valuetype  [mscorlib] System.Collections.Generic.List`1/Enumerator<int32> CS$5$0000)
  9.   IL_0000:  newobj     instance void class  [mscorlib] System.Collections.Generic.List`1<int32>::.ctor()
  10.   IL_0005:  stloc.0
  11.   IL_0006:  ldloc.0
  12.   IL_0007:  ldc.i4.0
  13.   IL_0008:  ldc.i4.s   100
  14.   IL_000a:  call       class  [mscorlib] System.Collections.Generic.IEnumerable`1<int32>  [System.Core] System.Linq.Enumerable::Range(int32,
  15.                                                                                                                                   int32)
  16.   IL_000f:  callvirt   instance void class  [mscorlib] System.Collections.Generic.List`1<int32>::AddRange(class  [mscorlib] System.Collections.Generic.IEnumerable`1<!0>)
  17.   IL_0014:  ldloc.0
  18.   IL_0015:  callvirt   instance valuetype  [mscorlib] System.Collections.Generic.List`1/Enumerator<!0> class  [mscorlib] System.Collections.Generic.List`1<int32>::GetEnumerator()
  19.   IL_001a:  stloc.2
  20.   .try
  21.   {
  22.     IL_001b:  br.s       IL_002b
  23.     IL_001d:  ldloca.s   CS$5$0000
  24.     IL_001f:  call       instance !0 valuetype  [mscorlib] System.Collections.Generic.List`1/Enumerator<int32>::get_Current()
  25.     IL_0024:  stloc.1
  26.     IL_0025:  ldloc.1
  27.     IL_0026:  call       void  [mscorlib] System.Console::WriteLine(int32)
  28.     IL_002b:  ldloca.s   CS$5$0000
  29.     IL_002d:  call       instance bool valuetype  [mscorlib] System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
  30.     IL_0032:  brtrue.s   IL_001d
  31.     IL_0034:  leave.s    IL_0044
  32.   }  // end .try
  33.   finally
  34.   {
  35.     IL_0036:  ldloca.s   CS$5$0000
  36.     IL_0038:  constrained. valuetype  [mscorlib] System.Collections.Generic.List`1/Enumerator<int32>
  37.     IL_003e:  callvirt   instance void  [mscorlib] System.IDisposable::Dispose()
  38.     IL_0043:  endfinally
  39.   }  // end handler
  40.   IL_0044:  call       valuetype  [mscorlib] System.ConsoleKeyInfo  [mscorlib] System.Console::ReadKey()
  41.   IL_0049:  pop
  42.   IL_004a:  ret
  43. } // end of method Program::Main

A lot of the verbosity here is due to the explicit referencing of various framework types. it’s also interesting that the resulting IL has an Exception Handler which is most likely attached through scope. That is, scoping braces in blocks will cause any declared variables within to be deconstructed as necessary. This doesn’t run measurably slower than the Java version. Fundamentally, while this IL looks longer (and a reasonable assumption to base on that would be that it’s slower) it’s also just a representation of the internal IL code. Additionally, the CLR has a very powerful JITter that will compile segments of code on the fly to Machine language, which is particularly helpful for looping constructs, or really any code that repeats more than once.

In order to better flesh out differences as I encounter them or learn enough about them, I’ve decided this will be something I shall repeat- a series, if you will. Expect more blog posts on the subject of C# and Java differences. If necessary consider this post a primer and look at their run-times.

288 total views, no views today

Posted By: BC_Programming
Last Edit: 15 Apr 2013 @ 04:10 AM

EmailPermalinkComments (0)
Tags
Categories: .NET, C#, Java, Programming
 01 Apr 2013 @ 4:21 AM 

C#’s linq(language-integrated query) features are some of the more powerful features available through the language. Aside from it’s query operators that are, as it’s name would suggest, integrated into the language, the feature also brings along a large set of Extension methods to the IEnumerable interface type.

One interesting re-use of the IEnumerable type for extension methods is to create ad-hoc language structures using it, for example:

  1. class Program
  2. {
  3.     static void Main(string []  args)
  4.     {
  5.         Random rgen = new Random();
  6.         var doubles = (from p in Enumerable.Range(0, 100) select rgen.NextDouble());
  7.         doubles.EachCase(
  8.             (t) => t < 0.5d,
  9.             (value) =>
  10.             {
  11.                 Console.WriteLine(value.ToString() + " is less than 0.5d.");
  12.             }).EachCase(
  13.             (t) => t > 0.75d,
  14.             (value) =>
  15.             {
  16.                 Console.WriteLine(value.ToString() + " is greater than 0.75d.");
  17.             }).EachCase((t) => true,
  18.             (value) =>
  19.             {
  20.                 Console.WriteLine(value.ToString() + " is not handled…");
  21.             }).Count();
  22.         Console.ReadKey();
  23.     }
  24. }

What we have here is similar- but not quite the same- as a switch statement within a loop. What makes this particularly interesting as a structure is that it acts sort of like a seive. The source to the extension EachCase() method is shown here:

  1. public static class SelectExtension
  2. {
  3.     public static IEnumerable<T> EachCase<T>(this IEnumerable<T> Enumeration,Func<T,bool> TestExpression,Action<T> CodeBlock)
  4.     {
  5.  
  6.         if (Enumeration == null) yield break;
  7.         foreach (var iterate in Enumeration)
  8.         {
  9.             if (TestExpression(iterate))
  10.             {
  11.                 CodeBlock(iterate);
  12.  
  13.             }
  14.             else
  15.                 yield return iterate;
  16.         }
  17.      }
  18. }

The function works by calling the passed Action for all entries in the enumeration that cause TestExpression to return true. Those that return false are yielded to the caller. In the original code the EachCase() calls were chained, one after the other; each one operated on the entries that the previous one didn’t work with. the final .Count() call in the original code is to force it to be enumerated, allowing all the code blocks to evaluate appropriately. What use-cases might this have? I have no idea. However I feel confident in saying that it could make for a more readable alternative to something that might otherwise require a separate Finite-State machine.

320 total views, no views today

Posted By: BC_Programming
Last Edit: 01 Apr 2013 @ 04:21 AM

EmailPermalinkComments (0)
Tags
Tags: , , ,
Categories: .NET, C#
 21 Mar 2013 @ 9:08 AM 

Most application frameworks/languages provide access to the Command Line parameters passed to your application. Generally it is passed to your application as either a string or an array of strings. What you do not get automatically is the functionality to parse out switches.

Command-line parameters used to be the only way to communicate with a program. Fundamentally, the command line was your UI into the program. Different platforms took different approaches. Unix-like systems typically take the “invasive” route; they replace wildcards and then pass the resulting command line to the application. This means that you don’t have to do any shell expansion of wildcards (as it is known) but you have to account for the fact that your command line could include a lot of files. It’s a trade-off, really. Either way, I figured for the purposes of this library, we could stick to the platform- if the program is run with a wildcard, you’ll see the wildcard on windows, but it will have been expanded if you run the same program on Linux. It might be worth adding an option to “auto-expand” wildcards- just for consistencies sake, but that seems like a post for another day.

Either way, most applications also include flags and switches. This is more a De Facto standard that has cropped up- there is no hard and fast rulebook about what flags and switches are or how you are supposed to pass arguments, which can cause no end of confusion when it comes to reading application documentation. the .NET language just gives you the string, and leaves it up to you to decide how to interpret it. Some language libraries provide functionality to parse the Command Line appropriately, such as Python. C# doesn’t come with such a class…. So let’s make one!

First we need to determine what exactly can exist in a command line. My method allows for two things: Switches, and arguments. A Switch can include an argument, separated from the switch with a colon. For example:

  1.  
  2. someprogram.exe /switch:argument /sw:"file 1.txt" "filename.txt" /doall
  3.  

In this case, we have three switches- switch, sw, and doall. The first two include an argument. My “syntax” allows for quotes in the arguments of switches as well as the “loose” arguments. We will evidently need classes to represent and parse Arguments, and another one for Switches. The parsing can be done sequentially. Although it’s not a recommended best practice, I chose to use by reference parameters in the class constructors. In order to keep things generic and accessible, both Switches and Arguments will derive from a CommandLineElement abstract class, which will force each base class to implement toString(). the ArgumentItem class will be used for parsing both “loose” arguments, as well as arguments found after a switch.

Arguments

Arguments are simple- if the first letter of the position is a quote, we look for the next quote that isn’t doubled up. Otherwise, we look for either the next whitespace or the end of the string. Each argument only needs the actual argument value.

  1.  
  2.   /// <summary>
  3.         /// Represents an Argument. This includes arguments that exist bare on the command line as well as arguments used with a given switch.
  4.         /// </summary>
  5.         public class ArgumentItem : CommandLineElement
  6.         {
  7.             public static ArgumentItem Empty = new ArgumentItem();
  8.             private String _Argument;
  9.  
  10.             protected internal ArgumentItem()
  11.             {
  12.                 _Argument = "";
  13.             }
  14.  
  15.             /// <summary>
  16.             /// Construct an Instance from the given string, assuming the start of an Argument element at the given position.
  17.             /// </summary>
  18.             /// <param name="strParse">Command Line to parse.</param>
  19.             /// <param name="Position">Location to start. This variable will be updated with the ending position of the argument that was discovered upon return.</param>
  20.             public ArgumentItem(String strParse, ref int Position)
  21.             {
  22.                 int startpos = Position;
  23.                 int sloc = startpos;
  24.                 while (char.IsWhiteSpace(strParse.ElementAt(sloc))) sloc++;
  25.                 if (strParse.ElementAt(sloc) == ‘"’)
  26.                 {
  27.                     sloc++;
  28.                     while (true)
  29.                     {
  30.                         if (sloc >= strParse.Length) break;
  31.                         bool doublequote = strParse.Length > sloc + 2 && strParse.Substring(sloc, 2).Equals("\"");
  32.                         //if we found a quote and it’s not a double quote…
  33.                         if (strParse.ElementAt(sloc) == ‘"’ && !doublequote)
  34.                         {
  35.                             sloc++;
  36.                             break;
  37.                         }
  38.                         if (doublequote) sloc++; //add an extra spot for the dual quote.
  39.  
  40.                         sloc++;
  41.                     }
  42.                 }
  43.                 else
  44.                 {
  45.                     sloc = strParse.IndexOfAny(new char []  {‘/’, ‘ ‘}, sloc);
  46.                 }
  47.                 _Argument = strParse.Substring(Position, sloc – startpos);
  48.                 Position = sloc;
  49.             }
  50.  
  51.             /// <summary>
  52.             /// returns the Argument this Object represents. This will include quotation marks if they were used in the originally parsed string.
  53.             /// </summary>
  54.             public String Argument
  55.             {
  56.                 get { return _Argument; }
  57.             }
  58.  
  59.             /// <summary>
  60.             /// implicitly converts an ArgumentItem to a String.
  61.             /// </summary>
  62.             /// <param name="value">ArgumentItem to implicitly convert.</param>
  63.             /// <returns>the result from calling Chomp() on the given instance.</returns>
  64.             public static implicit operator String(ArgumentItem value)
  65.             {
  66.                 return value.Chomp();
  67.             }
  68.  
  69.             /// <summary>
  70.             /// returns the Argument value. If it starts with and endswith quotation marks, they will be removed.
  71.             /// </summary>
  72.             /// <returns></returns>
  73.             public String Chomp()
  74.             {
  75.                 if (_Argument.StartsWith("\"") && Argument.EndsWith("\""))
  76.                     return _Argument.Substring(1, _Argument.Length2);
  77.                 else return _Argument;
  78.             }
  79.  
  80.             public override string ToString()
  81.             {
  82.                 if (Argument.Any(Char.IsWhiteSpace))
  83.                     return "\"" + Argument + "\"";
  84.                 else return Argument;
  85.             }
  86.         }
  87.  

The constructor is where the important stuff happens. the by reference parameter is used to define the starting position, and we update it when the constructor returns to point at the character after the argument. The class also defines some statics for implicit conversions to and from a string.

Now that we have the Argument class, we can define the Switch class. The actual syntax of switches often depends on the application but also seems to depend on the platform. for example, Linux tools favour the hyphen for single letter flags, and double hyphens for multi-character flags. Switches are also called flags. forward slash is not generally used as a switch or flag indicator. Windows platforms prefer the forward slash but generally allow for single hyphens as well. We aim to support all three syntaxes, and make the client application not have to worry about which it is. We also add support for arguments- a switch can be specific as such:

 
someprogram /d:argument.exe
 

The element after the colon will be parsed as an argument and attached to the switch itself. But enough waffling- on to the Switch:

  1. public class Switch : CommandLineElement
  2. {
  3.     internal static String []  SwitchPreceders = new string []  {"–", "-", "/"};
  4.     private ArgumentItem _Argument = ArgumentItem.Empty;
  5.     private String _SwitchValue;
  6.  
  7.     public Switch(String strParse, ref int StartLocation)
  8.     {
  9.         while (String.IsNullOrWhiteSpace(strParse.ElementAt(StartLocation).ToString())) StartLocation++;
  10.         var sLoc = StartLocation;
  11.         var retrieved = SwitchPreceders.
  12.             FirstOrDefault((s) => !(sLoc + s.Length > strParse.Length) &&
  13.                                   strParse.Substring(sLoc, s.Length)
  14.                                           .Equals(s, StringComparison.OrdinalIgnoreCase));
  15.         if (retrieved == null)
  16.         {
  17.             throw new ArgumentException("Passed String " + strParse +
  18.                                         " Does not have a switch preceder at position " + StartLocation);
  19.         }
  20.         var NextSpace = strParse.IndexOfAny(new char []  {‘ ‘, \t, ‘/’, ‘:’}, sLoc + 1);
  21.         //if(((NextSpace-sLoc)-sLoc+1) <= 0) throw new ArgumentException("Error Parsing Switch");
  22.         _SwitchValue = strParse.Substring(sLoc + 1, NextSpace – sLoc – 1);
  23.         sLoc += retrieved.Length; //we don’t want the switch itself.
  24.         //now we need to determine where the Switch ends. colon or space seems reasonable. If a colon, the next entity will be an argument.
  25.         StartLocation = NextSpace;
  26.         //if the char at NextSpace is a Colon…
  27.         if (strParse.ElementAt(NextSpace) == ‘:’)
  28.         {
  29.             //interpret as an argument
  30.             NextSpace++;
  31.             _Argument = new ArgumentItem(strParse, ref NextSpace);
  32.         }
  33.         StartLocation = NextSpace;
  34.     }
  35.     public String SwitchValue
  36.     {
  37.         get { return _SwitchValue; }
  38.     }
  39.     public String Argument
  40.     {
  41.         get { return _Argument; }
  42.     }
  43.     //Constructs an instance of a switch from the given location.
  44.     public static bool SwitchAtPos(String strParse, int Location)
  45.     {
  46.         var retrieved = SwitchPreceders.
  47.             FirstOrDefault((s) => !(Location + s.Length > strParse.Length) &&
  48.                                   strParse.Substring(Location, s.Length)
  49.                                           .Equals(s, StringComparison.OrdinalIgnoreCase));
  50.         return retrieved != null;
  51.     }
  52.     public override string ToString()
  53.     {
  54.         return "//" + _SwitchValue + ":" + _Argument.ToString();
  55.     }
  56.     public bool HasArgument()
  57.     {
  58.         return _Argument.Equals(ArgumentItem.Empty);
  59.     }
  60.         }

With the basic parsing logic completed, we need to consider how we want this to be used. Best way is to think of how we would like to use them:

  1. CmdParser cp = new CmdParser();
  2. if(cp.HasSwitch("f") && cp ["f"] .HasArgument()) _usefilename=cp ["f"] .Argument;

Some basic take-aways from this. First, the Core Parser Object needs to provide an Indexer. In the above example, we see it is accessing Switches by passing in the Switch name. Other possibilities include using direct numeric indexes to refer to any argument- much like you would access elements in the framework provided args [] String array. Another possibility is to have the Argument of a switch auto-populate, rather than be null, when accessed:

  1.  _usefilename=cp.HasSwitch("f")?cp ["f"] .Argument:_usefilename;

1,092 total views, 2 views today

Posted By: BC_Programming
Last Edit: 21 Mar 2013 @ 09:10 AM

EmailPermalinkComments (0)
Tags
 04 Feb 2013 @ 9:24 PM 

Is XNA Going Away?

The following consists of my opinion and does not constitute the passing on of an official statement from Microsoft. All thoughts and logic is purely my own and I do not have any more ‘insider’ information in this particular topic than anybody else

I’ve been hearing from the community a bit of noise about Microsoft’s XNA Framework- a Programming library and suite of applications designed to ease the creation of Games- being cut. A google reveals a lot of information, but a lot of it is just plain old rumours. The only one I could find that was based on actual information still makes a lot of assumptions. It is based on this E-mail:

Our goal is to provide you the best experience during your award year and when engaging with our product groups. The purpose of the communication is to share information regarding the retirement of XNA/DirectX as a Technical Expertise.

The XNA/DirectX expertise was created to recognize community leaders who focused on XNA Game Studio and/or DirectX development. Presently the XNA Game Studio is not in active development and DirectX is no longer evolving as a technology. Given the status within each technology, further value and engagement cannot be offered to the MVP community. As a result, effective April 1, 2014 XNA/DirectX will be fully retired from the MVP Award Program.

Because we continue to value the high level of technical contributions you continue to make to your technical community, we want to work with you to try to find a more alternate expertise area. You may remain in this award expertise until your award end date or request to change your expertise to the most appropriate alternative providing current contributions match to the desired expertise criteria. Please let me know what other products or technologies you feel your contributions align to and I will review those contributions for consideration in that new expertise area prior to the XNA/DirectX retirement date.

Please note: If an expertise change is made prior to your award end date, review for renewal of the MVP Award will be based on contributions in your new expertise.

Please contact me if you have any questions regarding this change.

This is an E-Mail that was sent out- presumably- to XNA/DirectX MVPs. I say presumably because for all we know it was made up to create a news story. If it was sent out, I never received it, so I assume it would have been sent to those that received an MVP Award with that expertise. It might have been posted to an XNA newsgroup as well. Anyway, the article that had this E-mail emblazoned as “proof” that MS was abandoning XNA seemed to miss the ever-important point that it actually says nothing about XNA itself, but actually refers to the dropping of XNA/DirectX as a technical Expertise. What this means is that there will no longer be Awards given for XNA/DirectX development. It says nothing beyond that. Now, it could mean they plan to phase it out entirely- but to come to that conclusion based on this is a bit premature, because most such expertise-drops actually involved a merge. For example, in many ways, an XNA/DirectX expertise is a bit redundant, since XNA/DirectX works using a .NET Language such as VB.NET and C# and very few XNA/DirectX MVPs truly can work with XNA in any language at all, it might make sense to just clump them with us lowly Visual C# and Visual Basic MVPs.

To make the assumption that XNA is being dropped based on this E-mail is a bit premature. In my opinion, I think the choice was made for several reasons. I guess some of the misconceptions might be the result of misconceptions about just what a Microsoft MVP is. First, as I mentioned before, a lot of the expertise of XNA/DirectX involves an understanding- and expertise- in some other area. Again, Visual C#, Visual Basic, Visual C++, etc. So in some ways they might have considered a separate XNA/DirectX expertise redundant. Another reason might have to do with the purpose of an MVP. MVP Awards are given to recognize those who make exceptional community contributions in the communities that form around their expertise. For example, my own blog typically centers around C#, solving problems with C# and Visual Studio, and presents those code solutions and analyses to the greater community by way of the internet, as well as sharing my knowledge of C# and .NET in those forums in which I participate. MVP awardees don’t generally receive much extra inside information- and that they do get is typically covered by a NDA agreement. The purpose of the award is to also establish good community members with which Microsoft can provide information to the community. MVPs are encouraged to attend numerous events where they can, quite literally, talk directly to the developers of the Products with which they acquainted. in some way you could consider MVPs “representatives” of the community, who are chosen because their contributions mean they likely have a good understanding of any prevalent problems with the technologies in question, and interacting with MVPs can give the product teams insight into the community for which their product is created. Back to the particulars here, however- as the E-mail states, XNA Game Studio is not under active development. Now, following that, it seems reasonable to work with the assumption that either that product has no Product Team, or those that are on that Product Team are currently occupied in other endeavours, or other products for which their specific talents are required.

It’s not so much that they are “pulling the plug in XNA”- the product is currently in stasis. As a direct result of this, it makes sense that without an active Product Team, having specific MVP Awardees for that expertise isn’t particularly useful for either side- MVPs gain from personal interactions with the appropriate Microsoft Product team as well as fellow MVPs, and Microsoft gains from the aggregate “pulse of the community” that those MVPs can provide. Without a Product Team for a expertise, that expertise is redundant, because there is nobody to get direct feedback. This doesn’t mean the XNA community is going away, just that, for the Moment, there is no reason for Microsoft to watch it’s pulse, because the product is “in stasis” as the OS and other concerns surrounding the technology metamorphize and stabilize (The Windows 8 UI style, Windows Store, and other concerns in particular). Once the details and current problems with those technologies are sussed out, I feel they will most certainly look back and see how they can bring the wealth of game software written in XNA to the new platform. Even if that doesn’t happen, XNA is still heavily used for XBox development- which is also it’s own expertise.

I hope this helps clear up some of the confusion that has been surrounding XNA. It doesn’t exactly eliminate uncertainty- this could, in fact, be a precursor to cutting the technology altogether. But there is nothing to point to that being the direction, either.

460 total views, no views today

Posted By: BC_Programming
Last Edit: 04 Feb 2013 @ 09:24 PM

EmailPermalinkComments (0)
Tags
 01 Feb 2013 @ 10:23 AM 

Randomization is something that is pretty much a staple in games. But the tricky part is randomizing in an expected way.

Some kinds of randomization, you don’t want to be truly random- just mostly random- and you do in fact want it to go through all the possibilities more frequently, though in a random way.

The best example I can think up is to imagine you have a Enemy that can shoot forwards, backwards, up, and down. Now, targeting the player notwithstanding, let’s assume you want them to shoot randomly. If you go with the approach of just choosing a direction completely at random, you will find that the code will often choose the same direction many times in a row. This is more or less the problem with trying to randomize small sets of data. Each selected element is more or less chosen without regard to those chosen before. This fits probability, of course, but can be a bit weird gameplay wise.

Enter ItemBucket

The solution is fundamentally to make sure that items are chosen at random, but also that every item get’s used. The best solution I could think of was one where you choose elements at random, but you make sure you don’t choose the same elements twice during any one run. The class I created for this purpose I called “CItemBucket”. It’s functionality is fairly simple: it is constructed with the items it will contain. This initializes two lists with those elements. The ItemBucket can “dispense” items; when an item is dispensed, it is removed from the list. if the list is empty, it is reset from the Original List. this makes sure that in any number of elements of size N, any element in that list will occur exactly once during N dispenses. My original idea was to return a randomly indexed element each call, but then I got to thinking that, in many ways, we are simply dealing with a “shuffled deck” of elements, and returning items from that “deck”. So, at the cost of making Adding a bit more expensive, I think I was able to make the retrieval method O(n) for the number of present elements (based on the Queue implementation, that is).

Here, the, is the C# Implementation for this class:

  1.  
  2.     public class ItemBucket<T>
  3.     {
  4.         private int _dispensed = 0;
  5.         private Queue<T> _elements;
  6.         private T []  _original;
  7.         private readonly Random rgenerator = new Random();
  8.  
  9.         public ItemBucket(Random rg, params T []  source)
  10.             : this(rg, (IEnumerable<T>)source)
  11.         {
  12.         }
  13.         private IEnumerable<T> Shuffle<T>(IEnumerable<T> source)
  14.         {
  15.  
  16.             return source.OrderBy<T, int>((item) => rgenerator.Next());
  17.         }
  18.         public ItemBucket(params T []  source)
  19.             : this((IEnumerable<T>)source)
  20.         {
  21.         }
  22.  
  23.         public ItemBucket(Random rg, IEnumerable<T> source)
  24.             : this(source)
  25.         {
  26.             rgenerator = rg;
  27.         }
  28.  
  29.         public ItemBucket(IEnumerable<T> source)
  30.         {
  31.             _original = source.ToArray();
  32.             _elements = new Queue<T>(Shuffle(_original));
  33.         }
  34.  
  35.         public static T []  RepeatArray(T []  array, int count)
  36.         {
  37.             var resultarray = new List<T>(array);
  38.             for (int i = 0; i < count; i++)
  39.             {
  40.                 resultarray.AddRange(array);
  41.             }
  42.             return resultarray.ToArray();
  43.         }
  44.         public ItemBucket<T> AddRange(IEnumerable<T> Elements)
  45.         {
  46.             foreach (var iterate in Elements)
  47.             {
  48.                 _elements.Enqueue(iterate);
  49.                 var neworiginal = new List<T>(_original) { iterate };
  50.                 _original = neworiginal.ToArray();
  51.             }
  52.             _elements = new Queue<T>(Shuffle(_elements));
  53.             return this;
  54.         }
  55.         public ItemBucket<T> Add(T element)
  56.         {
  57.             _elements.Enqueue(element);
  58.             _elements = new Queue<T>(Shuffle(_elements));
  59.             var neworiginal = new List<T>(_original) { element };
  60.             _original = neworiginal.ToArray();
  61.             return this;
  62.         }
  63.         private T DispenseSingle()
  64.         {
  65.             //dispense a single item.
  66.             //get an index into the Elements array.
  67.             T retrieved = _elements.Dequeue();
  68.  
  69.             if (!_elements.Any())
  70.             {
  71.                 //no elements, so re-create from Original.
  72.                 Debug.Print("Bucket Empty!");
  73.                 _elements = new Queue<T>(Shuffle(_original));
  74.             }
  75.  
  76.             return retrieved;
  77.         }
  78.         public T Dispense()
  79.         {
  80.             return DispenseSingle();
  81.         }
  82.         public IEnumerable<T> Dispense(int count)
  83.         {
  84.             for (int i = 0; i < count; i++)
  85.             {
  86.                 yield return DispenseSingle();
  87.             }
  88.         }
  89.     }
  90.  

Here is some code that consumes this implementation:

  1.  
  2. class Program
  3.     {
  4.         static void Main(string []  args)
  5.         {
  6.             ItemBucket<int> usebucket = new ItemBucket<int>(ItemBucket<int>.RepeatArray(Enumerable.Range(0, 12).ToArray(), 3));
  7.             Console.WriteLine();
  8.             for (int i = 0; i < 120;i++ )
  9.             {
  10.                 Console.Write(i + ":" + usebucket.Dispense() + ",");
  11.  
  12.  
  13.             }
  14.             Console.ReadKey();
  15.         }
  16.     }
  17.  

Works quite well, as far as I can tell.

But wait, there’s more!

Perhaps because I like to think of myself as something of a polyglot, let’s go ahead and come up with an implementation of this for Java. Now, doing this in Java would be a bit more tricky- that is, directly. Unlike the C# implementation, we don’t have the convenience of lambda’s to make a ‘pure’ shuffle. Instead, we would have to write our own implementation. Instead of that, I went with the original concept- that is, to choose,remove, and return a random index, and re-create the Bucket contents when we’ve emptied it. Here is the Java version of this class:

  1.  
  2. import java.lang.reflect.Array;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import java.util.Random;
  6.  
  7. public class ItemBucket<T> {
  8.     private ArrayList<T> _Elements;
  9.     private ArrayList<T> _Original;
  10.     private Random rgen = new Random();
  11.  
  12.     public ItemBucket(T… Source) {
  13.         this(new Random(), Source);
  14.     }
  15.  
  16.     public static <K> K []  RepeatArray(K []  tocopy, int copies, Class classtype) {
  17.         if (copies < 0)
  18.             throw new IllegalArgumentException("copies must be non-negative.");
  19.  
  20.         @SuppressWarnings("unchecked")
  21.         K []  resultarray = (K [] ) Array.newInstance(classtype, tocopy.length
  22.                 * copies);
  23.         for (int copy = 1; copy < copies; copy++) {
  24.  
  25.             for (int index = 0; index < resultarray.length; index++) {
  26.                 resultarray [index]  = tocopy [index % tocopy.length] ;
  27.             }
  28.  
  29.         }
  30.         return resultarray;
  31.  
  32.     }
  33.  
  34.     public ItemBucket(Random rg, T… Source) {
  35.         rgen = rg;
  36.         _Original = new ArrayList<T>();
  37.         _Elements = new ArrayList<T>();
  38.         for (T addto : Source) {
  39.             _Original.add(addto);
  40.             _Elements.add(addto);
  41.         }
  42.     }
  43.  
  44.     private T DispenseSingle() {
  45.         // dispense a single item.
  46.         // use the Random instance to get a random index.
  47.         int randompos = rgen.nextInt(_Elements.size());
  48.         // grab that element.
  49.         T retrieved = _Elements.get(randompos);
  50.         _Elements.remove(randompos);
  51.         // if the Elements list is empty, ‘refresh’ it from the Original.
  52.         if (_Elements.isEmpty()) {
  53.             _Elements.addAll(_Original);
  54.         }
  55.         return retrieved;
  56.  
  57.     }
  58.  
  59.     public T Dispense() {
  60.         return DispenseSingle();
  61.     }
  62.  
  63.     public List<T> Dispense(int Count) {
  64.         ArrayList<T> buildlist = new ArrayList<T>();
  65.         for (int i = 0; i < Count; i++)
  66.             buildlist.add(Dispense());
  67.  
  68.         return buildlist;
  69.     }
  70.  
  71. }
  72.  

Test code for the above Java implementation:

  1.  
  2. public class testItemBucket{
  3. public static void main(String []  args) {
  4.         ItemBucket<Integer> bucket = new ItemBucket<Integer>(ItemBucket.RepeatArray(new Integer [] {1, 2, 3,4,5,6,7,8,9,10},3,Integer.class));
  5.         //choose 90 items.
  6.         for(int i=0;i<90;i++){
  7.             int gotvalue = bucket.Dispense().intValue();
  8.             System.out.print(i + ":" + gotvalue + ",");
  9.         }
  10. }
  11. }
  12.  

As far as I’m concerned, the most interesting thing in the Java implementation is the “RepeatArray” method. Java’s Generic limitations prevent us from creating Arrays of the Generic Type Parameter directly, so instead we need to use some reflection magic. unfortunately, as far as I can tell there is no way to get the class of the actual type parameter in Java, so I had to resort to accepting that class as a parameter. Also, because of the lack of Generators/Enumerable methods, I ended up simply having that method return a List of the generic type, rather than an Enumerable.

It’s not over yet!

You might think, “OK, he’s covered C# and Java implementations- can I please go home. Well, yes, you can. But then you’ll miss my Python implementation! I went with the same approach I chose for Java- that is, retrieving items randomly and removing them. It’s fully possible to use the same methodology I used for the C# approach- using Queues and sorting on randomized keys- but I found this approach a bit less verbose, and more straightforward. And, it is my opinion that ‘straightforward’ is sort of the “python way”, so I went with that.

  1.  
  2. import random
  3. class ItemBucket:
  4.     def __init__(self,pelements):
  5.         #copy the provided elements.
  6.         self.elements= []
  7.         self.original= []
  8.         for iterate in pelements:
  9.             self.original.append(iterate)
  10.        
  11.         #copy the original list into the elements list.
  12.         self.elements=self.original [1:]
  13.     def DispenseSingle(self):
  14.         #select a random index.
  15.         index = random.randrange(len(self.elements))
  16.         result=self.elements.pop(index)
  17.         if not self.elements:
  18.             #if list is empty, recreate from original.
  19.             self.elements=self.original [1:]
  20.         return result;
  21.     def DispenseMulti(self,n=1):
  22.         #select n items and return them
  23.         x=0
  24.         while x < n:
  25.             yield DispenseSingle(self)
  26.             x+=1
  27.  

And, of course, the Python code that uses it:

  1.  
  2. ib=ItemBucket( [1,2,3,4,5,6,7,8,9] *3)
  3. for i in range(0,40):
  4.     print str(i) + ":" + str(ib.DispenseSingle())
  5.  

The first thing that stands out is just how much shorter this one is to either the Java or C# implementations. This is probably mostly due to the dynamic typing of Python, as well as a few syntactic shortcuts. The only “gotcha” I found was that Python didn’t really support overloaded methods. Technically, I could create one method and then verify what parameters were actually passed, but in this case I wanted one to be a Generator Method, and the other to simply return a single element. Only way I could figure out how to do that was to have separate DispenseSingle() and DispenseMulti() methods. It also doesn’t expose the innards like the other implementations, in that you cannot add Elements to an already constructed instance. In retrospect, I’m not really sure if it’s a good idea to make the design Mutable at all. The Most typical use-case would be to construct it with all the elements it will use, and not change it afterwards- that’s the use case I have in BASeBlock, and the use-case I’m considering using my Java implementation for. So having extra methods to add elements, and keep fields “fresh” and consistent adds implementation complexity for little gain.

606 total views, no views today

Posted By: BC_Programming
Last Edit: 01 Feb 2013 @ 11:46 AM

EmailPermalinkComments (0)
Tags
 18 Jan 2013 @ 11:53 PM 

Undo/Redo Stacks

The BASeBlock Editor has had an Undo/Redo stack for quite a while. The implementation of this logic is relatively simple, but the implementation- or rather, my recent re-implementation- seems like a good subject for a blog post.

Basically, an Undo/Redo Stack Let’s your Program reverse through changes that have been made, and then, if necessary, go forward through those changes. What makes this problem interesting is that, by and large, the core logic is really quite similar. I will attempt to outline the process of creating a Generic Undo/Redo Object that can be used in many contexts.

First, we’ll start with The abstract base class that we will use to represent Undo Elements:

  1.  
  2.     public abstract class UndoRedoStackItem
  3.     {
  4.         protected DateTime _ItemTime;
  5.         protected String _Description;
  6.  
  7.         public DateTime ItemTime { get { return _ItemTime; }}
  8.         public String Description { get { return _Description; }  }
  9.        
  10.         ///  <summary>
  11.         /// Constructs this object, giving it the appropriate Description.
  12.         ///  </summary>
  13.         ///  <param name="Description"/> Description for the constructed instance
  14.         protected UndoRedoStackItem(String Description)
  15.         {
  16.             _Description = Description;
  17.             _ItemTime = DateTime.Now;
  18.  
  19.         }
  20.         ///  <summary>
  21.         /// Copy constructor. This should be implemented by derived classes.
  22.         ///  </summary>
  23.         ///  <param name="copythis"/> Item to copy.
  24.         protected UndoRedoStackItem(UndoRedoStackItem copythis)
  25.         {
  26.             _ItemTime = copythis.ItemTime;
  27.             _Description = copythis.Description;
  28.             _ItemTime = copythis.ItemTime;
  29.         }
  30.         ///  <summary>
  31.         /// Creates a Deep Clone of this Object.
  32.         ///  </summary>
  33.         ///  <returns> A new instance of the same type, with appropriately deep-copied instances for all it’s instance data. </returns>
  34.         public abstract UndoRedoStackItem DeepClone();
  35.        
  36.     }
  37.  

Since we don’t know what, specifically, is being handled, we use this abstract class and provide only very basic methods. The DateTime can be used on appropriate menus or as a sort key, and the Description can be used for any menu text, or other UI elements as needed by the app consuming the class.

This will be used for a generic class, which I will call UndoRedoManager. This will, unsurprisingly, manage the undo and redo operations, or, more specifically, it will manage the data structures dealing with the Undo and Redo information. In order to actually undo, we will need to delegate the task to the caller, on the assumption that they know more about the StackItem. We will call the Events HandleRedo and HandleUndo, and they will take a simple EventArgs. First, we will define the EventArgs class definition.

  1.  
  2. class UndoRedoEventArgs<T>:EventArgs where T:UndoRedoStackItem
  3.     {
  4.         public T StackElement;
  5.         public Boolean Cancel = false;
  6.         public UndoRedoEventArgs(T stackelement)
  7.         {
  8.             StackElement = stackelement;
  9.         }
  10.  
  11.  
  12.     }
  13.  

The Event Argument class is relatively simple; we just have a field for the StackElement, and a field for Cancel, which we will deal with when we fire the event. We use a generic class because we need to support the management of any class type that derives from UndoRedoStackItem, where the appropriate application-specific data will be dealt with and stored.

The “UndoRedoManager” class we will create will be designed as generically as possible. And, to be honest, my original implementation will be a naive one, each Stack Element will be designated as storing a complete “state” for whatever the application is doing. A better approach for applications that have a large amount of state data is to instead store the changes, rather than the entire thing, but that sort of extra functionality is best discussed and designed after we have the basic framework in place.

The first step is to designate what we need to keep track of in the ‘Manager’ Class, as well as our events.

  1.  
  2. private int _maxsize = 10;
  3. //Stack of Undo Elements
  4. private Stack <t>  _UndoStack = new Stack </t>  <t> ();
  5. //stack of Redo Elements
  6. private Stack </t>  <t>  _RedoStack = new Stack </t>  <t> ();
  7. //events.
  8. public event EventHandler <undoredoeventargs <T> > UndoEvent;
  9. public event EventHandler </undoredoeventargs>  <undoredoeventargs <T> > RedoEvent;
  10.  </undoredoeventargs>  </t>  

We need a Maximum size, otherwise it’s possible for the stack to fill up with old Undo elements. We keep a stack for Undo as well as Redo elements. The actual public functionality we need to implement is a method to Undo, a Method to Redo, and a Method to “Push” a new element onto the Undo stack (register a change).

We’ll start with the first method that will usually be used: PushUndo. This will accept a parameter that is the type of the generic type parameter. It will need to:

  1. Make a Deep copy of the item being pushed.
  2. Push that deep copy onto the Undo Stack
  3. Trim the stack to the maximum size.
  4. Clear the Redo Stack

Here is the code to do that. TrimStack() is private method who’s implementation I will cover shortly:

  1.  
  2. public void PushUndo(T pushitem)
  3. {
  4.     Debug.Print("Undo Pushed…");
  5.     T pushthis = pushitem.DeepClone() as T;
  6.     _UndoStack.Push(pushthis);
  7.     TrimStack(_UndoStack, _maxsize);
  8.     _RedoStack.Clear();
  9. }
  10.  

Most of this is self-explanatory. TrimStack’s implementation is a bit trickier, since the Stack class is a bit less revealing beneath it’s Clothing, but we can seduce it:

  1.  
  2. private static void TrimStack<TStackType>(Stack<TStackType> stacktotrim, int maxelements)
  3. {
  4.     if (stacktotrim.Count < maxelements) return; //nothing to do…
  5.     Stack<TStackType> pushto = new Stack<TStackType>();
  6.     while (stacktotrim.Count > 0 && pushto.Count < maxelements)
  7.         pushto.Push(stacktotrim.Pop());
  8.     stacktotrim.Clear();
  9.     while (pushto.Count > 0)
  10.         stacktotrim.Push(pushto.Pop());
  11. }
  12.  

TrimStack here is written to take any Stack Type, though, arguably, this isn’t necessary in this current implementation. (No reason, however, to make it more specific, in my opinion)

First, if the stack has fewer elements than the passed maximum, we have no work to do, so we return right off the bat. Making our work quite easy.

If the Stack does have more elements than the maximum, we pop elements until either the stack to trim is empty (for some reason) or the temporary stack has maxelements elements.

The effect here is to grab the top maxelements items. After this, we clear the stack and push the elements we popped.

The task of performing the Undo has the following steps:

  1. If CanUndo returns false, return only null.
  2. Otherwise, Peek at the top element from the UndoStack.
  3. Create a new instance of the EventArgs class with the peeked element.
  4. Fire the Undo event with the created EventArgs.
  5. If the Event’s Cancel field has not been set, perform a Pop on the Undo Stack, and Push the item we retrieved earlier to the Redo Stack.
  6. Return the Item we removed

The idea here is that the Event handler that is tied to the class will do the application-specific activity for the “undo” operation- we don’t know what the data is, nor what it represents, but the program using us will, so we leave them to it. This also enables the less naive implementation concept that I’ll be using later to extend this.

  1.  
  2. public T Undo()
  3. {
  4.     if (CanUndo)
  5.     {
  6.         //pop element of UndoStack.
  7.         T popped = _UndoStack.Peek();
  8.         //fire Undo…
  9.         var useargs = new UndoRedoEventArgs<T>(popped);
  10.         fireUndo(useargs);
  11.         //if it wasn’t cancelled, really pop it off the stack, and push it to the Redo Stack.
  12.         if(!useargs.Cancel){
  13.             _UndoStack.Pop();
  14.             _RedoStack.Push(popped);
  15.         }
  16.         return popped;
  17.     }
  18.  
  19.     return null;
  20.  
  21. }
  22.  
  23.  
  24. Redo is, of course, very much the opposite-
  25.  <ol>
  26.  <li> If we cannot Redo, return null. </li>
  27.  <li> peek and store the first element of the Redo Stack. </li>
  28.  <li> Create a new UndoRedoEventArgs instance with the peeked element. </li>
  29.  <li> fire the Redo Event with the created instance. </li>
  30.  <li> if the passed argument‘s cancel field has not changed, pop the element from the redo stack, and push it onto the Undo stack. </li>
  31. </ol>
  32.  
  33.  
  34.  
  1.  
  2. public T Redo()
  3. {
  4.  
  5.     if (CanRedo)
  6.     {
  7.         T popped = _RedoStack.Peek();
  8.         //fire redo…
  9.         var useargs = new UndoRedoEventArgs<T>(popped);
  10.         fireRedo(useargs);
  11.         if (!useargs.Cancel)
  12.         {
  13.             _RedoStack.Pop();
  14.             _UndoStack.Push(popped);
  15.         }
  16.         return popped;
  17.  
  18.     }
  19.     return null;
  20. }
  21.  

And that is pretty much the core implementation. Of course, as it is, we don’t actually have an implementation for the StackElement class. Since that is something we left up to the client application, let’s create one. Here is a small Windows Form that utilizes the aforementioned classes as well as providing an implementation of the Stack Item for a TextBox:

The Designer class:

  1.  
  2.     partial class Form1
  3.     {
  4.         ///  <summary>
  5.         /// Required designer variable.
  6.         ///  </summary>
  7.         private System.ComponentModel.IContainer components = null;
  8.  
  9.         ///  <summary>
  10.         /// Clean up any resources being used.
  11.         ///  </summary>
  12.         ///  <param name="disposing"/> true if managed resources should be disposed; otherwise, false.
  13.         protected override void Dispose(bool disposing)
  14.         {
  15.             if (disposing && (components != null))
  16.             {
  17.                 components.Dispose();
  18.             }
  19.             base.Dispose(disposing);
  20.         }
  21.  
  22.         #region Windows Form Designer generated code
  23.  
  24.         ///  <summary>
  25.         /// Required method for Designer support – do not modify
  26.         /// the contents of this method with the code editor.
  27.         ///  </summary>
  28.         private void InitializeComponent()
  29.         {
  30.             this.textBox1 = new System.Windows.Forms.TextBox();
  31.             this.cmdUndo = new System.Windows.Forms.Button();
  32.             this.cmdRedo = new System.Windows.Forms.Button();
  33.             this.SuspendLayout();
  34.             //
  35.             // textBox1
  36.             //
  37.             this.textBox1.Location = new System.Drawing.Point(12, 30);
  38.             this.textBox1.Multiline = true;
  39.             this.textBox1.Name = "textBox1";
  40.             this.textBox1.Size = new System.Drawing.Size(490, 284);
  41.             this.textBox1.TabIndex = 0;
  42.             //
  43.             // cmdUndo
  44.             //
  45.             this.cmdUndo.Location = new System.Drawing.Point(12, 1);
  46.             this.cmdUndo.Name = "cmdUndo";
  47.             this.cmdUndo.Size = new System.Drawing.Size(75, 23);
  48.             this.cmdUndo.TabIndex = 1;
  49.             this.cmdUndo.Text = "Undo";
  50.             this.cmdUndo.UseVisualStyleBackColor = true;
  51.             this.cmdUndo.Click += new System.EventHandler(this.button1_Click);
  52.             //
  53.             // cmdRedo
  54.             //
  55.             this.cmdRedo.Location = new System.Drawing.Point(93, 1);
  56.             this.cmdRedo.Name = "cmdRedo";
  57.             this.cmdRedo.Size = new System.Drawing.Size(75, 23);
  58.             this.cmdRedo.TabIndex = 2;
  59.             this.cmdRedo.Text = "Redo";
  60.             this.cmdRedo.UseVisualStyleBackColor = true;
  61.             this.cmdRedo.Click += new System.EventHandler(this.button2_Click);
  62.             //
  63.             // Form1
  64.             //
  65.             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
  66.             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
  67.             this.ClientSize = new System.Drawing.Size(506, 318);
  68.             this.Controls.Add(this.cmdRedo);
  69.             this.Controls.Add(this.cmdUndo);
  70.             this.Controls.Add(this.textBox1);
  71.             this.Name = "Form1";
  72.             this.Text = "Form1";
  73.             this.Load += new System.EventHandler(this.Form1_Load);
  74.             this.ResumeLayout(false);
  75.             this.PerformLayout();
  76.  
  77.         }
  78.  
  79.         #endregion
  80.  
  81.         private System.Windows.Forms.TextBox textBox1;
  82.         private System.Windows.Forms.Button cmdUndo;
  83.         private System.Windows.Forms.Button cmdRedo;
  84.     }
  85.  

Proper code-behind class:

  1.  
  2.     public partial class Form1 : Form
  3.     {
  4.         TextBoxUndoManager tboxManager;
  5.         public Form1()
  6.         {
  7.             InitializeComponent();
  8.         }
  9.  
  10.         private void Form1_Load(object sender, EventArgs e)
  11.         {
  12.             tboxManager = new TextBoxUndoManager(textBox1, 50, 500);
  13.         }
  14.  
  15.         private void button1_Click(object sender, EventArgs e)
  16.         {
  17.             //undo
  18.             tboxManager.Undo();
  19.         }
  20.  
  21.         private void button2_Click(object sender, EventArgs e)
  22.         {
  23.             tboxManager.Redo();
  24.             //redo
  25.         }
  26.     }
  27.     public class TextBoxUndoManager
  28.     {
  29.         private int _DelayTime;
  30.         private TextBox _ManageBox = null;
  31.         private UndoRedoManager<TextUndoItem> UndoObject = null;
  32.         private Thread pressdelaythread = null;
  33.         private DateTime? StartDelay;
  34.         public TextBoxUndoManager(TextBox managebox, int nMaxSize,int msdelay)
  35.         {
  36.             UndoObject = new UndoRedoManager<TextUndoItem>(nMaxSize);
  37.             UndoObject.UndoEvent += UndoObject_UndoEvent;
  38.             UndoObject.RedoEvent += UndoObject_UndoEvent;
  39.             _DelayTime = msdelay;
  40.             _ManageBox = managebox;
  41.            
  42.             _ManageBox.KeyPress += _ManageBox_KeyPress;
  43.         }
  44.  
  45.      
  46.  
  47.         void UndoObject_UndoEvent(object sender, UndoRedoEventArgs<TextUndoItem> e)
  48.         {
  49.             _ManageBox.Text = e.StackElement.Text;
  50.             _ManageBox.SelectionStart = e.StackElement.SelectionStart;
  51.             _ManageBox.SelectionLength = e.StackElement.SelectionLength;
  52.         }
  53.  
  54.         void _ManageBox_KeyPress(object sender, KeyPressEventArgs e)
  55.         {
  56.  
  57.             StartDelay = DateTime.Now;
  58.             Debug.Print("StartDelay set to " + StartDelay);
  59.             if (pressdelaythread == null)
  60.             {
  61.                 //if it’s null, we are waiting for input, so we will push here too.
  62.                 UndoObject.PushUndo(new TextUndoItem(_ManageBox.Text, _ManageBox.SelectionStart, _ManageBox.SelectionLength, "Edit Text"));
  63.                 pressdelaythread = new Thread(DelayThread);
  64.                 pressdelaythread.Start();
  65.             }
  66.         }
  67.         private void DelayThread()
  68.         {
  69.             while(true){
  70.                 Thread.Sleep(0);
  71.                
  72.                 if((DateTime.Now-StartDelay).Value.Milliseconds > _DelayTime)
  73.                 {
  74.                     Debug.Print("Timeout expired");
  75.                     _ManageBox.Invoke((MethodInvoker)(() =>
  76.                     {
  77.                         _ManageBox.ClearUndo();
  78.                         UndoObject.PushUndo(new TextUndoItem(_ManageBox.Text, _ManageBox.SelectionStart, _ManageBox.SelectionLength, "Edit Text"));
  79.  
  80.                         pressdelaythread = null;
  81.                     }));
  82.                     return;
  83.                 }
  84.             }
  85.         }
  86.         public void Undo()
  87.         {
  88.             UndoObject.Undo();
  89.            
  90.  
  91.  
  92.         }
  93.         public void Redo()
  94.         {
  95.             UndoObject.Redo();
  96.  
  97.         }
  98.  
  99.  
  100.     }
  101.     public class TextUndoItem : UndoRedoStackItem
  102.     {
  103.         private String _Text;
  104.         private int _SelectionStart;
  105.         private int _SelectionLength;
  106.         public String Text { get { return _Text; } set { _Text = value; } }
  107.         public int SelectionStart { get { return _SelectionStart; } set { _SelectionStart = value; } }
  108.         public int SelectionLength { get { return _SelectionLength; } set { _SelectionLength = value; } }
  109.  
  110.         public TextUndoItem(String pText,int pStart,int pLength,String Description):base(Description)
  111.         {
  112.             _Text = pText;
  113.             _SelectionStart = pStart;
  114.             _SelectionLength = pLength;
  115.  
  116.         }
  117.  
  118.         public TextUndoItem(TextUndoItem clonethis)
  119.             : base(clonethis)
  120.         {
  121.  
  122.             _Text = (string) clonethis.Text.Clone();
  123.  
  124.         }
  125.         public override UndoRedoStackItem DeepClone()
  126.         {
  127.             return new TextUndoItem(this);
  128.         }
  129.        
  130.  
  131.     }
  132.  

In the above implementation, TextUndoItem is the UndoRedoStackItem implementation I created for textboxes; this stores the selection start and length as well as the full text. The Actual Undo implementation was less trivial than I had hoped; in this case I created a “Managing” class that uses the UndoRedoManager specifically with Textboxes, hooking the appropriate textbox events and implementing a delay after typing stops before Undo’s are pushed onto the stack. This is a very simple implementation of this particular class design; BASeBlock uses a very similar class in it’s Editor, but for the far more complex structures dealt with there, which include several lists of objects.

The extension and addition to this design that I mentioned earlier consists of storing not the entire state, but rather what changed from the previous element. This is unlikely to be a trivial thing to implement.

736 total views, 2 views today

Posted By: BC_Programming
Last Edit: 18 Jan 2013 @ 11:54 PM

EmailPermalinkComments (0)
Tags
 20 Dec 2012 @ 9:12 AM 

I was working on BASeBlock’s splash screen a bit, and thought it would be neat to have a little animation to expand and contract the list of loaded assemblies. I suddenly found myself wanting something similar to JQuery.

It didn’t seem inexorably difficult; so I got to work. Soon I had a simple little class that could move and size a object.

 

But that wasn’t enough. it wasn’t flexible enough- what if I wanted to animate, say, the background color, too? So I created a new project- BCQuery. The purpose is to provide a simple control animation framework; I came to realize that even restricting it to just controls could be limiting, so it really accepts any object at all.

The design is based around a simple threading model. Obviously, all UI actions (such as moving or interacting with Windows Forms controls) need to occur on the main application thread. Thankfully, Control’s expose a “Invoke” and “BeginInvoke” method that can be used to run code on that thread while closing over local variables, which is immensely useful.

 

This runner thread is only active while things are animating. When an animation is added and there is no thread running, it starts it; otherwise, when the last animation completes, the Thread removes itself. The interesting part is that it only uses one extra thread- All animations are performed concurrently here, with extra operations being queued up for execution in that thread before the iteration runs. One of the main concerns here is with the use of a foreach to iterate through and update each animation; since the animation can easily complete and there is no way to directly remove the instance from the collection without the next iteration of the foreach throwing an InvalidOperationException because the collection was changed. Code that needs or wants to remove or otherwise modify that collection can now do so by simply queuing up a piece of code to run the next time through the main animation loop.

I rather like how the project has come so far; I have it so I now need only two lines of code in a form to set up a basic “expando” whereby one control expands and the expander control moves. Given the amount of effort in dealing with what is essentially a finite state machine otherwise, this is extremely helpful IMO. Currently I have “easers” that can work with Size, Point, float, and int property’s, but it isn’t too much trouble to add more; the Point and Size versions use a corresponding easer of the appropriate type; for example, there is a PointFEaser, which uses two FloatEaser’s to ease the X and Y coordinates. This could be useful if I create custom float easers later on to support say… easing. (Though that is far from easy.

It works a treat, and will definitely be the subject of a future blog post.

It’s worth mention that this sort of library would be valueless for, say, WPF. This functionality is far better provided by WPF Storyboards via the Windows XAML rather than using something like this. But you can’t always use WPF, or don’t want to make something “heavy” that uses WPF, but might want some interesting animations like those you might need a simple storyboard for without writing too much code; and that’s what this library will be for.

 

EDIT: It didn’t exactly come to me quickly, but it did only take one debug run (I accidentally swapped two parameters because I named them poorly) before I had it working; considering it uses reflection to change members and properties on the fly, it works quite well. Definitely a class library to be expected with new releases of most of my projects, and of course available standalone.

228 total views, no views today

Posted By: BC_Programming
Last Edit: 20 Dec 2012 @ 09:16 AM

EmailPermalinkComments (0)
Tags
Tags: , , , ,
Categories: .NET, C#
 17 Dec 2012 @ 12:33 PM 

Many developers and programmers may describe their experience with a language or technology as them having “mastered” it. But is this really the case?

Take me as an example- I cannot think of a single technology that I feel comfortable saying I “mastered”; even those that I’ve worked with extensively, such as the C# language itself, or the .NET Framework, or the Java Base Class Library, I don’t feel safe saying I’ve “mastered”. The way I see it, “mastered” implies that for any question about that technology, you will have an answer for. I cannot, personally, say that I’ve reached that stage. In fact, it’s debatable whether any person reaches that stage about anything. C#-wise I’ve worked extensively with the framework, serialization, dynamic dispatch (via C# 4.0/5.0′s “dynamic” keyword).

“Mastered ” for me implies that there is nothing left to learn for that person in that field; but when you think about it, that’s sort of impossible, particularly in regards to software development, programming, and even just computers in general. There is always more to learn, there is always ground left uncovered, and as you uncover that ground you reveal just how much you don’t know. One of my favourite quotes, attributable to Dave Ward, is:

“the more you know, the more you realize just how much you don’t know. So paradoxically, the deeper down the rabbit hole you go, the more you might tend to fixate on the growing collection of unlearned peripheral concepts that you become conscious of along the way.”

This is from Scott Hanselmans blog post on a similar subject- titled “I’m a phony. Are you?”   In many ways, I find myself identifying with this- For example, I still often try to rationalize my reception of an MVP Award as “oh, it’s nothing” or “must have been a mistake”; that is, like the post describes and quotes, people that feel like an imposter. The MVP Award is not just given away to anybody, though. Best I can think of would be that my Blog posts with regard to C# Programming (and programming topics in general) were that good . Personally I have a hard time really believing that.

Much like Scott Hanselman describes in the post, I try to learn a new programming language- even if I don’t use it for a large project, the exposure to new concepts and problem domains can really improve my work in those languages that I’ve used for a longer period, and hold off stagnation. But even so, very seldom do I ever get deep enough into those languages to truly grasp their idioms.

And yet, at the same time, When I push myself into a language- I  eventually catch on. For example- and I’ve written about this before- I languished with Visual Basic 6 for a very long time. I thought it was good enough- there is nothing better. This is what I told others, but who was I trying to convince, them, or me? I aim for the latter. I don’t know what prompted me to do so but I moved on to C#. Now in fairness even then I did at least give other languages a shot, but VB6 was the only one that felt “familiar”; that is, that I could easily type code in without looking up documentation. At some point I’d had enough. Visual Basic 6 was an old, dead, language, and so too would my experience if I didn’t do something. I moved to C# instead of VB.NET mostly out of my own self-interest; I still had many projects in VB6 and I (possibly erroneously) thought that learning VB.NET might cloud my ability to work on those projects. That, and C# seemed to be the de riguer standard.

My first applications were rather simple. I made an attempt to duplicate the functionality of HijackThis first- this was a learning experience, particularly since I was now able to use those OO concepts I knew about but was never able to leverage properly in VB6, which only had interface inheritance. I moved forward with a simple game. This was to become the first version of BCDodger, which is a relatively simple game. The major stumbling block here was with regard to the use of multiple threads and handling concurrency and handling repainting. I eventually looked at my ancient ‘Poing’ game, which was an arkanoid/breakout clone I had written in Visual Basic 6. It was terrible- the drawing code was limited, everything was ugly and there was very little “whizbang” to the presentation. I decided to make a variant of the game in C#, using a better design and a class heirarchy. This snowballed pretty quickly, and I now have a game that is able to dynamically load new components from scripts (which it compiles at startup), has a fully-featured editor that is able to find and show any class that implements a specific interface or derives from a given class in portions of the interface; for example the “add block” toolbar dropdown get’s populated with every single block in the game, categorized based on attributes on the appropriate classes.

With Freelancing, my results have been met with an overwhelmingly positive response, in one case, where I was tasked with using Semantic cleanup of a longest common subsequence algorithm, there was some back-and forth over what might be the best output given what we were working with; the client eventually responded that they did some research and are pretty sure it’s impossible. By which time, I had actually finished implementing it. Needless to say, the results were very positive. The same applies for a similar project where I created the Product Key registration and generation logic in a self-contained class.

The nice thing is that these projects exposed me to things I might not have dealt with before. WPF was a technology I didn’t use until it’s appeal in a given situation made it very much preferable. Full screen, resolution independence was a lot easier with WPF than it would be with Windows Forms- so now I have experience with WPF as well. Naturally the overwhelmingly boring nature of Semantic cleanup of the output of a longest common subsequence algorithm (I nearly fell asleep writing that…) meant I wouldn’t otherwise explore it; however it turned out to be very interesting as well as mentally taxing. There was, of course, some confusion. But each time I was able to look at it with freshly rested eyes (apparently staying up for 48 hours working on the same problem clouds your judgement), I was able to find some very obvious fix or addition to resolve that which I was working on. I guess it boils down to- if you just write what you <want> you will always try to work on something interesting, but not always useful. When working on an actual project- for somebody else, or as an otherwise professional undertaking, what you work on might not always be fun, but it will always be useful to somebody. So in some respects this rubs off; with my own projects, I try to make them fun to work on, but might not always pay the closest attention to how useful they are; in retrospect when working in a professional capacity, whether they are useful is the most important goal. A program that isn’t useful is useless by definition.

This isn’t to say the experience isn’t occasionally frustrating; when you provide a product or service to somebody or something, I like to think there is some sort of a promise of the workmanship of that product; for example on more than one occasion, a product has stopped suiting the original purpose; for example, this could be because it was not as scalable as it needed to be, or perhaps a database corruption has caused some other problems. Whatever the case, since the product no longer works for the original intent, I could never charge for the service of getting the product working again- because that almost seems like holding them hostage.

At the same time, however, part of me doesn’t like releasing new products, simply because it feels like a lifetime contract to keep working on and improving them. This is part of why the vast majority of projects I’ve worked on I’ve not released. and by “vast  majority” we’re talking about nearly a hundred projects. Some big, some small; most of them unfinished in some fashion but most quite usable.

But I’m getting off the topic of this post. My point is, that I like to think I’m fairly awesome, but at the same time, not too awesome. There is plenty out there to learn, and the pursuit of awesomeness demands that I seek them out, absorb them, and then continue. Like a sponge that comes alive and wants to suction up all the water in the world, my task will never be completed. But that doesn’t stop me from trying anyway.

This applies in a general sense, as well; It’s not just programming that I’m very interested in, but rather tangential topics such as gaming and whatnot. I do also enjoy science-fiction- statistically, as a person who works in Software Development, this is more likely than not- as well as simply general knowledge. A good example being a tab I have open in my browser, where I was researching Eggplant. Why? I haven’t a clue. Just something I wanted to absorb and learn about, I suppose.

Conclusion: learning about Eggplants is unlikely to make you a better programmer. But it never hurts to stay versed on vegetables.

366 total views, 2 views today

Posted By: BC_Programming
Last Edit: 17 Dec 2012 @ 12:34 PM

EmailPermalinkComments (0)
Tags
 10 Dec 2012 @ 2:51 AM 

One of the trickiest parts I imagine with hiring a new developer is figuring it out several things about them. One thing you need to figure out is wether they will fit. What I mean is, even the best developer in the world won’t increase a team’s productivity if they don’t mesh well with that team. This means avoiding people that are more likely to force their programming viewpoints on others, or abuse their repo access to “refactor” other peoples code for no distinguishable reason. Additionally, and most obvious- is whether they can actually write code. An astonishing number of applicants to developer positions could not write trivial code in the language they were supposed to know.

The former is why personal interviews- or, if nothing else is possible, a voice communication or phone interview- are used. Though in-person interviews also help determine their personality based on their presentation. The latter- determining whether they are really a developer- is why you often have coding interview questions. I thought I’d look some up and explore them. Why? I dunno.

1.

Given that Pi can be estimated using the function 4 * (1 – 1/3 + 1/5 – 1/7 + …) with more terms giving greater accuracy, write a function that calculates Pi to an accuracy of 5 decimal places.

Now, some developers might end up with something like this:

  1.  
  2.  public static double CalcPI()
  3.         {
  4.             float accuracy = 0.000001f;
  5.             float buildit = 1;
  6.             int multiplicand = 1;
  7.             for (int currdivisor = 3; (1f / (float)currdivisor) > accuracy; currdivisor += 2)
  8.             {
  9.                 buildit += ((multiplicand *= -1) * (1f / (float)currdivisor));
  10.             }
  11.             return 4f * buildit;
  12.         }
  13.  

I rather like the use of the *= directly in an expression. Anyway, this is sort of overthinking it. Look at the question. Like a proof, it provides a given- but, you don’t have to use it Since Pi is a constant, you could just do this:

  1.  
  2. public static double CalcPI() { return 3.14159;}
  3.  

It does what the function wants- it returns Pi to 5 decimal places. However, it also sort of defies the spirit of asking the question; the purpose is to see if you can use loops and basic control structures. This is more a early screen phase, so those looking to hire can avoid the people who thought “C# Developer” in the ad meant somebody who had expertise building Musical instruments. Even my implementation could easily be improved in any number of ways (not using a int as the for loop variable being one example). But it get’s the point across.

The Clock Angle Problem

Another common question is a tad more involved:

 Write a procedure that, given the time of day, will compute the angle (positive) between the minute hand and the hour hand. 

Alright, now we get to some mild brainwork here.It’s interesting because it promotes a bit of thought about the problem. First, you mgiht start by figuring you can just get the angle for the Hour, the angle for the minute, and take the difference:

  1.  
  2. public static double getAngle(DateTime fortime)
  3. {
  4. return Math.Abs((((float)fortime.Hours%12)/12f)-((float)fortime.Minutes/60f))*Math.PI*2);
  5. }
  6.  

However, it is not that simple. Consider the following-

1. Look at an analog clock. When it is 9:30, for example, the hour hand is not pointing at the 9. It’s pointing halfway between 9 and 10. So we need to add an angle equal to the percentage the Minute hand is around a full revolution of the distance between two hours.
2. The difference between the 59′th minute and 12AM or 12PM is not one degree from a full revolution as this would show.

The first problem is “solved” by adding the appropriate amount. The second requires a bit of finagling. The final result for me was this:

  1.  
  2. static double getShortAngle(double a1,double a2)
  3. {
  4.     var angle = (Math.Abs(a1 – a2))%360;
  5.     if(angle > 180)
  6.         angle = 360 – angle;
  7.     return angle;
  8. }
  9. static double CalcAngle(DateTime timetest)
  10. {
  11.     //Write a procedure that, given the time of day,
  12.     //will compute the angle (positive) between the minute hand and the hour hand.
  13.  
  14.     //First get the minute hand angle.
  15.     double MinuteAngle = (2*Math.PI)*(float)timetest.Minute / 60;
  16.  
  17.     //now we need the hour Angle. One common ‘mistake’ here is to forget that
  18.     //the hour hand moves between the numbers smoothly, so the angle will also
  19.     //depend on the minute.
  20.     //first, we get the angle between any two numbers. this is single, a full revolution divided into 12.
  21.     double hourincrement = ((Math.PI * 2) / 12); //this is the angle between the hours.
  22.  
  23.     //hour angle is hour increment multiplied by the hour plus
  24.     //we need to also modulus the hour
  25.     int currhour = timetest.Hour % 12;
  26.  
  27.     return getShortAngle((Math.PI * ((float)currhour / 12)) + (((float)timetest.Minute / 60) * hourincrement),
  28.     MinuteAngle);
  29.            
  30.  
  31. }
  32.  

You can see my comments in there as well; I wrote those before I added the code which they “document”. Now, even this could be argued as being wrong in much the same way as the original version was wrong; the minute hand, like the hour hand, does not “jump” between each minute (depending on the clock); instead the minute hand moves smoothly between the minute markings, based on the second. So in order to be “complete” we’d need to also add in that. But this is much more accurate. The Angle check is perhaps the least obvious part, but is relatively simple and doesn’t require any super advanced trigonometry either.

460 total views, 4 views today

Posted By: BC_Programming
Last Edit: 10 Dec 2012 @ 01:43 PM

EmailPermalinkComments (0)
Tags

 Last 50 Posts
 Back
Change Theme...
  • Users » 861
  • Posts/Pages » 192
  • Comments » 67
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

PP



    No Child Pages.

Windows optimization tips



    No Child Pages.