Adding double click support in Silverlight
Silverlight Beta 2 doesn’t support double click, but since I needed it, I implemented it. I’ve created a class named Mouse. You create a Mouse instance that wraps an UIElement. The instance attaches itself to the MouseLeftDownButton and, using a timer, it allows you to recieve events when double click is performed.
Actually, you can detect as many clicks as you wish: the event arguments include the number of clicks performed by the user.
But I don’t want to attach to mouse events in code. I want to do it in XAML, like with MouseLeftButtonDown or Click. But, unfortunately, you can’t use attached properties whose type is an event handler. If you do that, you get an ugly exception.
“What a pity”, I thought, “now I need to remove some of my MouseLeftButtonDown events and replace them by code that creates Mouse instances and then attaching to Mouse events programatically”. But before doing that, I decided to give it another shot. What if I created an attached property whose type is string, and then at runtime I searched the method and invoke it?
The problem with that approach is that the method won’t be declared in the object where you are attaching the event, but probably in some parent control. For example:
<UserControl> <Rectangle manas:Mouse.Click=”SomeMethod” /> </UserControl>
SomeMethod is probably declared in our custom UserControl, not in Rectangle. But that poses no problem at all: just go up in the visual hierarchy throught the Parent property until we find a class that declares SomeMethod with the signature of our interest.
But, alas, at the time attached properties are processed by the XAML processor, the object in question is not yet in the visual hierarchy: it doesn’t have a parent. That’s no problem at all: we attach to the Loaded event and do the lookup in that moment, and we are guaranted that we can reach the parent we are interested in.
Once I did that I was really amazed that it worked!
Then, I refactored the code so I could use that trick to support other custom event handlers in XAML as well. Finally, changing the old event handlers to start firing at double clicks instead of single clicks was a matter of seconds.
Here’s the full code in case someone finds it useful.
Google translate curiosity
I tend to have phrases in many languages (Spanish, English, French, Esperanto) in my instant messenger, and my coworkers always ask me what they mean. Today I have this french phrase:
Le voilà, le gros cochon, le voilà, le bon à rien! C’est du joli, c’est du joli!
(from the story Toine, from Guy de Maupassant) which means, more or less
Here it is, the big pig, here it is, the good for nothing! How nice, how nice!
But instead of saying that to my coworkers, I told them to use Google translate, which I did to check the result. And what a surprise:
Notice how Google translated differently the words “C’est du joli”. I wonder if that’s because of the statistical translation (you know, feeding a lot of books to the machine) or because it tries to not repeat the same words over an over, much like what a person does when she writes.
Now, we wanted to see what happened if we repeated the words a lot of times:
Le voilà, le gros cochon, le voilà, le bon à rien! C’est du joli, c’est du joli, c’est du joli, c’est du joli, c’est du joli, c’est du joli, c’est du joli, c’est du joli, c’est du joli!
And again, to our surprise:
There he is, the big pig, here it is, good for nothing! It’s pretty, it’s pretty, it’s pretty, it’s pretty, it’s pretty, it’s pretty, it’s pretty, it’s nice, that east of beautiful!
Further, changing capital letter to small letters, or removing the exclamation mark gives you different results.
Generating 3D trees
The goal is to generate 3D trees programatically rather than using a design tool. A tree is a complex model, containing thousand of vertices, which are both hard to create and inneficient to store. By saving just the information necessary to generate them we save memory and make their creation easier. The steps to accomplish this are:
- Create a language that allows specifying an L-System, and write a lexer and a parser for it.
- Interpret the language and create a 3D model from it.
- Give the model life: create branches and leaves.
The grammar of the L-System language is the following:
LSystem ::= ( Rule )*
Rule ::= RuleName ParenthesizedNumber? ':' Actions ';'
Actions ::=
(
( f | '+' | '-' | '<' | '>' | 'v' | '^' ) ParenthesizedNumber?
|
( s | h | u | l | r ) ParenthesizedNumber
|
RuleName
|
Branch
)*
ParenthesizedNumber ::= '(' Number ')'
Branch ::= '[' Actions ']‘
RuleName ::= [A-Z]
Number ::= [0-9]+ ( ‘.’ [0-9]+ )?
A tree will be drawn by a turtle. The turtle starts at a certain position, for example (0, 0). The turtle follows the actions given by a rule of the L-System.
If it encounters f, it advances a step. +, -, <, >, v and ^ tell the turtle to turn clockwise or counterclockwise aroung a given axis relative to the turtle, for example up, left or head. A number between parenthesis indicates the ammount to step or turn. For example, f(2) advances two steps instead of one.
s, h, u, l and r are multipliers. s multiplies the current step by the given number. h, u and l multiplies the turn angle along each of the axis. r multiplies the trunk radius.
A branch tells the turtle to push it’s state into a stack, do the actions inside the branch, and then pop the state. This effectively allows making many branches from a given point.
If the name of a rule is found, it is consumed (interpreted again by the turtle). Since this may lead to infinite recursion, a number of iterations is defined: each time a rule is consumed, the number of iterations is decremented, until no further rules are consumed.
To see this in action, I first wanted to know if it worked in a 2D environment: requestor pattern in action! A TurtleCommander interprets the rules, starting by an axiom (the name of the first rule to intepret). As it interprets the rules and actions, it notifies an ITurtle what to do. An ITurtle is an interface that has methods like Advance, RotateAlongAxis, MultiplyCurrentStep, etc. In this way, the intepretation of the rules is decoupled from their processing. A 2D ITurtle will ignore the rotation axis because there is only one in a 2D plane. Also, I started without trunk radius, so these calls are ignored.
Another important aspect is to give realism to the generated trees. If the rules are obeyed without modification, the trees will look too symmetric, too perfect. To fix this, we introduce randomness when intepreting an action, so a step or a rotation becomes a little longer or shorter. This is all handled by the ITurtle implemantation.
Here are some screenshots of 2D trees, together with their L-System, step, rotation angle and number of iterations:
| A: f[+A][-A];
1 iteration |
| A: f[+A][-A];
2 iterations |
| A: f[+A][-A];
3 iterations |
| A: f[+A][-A];
4 iterations |
| A: f[+A][-A];
4 iterations with randomness |
| A: fA [+fA] fA [-fA] fA;
3 iterations |
| A: fA fA +[+fA -fA -fA] - [-fA +fA +fA];
3 iterations |
The next step is to make it 3D. I made another implementation of ITurtle which now understood every action except the radius change. It creates 3D instead of 2D lines. Here’s a screenshot of some early trees:
| A: f[+A][-A][A]; 4 iterations |
| A: f [-s(0.6)C] s(0.5) f [+^C] f s(2) [+B][-B][^B][vB]; B: s(0.7)f[+B][-B][^B][vB]; C: f; 5 iterations |
Next, to draw textured cylinders instead of lines:
| A: f [-s(0.6)C] s(0.5) f [+^C] f s(2) [+B][-B][^B][vB]; B: s(0.7)f[+B][-B][^B][vB]; C: f; 5 iterations |
Finally, it starts looking like a real tree. This is being drawn with the DirectX API, but without using vertex shaders and pixel shaders.
The next step is to make use of vertex and pixel shaders to give branches a more realistic appearance. To do this, instead of just sticking branches together, I stick them and twist them. Also, radius changes are now interpreted. The result is this:
| A: f r(0.6) [+B][-B][^B][vB]; B: s(0.6) f r(0.5) [+B][-B][^B][vB]; 5 iterations |
|
Nice, huh? Finally, I use a billboard technique to draw leaves in the last branches. Here are some screenshots of trees:
I really enjoyed how the look of the trees changed as I added, little by little, more details to them.
The requestor pattern: avoid looping twice
In my quest for making every piece of code testable, I run across the requestor pattern. You won’t find it doing a Google search. I first saw it in many places in JDT’s source code. The idea is separating an extraction of information (a processor) from it’s actual processing (a requestor).
For example, JDT has a class named SourceElementParser that parses a source file and notifies it’s top-level memebers, like classes, methods and fields. This class only does the parsing job and notifies the result to an ISourceElementRequestor, which has methods like enterType, exitType, acceptField, etc. In this way, the extraction of the top-level members is separated from what is actually done with that information, allowing testabilty of the processor by mocking the requestor.
Also, as the top-level members are discovered, they are notified to the requestor. Another possible implementation could be that the job done by SourceElementParser would return a tree structure representing the top-level members. This tree structure could then be processed by any class wishing to use it. The problem with this approach is that you loop twice: first for building the structure, then for processing it.
A second example is a processing REST requests. Imagine a simple contacts service, where you can retrieve all the contacts, create, edit, or delete one. The URLs could be “…/all”, “…/create?id=…&name=…”, etc. The requestor pattern solution is the following: a class that parses an URL and notifies interesting, object oriented information to a requestor.
public class RestProcessor {
public void process(String url, IRestRequestor requestor) {
if (".../all".equals(url)) {
requestor.getAllContacts();
}
// ...
}
}
public interface IRestRequestor {
void getAllContacts();
void createContact(String name);
void editContact(int id, String name);
void deleteContact(int id);
}
Yet another example: treemaps. Given an array of numbers, tell in which rectangle to position them. The class responsible for doing this could return an array of rectangles, but if the numbers to process are a lot, then two loops will happen: one for the calculation of the rectangles, the second for the actual use of them. Using the requestor pattern is straight forward:
public class TreemapProcessor {
public void doTreemap(double[] numbers,
double width, double height,
ITreemapRequestor requestor) {
// ...
}
}
public interface ITreemapRequestor {
void position(int numberIndex,
double left, double top,
double width, double height); }
Java tips learnt from Eclipse
Here are some Java tips for making your code more beautiful, understandable, reliable and maintable. They are in no particular order.
- Suppose your code will be read by somebody else. Even if you are working on a project on your own, it’s worth commenting properly your code, using interfaces and trying to make your code understanable. That somebody else might be you: in a couple of months you won’t remember all the details of your implementation without good comments.
- Comment properly your code: try writing the comment of a function or class before getting into implementation details. That will also give you a better understanding of the problem. Appart from this, there are some very useful comments:
- This interface is not intended to be implemented by clients. Sometimes interfaces are used to hide implementation details. This kind of comment is used to tell the user about this.
- This interface may be implemented by clients. It’s almost the opposite of the previous point, except that the library may already provide some implementations.
- This class is not intended to be instantiated by clients. Some classes are used for internal purposes or as results of method invocations. This tells the user they are expected to obtain instances of the class, not to create them.
- This class is not intended to be subclassed. Even if the class is final, this method tells the user it’s not correct to subclass some class, because it may lead to poor performance or incorrect behaviour.
- You can obtain an instance of this class/interface from Foo. In case of an interface or a class that is not intended to be instantiated, this helps the user get instances of them.
- See Foo. This tells the user the referenced class is somehow related to the commented class. Even if the referenced class is already mentioned in the general comment, these kind of references are more visible than some word in a big comment.
- Provide clean interfaces between different modules of a system. Typical modules are UI and logic (or core). As much as possible, these modules should communicate using interfaces in order to hide implementation details.
- Use internal packages. Classes that are not supposed to be used outside of a module should be in a separate package hierarchy. Eclipse usually uses the name “internal” for this purpose. For example, in JDT, there’s “org.eclipse.jdt.core”, “org.eclipse.jdt.ui”, and “org.eclipse.jdt.internal.core” and “org.eclipse.jdt.internal.ui”. Note that “internal” is the root of all internal packages; you should not name the internal packages, for example, “org.eclipse.jdt.core.internal” and “org.eclipse.jdt.ui.internal”. This makes it easier for users browsing the packages to recognize internal packages.
- Use interfaces. Interfaces may have different purposes:
- Provide different implementations for the same goal. The typical example is a list, which may have different implementations for different performance use cases (LinkedList, ArrayList, etc.).
- Allow criteria modification. For example, a sort function may accept a Comparable interface in order to provide any kind of sort criteria, based on the same algorithm.
- Hide implementation details. This also makes it easier for a user to read the comments, since in the body of the interface there are only methods, fields and comments, no long chunks of code to skip.
- Use the I prefix for interfaces. This maks it easier for a user to recognize an interface.
- Treat interfaces that have one implementation differently. Usually interfaces that are used to hide implementation details have a single implementation in the whole system. In these cases:
- Don’t prefix a name with implementation details. For example, there could be an IUser interface which has an implementation based on a database. Don’t name it DatabaseUser if the chances of changing the implementation are very low; User is enough, with a comment saying “implementation of IUser using a databasea”. Long names are harder to read. The User class should be in an internal package.
- Use casts without fear. You interfaces return and accept IUser instances. Since they are interfaces, you might think you need to put in the IUser interface every method needed to accomplish client tasks as well as internal tasks. This is not true. Provide interface methods for things a client might need, and in method implementations cast to the single implementation and use the internally available methods. IUser should be marked with a comment saying a client should not implement it.
- Implement toString() as much as possible. Ideally, every class should implement the toString() method. When you are debugging in Eclipse, it’s much easier to see important details of a class by seeing it’s toString() information instead of manually expanding lots of nodes. You should’t worry about performance details in this method.
- Prefer packages with lots of classes than lots of packages with two or three classes. Having too many packages makes it difficult for a user to browse the source code.
- Write all comments in english. Although in an ideal world I would recommend doing it so in a neutral language, like Esperanto, there’s a high chance someone from another country will need to understand your code.
- Write tests, even if it seems impossible to do so. For example, if you need to debug a web page, how can you test correct use of the Request and Response classes? Abstract them with an interface that only provides the methods needed by your application, and use mocks in the tests. Also, try to make your tests as short and self-explaining as possible. If you need to write utility classes just for tests, do so, you won’t be losing time.