Lorenz Cuno Klopfenstein

Articles from November 2008

As I started working on a little pet project for my friend NiKo, before clicking on the Visual C# icon (as I usually do) I actually started thinking about using languages other than C#. As blasphemous as it might sound, I really liked the idea of getting something to work using a "new" language, even if I had to study it and glance over the documentation the whole time (besides, you should learn a new language every year).

Jaipur picture by Carolina Mendonça on Flickr.com But still, I absolutely wanted the program to run on .NET because I'm really used to the base class library and to Windows Forms in particular: therefore, IronPython, IronRuby and similar languages came to my mind. Brooding about that on the train back to Foligno, I was almost sold on using Python, since I have been reading a lot about it and never had the chance to use it. But then, I discovered another "reptile" programming language for .NET: the Cobra language.  :)

Cobra has a similar syntax to Python but seems to better adapt to .NET (properties and such) and drops all the - in my opinion - extremely ugly conventions of Python (like the double underscores, all the self declarations in member functions, and so on).

Starting using Cobra

All you need to start programming with Cobra is in the small package you find on the website: the Cobra compiler essentially converts all cobra code to C# files (referencing its runtime Cobra.Lang.dll if needed) and then compiles to an executable using the standard C# compiler.

I also didn't use any IDE for my work with Cobra: just Notepad++ (Python syntax highlighting works quite well) and a hand made batch file to compile all files. This rudimental programming style was especially painful in the beginning: I noticed I can't even remember the namespaces of all classes I use...  :S But anyway, at the end of the day you gain some speed and I also noticed that I seemed to be more focused without IDE (might as well be a completely wrong impression since I was still struggling with the language).

Writing a Windows Forms project

The project I mentioned is mainly focused on the GUI and working with Windows Forms on Python, without a visual designer can be pretty boring and painful. Anyway, it works and it actually forces you to realize how hard it is to design a decent looking GUI directly in code.

Anyway, I was almost stuck with two big problems. I will explain them here, hoping that someone will find the solutions I found useful someday...  :)

Nested class references

The Cobra compiler (version 0.8) has some problems in referencing nested classes sometimes. I had the exact problem as also seen on the Cobra forums, where the compiler would spit out this

error: Cannot locate nested CLR type "System.Windows.Forms.Layout.LayoutUtils+MeasureTextCache" (simple name is "MeasureTextCache"). Compilation failed - 1 error, 0 warnings

as soon as I referenced the "Label" class in my code (and working without labels can be quite difficult  :D).

There is no working solution, but only an ugly workaround hack: first of all, download the Cobra source from the repository:

svn co http://cobra-language.com/svn/cobra/trunk/ cobra-workspace

You'll discover that the Cobra compiler itself is written in Cobra. Open up the file /Source/TypeProxies.cobra and go to line 182 or so. You'll find this:

if potential is nil # comes up on MS Windows .NET 2.0 for multiple types when using System.Windows.Forms # error: Cannot locate nested CLR type "System.Windows.Forms.UnsafeNativeMethods+IOleControl" (simple name is "IOleControl"). if 'NativeMethods' in clrType.toString return _hack(clrType) .throwError('Cannot locate nested CLR type "[clrType]" (simple name is "[clrType.name]").') else if potential inherits IType return potential else .throwError('Located CLR type spec "[clrType]" but got a [potential.englishName] instead of a type.')

As you can see, the bug is known but not fixed. Replace the code with something like this:

if potential is nil # comes up on MS Windows .NET 2.0 for multiple types when using System.Windows.Forms # error: Cannot locate nested CLR type "System.Windows.Forms.UnsafeNativeMethods+IOleControl" (simple name is "IOleControl"). if 'NativeMethods' in clrType.toString return _hack(clrType) #.throwError('Cannot locate nested CLR type "[clrType]" (simple name is "[clrType.name]").') return _hack(clrType) else if potential inherits IType return potential else .throwError('Located CLR type spec "[clrType]" but got a [potential.englishName] instead of a type.')

I know this is ugly and could probably bite you somewhere in other code, but it worked for me.  :D Recompile cobra (launching comp.bat) and replace the generated cobra.exe with your current compiler from the 0.8 version.

OpenFileDialog blocking

Another mysterious problem was caused by a simple call to OpenFileDialog.ShowDialog() which was blocking the whole application thread without showing any dialog. I investigated for hours to find the reason for this very weird behavioud and finally found out it was all my fault for forgetting something very basic...  :|

Therefore: always ensure that your Windows Forms application has the STAThread attribute set! It's easy to forget it because Visual Studio always generates those bits of code for you...

use System.Windows.Forms class MyApplication def main is shared has STAThread Application.enableVisualStyles Application.setCompatibleTextRenderingDefault(false) Application.run(MainForm())
Posted on Tuesday, November 04, 2008
380 Views
0 comments posted

Stopwatch - from Geekpedia.com I just published my new small project "MotoX Stopwatch" on the website: it's basically a simple stopwatch that allows you to keep track of times and laps for multiple people.

It's also my first program written with the Cobra language and released under the "Do What The Fuck You Want" public license (I always wanted to use it  :D)!

Posted on Monday, November 10, 2008
Tagged as
252 Views
1 comments posted

This evening I pulled together the last updates to my side project OnTopReplica and published it under version 2.1.

The update contains two nice features: first of all you can now adjust the opacity of the window by turning the mouse wheel. This also makes possible to set the opacity in finer increments than through the default menu.

Additionally, the fullscreen mode has been completely overhauled and now adapts much more nicely to the screen (in fact it now leaves the taskbar free and doesn't cover potential notifications). There's also a new click-through mode (you can enable it in the "resize" menu and by setting the window opacity to non-opaque) which transforms the default fullscreen mode into an "overlay" mode: the window will sit in the foreground as usual, but you will be able to click on every window underneath. Very cool to watch movies in full resolution!  ;)

Hope you like it! Download it here.

Posted on Monday, November 10, 2008
309 Views
0 comments posted

While I was implementing the data import/export functionalities of MotoX Stopwatch, having decided to use the XmlSerializer to load and save human readable files, I found out that the serializer doesn't work for TimeSpan values for some reason!  :S

It appears to be a known problem and several other people have already posted their workarounds. However, here's my solution using Cobra: mark the TimeSpan properties (which cannot be serialized normally) with the XmlIgnore attriute. This will force the serializer to skip them. Then declare new string properties, which you will never use in your code, that simply wrap the original TimeSpan value.

use System.Xml
use System.Xml.Serialization

class StopWatchInfo
	has Serializable

	# ... normal properties ...
	
	# The next property will be ignored by the serializer
	var time as TimeSpan
		is public
		has XmlIgnore
		
	# This property wraps the one above for the serializer
	pro timeWrap as String
		get
			return .time.toString
		set
			ret = TimeSpan()
			if TimeSpan.tryParse(value, out ret)
				.time = ret
			else
				.time = TimeSpan.zero

Remember that the serializer uses the property names of the class, therefore "timeWrap" will appear in the output file instead of "time". To avoid this, you'll want to rename the wrapping property adding an XmlAttribute to it.

Posted on Tuesday, November 11, 2008
378 Views
2 comments posted

I'm finally getting back to my XNA series of posts, which will eventually lead to the release of the - cleaned up - source code of my little game (I just hope that I'll be able to do so before XNA 6.0 comes out...).

Anyway, one of the truly biggest problems I had while developing the game, was to figure out HOW exactly to point an object towards another point in space. This sounds really basic, probably is, but my math skills are so weak that I had to think about it almost an entire day before finding a solution. Perhaps this will be useful to similarly counfounded people, like me.  :D

The main problem is that you are trying to orient something along a vector, which starts in one tridimensional point and ends in another one. These two points in space are sufficient to give us a simple directional vector (the distance between the two points), but not enough for a full translation matrix (or a rotational matrix, in this case). This is because there are infinite positions in which the object we are trying to rotate could be in, while still pointing to the correct destination point. To exemplificate:

Awful scheme of the problem.

Yes, I know the drawing is extremely ugly.  :) You try doing something better with Paint.NET!

Anyway, assume the two balls are the two points I was talking about and the black thick line is the distance vector between them. Then, the disc around the red ball (or that what should look like a disc) is the plane on which all possible "up" vectors of the object could be, while still having its nose pointed straight at the blue ball.

The problem thus is that we have too much "correct" solutions: but we must decide for one (and consistently). Therefore, the simple way to do it is to simply pick a completely arbitrary vector:

//Get distance between points
Vector3 dist = ballBlue.Position - ballRed.Position;
dist.Normalize();

//Get angle to arbitrary vector and compute the rotation axis
float theta = (float)Math.Acos(Vector3.Dot(dist, Vector3.Up));
Vector3 cross = Vector3.Cross(Vector3.Up, dist);
cross.Normalize();

Quaternion rotation = Quaternion.CreateFromAxisAngle(cross, theta);

The code is pretty straightforward: first of all you compute theta, the angle between the distance vector and the arbitrary vector (in this case I chose the up vector, but you can use whichever makes more sense in your case). Then we compute the cross product between those two vector and normalize it: this will yield a nice vector (one of those on the "correct" plane I mentioned above) that can be used to generate a rotation quaternion or a matrix.

The result in my game: notice the arrow pointing towards the golden point in space.

And this is the result in my game: notice the golden "thing" above the spaceship? It's a green arrow that points exactly towards the yellow point in space on the right.

Posted on Thursday, November 13, 2008
Tagged as
346 Views
0 comments posted

Today I'm starting another new exciting pet-project of mine!  :) I'm planning to buy some DMX hardware (DMX is a simple protocol to control lighting shows and such) and build a custom piece of software, that I could then use on live shows to give life to the gig with rhythmic lighting, effects and whatnot.

The most immediate use for it would by on gigs of my brother's band, Spasmodicamente. That would be totally awesome.  :D

So, for starts, I went looking for a cheap DMX controller that can be used interactively by a computer. There are several solutions by different companies, but the most convincing seemed to be those made by Nicolaudie-Sunlite. Different models exist, some of them are pretty expensive but they also include much stuff I don't really need. Fortunately, Sunlite also sells simple kits that come with a software development kit to program the thing.

Unboxing

Two days ago I ordered one SIUDI-6C (the cheapest model, since I wasn't completely sure it was going to work). It cost 100 € plus 25 € for shipping and it was one of the quickest deliveries I ever witnessed in my life! This morning at 10 o'clock it arrived safely in my hands (that's roughly a single day from France to central Italy). Thank you Sunlite!  :)

The unwrapped box.

The nice cardboard box is definitely overkill for the three items contained in it:

Contents of the box.

The little blue plastic box is the SIUDI-6C DMX controller. The disc contains a collection of software (most of which I won't use anyway), the SDK and some documentation (it's not MSDN, but it will do). A standard printer usb cable is also in the box.

Installing

As soon as I plugged the controller in the usb slot, Vista went searching for drivers on Windows Update for almost ten minutes. Without success.  :) Anyway, all drivers are on the CD (and on the website as well).

Just make sure you don't install the drivers in the /drivers folder, but directly install the SDK in /siudi/siudi5-6_developerkit.exe. The first set of drivers cannot be installed (on Vista) because of some error in the INF file. After some hacking around in the file I managed to get them installed (and thought all was well) but the example programs did not work: "no DMX interface installed". Duh.

Then I exumed my old XP disc, installed it on the former Linux partition (won't need that for this project, that's for sure) and tried again: same story. Those drivers simply do not work. I was almost about to send a mail to Sunlite, but I tried the (slighty smaller) driver pack included with the SDK and that did the trick!  :)
Now the little fellow is blinking like mad and responds to some basic DMX command.

The SIUDI-6C DMX Controller

So, now I'm ready to do some nice stuff with my new gadget! I ordered some other hardware that can be controlled via DMX today (a DMX dimmer), therefore I will probably have something working by the end of the next week.

Posted on Friday, November 14, 2008
1073 Views
1 comments posted

I'm continuing to add more functionalities to the website and this time I've been working on "e-mail notifications" (which are sent to whoever commented on a post when a new comment is written). In order to send those e-mails asynchronously I decided to add the Quartz.NET Job Scheduler to the project and try to get it working.

So, after struggling to setup NHibernate, use the new ASP.NET MVC framework and getting Lucene.NET and NHibernate.Search to work, let's tackle the next library...  :S

Quartz.NET logo The latest version (1.0) of the library should be compatible with "partial trust" scenarios, but nonetheless still failed to work on the live website. I digged around in the source code to find the pieces of code which didn't work: I've documented my findings on the Quartz.NET mailing list and it should be fixed in the next versions (actually, the Common Logging framework would need to be fixed too for partial trust scenarios).

Anyway, if you need Quartz.NET now, here's what you need to do.

Remove the Common Logging library

After grabbing the source code from SourceForge, the first thing to do is to remove all references to the Common Logging library (which, as said, doesn't run on medium trust right now). To do so, remove the dll reference from the Quartz project:

Remove the Common Logging dll reference from the project.

Ok, now we end up with a lot of errors in the code.  :D Instead of removing the references to the logging library from the code, we can simply re-route all calls to a fake stub of the library, implementing some of the classes and copying the interface signatures with Reflector.

First of all, ILog.cs:

namespace Quartz {
	public interface ILog {
		// Methods
		void Debug(object message);
		void Debug(object message, Exception exception);
		void Error(object message);
		void Error(object message, Exception exception);
		void Fatal(object message);
		void Fatal(object message, Exception exception);
		void Info(object message);
		void Info(object message, Exception exception);
		void Trace(object message);
		void Trace(object message, Exception exception);
		void Warn(object message);
		void Warn(object message, Exception exception);

		// Properties
		bool IsDebugEnabled { get; }
		bool IsErrorEnabled { get; }
		bool IsFatalEnabled { get; }
		bool IsInfoEnabled { get; }
		bool IsTraceEnabled { get; }
		bool IsWarnEnabled { get; }
	}
}

Then ILoggerFactoryAdapter.cs:

namespace Quartz {
	public interface ILoggerFactoryAdapter {
		// Methods
		ILog GetLogger(string name);
		ILog GetLogger(Type type);
	}
}

Then create an implementation of ILog (I called it LogImpl) which simply does nothing on each call and returns false on all properties. Finally, let's implement LogManager.cs:

namespace Quartz {
	public sealed class LogManager {
		public static ILog GetLogger(string name) {
			return new LogImpl();
		}
		public static ILog GetLogger(Type type) {
			return new LogImpl();
		}

		// Properties
		public static ILoggerFactoryAdapter Adapter { get; set; }
	}
}

We don't need to implement the full class, just the methods used by Quartz, and return an instance of our stub logger.

Fixing Quartz.NET

Ok, now that the Common Logging library has been removed cleanly, we need to fix some of the calls in Quartz.NET which are not allowed in partial trust. Let's start with /Impl/StdSchedulerFactory.cs: in the Initialize() method you'll find a call to GetEnvironmentVariable() that must be removed.

string requestedFile = null;// Environment.GetEnvironmentVariable(PropertiesFile);

And then the same function call must be removed from the OverrideWithSysProps() method:

private static NameValueCollection OverrideWithSysProps(NameValueCollection props)
{
    NameValueCollection retValue = new NameValueCollection(props);
    /*ICollection keys = Environment.GetEnvironmentVariables().Keys;

    foreach (string key in keys)
    {
        retValue.Set(key, props[key]);
    }*/
    return retValue;
}

Ok, now to the /Core/QuartzScheduler.cs file. This class calls the GetAssembly() method to get the library's version number when initialized: this isn't allowed either on medium trust, so we'll have to remove that code.

/// 
/// Initializes the <see cref="QuartzScheduler"/> class.
/// 
static QuartzScheduler()
{
	//Assembly asm = Assembly.GetAssembly(typeof(QuartzScheduler));
	//versionInfo = FileVersionInfo.GetVersionInfo(asm.Location);
	//versionInfo = new FileVersionInfo();
}

And finally, remove all code in the "Version" properties with some hard-coded arbitrary values (you won't need them in most cases I think), like so:

public string Version
{
    get {
		//return versionInfo.FileVersion;
		return "1.0.0";
	}
}

That's it! Recompile the whole thing and add the new library to your project.  :)

Lazy?

If you don't want to mess with the source code and simply want a working version of Quartz.NET 1.0, download it here.

Posted on Wednesday, November 19, 2008
Tagged as
2229 Views
8 comments posted

Setup: notebook, DMX controller, DMX dimmer and lamp. My adventures with the DMX Lightshow go on.  :)
After successfully installing and setting up the SIUDI-6C DMX controller I ordered a DMX dimmer on the german Pro Lighting internet shop.

The package was delivered today:
it's a nice Eurolite "EDX-4" 4-channel dimmer, that is, a piece of hardware that has four standard power sockets and can adjust the power output on each of them, on a more or less linear scale from 0 to 100%. An arbitrary number of lights can be connected to each socket (without exceeding the unit's total power limit of course): the beauty of it is that since it uses standard Shuko sockets you can connect almost everything to it (even my old and dusty bedside lamp).

The Eurolite EDX-4 unit.

I didn't expect it to be so big. My hand is on the picture for scale reference purposes.  :D

This evening I decided to give the dimmer unit a try and wrote a little .NET managed library that wraps the programming interface included in the SIUDI-6C SDK by Sunlite. Then I quickly threw together a very ugly interface that enables to interactively set the output value on a single DMX channel, hooked the dimmer on the DMX controller, switched the power on and... lo' and behold, it works!  :D


Video hosted by Vimeo.

Ok, the hardware part would be ready... now it's time to get working on the software! I think I'll try to build something using WPF, which is a fairly new technology to me and seems to have a lot of interesting additions in .NET 3.5 SP1. We'll see.  :)

Posted on Thursday, November 20, 2008
921 Views
1 comments posted

More than a year ago I was working at my thesis using the wireless TMote modules and TinyOS on Cygwin. Today, since the whole TinyOS SDK was still laying around on my hard disk, I decided to compress everything and to back it up, in order to free some space.

But it seems that, as it was installed, Cygwin completely messed up the folder's permissions: the only user with access was the very familiar sounding user "S-1-5-21-3632630550-1273522795-1072632642-1004" (WTF?). Neither the standard user nor the administrator had any permission on the whole folder.

In this case, the only thing you can do is to launch a command promt as administrator (the GUI permission interface doesn't work at all):

Admin command prompt, taking ownership of the folder.

Launch the following command:

takeown /F <folder> /R

This will assign ownership of the entire folder (and its subfolders) to the current user (the administrator). However, you still have no permissions:

icacls <folder> /grant:r <User>:(F) /T

The /grant:r part tells Icacls to grant permissions and to revoke (:r) all previously assigned permissions. This will clean up everything. The (F) part tells the utility to assign "Full" permissions to the specified user. Finally, the /T option extends all changes to all subfolder recursively.

Posted on Friday, November 21, 2008
Tagged as
413 Views
0 comments posted

One of the last steps in the production of my game for the XNA Contest was the gathering of all the needed sound clips and the implementation of a little game component that would take care of playing the different audio cues, based on what would happen during the game. (more...)

Posted on Sunday, November 23, 2008
Tagged as
1323 Views
1 comments posted
Back to Klopfenstein.net
Clemens Klopfenstein Serena Kiefer Lukas Tiberio Klopfenstein Lorenz Cuno Klopfenstein
English German