Every single time I write a post that contains source code, it’s a bloody struggle.
Take my previous “snippets” entry.
Normally, I draft it and plan it in advance, and use Editpad Pro on my windows machine to write it out. Now, in a ideal universe where stuff works properly, I would be able to just paste the code in without putting dumbass escapes- that’s what the CMS is supposed to do, manage my content- but no such luck. So, I replace all < with < and all > with > and all that drollish crap that people use software to avoid. It’s especially fun when the blog helpfully assumes I am using some secret tag when I use generics.
Anyway, first problem: well, some of my swapping was wrong. Second, everything was double-spaced thanks to the magic of me making the original textfile on a windows machine (crlf versus just cr).
I had to actually get the original source from the project I based the post on, perform the replacement, paste it into the proper tag, and hope the gods of blog software were smiling upon me.
Long story short- Putting code in posts is more painful than it should be. I sort of expected the add-in I use for highlighting and code blocks to have been smart enough to properly mark-up the text itself without intervention, but no such luck.
Naturally, as we write programs we create a small set of useful functions. BASeBlock has been no exception. I’ve created quite a few functions that offer generic functionality that could be used elsewhere. Here, I share some of them.
Clamping values is a very common activity. It started to get on my nerves, repeating code to make sure a given value was within a range. As a result I conceived of a generic function that could be used for any IComparable.
The basic idea is fairly simple. First, in order to clamp the value, we will need to be able to compare them, so we constrain the function to accepting only type T’s that implement that interface. The first step is casting each value to an IComparable; then we use those variables to compare and return the appropriate value. if the value is larger than max, max is returned; if it is smaller than min, min is returned. otherwise, value is returned unchanged. This function is most useful for numbers, but it can also have interesting implications and usage cases for other classes that are comparable, even strings.
This also came up quite a lot- some parts of the game needed to randomly choose some set of values from a larger set of values. Naturally this gave birth to another generic routine for the purpose:
The idea is simple- make a SortedList that sorts the given listing using a random value as a key, then take the top numselect items off the top. This code will not work properly if numselect is larger than the size of the enumeration, but using count to clamp the size of the array would enumerate twice.
It’s probably possible to make this faster- possibly much faster- since we only need numselect elements. The core idea here is to shuffle the input array and choose two elements. One flawed approach for shuffling an array is to choose a random index and swap it with another random index, but this has myriad problems since it doesn’t really guarantee that everything is shuffled, and the result could very well have runs of the original card order.
Now, what if we had three objects we wanted to randomly choose from, and we wanted one of them to be chosen more frequently? One way of doing this is to use the above choose function and add duplicate entries. However, this could be tricky if you had odd requirements. This is where the Select<T> function would come in. this function is designed to accept an array and a corresponding array of probability weightings; if all the weightings are equal, than the result should be similar to what we get from Choose. Select accomplishes this by keeping it simple. each array element is essentially assigned a given range within the total, and a random number is generated from the complete total of all weightings. For example, if we had the following elements:
| # | Name | Weight |
|---|---|---|
| 1 | Billy | 15 |
| 2 | Thomas | 35 |
| 3 | Jack | 70 |
| 4 | Selmac | 40 |
| 5 | Patrick | 80 |
We can see that if we generate a value between 0 and 240, than if it is between 0 and 15, we choose Billy, if it is between 15 and 50, we choose Thomas, etc.
Here is the code for the Select Function:
A short test Main() routine that can be used to… test it:
The test is created in such a way that the values can be thought of directly as percentages. The resulting output shows that after a run the occurences of each lie around the percentages as given; Bill appears 50 percent of the time on average, Tom 20 percent, Dick 30 percent, etc. Obviously there is no requirement that the values add up to 100, but the values end up as percentages anyway. (choosing the values 100,40, and 60 for the probability array results in similar results).
This particular method has a bit of a “problem”; what if we run it repeatedly on the same array? Then we are constantly recreating the sumulations array and calculating the totals. How can we cache it? Easy- we use a Dictionary and keep weak references to the given array.
But all is not that simple! This is a generic method and the type T could easily change between calls- so what do we do? Well, it is possible to create a static object that contains a Dictionary indexed by a Type that has a value that is a KeyValuePair<weakreference ,List<T>>, and then inspect the Dictionary for the appropriate values, make sure the cache doesn’t get to big, dispose ofthe WeakReferences that point to arrays that have since been destroyed, blah blah, tricky business. We don’t want that, because for one thing it will be a pain to write- and for another, it will probably be slower overall to begin with. Instead, how about absolving the method itself from the responsibility, and having a ref parameter that can accept a calculated sum array.
For me, the above testing Main() routine took 200ms to execute, on average (I placed calls to System.Diagnostics.Stopwatch members before and after the loop). There was no appreciable difference in speed. Thnakfully, however, the extra logic did not slow it down, either.
The speed improvement can be seen when we have a lot more members. With 5000 members in the probability and Values arrays, and executing a Select on them 50,000 times, the average time was around 5-6 seconds. When the Main function instead gave a float [] ref as the third parameter, the average time dropped to one second. The code for the revised version of the procedure. This also adds some overloads:
A lot of the above could even be implemented as Extension methods to the appropriate classes, making it seamless.
Since I am working on a game, dealing with vectors and speeds and whatnot is common. One frequent requirement is for items to move at a random angle at a random speed within a given range. The obvious base case here is creating a Vector given a angle and a magnitude:
This uses standard trigonometry to calculate what would be the X and Y axes of a fictitious triangle with the given direction as it’s hypoteneuse. Extending from this, we simply create a few extra routines that perform the randomizations:
easy as 3.1415926!
Another interesting endeavour is simplifying the otherwise messy world of Object serialization, such as easily converting a Serializable Object to and from a Stream:
[code]
public static void ObjectToStream<T>(T saveme, Stream outstream) where T : ISerializable
{
BinaryFormatter bf = getFormatter();
using(GZipStream gz = new GZipStream(outstream,CompressionMode.Compress))
{
bf.Serialize(gz, saveme);
}
}
public static T StreamToObject<t>(Stream instream) where T : ISerializable
{
BinaryFormatter bf = getFormatter();
using(GZipStream gz = new GZipStream(instream,CompressionMode.Decompress))
{
return (T)bf.Deserialize(gz);
}
}
[/code]
This also plonks in a bit of compression through the use of a GZipStream.
Anyway, that’s a quick sampling of a few snippets of possible usefulness
A quick update on the functionality I was trying to use ReferenceCounted List for in BASeBlock.
I ended up not using the class at all. I actually ended up just using a different method- instead of the powerup changing the drawattributes when it starts and ends, instead it is simply called each frame- basically the character is like “OK, before I draw- you abilities got anything to add” and it will change what it wants as needed. The gamecharacter resets it after drawing so if the ability is removed it will “revert” to normal appearance.
Also, this is possibly my shortest blog post ever. In order to bulk it up- I made some changes to the main page as well as the theme of the blog. The main page’s various images were tweaked, and the blog has had it’s font’s changed because the font it was using was annoying. (Windows Vista and later will be unaffected by the change). BASeBlock now has a “BuilderShotPowerup” thingamajig that let’s you shoot blocks and build stuff, which I think will be useful for building a “bridge” for the GameCharacter, and other purposes. (This idea was Mulreay’s, btw, he has great ideas). I tweaked a lot of stuff such as the editor’s sound data list editor now showing progress and being less annoying to use, and a few general tweaks and minor fixes here and there. I documented it all in the changelog which I will post when I finally upload the new version.
AMD, like Cyrix VIA, and Nextech (I believe was the name) were all clone makers, they made pin compatible processors for PCs. Their primary advantage was their lower cost. the AMD k5, designed to compete with the Pentium, as a Socket 5 processor just like the Pentium. The idea was that as a lower cost alternative their processors could be used in machines instead of Intel's. AMD, specifically, excelled in integer operations, doing them a lot faster than the equivalent Intel Processor. So in some cases the AMD processor was not only cheaper but also a better choice, if it was for use in applications that did a lot of integer arithmetic. Nextech was working on a new processor to compete with the Pentium and the K6; AMD bought the company and relabelled the in-development Nextech chip the K6-2; the K6 and K6-2 are completely different processors, and not in any way the same (they were basically designed by two different companies). The K6-2 supported a set of 3-D extensions (much like MMX)- whether this was Nextech or AMD that implemented it, I don't remember- at the same time it supported MMX, and it's floating point performance no longer sucked ass, and was very nearly comparable to Intel's offering.
Over time, all the other clone vendors died, or were purchases; VIA, to my recollection, bought Cyrix, made a few processors (the VIA Samuel C3 being the only one I distinctly recall) and then killed their processor division entirely, focusing on their motherboards and embedded solutions. AMD became the only competitor to intel that had any “weight”. Also, as their processors became equal to Intels both in performance and price, they started being made using different Pin designs. I believe this was originally because the socket or slot for some Pentium processor was patented so AMD couldn't make a compatible equivalent; at the very least, the Pentium itself was named the Pentium- rather than the 586- in order to prevent other vendors from using the same name.
One interesting thing about the Pentium Processor is that it is the first CISC instruction set processor to be considered SuperScalar. This is because of it's pipeline architecture which allows it to, in many cases, execute two instructions per clock cycle. The Pentium came in two revisions; the earlier versions didn't have things like MMX, and in many cases had the infamous FPU issue (Intel Errata #23). The second generation came in higher clock speeds (90Mhz, 100Mhz,and 133Mhz, as opposed to the 50 and 75Mhz of their original incarnations), as well as any number of improvements, such as a smaller die size and an on-chip APIC. It didn't have MMX, that was the third revision, which came in even higher clock speeds, FSB/Clock:66/166,66/200,66/233,66/266 (mobile only for the last one). the third revision had MMX, a smaller still die size, lower voltage requirements, a 16KB write-back cache (compared to the earlier versions 8KB). The interesting thing about some pentium boards, including those designed for slot CPUs, is that a lot of them actually had two processor slots. Usually the second one was labelled “for testing only” but you could literally plug in another processor and have dual processors. The only downside is that you pretty much required Windows NT to use them (9x doesn't support multiple cores or processors). Heck that wouldn't even work with XP Home, which only supports a single physical processor.
AMD's lower cost offerings impacted Intel's market, so they came up with their own low-cost alternatives. Which isn't too surprising given they'd been doing that for years, with the 386SX and 486SX, The 386SX being a slower variant of the 386DX, whereas the 486SX was a 486DX with it's FPU disabled. Installing the companion “co-processor”, the 487SX was actually installing a 486DX, which then took over all system operations from the SX. In addition, they created lower-cost upgrade capabilities for the 486, since the k5 was almost feature par with the pentium (and better in some ways, with 6 5-stage instruction pipelines rather than 2). To compete with this they created the Pentium “Overdrive” chip, which would be installed in a 486DX board, and take over all operations from the installed 486DX. Naturally, it was on a 486 board so some operations would still be slow, particularly bus transfers and DMA, but it sped up processor intensive tasks, and sped up a lot of tasks because of that. Later, with the K6 and K6-2 eating into their Pentium II Market share, they came up with another lower cost segment, the Pentium Celeron.
sidebar:*technically, the first Intel 6th generation processor was not the Pentium II, but rather the Pentium Pro*
Of important note is that the first Celerons were not Pentium processors, but rather Pentium II processors; it took a generation for Intel to catch on to AMD's low-cost niche tactic and come up with a response in the celeron. The Celeron was typically a slotted processor, at least all that I've seen are. The basic difference is that it has less on-die cache, and no L2 cache (some revisions had 128KB, compare to the Pentium II's standard 512KB). Ironically, the Celeron usually performed much worse than the K6 and K6-2 it was designed to compete with; Not to mention the awkwardness of the slotted processor design. Even so, and particularly through partnerships with retail computer manufacturers, Intel was able to squeeze the Celeron boards into the market. (the “Barbie” and “Hot wheels” machines from mid to late 1998 are a good example of this, since they sported celeron processors). The Celeron Brand lives on, but it is still a lower cost alternative to their other offerings, and is almost never a wise choice for a desktop machine. Many users are woo'd by the higher clock speed, but with so little cache, the clock speed barely compensates.
The 6th generation gave us the above Pentium II's, Celerons and K6-2s; the seventh gave us Pentium 2s…. Wait? P2s? What about Pentium III's and K6-2s? Well, they aren't 7th gen processors, since they are based on the same die as the sixth gen chips (for Intel, this was the Pentium Pro, for AMD, the K6-2).
The Original Pentium III was practically a Pentium 2 with SSE (MMX2) and a higher clock speed. An interesting sidebar is that the P6 chips from intel (pentium Pro, Pentium II, and Pentium III) are only fully utilized by NT versions of windows; since the Microops that the CISC instructions are reduced to are optimized for use with 32-bit code. windows 9x executes a good half of the time in 16-bit mode (for compatibility with older software, mostly) so you don't get the biggest improvement with it.
Intel failed miserably on their first attempts at a consumer-appealing x64 architecture. The Itanium was 64-bit, but it's execution of 32-bit code had to be fully emulated. It found some uses in business and servers, but it's limited ability with 32-bit code abhorred it's adoption in the consumer sector.
AMD created it's own 64-bit processors, but made it so that 64-bit was just another “mode” of the processor. In this way, 32-bit code could be run quite easy with minimal virtualization. Intel followed suite with their own extensions that implemented the same instruction set as AMD, making it compatible.
I'm not nearly as familiar with their history after around the Pentium III/Athlon XP area.
The two are practically the same now. They offer consumers a choice, but at the same time that choice is practically useless. The fact is that we've pretty much hit the architectural limit that different die configurations can give us, and we are not easily able to reduce the process further without invoking the dangers of quantum tunnelling. The best considerations for the future is to add more processor cores, and, even more important, have software that is better able to extort the best power from those cores. My opinion is that the big problem right now is not the hardware, or the software, but rather the programming languages that are dominant in the industry today, largely C/C++. What is needed is the adoption of one of the myriad languages that have built in support for concurrent execution of constructs; for example, some languages are able to compile a simple for iterative construct in a way that it can execute on separate cores. This approach is particularly powerful in a stateless environment, such as a functional language. to that end many functional languages include built-in concurrency support. What makes this particularly interesting is that most programmers think of “concurrency” and immediately think of threads; but threading is only one of the ways that concurrency can be achieved, and it is one of the least powerful, as well. Erlang, for example, takes the approach of sending messages between processes, instead of having different threads. Since Erlang is a functional' language, most of it's constructs are largely stateless; this is as opposed to most imperative languages which are typically state-heavy. It is the abundance of state in our standardized' programming languages that is causing the difficulties we are seeing with concurrency, not the cores or the implementations thereof. Consider for a moment that most of the benchmarking tools being used to compare processors are he written in C/C++. In order to trust the performance results, you have to trust that the code is making the best use of the available hardware. But the fact is that imperative stateful programming abhors concurrency; threads deadlock, and you have data synchronization issues and race conditions to deal with. So, while processor performance benchmarks might state that a Bulldozer is “worse” than another CPU, I move that that result is as much a testament to weaknesses in the program and the stateful imperative programming paradigm at least with regards to it's use with concurrent solutions. This is why I have never put faith in benchmarks; the fact is that any weakness being shown could easily be an oversight or problem with the software being used to test. If a benchmark tool only uses two threads, how can you trust it's result when it runs on 6 cores? And even if it was to use more, you're still placing your trust in how the program was written. And while one could argue that the test will show how a lot of current software and games run on a given system, it doesn't test the actual potential of that system; a properly written game could be written to take advantage of 6 cores and it would scream compared to running that program with fewer cores. At this point, concurrency is the answer to improving system speed, and in order to properly leverage concurrency, we don't just need more cores, but we need software and programming languages that provide built-in support for concurrency constructs. C/C++ simply does not offer this, and while I'm sure a library could be written that does, there are already loads of languages that provide built-in support for concurrency in any number of different ways; either through C# and .NET's addition of parallel constructs in C# 5.0, or the ability of functional languages to make assumptions because the code is primarily stateless and thus easier to make parallelize.
Personally I don't have a preference for either. I used a K6-2 for nearly 5 years, a Pentium 4 for about a year, and am now using Intel Q8200 and a laptop with a Intel T3200 (I think). Maybe my next build wilent l be AMD, I don't know. Either way, I'm not going to base any of my choices on how a given system performed with a piece of software. The heart of the matter is that I never trust software. I don't even trust software I wrote half the time. Software is a loose thread on a sock. If you pull out the thread, the sock is going to fall down regardless of how well formed the ankle is, and you cannot declare “this ankle sucks, because my sock keeps falling down” just as you cannot say “This hardware sucks, because this piece of software says so”.
After much mulling over it, I have decided that BASeBlock 2.0 will be “shareware” sort-of. This version will add a numbectr of new blocks, loads of bugfixes, and even fix the high-scores to work properly, which should have been simple but was dastardly to remedy.
What I mean isn’t that it will actually be shareware but rather that the program will be free but some parts of it will require “registration” to unlock. In BASeBlock’s case I’ve decided that the entire application will be free, along with almost everything that comes with the game, including the editor.
The difference is that the editor will be “crippled”- you can create and edit LevelSets and test them with the main game, but you cannot save them to a file unless the game is registered.
DWM
The “protections” will be relatively simple, and almost surely a breeze to crack. I plan to document some of it, in fact. I might utilize the otherwise dead-code that is part of the new licensing component to release encrypted .reg files that are specific for each user’s key and will only decrypt properly with the right key(making it difficult to work around by simply inserting a few jumps or skipping code or something)
The original plan for BASeBlock was to make the entire thing free; but it represents a lot of work- Graphics, some of the music, sound effects, etc. and I haven’t gotten anything monetary out of it yet. It’s not a particularly good breakout clone but it has it’s merits. loads better than my previous attempt, Poing, which is embarassing in comparison. It’s certainly no Ricochet Lost worlds (A fine game and one I highly recommend if you have any interest in the “block and ball” type genre), but then again, I’m only one person, right?
Basically, I’ll add code for simple protection to try to prevent casual piracy (well, really casual piracy) but anything more than that and I risk screwing up when the game is in fact legitimately obtained; which is something I absolutely will not tolerate.
In some of my recent posts, I’ve covered the topic of accessing and parsing an INI file for configuration data in a C# Application.
Some may wonder why. After all; the “norm” for C# and .NET applications is to use XML files for configuration information, isn’t it? Well, yes. But to be honest, XML files are a fucking pain in the ass. They aren’t human readable to your average person the same way an INI file is, and getting/setting values is tedious. Primarily, the reason I use INI files is that they are:
Mostly, I feel that XML, and in many ways other configuration options, are more or less driven by fad. Another option for configuration settings on Windows is the Registry, which is in fact often the recommended method; but this is anything but accessible to the user. Would you rather guide a user to edit a INI file or to fiddle with registry settings?
With that said, INI Files do have their own issues. For example, their data is typically typeless; or, more precisely, the Values are all strings. Whereas using a .NET XML Serializer, for example, you could easily(relatively speaking) serialize and deserialize a special configuration class to and from an XML file and preserve it’s format, with my INI file class there will typically be some work to parse the values.
It was with the idea of turning my string-only INIFile configuration settings into something that can be used for nearly any type that I created the INItemValueExtensions class, which is nothing more than a static class that provides some extension methods for the INIDataItem class. I covered this in my previous post.
The prototypes for the two static functions are:
How would one use these extension methods? Well, here’s an Example:
Woah, hold the phone! What’s going on here? We’re loading DateTime values directly from the INI File? How does that work?
All the “magic” happens in the getValue
If it does implement a TryParse() routine, (like, for example, DateTime) it doesn’t try quite as hard. It takes the string from the INI file and hands it to the Type’s TryParse() routine, and then returns what that gives back. Naturally, the inverse function (setValue) does something somewhat opposite; it checks the Base64 logic, and if so it sets the value of the item to the Base64 encoded value of the serialized object. Otherwise, it just uses toString().
This typically works, particularly with DateTime, because usually ToString() is the inverse of TryParse(). In the case of DateTime, this has a few edge cases with regards to locale, but usually it works quite well. And more importantly, the introduction of allowing any object that implements ISerializable to simply be thrown as an INI value via a Base64 encoded string is useful too, although with large objects it’s probably not a good idea for obvious reasons.
Of Course, an INIFile is only one of any number of ways to store/retrieve configuration settings. And while they don’t typically lend themselves to the same syntax provided by the INIFile class, it would be useful to have some sort of common denominator that can handle it all. That was the original intent of the relatively unassuming ISettingsStorage interface:
This uses a concept known as a “category” which is pretty much the same idea as an INI File section. What makes it different is that, for implementors that use other storage mechanisms, it could have additional meaning; for example, a fictitious XML implementation of ISettingsStorage could use the “Category” string as an XPath to an element; and the Value could be stored/retrieved as a Attribute. a Registry implementation might use it as a Registry path, and so on.
The problem is, even though the INIFile class implements this interface, it’s too basic, and doesn’t provide nearly the syntactic cleanliness that just using the INIFile does. Stemming from that, and because I wanted to try to get a way to store settings directly in a DB, I introduced two events to the INIFile class; one that fires when a Value is retrieved, and one when a value is saved. This way, the event could be hooked and the value saved elsewhere, If desired. Now, to be fair, this is mostly a shortcoming of my interface definition; as you can see above, there is no way to, for example, inspect category or Value names. I toyed with the idea of adding a “psuedo” category/value combination that would return a delimited string of category names, but that felt extremely silly. The creation of a generic interface- or abstract class- that provides all the conveniences I currently enjoy using my INIFile class but allowing me to also use XML, Registry, or nearly any other persistent storage for settings will be a long term goal. For now, I’m content with accessing INI files and having a unclean event to hack in my own behaviour.
My first test of the above feature- whereby it allows values to be TryParse’d and ToString’d back and forth from a given type on the fly- was the creation of a FormPositionSaver class.
The proper way to save and restore a window’s position on Windows is using the GetWindowPlacement() and SetWindowPlacement() API Functions. These use a structure, named, quite aptly, “WINDOWPLACEMENT” to retrieve and set the window position and various attributes. Therefore, our first task is to create the proper P/Invoke’s for these functions:
I also include OffsetRect(), but I’ll get to that in a bit. Now the “big one” is the definition of the WINDOWPLACEMENT structure and it’s various aggregate structures. Why? well, in the interest of leveraging the INIFile’s static extensions, Why not define a static TryParse() and a toString() method on the structure that can set and retrieve the member values:
WHEW! that’s quite a bit of code for a structure definition, but we’ll make up for it with the brevity of the actual FormPositionSaver class itself. First, my design goal with this class was to make it basically do all the heavy lifting; it hooks both the Load and Unload event, and saves to and from a given INIFile Object in those events. Since the application I was working on at the time didn’t actually get a Valid INI object until during it’s main form’s Load event, and since there is no way to say “Invoke this event first no matter what” I also added a way for it to be told that hooking the load event would be pointless since it already occured, at which point it will not hook the event and instead set the form position immediately. Values are stored
Alright, so maybe I lied a bit. It's not super short. Although a lot of it is comments. Some might note that I only sporadically add doc comments, even though I ought to be adding them everywhere. Well, sue me. I just add them when I feel like it. When I'm concentrating on function, I'm not one to give creedence to form.
This is where I explain OffsetRect(). Basically, if your application is run twice, and you load the form position twice, the second form will open over the first one, and the screen will look pretty much the same. So we detect previous instances and offset by an amount to make it's position different from any previous instances as necessary. That's pretty much the only purpose of OffsetRect.
I have packaged the current versions of cINIFile.cs and the new FormPositionSaver.cs in a zip file, it can be downloaded from here .
HAHA! How’s that for a clever title?
Oh… well… ahem… nevermind.
As a avid user of my own INIFile class, which I first write about- at least it’s C# implementation- in my parsing INI files posting , I am always looking for ways to improve it’s usage make it more “accessible”.
Recently, I have been tasked (by way of my new title of “freelance consultant”) with creating several LOB (Line of Business) Type applications. Applications, naturally, have a tendency to lend their implementations to the creation and reading of settings. Being something of a fan of the simplicity of INI Files, I chose to use my INIFile class in the application. It works well, however, I have noticed that I have a lot of duplicate code. More specifically, I typically have to implement a “wrapper” class, which manages configuration information and reads/writes values to and from the INIFile as its own properties are accessed. For example:
Nothing too dreadful, but imagine having nearly the exact same thing repeated a number of times! The code is repeated and as Larry Wall says, one of the traits of a good programmer is sloth. I don’t like having to write this same code over and over again! The INIFile is supposed to make it easy!
The trouble here stems from the fact that the INIFile values are only strings; and typically, many settings are represented in the application itself as integers and booleans, dates, and so forth. My first attempt to mitigate the clutter was a static method, which I called xParse:
relatively straightforward- basically it’s a shell of what I had repeated over and over again. This mitigated the issue somewhat, so my properties in the wrapper looked like this:
much more managable, but still, could we not make this more concise? My first thought, was that perhaps I could eliminate the necessity of having the wrapper at all; I recalled two interfaces from my old COM programming days, specifically, IDispatch and IDispatchEx. Surely, I could do something similar?
Unfortunately, the interfaces are for COM, and C# doesn’t have dynamics until Version 4.
So, I fired up Visual Studio 2010 express to see if I couldn’t add the dynamic language constructs to the INIFile class; additionally, since I still need to work with .NET 3.5, I’ll add the new code as a conditional compilation.
The first step was deciding exactly what I wanted to happen. Imagine code like this:
The holy grail of the INIFile simplicity! Naturally, the .NET framework does provide the facility with which to add this functionality, as part of the System.Dynamic namespace.
The first step was deciding on the method by which to conditional compile. Since projects copy the source of a file to your project folder when you add them, it seemed reasonable to simply add it as a #define right inside the INIFile class itself.
#define CS4
And now, I just need to enclose all my new happy stuff in a conditional directive, and I’ll get the best of both worlds- C# 4.0 consumers who keep the #define will be able to use the suave new feature, and older consumers will still be able to work without ripping apart the classes. The code to add this was surprisingly simple; as it stands now the longest method (An implementation of TryDeleteMember, which is never called from C#/VB.NET consumers, so is excessive for my usage). First, obviously we enclose the import statement in the conditional compile; the class headers are conditionally compiled as well, only deriving from DynamicObject with CS4 set.
The core of the new functionality is in the overrides to the Dynamic Object’s TryGetMember.
For the INISection:
And for the INIFile…
Exactly the same, in fact. This works because of the indexer I added; the indexer will add the item if it doesn’t exist and return the new value, so even if the member name doesn’t exist, the INIFile will simply have that section added.
That’s for the retrieval of erements; to allow the assignment to them in the same fashion, we need to override TrySetMember(). In my case, this was a bit more involved, for flexibility purposes.
For example, code like INIFile.MainSection=”hello” should work, and change the name of the section. And why allow things like assignments from a Dictionary<String, String>, or maybe even a list (assigning a numbered id to set values)? And of course allow setting the Value directly, which will likely use the indexer much as I did for the TryGet… Implementations.
setting the Value should be equally flexible; since we can, why not?
for example, why not make the following “legal”?
The first example sets the Value to a string, the second sets it to a DateTime that is silently casted to a String (using toString(), and the last two use the new C# 4.0 tuples, to set both the name of the value and the value simultaneously.
A more elegant solution would be to add this code to the Indexer, and merely call the indexer with the name and the value and return true if no exception occurs and false otherwise. However, I’m reluctant to go that route since some of the types are C# 4 types (Tuples).
So Now, I’ve got an INI File implementation that supports Dynamic invocation. Well, that’s great… except that the application I first found it clumsy in is using .NET 3.5, so I can’t use the dynamic features. Back at square one.
In C# 2008/3, we might not be able to leverage the power of dynamics, but we do have generics and Extension methods at our disposal. a feasible alternative could be to add a extension method to the INIDataItem class that has a generic type parameter that it will attempt to convert it’s string Value into. First, using ChangeType, second, it can try to invoke a static TryParse on the given Type to parse the “value” string. And if none of that works, it can return a passed in default. This is still more verbose than the dynamic solution, but it has two distinct advantages- first, it’s type-safe, so you get all the intellisense goodness, and second, it’s still shorter than the alternative.
Here is the code, which can be found in the cINIFile.cs file attached to this posting as well.
And there you have it, a bunch of awesome additions. INI files are often thought of as deprecated, but that’s only the INIFile functions. This class was designed because working with the registry makes it difficult to test properly, and because JSON,YAML, and many other formats are excessively complicated. when you just need a few basic settings, all you need is the clean, simple format of a INI file. And now, with these additions, code for reading from those INI files is clean and simple as well!
As I posted previously here , Sorting a Listview can be something of a pain in the butt.
In that article, I covered some basics on providing a class that would essentially give you sorting capabilities for free, without all the messy code that would normally be required. A lot of the code required for sorting is mostly boilerplate with a few modifications for sorting various types. As a result, the generic implementation works rather well.
However, as with any class, adding features never hurts. In this case, I got to thinking- why not have right-clicking the ColumnHeaders show a menu for sorting against that Column? Seems simple enough. I quickly learned that apparent simplicity often is misattributed.
I faced several issues. The first thought was that I could hook a Mouse event for Right-Clicking a column header. Unfortunately, I soon discovered two facts about the .NET ListView control. First, was that there was no event for right-clicking a header control. Second, no even was fired at all by the ListView control when you right-clicked a header.
This left me stymied. How the heck do I implement this feature? I discovered something of a “hack” however, in that when the ListView’s ContextMenuStrip property is set, that ContextMenu Strip will be shown regardless of the location the ListView is clicked. This at least gave me something to work with. Since a ContextMenuStrip’s “Opening” event can be easily hooked, we can use that as an entry point and perform needed calculations to determine if we are indeed on a columnheader.
Which brings me to the next problem, which is determining when a columnheader was in fact the item that was clicked. This requires determining the rectangle the Header control occupies, first. The Header Control is a child control of the ListView; as such, a platform Invoke using the EnumChildWindows() API was required, something like this:
private Rectangle _HeaderRect;
private delegate bool EnumWindowsCallBack(IntPtr hwnd,IntPtr lparam);
[DllImport("user32.dll")]
private static extern int EnumChildWindows(IntPtr hwndParent,EnumWindowCallBack callbackFunction,IntPtr lParam);
[DllImport("user32.dll"]
private static extern bool GetWindowRect(IntPtr hWnd,out RECT lpRect);
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
private bool EnumWindowCallback(IntPtr hwnd, IntPtr lParam)
{
RECT rct;
if(!GetWindowRect(hwnd,out rct))
{
//first child of the listview should be the header control
_HeaderRect=Rectangle.Empty; //likely the listview is not in Details mode, so there is no header control.
}
else
{
_HeaderRect = new Rectangle(rct.Left,rct.Top,rct.Right-rct.Left,rct.Bottom-rct.Top);
}
return false; //cancel enumeration.
}
private static ColumnHeader [] GetOrderedHeaders(ListView lvw)
{
ColumnHeader [] returnarray = new ColumnHeader [lvw.Columns.Count] ;
foreach(ColumnHeader loopheader in lvw.Columns)
{
returnarray [loopheader.DisplayIndex] = loopheader;
}
return returnarray;
}
Quite a bit of boilerplate to add in. Basically, the idea is that we will hook the contextMenu Opening event of the Listview, (and we add a context menu to hook if the listview in fact doesn’t have one) in our constructor; and then when we receive the event we need to determine if the click occured within the area of the header control of the listview, if so, we cancel the event (which stops the default context menu from appearing) and show our own menu for the columnheader, which we can acquire using a bit of math and the static “GetOrderedHeaders” function, which retrieves the array of columnheaders of a ListView in order of appearance Left to Right (since the user could rearrange the Columns).
So First, we need to add code to the GenericListViewSorter’s Constructor. We also have a few private variables that are added; in this case, we need a ContextMenuStrip variable called “_ghostStrip” which we will use if we need to create a context menu for the control, since we don’t want that to appear in the default case. Of course we create our own ContextMenuStrip which we will show in the event instead of the default when appropriate. so we add this beneath the existing code in the constructor:
if(handleListView.ContextMenuStrip==null)
{
handleListView.ContextMenuStrip = new ContextMenuStrip();
handleListView.ContextMenuStrip.Items.Add("GHOST"); //add a ghost item so we get the Opening Event
_ghoststrip = handleListView.ContextMenuStrip;
}
//create OUR context menu
_headerContextMenuStrip = new ContextMenuStrip();
//add a ghost item to make sure Opening will fire.
_HeaderContextMenuStrip.Items.Add("ghost");
handleListView.ContextMenuStrip.Opening += ContextMenuStrip_Opening;
handleListView.ContextMenuStripChanged += handleListView_ContextMenuStripChanged;
Of course we need to add the two referenced event handlers, too. The ContextMenuStripChanged being a rather simple implementation designed to keep changes in the contextmenu of the listview from causing us to balls up and stop showing ours (since we are now hooking a orphaned context menu not being shown by the listview).
void handleListView_ContextMenuStripChanged(object sender,EventArgs e)
{
OurListView.ContextMenuStrip.Opening+=ContextMenuStrip_Opening;
}
Now the meat of the code is in the ContextMenuStrip_Opening() routine. This will need to determine wether its applicable to show the Column menu, or the already present menu (which it doesn’t show either if it happens to be the _ghoststrip). This is accomplished by use of the GetCursorPos() API routine paired with the already present GetWindowRect() implementation, which we update by calling EnumWindows.
void ContextMenuStrip_Opening(object sender,System.ComponentModel.CancelEventArgs e)
{
//first, get screen coordinates of Cursor.
POINTAPI gapi;
GetCursorPos(out gapi);
Point gotposition = new Point(gapi.X,gapi.Y);
//acquire the HeaderRect of the control...
EnumChildWindows(OurListView.Handle,new EnumWindowCallBack(EnumWindowCallback),IntPtr.Zero);
//if the mouse position is within the retrieved rectangle, cancel the display of the normal menu and create and show ours.
if(_HeaderRect.Contains(gotposition))
{
e.Cancel=true;
int xoffset = gotposition.X - _HeaderRect.Left;
ColumnHeader clickedheader = HeaderAtOffset(OurListView,xoffset);
if(clickedheader != null)
{
//create the context menu as needed.
_HeaderContextMenuStrip = new ContextMenuStrip();
_HeaderContextMenuStrip.Tag = clickedheader;
//two items, one for ascending order, one for descending order.
ToolStripMenuItem AscendingHeaderItem = new ToolStripMenuItem(String.Format("Sort Column \"{0}\" Ascending",clickedheader.Text));
ToolStripMenuItem DescendingHeaderItem = new ToolStripMenuItem(String.Format("Sort Column \"{1}\" Descending",clickedheader.Text));
//if the current sort column is the header, check it off and disable it.
if(CurrentSortColumn == clickedheader)
{
if(OurListView.Sorting ==SortOrder.Ascending)
{
AscendingHeaderItem.Checked=true;
AscendingHeaderItem.Enabled=false;
}
else if (OurListView.Sorting==SortOrder.Descending)
{
DescendingHeaderItem.Checked=true;
DescendingHeaderItem.Enabled=false;
}
}
AscendingHeaderItem.Tag = ClickedHeader;
DescendingHeaderItem.Tag = ClickedHeader;
//set event handlers for the two items.
AscendingHeaderItem.Click+= AscendingHeaderItem_Click;
DescendingHeaderItem.Click+= DescendingHeaderItem_Click;
//add them to the context menu strip.
_HeaderContextMenuStrip.Items.Add(AscendingHeaderItem);
_HeaderContextMenuStrip.Items.Add(DescendingHeaderItem);
//display the menu.
_HeaderContextMenuStrip.Show(gotposition);
}
}
else
{
//show the default menu, but only if it isn't the ghoststrip.
if(OurListView.ContextMenuStrip == _ghoststrip)
e.Cancel=true;
}
}
The events for the two buttons basically sort based on the columnheader in their tag, nothing particularly special there. the actual details can be seen in the source file itself, really.
It actually works quite well, I’m using it in a production application, and it’s working quite well.
Some obvious enhancements, of course, include making it possible to customize the shown menu, to present other options; perhaps a delegate or event that can be hooked that is given the Strip and the clicked column, and any number of other parameters? This would essentially give the equivalent of a ColumnHeaderRightClicked type event, too.
Anybody who has used windows is probably familiar with the ListView control. It is used in Windows Explorer; it is even used for the desktop. Heck, the ListView control even has implementations on Linux and Mac, and in the latter case it was there first.
The ListView itself can display in several modes. Normally, it shows things as Icons. But it can also be set to show Small Icons, a List, in some Operating Systems, there is a ‘Tile’ option, or even options like Large,Medium, and other sizes of Icons. My Personal favourite is the details mode.
Because I mostly see and use Listviews in Details mode, I also force people who use my software to deal with Details mode. Mostly because the reason I am displaying a ListView is to show some data in a somewhat tabular format and not just give them a few icons to drag around with minimal actual information, but I digress. Anyway, I think a good question at this point might be to look at what different parts this particular ListView has. First, the gray “buttons” at the top, which serve to title each column, are referred to affectionately as ColumnHeaders. Under each ColumnHeader there is data for a given “subitem” of each item. For example, the “Size” entry here is a Subitem for each drive. An interesting feature of columnheaders that is nearly universal is that you can click on one, and it will sort by that column.
Another interesting thing, is that in many programming environments, the ListView control doesn’t actually provide this feature for you, and you have to code it yourself. It is rather frustrating. In particular, Visual Basic 6 allows you to sort, but you can’t really customize what you sort by; it always treats it as text. In one of my VB6 applications, BCSearch (which is available for download from my Downloads page) I managed to use a Custom control, available from VBAccelerator.com, which exposes additional functionality of the ListView Control on top of that provided in either of the MS provided libraries for use within Visual Basic. One of these features is that it has better support for sorting. I still had to add my own “arrow” to show the sort direction, though.
The VBAccelerator control exposes a number of events and properties for controlling sorting, which I use to properly sort the various subitems, so that various entries like date or size aren’t sorted as text.
Curiously, the .NET Windows Forms ListView control, while having more functionality, still leaves a lot of effort to the programmer for what ideally ought to be a free feature supported by the OS. In fact it IS a free feature supported by the OS. Thankfully, the .NET control does in fact provide a feature for customizing sort functionality, And all you need is a class to implement IComparer. the IComparer will be used to compare the listitems as the Listview sorts. But if you have, say, Date and Time fields and size fields or other fields that can’t just be sorted as text, you are going to need to implement your own special comparer for each. This amounts to quite a bit of glue code; on top of that, you will need to handle the ColumnClick events on the ColumnHeader, change the sort mode, and sort it, and so forth.
To combat this bloating code, I wrote a relatively small class designed to encapsulate sorting. The idea being that you create a instance of this class for each listview, pass in the ListView to it’s constructor, and the class handles all the details. It worked quite well. There was a minor issue that amounted to a gigantic pain in the ass but at the same time made the result a lot better.
As you can see, it it relatively small (overall). the API code at the top might be a bit confusing, but it is a result of what can only be described as an oversight on Microsoft’s part; see, originally, I was changing the sort arrow header by simply changing the columnheader image. This worked, sorta of, but there was no way to remove the image and it had this weird effect where it would basically move the text and make it aligned sorta weird. Turns out that the way the ListView would “normally” show sort order icons was a built in feature of the Listview since Common Controls 6 (XP). After some SDK digging I was able to use the Platform Invoke feature of C# to call all the appropriate API functions and “force” the Listview to show the sort order in the header appropriately.
The class also exposes a custom delegate which can be implemented and passed in to the constructor, which will allow for “custom” sorts. This is useful if columns contain data like dates, or numbers that you don’t want to be sorted using the normal “text” comparison.
All in all, It’s a class I’ve added to my “toolbox”, alongside my INIFile class for accessing INI Files. did I write about that one? I forget.
So, as mentioned in the previous post, I added a “sort” of scriptability to BASeBlock.
I made some tweaks, and refactored the code so it was a bit more abstracted; the original implementation was directly in the MultiTypeManager, but that didn’t really have anything to do with it, so I tweaked some of the parameters to a few methods there, added a new class with the static routines required for the needed functionality, etc. I also made it so that a “BASeBlock Script Group file” (.bbsg extension) could be used to both compile a set of files into an assembly, as well as include various other assemblies as required. Future additions will probably include the ability for each assembly to define a sort of “main” method, which can be called when the assembly is initialized.
However, once again, Serialization was the constant thorn in my side. I was able to mess about with a custom block written in a .cs script, and it even saved properly.
But the game encountered an exception when I tried to open that LevelSet; I forget the specifics, something to the tune of “failed to find assembly” type of error. What could I do?
What this basically meant was I was going to have to learn even more about the Serialization structure of .NET. Specifically, SerializationBinder’s. The concept was actually quite simple. You basically just derive a type from SerializationBinder, and use that as the .Binder property on a IFormatter class, overriding one method seems to be enough for the most part:
Simple! it gives you an assembly Name, a Type Name, and you simply return the appropriate type. The reason the default implementation wasn’t working was certainly as a result of the assembly being loaded dynamically, since it wasn’t [i] really [/i] being referenced by the BASeBlock assembly, so the default implementation didn’t find the “plugin” class assembly or the appropriate type, so threw an exception.
The trick here is not to enumerate the referenced assemblies, but rather to use all loaded assemblies in the current AppDomain. The general consensus with regards to using CodeDOM and compiling things like this is to compile them to their own AppDomain; however, since the assemblies were being kept “alive” for the duration of the application, that wasn’t necessary, and in this case would have complicated things. Well, it would have complicated things more than they already were.
The “AssemblyName” parameter, however, was more akin to the FullName property of the System.Reflection.Assembly; for example, BASeBlock’s assembly would (for the current version) be passed in as “BASeBlock, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null”. Since we are only interested in the actual name of the assembly, we can simply grab everything up to the first comma.
Armed with the Assembly’s base name, we can start enumerating all the loaded Assemblies and looking for a match:
Then, we compare the Assembly.FullName.Split(‘,’) [0] (the text before the first comma) to the modified string, BaseAssemblyName that was changed in the same manner. I decided to go string insensitive for no reason; mostly because the assembly names for the scripts are formed from the filenames and I wouldn’t want filename capitalization to prevent a script from serializing/deserializing properly. If we find a matching assembly, we return the result of a GetType() call to that assembly with the same typename passed in as a parameter to the method. The Formatter will than attempt to deserialize the data it has to that type as needed.
There are a few issues with this- for one thing, it doesn’t work with Generic types. At least, I assume it doesn’t; I assume I would need some special code to get the appropriate Type for a generic type given type arguments. I’ll cross that bridge when I come to it.
Right now, I’ve not actually tested this extensively. My main concern would be to test that it can serialize in one session, and deserialize in another. This concern is based on the fact that the two assemblies would in that case be literally distinct- in that it would have been compiled on two occasions. Assuming the Binder is enough to convince the serializer it can deserialize something, there shouldn’t be any issues. Once I decide to figure out how to add Generics support to this Binder, I’ll definitely write about it here.

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 