Latest Game

Right Margin Line in Visual Studio 2008

by Benjamin Nitschke 25. February 2010 15:12
I might have blogged about this before, but I could not find my own blog post, so why not blog it again.
Since the recent CodeRush 10 beta, which works in VS2010 RC finally, there is no more Right Margin line that can be enabled under Options->Editors->Painting. I also tried to enable some modules, but I cannot see the margin line anymore (works fine with CodeRush 9).

Well, in Visual Studio you can also enable a margin line with a registry entry at:
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\Text Editor]
"Guides"="RGB(64,64,192) 79"
This will produce a blue margin line right before the 80th column. It looks good on white and black backgrounds, but you can of course change it easily to any color and position. If you don't want to go into regedit, just execute this handy RightMarginLineVS2008.reg (280 bytes) file.

Seattle 2010 - MVP Summit - Day 5

by Benjamin Nitschke 17. February 2010 22:37
This day we MVPs will go deep into sessions about lots of cool new technology. Everything is under NDA, so we are not allowed to talk about it. Most of my picture will just show people and what happened over the day. There might be information out in the web, but we MVPs are not allowed to comment on that ^^

Seattle 2010 Day 5
First thing of the day is to get some breakfast, which was very good in my hotel.

Seattle 2010 Day 5
I tried to take the last bus at 08:30, which was not such a good idea because the bus was late 20 minutes, which leaded to getting a little late on the first meeting at 09:00. But at least I met another new nice MVP from Korea: Dong-Hoon Kim

Seattle 2010 Day 5
The bus ride to Microsoft Campus was pretty quick once the bus finally arrived.

Seattle 2010 Day 5
We are almost at building 92, where Studio A is just a walking distance away.

Seattle 2010 Day 5
While searching for Building Studio A we went through building 92 and saw the company store right there (must have moved, last time it was somewhere completely different).

Seattle 2010 Day 5
There were lots of guys and girls standing around helping us with directions.

Seattle 2010 Day 5
We finally reached Studio A, pretty colorful posters up here, but finding the actual conference room was not very easy, 5000 room numbers, wtf?

Seattle 2010 Day 5
Lots of XNA MVPs here.

Seattle 2010 Day 5
And even more on the other side.

Seattle 2010 Day 5
And some guys from the XNA team.

Seattle 2010 Day 5
Dong-Hoon is also taking pictures. Funniest thing he told me yet was a joke from Korea: If someone asks you when the shuttle is coming, answer: You are not Protoss, there is no Shuttles for you.

Seattle 2010 Day 5
This is Nick Gravelyn, a former XNA, which now is part of the Borg, erm, Microsoft XNA team :)

Seattle 2010 Day 5
This is was happens to gramophone record here ..

Seattle 2010 Day 5
XNA guys running around, I am too lazy to tag them now ..

Seattle 2010 Day 5
Almost there at the new conference room location.

Seattle 2010 Day 5
A big room with lots of MVPs, big meeting ahead. Sorry, not allowed to disclose any more details .. at least it was interesting stuff.

Seattle 2010 Day 5
And finally walking back to the bus stop, the day is almost over. Time for a XNA party.

Seattle 2010 Day 5
Kathleen explains that we will go to the Big Picture bar and whats going on in general.

Seattle 2010 Day 5
On the bus ride everyone was checking and hacking on their phone. Most people have iPhones, which is kinda funny ..

Seattle 2010 Day 5
We had some extra time, so like last year we visted the Game Workshop board game shop, but I don't think anyone bought anything.

Seattle 2010 Day 5
The problem with the bar this time was that we were way to few people to fill it. Lots of room, but only a few guys in each. Last year this party was at this very same location, but we had some other teams here too and it was more crowded and party-like.

Seattle 2010 Day 5
XNA guys like Nick talking to XNA MVPs Andy and George.

Seattle 2010 Day 5
Everyone was taking pictures.

Seattle 2010 Day 5
After a while the UK and Irish MVPs were suggesting that we go to the Irish pub again because there is not much going on here (even though we had Pizza and free beer, yeah). This is a quick picture from the Big Picture ^^

Seattle 2010 Day 5
Some guys have their hotel right here, so they were quickly dropping of their stuff. I didn't want to go all the way to my hotel and back, so I just waited a bit here.

Seattle 2010 Day 5
Don't really know how this picture happend, but from the time stamp I can see this was taken BEFORE I was even drunk, which makes not much sense. I still think this is a cool photo.

Seattle 2010 Day 5
We stayed way too long in the pub, it was almost 1am when we finally left and I walked back to my hotel. At 7am my roommate got up, so there wasn't a long night sleep. Hopefully I won't be too exhausted the next day.

How to keep the Intellisense info box short and tidy

by Benjamin Nitschke 15. January 2010 08:39

If you ever have wondered why you need all these Object class method in your class intellisense list, this is the right article for you. I recently wrote an Assert class for our own unit testing system (as reported yesterday we were pretty unhappy with TestDriven.net+xunit in our engine). Even though I have only written 10 methods in the Assert class, which I think are the most essential ones for unit testing, whenever I write Assert. Intellisense pops up with 15 Items instead of 10. In my case (statically accessing Assert) the following 5 Items were displayed without my consens:

  • The Contains method appears 2 times because one is using strings, the other overload is using generics
  • object.Equals appears because every class is derived from object!
  • Same for object.ReferenceEquals
  • The sub class Tests appears to, but I only need it for unit testing (but it needs to be public for xunit)
  • And finally there is a delegate ThrowsDelegate, which is needed for the Throws method.

Additionally if you access a class via an instance (not statically) you will get the following object methods displayed in your intellisense too:

  • Equals (there is one static method with 2 arguments and a non static one with 1 argument)
  • GetType
  • GetHashCode
  • And finally ToString

 

I cannot remember the last time I really needed those object methods in any classes intellisense. Luckily there is an easy solution to fix this, but you need to be aware that it does not work in every situation. But as you can see I managed to reduce my Assert class intellisense list down to the 10 items I really wanted:

 

Basically you just add the following attribute to any method, sub class or property that you do not want to appear in the intellisense list:

[EditorBrowsable(EditorBrowsableState.Never)]

This works fine and dandy with your own methods (like in my example the ThrowsDelegate and the Tests sub class, but what about those nasty object methods? Well, static methods you can just re-implement with the new keyword (overwriting the original methods) and just specify the EditorBrowsable attribute there:

#region Hide object.Equals and object.ReferenceEquals
/// 
/// Equals
/// 
[EditorBrowsable(EditorBrowsableState.Never)]
public new static bool Equals(object objA, object objB)
{
	return object.Equals(objA, objB);
} // Equals(objA, objB)

/// 
/// Reference equals
/// 
[EditorBrowsable(EditorBrowsableState.Never)]
public new static bool ReferenceEquals(object objA, object objB)
{
	return object.ReferenceEquals(objA, objB);
} // ReferenceEquals(objA, objB)
#endregion

For the non-static methods we can even use a simpler trick by deriving your class from the following IHideObjectMembers interface, which already adds the required attributes to the 4 annoying object methods.

/// 
/// Helper interface used to hide the base  members from
/// your classes to make intellisense much cleaner. Note: This ONLY works
/// from other assemblies AND you MUST NOT have the project using this
/// interface in your solution (else VS will still show them).
/// 
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IHideObjectMembers
{
	[EditorBrowsable(EditorBrowsableState.Never)]
	Type GetType();

	[EditorBrowsable(EditorBrowsableState.Never)]
	int GetHashCode();

	[EditorBrowsable(EditorBrowsableState.Never)]
	string ToString();

	[EditorBrowsable(EditorBrowsableState.Never)]
	bool Equals(object obj);
} // interface IHideObjectMembers

One final thing I had to do to get rid of my two Contains methods was to rewrite the string one to a generic one, so it appears together with the other generic one (using lists) in the Intellisense list, but that was no biggy.


When you try this out you might wonder why the hell it is not working for you and sadly the answer is: Yes, it does not work all of the time. As already mentioned in the IHideObjectMembers implementation the hiding only works if you DO NOT HAVE the assembly from the class you are intellisensing in your solution. You need to reference it as an dll (a local file or from the GAC). Even then you might want to create a new solution for testing this out. The strange thing is that after a while VS seems to learn and will use your reduced intellisense even if you have the project in the solution, but I have no idea why this sometimes works (when writing this blog entry it almost always worked inside my Assert assembly even). Anyway, it is still a very useful trick IMO.

Collapsing Projects in Visual Studio Solutions

by Benjamin Nitschke 13. January 2010 11:09

DeltaEngine VS Collapse

If you have 50+ projects in a single solution it can be annoying that you cannot collapse them all with a single click or keystroke. Expanding everything can be simply done with Numpad * at any node in the solution explorer. Having so many projects in a solution and compiling them all everytime you F5 something is not such a good idea because compile time goes through the roof (even though each single project is compiled really quickly, usually in much less than a second). Please note that our projects are mostly very simple and having so many projects is by design because they only implement certain features and can be easily replaced (or there are several modules for the same feature, just doing differently or for different platforms). We should blog about that too, I think it is a pretty good idea and makes refactoring and multiplatform development much easier than big projects and lots of ugly defines (we have almost no defines right now and are pretty happy with it).

 

To solve this we have a little helper tool that recursively selects the projects you need for any given project you want to work on, then you end up with 3-4 projects instead of 50+ (we have like 10-20 new projects every month, so this will probably increase for a while). An alternate solution is to fiddle with the build settings in the Configuration Manager to just compile some projects, but not the rest. But this is very error prone and can cause many headaches because you forgot to compile some project you changed some little thing and then your code will still execute the old .dll with the old code missing your newly implemented functionality.

 

But the problem with so many projects, and usually in any kind of Visual Studio solution, is that you cannot easily collapse all projects at once. Instead you have to collapse them one by one, which can be fun with 5 projects, but it is certainly not funny with 50+ projects anymore and you practically have to do it every day to keep the solution explorer short and tidy. Luckily some clever people solved this problem many years ago with macros or extensions and I like the simple macro version. There is a great tutorial with all required steps available, which you can use to set it up for your Visual Studio. We use a slightly modified macro that works better with our sub folders that have projects too:

 

Imports System
Imports EnvDTE
Imports System.Diagnostics

Public Module Collapse
    Sub CollapseAll()
        ' Get the the Solution Explorer tree
        Dim UIHSolutionExplorer As UIHierarchy
        UIHSolutionExplorer = DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Object()
        ' Check if there is any open solution
        If (UIHSolutionExplorer.UIHierarchyItems.Count = 0) Then
            ' MsgBox("Nothing to collapse. You must have an open solution.")
            Return
        End If
        ' Get the top node (the name of the solution)
        Dim UIHSolutionRootNode As UIHierarchyItem
        UIHSolutionRootNode = UIHSolutionExplorer.UIHierarchyItems.Item(1)
        UIHSolutionRootNode.DTE.SuppressUI = True
        ' Collapse each project node
        Dim UIHItem As UIHierarchyItem
        For Each UIHItem In UIHSolutionRootNode.UIHierarchyItems
            'UIHItem.UIHierarchyItems.Expanded = False
            If UIHItem.UIHierarchyItems.Expanded Then
                Collapse(UIHItem)
            End If
        Next
        ' Select the solution node, or else when you click 
        ' on the solution window
        ' scrollbar, it will synchronize the open document 
        ' with the tree and pop
        ' out the corresponding node which is probably not what you want.
        UIHSolutionRootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)
        UIHSolutionRootNode.DTE.SuppressUI = False
    End Sub

    Private Sub Collapse(ByVal item As UIHierarchyItem)
        ' Recursively collapse
        For Each eitem As UIHierarchyItem In item.UIHierarchyItems
            If eitem.UIHierarchyItems.Expanded AndAlso eitem.UIHierarchyItems.Count > 0 Then
                Collapse(eitem)
            End If
        Next

        ' First try to collapse
        item.UIHierarchyItems.Expanded = False

        ' Check if it failed, if yes, then do it manually
        If item.UIHierarchyItems.Expanded = True Then
            item.Select(vsUISelectionType.vsUISelectionTypeSelect)
            DTE.ToolWindows.SolutionExplorer.DoDefaultAction()
        End If
    End Sub
End Module

Visual Studio 2010 Delayed, VS2010 RC coming in February 2010

by Benjamin Nitschke 13. January 2010 09:59

VS2010 logo

It is almost old news that Visual Studio 2010 was delayed from March 2010 to some unanounced date a few weeks later (plus the beta period was extended). However, many people I know are not doing anything with VS2010 Beta2 yet and only want to switch to VS2010 when it is really stable plus many addins are available. As reported 3 months ago (when VS2010 came out in Oct2009) we were pretty happy with VS2010 Beta 2, most things worked just fine, but we could not use CodeRush. Without CodeRush most team members were far less productive, so we switched back to VS2008 after a few days. Since DevExpress has not released a VS2010 compatible version of CodeRush yet (see their 2010 roadmap, CodeRush 2010 will be released when VS2010 is final), we are still using VS2008.

 

However, I am currently writing an addin for our engine and I really want to replace xunit/TestDriven.net because it just does not work for us anymore. We have a lot of problems with other platforms, with static unit tests, graphical tests, logging, etc. Instead of living or circumventing all these problems (this is what we have done in the last few months) we really want to be more productive and have things just work, which is especially important for unit tests IMO. I like writing VS2010 addins much more than to fiddle around with the VS2008 SDK and since we will switch soon anyway, I will write this plugin in VS2010. In the meantime we will try to use some simple VS macros to accomplish basic testing jobs. I will blog more about this in a bit.

 

How to write unmaintainable code

by Benjamin Nitschke 22. December 2009 10:47

In case you are afraid of being laid off, there are some tips how to make yourself irreplaceable by writing really unmaintainable code. It is a really funny read and every sane person will suggest the exact opposite. My only question is how can you really do any work when your own code is so unmaintainable ..

http://phpadvent.org/2009/unmaintainable-php-by-stoyan-stefanov

 

 

 

 

 

 

 

 

 

 

 

Have a nice christmas and a happy new year in case no one blogs here anymore. But we will probably take a few photos from our christmas party today and post something fun for christmas ..

 

How to change Flash z-order

by Benjamin Nitschke 18. December 2009 12:40
Flash

Just a little trick I found out, which helps if you have some Flash object on your website or multiple Flash objects overlapping and do not want the Flash object to block other Flash objects that are rendered later (e.g. loaded via javascript) or some other dynamic elements like javascript menus.

 

Well, all you have to do is to put the Flash object that is on top and blocking other elements you want to have visible on top of it via the transparent mode (not really intuitive, but it works):


 
And for the embed tag add the following parameter:
wmode="transparent" 
A complete example:

  
  
   
  

which produces this:

Posting code on this blog

by Benjamin Nitschke 16. December 2009 14:00

A few little tricks on how to blog code or any text files for that matter (.txt, .xml, .cs, .cpp, etc.):

You can use the Code Style from the Editor, but that code will just be monofont and handle the spacing, newlines and tabs if you paste it into the non-html editor.

A better way, but sadly incompatible with the non-html editor is to use the following tags (must be done in raw html mode and you should do it when all the rest of the text is written):


<pre class="brush: csharp">

or use


<pre class="brush: xml">

for xml, etc.

When you are done with your code block, just close it with


</pre>



To post images in the upper right corner like I always do, just upload an image, go to html mode and copy it to the very start of the blog post and add style="float:right" to the img tag!

References:

  • Other brush names:
Bash/shellbash, shell
C#c-sharp, csharp
C++cpp, c
CSScss
Delphidelphi, pas, pascal
Diffdiff, patch
Groovygroovy
JavaScriptjs, jscript, javascript
Javajava
JavaFXjfx, javafx
Perlperl, pl
PHPphp
Plain Textplain, text
PowerShellps, powershell
Pythonpy, python
Rubyrails, ror, ruby
Scalascala
SQLsql
Visual Basicvb, vbnet
XMLxml, xhtml, xslt, html, xhtml

Conditionally linking against DLLs depending on configuration/platform

by Henning Thöle 16. December 2009 12:31

Dynamic Linking

When developing for multiple platforms you will eventually run into a situation where you have to link against different platform specific libraries depending on which platform you compile for.

A very basic example would be compiling a very simple (non-graphic) application for Windows and Linux. On Windows you want to use the original .NET libraries and on Linux you want to link against the Mono libraries.

Without dynamic linking you have to create two different projects in the same folder and let them share the same code files. This is cumbersome and probably causes errors, because you may forget to include newly created files in one of the projects.

With dynamic linking you can use a single project file and instead create two project (and solution) configurations for each platform. The project configurations declare preprocessor defines (assume WINDOWS and LINUX), which we use to differentiate between the two configurations. You can also use these defines in code files to execute platform specific code.

(Note: For simplicity's sake I have only created debug configurations in the following example, no release configs)

The following snippet of the MultiPlatformTest.csproj file shows the two project configurations for our test application.

(Note: All of the modifications made here must be done using a text editor of your choice in the .csproj file)


  true
  full
  false
  bin\Debug\
  TRACE;DEBUG;WINDOWS
  prompt
  4


  true
  bin\Debug Linux\
  TRACE;DEBUG;LINUX
  full
  AnyCPU
  prompt



So, how do we declare different references based on platform?

"MSBuild Conditional Constructs" is the answer!

The XML of .csproj files know an element called "Choose", which allows you to implement simple "if"s inside the project definition. We can use this element to implement our multiplatform application.

First of all we have to define something that we can check for in the "When" part of the "Choose" element.

Add a new XML element to each of the above <PropertyGroups>:


  
  
  



At the same time, change the old preprocessor define in <DefineConstants> to use this new element. Our project configurations should now look like this:

  
    true
    full
    false
    bin\Debug\
    WINDOWS
    TRACE;DEBUG;$(MyPlatform)
    prompt
    4
  
  
    true
    bin\Debug Linux\
    LINUX
    TRACE;DEBUG;$(MyPlatform)
    full
    AnyCPU
    prompt
    true
  


(Note: I've also added the <NoStdLib> element to the Linux define, which is required when you want to link against the Mono version of mscorlib.)

Open the project in Visual Studio (or let VS reload it) and toggle between the two configurations in the project properties. The text box with "Conditional compilation symbols" will correctly show "WINDOWS and "LINUX" (respectively).

Now we still have to use these defines correctly. Let's replace the whole "Reference" ItemGroup block with the following:

  
  
  
    
      
        
        
        
      
    
    
      
        
        
        
        
      
    
  


(Note: Replace <Path_to_Mono> with your local Mono path)

Reload the project file.

The first thing you may notice is a shortcoming of Visual Studio:

In the solution explorer the "References" part of the project is now empty. (You may have to click the little "+" symbol to refresh this)
This is only a visual bug; the compiler and Intellisense handle this correctly!

You can easily verify this by adding a new reference (e.g. "System.Windows.Forms") to one of your configs and putting a "#using System.Windows.Forms" into one of your project code files. When switching between the configs you will get compiler/parser errors with the configuration where the reference is missing. Intellisense will only work with the config where the reference was added.

Congratulations! You can now add all your platform specific references to the new ItemGroup blocks and put all non-platform specific references into the old ItemGroup block.

By the way, you also do this with any other define you have. For example you can check for "DEBUG" define and only link testing libraries into debug builds.

References:
  • http://msdn.microsoft.com/en-us/library/ms164307.aspx


  • Using NDepend

    by Benjamin Nitschke 2. December 2009 15:16

    A fellow MVP Patrick Smacchia is the developer of the .NET tool NDepend, which allows to analyze any .NET code base and helps dealing with code complexity. Since I have been using the tool on and off for a while now and recently very much for the development of our new Engine (a multiplatform engine in .NET), I was asked to write a little review about it. Why not, it is a great tool :) NDepend is probably most recognized for generating interesting looking Bubble Graph. For example our current early testing engine produces the following graph. This tells us where we need to refactor the most, simplify stuff, add more features, etc. Please note that we are currently heavily editing the engine every day and this graph changes almost completely every week. This Bubble Graph shows which methods in all of our 32 projects are currently public (blue). As you can see maybe the Helpers assembly on the left is mostly gray because we already made lots of stuff private/protected. This is just one example, there are many many metrics that can be displayed.




    After extracting NDepend (there is no installer) you have a bunch of files in some directory. The most useful looking one is VisualNDepend.exe, which starts the GUI of NDepend. As you can see you can enable integration with Visual Studio 2005 and 2008 (no 2010 yet, but does not really matter, you can still start NDepend by yourself) and with the great Reflector tool. The integration via the addins just provides an easier way to load and inspect assemblies, you can do the same with Visual NDepend on your own.

     

    The second thing I noticed was the "Getting Started" panel, which provides a great deal of help and especially tutorials on how to do things. This is kinda important for NDepend because it is not clear what you actually do with this tool, even after using it for a while. The bad thing about all the tutorials (all of them can be found online: http://www.ndepend.com/Features.aspx) is that they have no sound or voice, just boring text boxes popping up. But if you search for a feature or want to know how to do things, you will most likely find some useful information after a very short while. Also good is that all the information can be found at a central location and everything is linked nicely together. After using the tool a few times it is also not that hard to write own commands with the CQL (Code Query Language) inside NDepend, which is pretty much self explanatory and can be written very easily with Intellisense, for example:

    SELECT METHODS  WHERE NbLinesOfCode >  50  AND IsPublic 

    This selects all public methods with more than 50 lines of code in the Bubble Graph. Since only a handful methods will popup (in blue), it is easy to now go and refactor those methods if we really want to reduce the complexity of methods that have too many lines of code. You can obviously show many other things with NDepend, but I usually just go to the Features page or play around with the dropdownbox values until I find something that looks interesting for my assemblies (lines of code, il instructions, complexity, accessors, number of callers, etc.). Then on our "Refactoring Friday" we can use this data to make more clever decissions and refactor methods that really need refactoring and are actually used instead of refactoring anything that is not called much anyway and we should not care much about yet anyway.

    VisualNDepend also shows some other interesting metrics. The Dependency Graph shows which assembly is required by which assembly and what assemblies they use in turn (until reaching mscorlib on the right usually). The cool thing is when investigating some assembly, e.g. in the Dependency Matrix, it will also be highlighted in the other views (e.g. Dependency Graph or the Bubble Graph in Metrics). The following image shows which assemblies are using Delta.Helpers and which assemblies it requires itself. Please note that most assembly loading happens dynamically in our engine, which NDepend does not show, so this is only partially useful for us. But for some rules, like every assembly should reference our base assembly Delta, we can easily check if any assembly does not follow this rule by hovering the mouse over Delta, which will highlight all assemblies that use it, the rest remains gray.

     

    One final image I want to share is the Dependency Matrix, which shows which assembly is used by which other assembly. Since most assembly and type usage happens dynamically at load time, most of this matrix should be empty. As you can see some assemblies still have quite a lot of references. For some it makes sense because it it can be easier to use Utilities statically instead of defining an interface for every freaking method. This is why we have a few exceptions for static modules, which have almost no other assembly requirements, but are used by many assemblies. It is still easy to replace such assemblies, but they cannot be replaced at runtime like our dynamic modules. I will blog more about this in the future. For now NDepend helps us to see that some assemblies still have too many static references and others are ok. Next Friday we will focus and removing some more references in those assemblies, which still have too many dependencies we do not want. Until then the Dependency Matrix will probably look pretty much like this (more modules are coming and going every day however):

     

     

     

    Disclaimer: The opinions expressed in this blog are own personal opinions and do not represent the companies view.
    © 2000-2010 exDream GmbH & MobileBits GmbH. All rights reserved. Legal/Impressum

    Recent Games

    Fireburst

    ArenaWars Reloaded

    Jobs @ exDream

    Current Poll

    Do you know what the Delta Engine is?



    Show Results Poll Archive

    Calendar

    <<  March 2010  >>
    MoTuWeThFrSaSu
    22232425262728
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234