JSEDLAK » .NET

Posts Tagged ‘.NET’

Provider Model – Design Pattern

A design pattern made famous in the .NET community by Microsoft’s ASP.NET, the provider model explains is a pattern that supplies the end-developer with a plug-and-play architecture. The provider model is most often used when you have a consumer object that is dependent on specific functionality that can be supplied by one or more underlying systems. The major benefit of which is an increase in manageability and reusability.

Read the rest of this entry »

FGF: A Helper For Creating Render Targets

Before I begin this post, big thanks to Eibx and David over at the Community Forums for helping me find these methods. I have modified the CheckTexture method a bit, but its purpose remains unchanged.

As of the last FGF article, the Application class was implementing the IGame interface but was missing the ability to create a render target object on the PC and Xbox 360. For PC games this can be a troubling problem since different hardware can obviously require different formats and dimensions of render target. Rather than bake this functionality into the Application class itself, it is moved to a static helper class so that all developers can make good use of its functionality at any point in time.

To start off, a simple default creation method is included to give the basic functionality an easy access point.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System;
 
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
 
namespace FocusedGames.Xna.Graphics
{
    public static class GraphicsHelper
    {
        public static RenderTarget2D CreateRenderTarget(GraphicsDevice device)
        {
            return CreateRenderTarget(
                device, 
                device.PresentationParameters.BackBufferWidth, 
                device.PresentationParameters.BackBufferHeight, 
                1, 
                device.PresentationParameters.BackBufferFormat
            );
        }

Read the rest of this entry »

2D Fog Of War

Fog Of War Sample

This tutorial covers a basic way of implementing two dimensional fog of war for a game in XNA and assumes you (the reader) has basic knowledge of C# and the XNA Framework. To get things started, create an empty Windows game project. Two textures will be needed: one for the Light and one for the Background. After adding these to the Content Project, go ahead and add the following members to the game class.

?View Code CSHARP
1
2
3
4
5
6
7
Texture2D lightTexture;
Texture2D backgroundTexture;
 
RenderTarget2D lightTarget;
RenderTarget2D mainTarget;
 
Effect basicFogOfWarEffect;

While the use of the texture fields is obvious, the use of the render targets may not. The concept behind this fog of war implementation is to draw the light texture to the lightTarget render target and then use the produced texture as the alpha channel for the texture produced from the mainTarget render target.

Read the rest of this entry »

A Letter To Microsoft: On Framework Design

Rather than writing an actual letter, which would do no good, I have chosen to write this post with the idea that as an MVP I should lead and teach by example. One of the most important design principles that factor into designing a framework is that of dependency hierarchies. In less fancy terms it simply means what classes implement what interfaces and where these things are maintained in the framework. Recently I placed a suggestion on Connect to Move INotifyCollectionChanged to System.dll so that more projects that do not require WindowsBase.dll (WPF) could use the functionality. Fortunately for .NET developers everywhere the suggestion was taken (although I won’t claim sole responsibility) and the move is happening.

This post is about the reasons for such a move, and such reasons are incredibly basic to realize. Consider a platform other than Windows whether it be Linux, Windows Mobile, the Xbox 360 or even the Zune HD. Now think about how you would write a framework that supports some of (or all) these platforms and consider the problem of developing a class that implements something like INotifyCollectionChanged. The problem, of course, is that not all the platforms have access to WindowsBase.dll. Thus the developers come to a crossroads: either recreate the functionality for the platforms or don’t implement the functionality.

While that may not seem too unreasonable a dilemma, the problem is that Microsoft implemented functionality in a branched assembly that really has no dependency on any classes or interfaces within that assembly. Here the principle is simple: when possible, move functionality up the assembly hierarchy so as to reduce cross dependencies. In layman’s terms, by moving the INotifyCollectionChanged interface to System.dll, many more projects can take advantage of it without requiring any sort of platform dependent code. And here it is important to remember that one of the original goals of .NET was to enable true cross platform development.

To say that this case is the only one of its kind would be ignorant. The scary thing is that I don’t think anyone actually has a list of where these mistakes exist and what can be done about them. Even scarier than that is the fact that Microsoft is making these mistakes. Consider the following which further demonstrates this point.

While helping someone today with a few questions on the System.Reflection namespace, a point was made about how odd it is to compare generic types. When you have a generic class such as Nullable<T> you cannot do something as simple as if(foo is Nullable) because the generic parameter can make a difference. While this isn’t too much of a problem, Microsoft later also developed the System.Data assembly and included an interface called INullable within this assembly under the System.Data.SqlTypes namespace. This, like INotifyCollectionChanged, constricts the use of this interface to only assemblies that reference System.Data.dll. Furthermore, the interface contains a single boolean property and has not a single dependency on anything within the System.data assembly.

The problem and its solution should be obvious: move INullable to the System namespace in System.dll and make Nullable<T> implement it. This allows developers to easily check whether or not a type represents a nullable type while not creating a single problem in the entire framework’s design. Furthermore it would allow developers to treat System.Nullable and System.Data.SqlTypes.* as the same types which can come in handy.

Update: I added a suggestion on Connect for moving INullable to System.dll.

Cross Platform XNA Projects (X64 Content)

One of the requirements of the framework I am building (FGF) is cross platform support. For my XNA games this means support for not only Windows but also the Zune and the Xbox 360. For my Windows based projects I often find that X64 can be used (and in the case of IIS in 2008 R2, encouraged) so I also support X64 versions.

The problem is that when using an XNA project template to build a library for the simple fact that XNA projects can automatically synchronized (across platforms), Visual Studio blocks the creation of an X64 build target. Rather you are stuck with X86, Zune or Xbox 360.

The good news is that you can get around this! Open up the Windows project file (csproj) in a suitable text editor and copy the sections for both “Debug|x86″ and “Release|x86″ and paste them right after.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
  <DebugSymbols>true</DebugSymbols>
  <DebugType>full</DebugType>
  <Optimize>false</Optimize>
  <OutputPath>..\Bin\x86\Debug\</OutputPath>
  <DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
  <ErrorReport>prompt</ErrorReport>
  <WarningLevel>4</WarningLevel>
  <NoStdLib>true</NoStdLib>
  <UseVSHostingProcess>false</UseVSHostingProcess>
  <PlatformTarget>x86</PlatformTarget>
  <XnaCompressContent>false</XnaCompressContent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
  <DebugType>pdbonly</DebugType>
  <Optimize>true</Optimize>
  <OutputPath>..\Bin\x86\Release\</OutputPath>
  <DefineConstants>TRACE;WINDOWS</DefineConstants>
  <ErrorReport>prompt</ErrorReport>
  <WarningLevel>4</WarningLevel>
  <NoStdLib>true</NoStdLib>
  <UseVSHostingProcess>false</UseVSHostingProcess>
  <PlatformTarget>x86</PlatformTarget>
  <XnaCompressContent>true</XnaCompressContent>
</PropertyGroup>

Next you simply replace the instances of x86 with x64 and change anything else you need.

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
  <DebugSymbols>true</DebugSymbols>
  <DebugType>full</DebugType>
  <Optimize>false</Optimize>
  <OutputPath>..\Bin\x64\Debug\</OutputPath>
  <DefineConstants>DEBUG;TRACE;WINDOWS</DefineConstants>
  <ErrorReport>prompt</ErrorReport>
  <WarningLevel>4</WarningLevel>
  <NoStdLib>true</NoStdLib>
  <UseVSHostingProcess>false</UseVSHostingProcess>
  <PlatformTarget>x64</PlatformTarget>
  <XnaCompressContent>false</XnaCompressContent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
  <DebugType>pdbonly</DebugType>
  <Optimize>true</Optimize>
  <OutputPath>..\Bin\x64\Release\</OutputPath>
  <DefineConstants>TRACE;WINDOWS</DefineConstants>
  <ErrorReport>prompt</ErrorReport>
  <WarningLevel>4</WarningLevel>
  <NoStdLib>true</NoStdLib>
  <UseVSHostingProcess>false</UseVSHostingProcess>
  <PlatformTarget>x64</PlatformTarget>
  <XnaCompressContent>true</XnaCompressContent>
</PropertyGroup>

One warning – this should only be used for projects that don’t require references to the XNA framework. At this time Microsoft has no support for x64 XNA references.

Debugging Unknown (IIS) Exceptions

One of the major gripes I have with the Windows operating system is its inability to build decent event logs when an exception occurs. This is particularly annoying on the server builds because as a developer, I need to know what is causing a crash or a hang. Recently I have been developing a site using Sitecore and after a publish the site started crashing and bringing down the entire server. The following is an overview of how I solved the issue.

The first thing I did was check the Event Viewer on the server itself – notice the horrible information within the error. The one important code to write down is the exception code (0xE053534F).

Event Viewer

After reading a tutorial on how to catch a crash I was able to catch the crash in a dump file. While the debug diag tool was useful for catching, I needed WinDbg to get to the root of the problem.

Note: I set the symbols location to SRV*c:\users\jsedlak\documents\websymbols*http://msdl.microsoft.com/download/symbols

Debug View

As you can see, the debug view is fairly useless. Run the following commands:

  • .loadby sos mscorwks
  • !clrstack

Now you can see what is causing the stack overflow. Turns out it was an XSLT file that was doing a recursive climb up the Sitecore tree without a base case. The cause of the problem however was that I had just implemented Workflow on all items which corrupted their state and seemed to have removed their published version from the web database. By fixing the XSLT to have a base case and submitting all content through their workflow I was able to get the site back.

Stack View

Managing Focus Across Different Platforms

With the upcoming release of FGF/Thrust comes the return of a more traditional GUI. One of the most problematic requirements of a large GUI system is the notion of focus. The question remains how do you efficiently determine who has focus and how do you pass focus between controls? On Windows this is incredibly easy because we have the mouse pointer. Focus is changed whenever your mouse acts on a control. What about on the Zune or the Xbox 360 though? On both of these systems their is no mouse (although Thrust supports a virtual mouse).

The answer is to look at what Thrust currently supports. What built in system supports all three systems seamlessly? (~ means some support, X means full support)

Event Zune Windows Xbox 360
Mouse   X  
Keyboard   X X
GamePad ~ X X
UniversalButton X X X

The problem is we can’t rely on each individual hardware controller being present and useable. For example we can’t rely on a keyboard being a focusing mechanism on the Xbox 360 because it isn’t a guarantee it exists. Likewise, we cannot rely on the GamePad on the Zune because of the lack of buttons.

To get to the point, the UniversalButton system was meant as a virtualization of the various hardware supported for each platform. It turns GamePad, Mouse, and Keyboard events into simple events like Up, Left, Down, Right, Select and Cancel. Because of this we can rely on it and implement a few more events.

  • TabPreviousLocal
  • TabNextLocal
  • TabPreviousGlobal
  • TabNextGlobal

You can consider local tabbing to be much like you would on a Windows form: hitting the tab key (or shift-tab) will move you from one control to another based on some order and only in the context of the global focus point (you never tab to a control in another window). The global tabbing can be considered like an Alt-Tab (or shift-alt-tab) where you can switch between windows.

So how do we implement this? We need a managing class (sorry Bjoern) to produce a bottleneck for the input events. As events are channeled through this class, it massages the data and figures out what to do. For instance if a global tab next event is received it has to switch focus to the next window in the system on the same level as the current window. If it receives a local tab event it will pass a message to the current focal point to tab to the next control.

What does this do for us? For one, it unifies the approach to focusing across all the UI subsystems. This means that a Window/Form implementation will focus in much the same way a simple screen will. Unfortunately it also means a complexity requirement for implementation developers. The age of the simple StateManager class is coming to an end. Elements on the screen now need to have a basic state for animation as well as a state for focus (or lack thereof). While it may still be possible to simply unload an element through the StateManager, the reality is that UI elements will have to do a little more management under the hood. Whether this is exposed to the user / developer is still to be decided.

A Spark of Genius?

Knowing how frameworks are designed and developed definately has its benefits. Awhile ago I spent some time looking into how DependencyObject and DependencyProperty work in WPF. Essentially, many of the properties are not simple properties but rather facades for method invocations.

Fast forward to today when I was working on Versionator, an application I am writing to help me manage my many projects’ versions. The problem is that project information files (AssemblyInfo.cs) are not straight forward in terms of parsing. They are merely text files, awkward and malformed code files in fact. To be able to support many properties so easily, I came up with a scheme to parse, manage and save the projects’ properties in the file.

What I do is parse the properties, extracting the data and storing it in a dictionary as “old values.” At the same time I create a copy of the values in a “current values” dictionary. As new values come in, I channel them through properties, then Get and Set methods which access the “current values” dictionary. When it comes time to save I have to do some management of the data based on whether or not the property was empty, non-existant or is being changed to empty. It is simple to say that it would have taken me a lot longer if I had not taken a look at WPF. So was it a spark of genius? Or just plain old learnedness?

The Code (Beware of its massive length):

?View Code CSHARP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
using System;
using System.Collections.Generic;
using System.IO;
 
namespace FocusedGames.Versionator.Data
{
    public class ProjectInfo
    {
        public enum Properties : ushort
        {
            Title = 0,
            Description = 1,
            Company = 2,
            Product = 3,
            Copyright = 4,
            Trademark = 5,
            AssemblyVersion = 6,
            FileVersion = 7,
            Guid = 8
        }
 
        private readonly string[] lookups = new [] { "AssemblyTitle", "AssemblyDescription", "AssemblyCompany", "AssemblyProduct", "AssemblyCopyright", "AssemblyTrademark", "AssemblyVersion", "AssemblyFileVersion", "Guid" };
        private readonly Dictionary<ushort, string> propertyValues = new Dictionary<ushort, string>();
        private readonly Dictionary<ushort, string> oldValues = new Dictionary<ushort, string>();
 
        public static ProjectInfo FromFile(string filename)
        {
            return new ProjectInfo(filename);
        }
 
        public ProjectInfo()
        {
            Array enumValues = Enum.GetValues(typeof (Properties));
 
            foreach(ushort prop in enumValues)
            {
                propertyValues.Add(prop, string.Empty);
                oldValues.Add(prop, string.Empty);
            }
        }
 
        public ProjectInfo(string filename)
            : this()
        {
            Load(filename);
        }
 
        #region Getting and Setting Project Properties
        protected void SetProperty(Properties prop, string value)
        {
            propertyValues[(ushort) prop] = value;
        }
 
        protected string GetProperty(Properties prop)
        {
            string newValue = propertyValues[(ushort) prop];
 
            if(string.IsNullOrEmpty(newValue))
                return oldValues[(ushort) prop];
 
            return newValue;
        }
        #endregion
 
        #region Loading and Saving
        public void Load(string filename)
        {
            Filename = filename;
 
            string[] lines = File.ReadAllLines(Filename);
 
            Array enumValues = Enum.GetValues(typeof (Properties));
 
            foreach(ushort prop in enumValues)
            {
                Load(lines, prop);
            }
        }
 
        private void Load(string[] lines, ushort lookup)
        {
            for(int i = 0; i < lines.Length; i++)
            {
                string currentLine = lines[i];
                string searchTerm = lookups[lookup];
 
                // Get the first index of the search term
                int firstIndex = currentLine.IndexOf(searchTerm);
 
                // The property wasn't found, continue
                // through the file.
                if(firstIndex == -1)
                    continue;
 
                // Now we need to extract the data out of the string!
                string data = currentLine.Substring(firstIndex + searchTerm.Length).TrimFront("\"").TrimBack("\"");
 
                oldValues[lookup] = data;
                propertyValues[lookup] = data;
            }
        }
 
        public void Save()
        {
            string[] lines = File.ReadAllLines(Filename);
 
            Array enumValues = Enum.GetValues(typeof(Properties));
 
            foreach (ushort prop in enumValues)
                Save(lines, prop);
 
            StreamWriter sw = new StreamWriter(Filename, false);
 
            for(int i = 0; i < lines.Length; i++)
                sw.WriteLine(lines[i]);
 
            sw.Close();
        }
 
        private void Save(string[] lines, ushort prop)
        {
            for (int i = 0; i < lines.Length; i++)
            {
                string currentLine = lines[i];
                string searchTerm = lookups[prop];
 
                // Get the first index of the search term
                int firstIndex = currentLine.IndexOf(searchTerm);
 
                // The property wasn't found, continue
                // through the file.
                if (firstIndex == -1)
                    continue;
 
                string oldValueLocal = oldValues[prop];
                string newValueLocal = propertyValues[prop];
 
                // If the old value didn't exist, we can adjust the 
                // replacement mechanism to remove the "" and add
                // them back in.
                if (string.IsNullOrEmpty(oldValueLocal))
                {
                    oldValueLocal = "\"\"";
                    newValueLocal = string.Format("\"{0}\"", newValueLocal);
                }
 
                // We also need to catch people emptying strings out.
                // To do this we adjust the saving mechanism the same way.
                if(string.IsNullOrEmpty(newValueLocal))
                {
                    oldValueLocal = string.Format("\"{0}\"", oldValueLocal);
                    newValueLocal = "\"\"";
                }
 
                // Replace the old value with the new value
                if (!string.IsNullOrEmpty(newValueLocal))
                        lines[i] = lines[i].Replace(oldValueLocal, newValueLocal);
            }
        }
        #endregion
 
        public string Filename { get; private set; }
 
        public string AssemblyVersion
        {
            get { return GetProperty(Properties.AssemblyVersion); }
            set { SetProperty(Properties.AssemblyVersion, value); }
        }
 
        public string FileVersion
        {
            get { return GetProperty(Properties.FileVersion); }
            set { SetProperty(Properties.FileVersion, value); }
        }
 
        public string Title 
        {
            get { return GetProperty(Properties.Title); }
            set { SetProperty(Properties.Title, value); }
        }
 
        public string Description
        {
            get { return GetProperty(Properties.Description); }
            set { SetProperty(Properties.Description, value); }
        }
 
        public string Company
        {
            get { return GetProperty(Properties.Company); }
            set { SetProperty(Properties.Company, value); }
        }
 
        public string Product 
        {
            get { return GetProperty(Properties.Product); }
            set { SetProperty(Properties.Product, value); }
        }
 
        public string Copyright
        {
            get { return GetProperty(Properties.Copyright); }
            set { SetProperty(Properties.Copyright, value); }
        }
 
        public string Trademark
        {
            get { return GetProperty(Properties.Trademark); }
            set { SetProperty(Properties.Trademark, value); }
        }
 
        public string Guid
        {
            get { return GetProperty(Properties.Guid); }
            set { SetProperty(Properties.Guid, value); }
        }
    }
}

P.S. The code is not done, is not even close to being efficient or functionally complete. But it works!

Tackling The Problem

Tackling the problem in the previous post I have decided to rely on providing more options than necessary. I have to remember that because Vodka is not client software, I have to write it as if the client software will be as simple as possible. The goal of Vodka is to give developers a way of setting up a software based CMS with great ease.

To do this, I have built in services that can be implemented and exposed via WCF as well as built in implementations of these services. If you had the binaries for Vodka, you could reference FocusedGames.Vodka.Services, create a class in a Service project and inherit from ContentService or MembershipService. After deploying the project, you can treat it like any other WCF service reference.

The original question dealt with translation services however, is it a client or server responsibility? You would generally make it client side because you may wish to get a different template for the content or change how translation is done. This is on par with most CMS software installs out there but there is a problem. Templates in the Vodka backend are treated as standard items of content. It then would require two calls to the service: one for the template and one for the content. You would also have to know how the template is extracted from the content item. This is a bad idea as it increases server load unecessarily.

The answer is simple: abstract it and keep it server side. The idea here is that the developers can plugin their own template provider into the service when setting it up. This will allow them to point to another service, a local directory or hardcoded templates. If no plugin is used, the service will continue on its standard course, grabbing the template from the standard content data store.

You may be asking why you would ever want to use a custom provider to point to a second service. Let’s say you have a ton of websites that you all want to look the same. For instance Microsoft may have microsoft.com, msdn.microsoft.com, creators.xna.com, xbox.com, et cetera and may want them to all use the same templates for items. They could use a provider to point to a single template service removing the need to change 5+ templates on 5+ servers.

Problems With Vodka

The Vodka Content Management System is a service based, multitier setup with the clients getting access to all content and member information via services. In turn, the services communicate with each other as well as their respective data stores. One of the goals of designing Vodka is to implement objects in a way that is easily extendable. To accomplish this, all content is managed in terms of the text data (XML) and its meta data (title, author, date stamps, et al).

The problem is how this data is transformed into its two main uses: HTML and .NET Objects. The question is where these transformations take place. In order to transform an XML file into HTML, the code needs access to an XSL file. The problem with this is that it too, is treated as a piece of content. It is regulated in exactly the same way with the same level of security. Thus it can be seen that this service should remain on the server. This is where it currently sits, so what is the problem?

The problem remains that it shouldn’t be a server side operation! That is slow! It requires more implementations than necessary and furthermore it builds a bad dependency on the server for specific implementation.