Korkboard is a little tool I have been developing that enables a uniform method of storing multiple items on the clipboard. When Korkboard runs, it hooks into the clipboard chain and attempts to intercept messages as you use the Copy and Cut commands. It then stores the items on its own list so that they may be retrieved at a later time. It is important to note that Korkboard does not mess with the functionality of the clipboard. If you copy an item, the clipboard works as expected without any interruption or user required interception. Check it out, and let me know what you think!
Korkboard is written in WPF/.NET4 and uses ClickOnce to manage the installation and update processes.
Update: Added the Zip file for those having trouble using the ClickOnce method.
During the last semester I was taking a class on ASP.NET where we formed teams to write a website from scratch. The website was a “project manager” that would help users maintain projects, employees and customers. Given my experience with ASP.NET prior to the class, my team hit the ground in a full on sprint. We hit a wall when it came time to bind the site’s controls to the data behind it, in this case a Microsoft SQL database. The problems weren’t associated with a lack of knowledge but rather the gross disconnect between interfaces and the data with which they associate. It is easy to think that a textbox on a page can represent a name, but how that name is actually filled in can be the most complicated process.
This is just one instance of running into issues with data. How many times have you used a converter of some sort to scrub data or used a validator to make sure it can be stored? How many times have you written the same try-catch block for the SqlConnection class? How many times have you written a statement with “XmlDocument” or an instance somewhere in the middle? I have come to realize that there within the .NET Framework, there are many classes to get all the work done, but they aren’t really put together in a unified way. When you look at all the data-oriented classes (e.g. System.Xml.*, System.Data.*) you will find that there is no grand picture. For some reason the framework architects didn’t take a step back and see a possibility to unify the approach to reaching, converting, validating and consuming data.
So what is DMS? In short, the Data Management System prototype is a look into how possible it is to unify the approach to using data and whether or not it can make a developer’s life easier. The first step is to consider open architectures that are highly extensible and configurable. The current version of the DMS Prototype is focusing on just that by experimenting with converting runtime objects to and from XML. The important part isn’t the conversion; XML serialization has been done to death before. The important part to take away is that the serialization is being done in an abstracted manner. It is trying to gain as much information as possible from as little information as possible. The fewer attributes a developer has to use and the more generic they are, the easier life will be.
One of the major themes present in the design of FGF is abstraction of functionality from its implementation. The major reason for this is because one of the major goals of FGF is to provide functionality without forcing developers into a corner. The idea is if the base of the framework is modular and open, the rest of the framework will fall into place very easily. So I begin the implementation of FGF by fixingimproving the XNA Framework’s Game class with an abstraction of its functionality. The reason for which will become apparent when the component classes are improved at a later time.
The important question to ask here is what can a game do? We can run a game, and exit a game but also add and remove components and services. Thus the IGame interface is born (within the FocusedGames.Xna project):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using Microsoft.Xna.Framework; namespace FocusedGames.Xna { public interface IGame { void Run(); void Exit(); Vector2 ObjectToScreen(Vector2 objectVector); Vector2 ScreenToObject(Vector2 screenVector); GraphicsDeviceManager DeviceManager { get; } DisplayOrientation DisplayOrientation { get; set; } Vector2 DisplaySize { get; set; } bool IsLoaded { get; } float TargetFrameRate { get; set; } ModuleCollection Modules { get; } } } |
This series is devoted to the design and development of my framework, FGF (Focused Games Framework), and aims to cover topics like async content management, WCF services, and many more. In this first article, I cover how to setup Visual Studio 2008 for coding the framework. It is important to understand that I will be using Visual Studio Team System 2008 and thus may have features that are not available in the Express edition. It is possible to get around many of these or ignore them completely, however, so not having Team System does not mean developing FGF is impossible.
The first step is to open up the IDE and create our solution. When starting a large solution such as the one for FGF, I find it useful to create a Blank Solution so that the solution’s name can be different than that of the first project. Again, this can be worked around in Express as well as other versions of the editor.

After developing with the Sitecore CMS for a couple of months I have seen what XSLT can offer in terms of a powerful web technology. I decided early on, before using Sitecore, that Vodka 2.0 would have to support XSL transforms since the content is stored as XML. The following is a sample of how to work with XML and XSLT in the second version of the Focused Games Framework (FGF 2.0).
While the XSLT code can go pretty much anywhere in the ASP.NET pipeline, for now I have put it in my main Controller. Note that this code is not final, I will be looking into a better way to streamline the content retrieval process.
1 2 3 4 5 6 | public class ContentController : Controller { public ActionResult Get(string uri) { Content content = GetContent(uri, -1); Content template = GetContent(content.TemplateId, -1); |
Next the XslTransformer class is instantiated and a test extension is added. Extensions can be simple or complext .NET classes. Again I plan to streamline this process and support loading from the web.config file.
1 2 3 4 5 6 7 8 9 10 11 12 13 | XslTransformer transformer = new XslTransformer(GetDocument); transformer.AddExtension( new XsltExtension { Namespace = "http://focusedgames.com/vodka", Provider = new VodkaXslExtensions() } ); ViewData["Content"] = transformer.Transform(uri, template.Meta.Uri); return View("Get", "~/Themes/FGDN/Theme.master"); } |
When the Transform method is invoked, the transformer attempts to load documents through a callback. This process will definitely be streamlined so that the re-implementation of the following method isn’t required. The callback method loads the content straight from the database through an SqlContentProvider object. Not much has really changed here since Vodka 1.0 except for the addition of support for both languages and versioning.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public Content GetContent(string uri, int parent) { SqlContentProvider scp = new SqlContentProvider(); NameValueCollection parameters = new NameValueCollection(); parameters.Add(SqlContentProvider.ConnectionStringParameterName, connectionString); scp.Initialize(parameters); Content content = scp.GetContent(uri.ToLower()); return content; } private XPathDocument GetDocument(Uri uri) { Content content = GetContent(uri.OriginalString, -1); XPathDocument document = new XPathDocument(new StringReader(content.Xml)); return document; } } |
And finally the simple extension object:
1 2 3 4 5 6 7 | public class VodkaXslExtensions { public string GetDate() { return DateTime.Now.ToString(); } } |
So what does this produce exactly? Well it takes the following XML…
1 2 3 4 5 6 7 8 9 | <?xml version="1.0"?>
<content>
<title>Home</title>
<description>
<p>This website is still under construction, please check back soon.</p>
<p>Thank you,</p>
<p><a href="http://jsedlak.com">John Sedlak</a></p>
</description>
</content> |
And uses the following XSLT file (stored in the Vodka Database)…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:test="http://focusedgames.com/vodka" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl test"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<h2>
<xsl:value-of select="title"/>
</h2>
<div class="Description">
<xsl:value-of select="description"/>
</div>
<p><xsl:value-of select="test:GetDate()"/></p>
</xsl:template>
</xsl:stylesheet> |
And produces the following HTML…
1 2 3 | <h2>Home</h2> <div class="Description">This website is still under construction, please check back soon.Thank you,John Sedlak</div> <p>9/21/2009 5:23:04 PM</p> |
Here is a quick and incredibly useful tip for using the Sitecore API. Recently I was looking for an easy way to strip HTML tags from a string (in C# code) and Alex de Groot responded to the call. Turns out that the process is insanely painless.
1 | Sitecore.StringUtil.RemoveTags(string) : string |
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):
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 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.
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.
This is from the most recent build of FGF:
Yes, it is my own implementation of the Aero style of windows done in XNA. What does this mean? Well I have decided that although the simple way of doing a menu system in games is fine for simple situations, I want something more powerful and prettier to look at. Thus I have started working on a new UI library for Thrust that is based on Aero and similar interfaces. I am doing it in a fully customizable but lightweight manner and working on Xbox 360 compatibility.