Disclaimer: this is an automatic aggregator which pulls feeds and comments from many blogs of contributors that have contributed to the Mono project. The contents of these blog entries do not necessarily reflect Novell's position.

January 30

Bubbles

Recently one of our customers asked about how to implement a conversation display similar to the iOS SMS/Messages display. You can find the BubbleCell sample in our Github repository.

This is what the conversation looks like:

To implement this, I used iOS's UITableView as it already provides a lot of the functionality that we need for this. What I did was to write a custom UITableViewCell that can render bubbles with their text.

I wrote both a MonoTouch.Dialog Element that you can host in your DialogViewController as well as a custom UITableCellView which can be reused by those using UITableViews directly.

This is how you could populate the initial discussion inside MonoTouch.Dialog:

Section chat;
var root = new RootElement ("Chat Sample") {
  (chat = new Section () {
    new ChatBubble (true, "This is the text on the left, what I find fascinating about this is how many lines can fit!"),
    new ChatBubble (false, "This is some text on the right"),
    new ChatBubble (true, "Wow, you are very intense!"),
    new ChatBubble (false, "oops"),
    new ChatBubble (true, "yes"),
  })
};

And this is how you would add a new element to the conversation:

chat.Section.Add (
  new ChatBubble (false, "I want more cat facts"));

Implementation

Bubble rendering is implemented in Bubble.cs and contains both the UITableViewCell as well as the element. It follows the pattern for creating UITableViewCells that I documented before.

Each cell is made up of two views: one contains a UIImageView that paints the bubble and the other one contains the text to render inside the bubble.

This is what the two bubbles images look like:

We load these using UIImage.FromFile and then use the iOS 5.0 UIImage.CreateResizableImage method to create a UIImage that can be stretched on demand. To create the resizable image we need to tell CreateResizableImage the region of the image that can be stretched. Anything outside of the UIEdgeInset will be kept as-is:

left = bleft.CreateResizableImage (new UIEdgeInsets (10, 16, 18, 26));
right = bright.CreateResizableImage (new UIEdgeInsets (11, 11, 17, 18));

This will stretch the region highlighted in red, while rendering the external border as-is:

With the above code, the image will be rendered in a variety ways depending on the Frame that is assigned to the UIImageView that hosts our resizable UIImage:

The only remaining interesting bit in the code is to configure our UILabel properly. We want to set its BackgroundColor to UIColor.Clear to avoid painting the background in a solid color and we also specify that the text should be word-wrapped if it does not fit in a single line:

label = new UILabel (rect) {
  LineBreakMode = UILineBreakMode.WordWrap,
  Lines = 0,
  Font = font,
  BackgroundColor = UIColor.Clear
};
	

Finally in our LayoutSubViews method we must compute the proper sizes for the bubbles and the text that goes in them. I made it so the bubbles did not take the entire space in a row. Instead they take 70% of the row to give a similar effect to the rendering of the iOS messages UI. The code is pretty straight-forward:

public override void LayoutSubviews ()
{
  base.LayoutSubviews ();
  var frame = ContentView.Frame;
  var size = GetSizeForText (this, label.Text) + BubblePadding;
  imageView.Frame = new RectangleF (new PointF (isLeft ? 10 : frame.Width-size.Width-10, frame.Y), size);
  view.SetNeedsDisplay ();
  frame = imageView.Frame;
  label.Frame = new RectangleF (new PointF (frame.X + (isLeft ? 12 : 8), frame.Y + 6), size-BubblePadding);
}
	

IL fun fact: not is not !

Picture yourself working on crafting a specific piece of CIL.

You need to write the compiled equivalent of:

bool b = ...;
bool n = !b;

It would be tempting to write:

ldloc b
not
stloc n

Except that it would not always work. not doesn’t negate booleans, it computes the bitwise complement of the value on the stack. It’s also not to be confused with the neg opcode, which negates a value, as in a multiplication by -1.

The usual pattern to negate a boolean is:

ldloc b
ldc.i4.0
ceq
stloc n

But that’s not really fun, is it?

Actual fun fact: there’s a misused “not” in the ECMA 335 in the example of the section 14.5 of the partition II.

Awesome details

I like small details in software. Here’s a nice one I spotted the other day:

IMG_0070 IMG_0071 IMG_0072

The Amazon Kindle app for iPad changes its background depending on the hour of the day. It even has some very nice effects, for instance, when switching to the night view, a falling star flies by.

Small details and nice polish shows your users that you care. Don’t be happy when it works, go the extra mile.

GithubSharp with ServiceStack.Text

At Xamarin, we’ve been using GithubSharp to access the GitHub API for some time. We ran into some issues with it, however, because the JSON serializers in .NET are buggy as hell (one had trouble deserializing a simple dictionary; another couldn’t handle large payloads). Therefore, we forked and branched the project and made it use ServiceStack.Text, which works nicely (and has the added effect of working on Mono).

Note that our branch is for version 2.0 of the GitHub API; the author of GithubSharp, Erik Zaadi, is now working on GithubSharp for GitHub’s 3.0 API, using ServiceStack.Text.


January 27

P4 break

Are you confined in perforce? Do you want to escape from it?

Materials

We need some tools to success in our adventure!

  1. Python 2.7 (http://www.python.org/getit/releases/2.7/)
  2. P4PythonLib 2010.1 for Python 2.7 (http://public.perforce.com:8080/guest/sven_erik_knop/P4Pythonlib/bin/?ac=83)
  3. Bzr Standalone (http://launchpad.net/bzr/2.4/2.4.2/+download/bzr-2.4.2-1-setup.exe)
  4. Bzr Python Based (http://launchpad.net/bzr/2.4/2.4.2/+download/bzr-2.4.2-1.win32-py2.7.exe)
  5. Git for windows (http://msysgit.googlecode.com/files/Git-1.7.8-preview20111206.exe)
  6. P4-fast-export.py (bzrp4)(http://dl.dropbox.com/u/2974293/trunk.rar)
  7. I assume you have the P4 client and server.

Dangers

It’s not going to be a Boy Scout trip… some brave people failed.

  1. If the Bzr and P4PythonLib is not able to find the Python installation directory please review the following link: (http://selfsolved.com/problems/setuptools-06c11-fails-to-instal/s/63)
  2. If the p4-fast-export.py fails regarding a Git error you have to follow this:(http://stackoverflow.com/questions/5299122/unable-to-import-with-git-p4-on-windows)
The plan

  1. Install all the materials, just install it, you don’t need to open or configure anything.
  2. Place the http://dl.dropbox.com/u/2974293/trunk.rar content inside a directory called “bzrp4” under the "C:\Program Files\Bazaar\plugins" directory, the path to the python migration file should be like this: “C:\Program Files\Bazaar\plugins\bzrp4\p4-fast-export.py”.
  3. Customize the “setup_env.bat” parameters with your environment info, adapt the Git path, P4PORT, and the Perforce server Path. Finally run it.
  4. Open a command line window and run: “python p4-fast-export.py //my/repo/path@all > p4fe.dat”. If you are strong enough you can review the command help. Make sure you are using the Python 2.7 executable.
  5. Create a temporal directory, change your command line directory to it and perform the following: “git init .” “type p4fe.dat | git fast-import” and then “git fast-export --all --tag-of-filtered-object=drop --signed-tags=strip > gitFe.dat”
  6. The last step is “cm fast-import p4ImportedRep gitFe.dat”

If all works fine you will have your repository inside PlasticSCM!!!

Survivors?


January 25

CmdRunner power!


The CmdRunner library is a tiny c# project that allows you to create porcelain applications using the “cm shell” strength.

What is the “cm shell” feature? The “cm shell” utility is able to execute cm commands like flash! It opens a shell interface where you can start issuing cm commands! Test it! first run four or five “cm lrep” lonely commands, not a big deal... Now try to issue “cm shell” and then type lrep & enter, lrep & enter, lrep & enter, lrep & enter... much faster!! ain’t it cool?

Using the CmdRunner library you will be able to use this incredible speed running cm commands and create small or big utilities for your daily work with PlasticSCM.

Let's see some examples, for example, if you want to list all the changesets inside the “default” repository you just need to write something like this:

You can also perform write operations, this example will return 0 or 1 regarding if the checkout operation was successful or not:

After the checkin you may want to modify the file and finally commit it:

You can go further! for example you can create your own c# replication scheduler, launch replication operations is as simple as this:

You only have to surround the cm commands with your stuff and you will able to create everything you can want!!! Every single cm command you can imagine can be executed by our CmdRunner! Some of our plugins are using this library to work! so can create big things!!

You can download the CmdRunner source code and easy examples here: http://www.plasticscm.com/externalcontent/CmdRunnerVS2010.zip

The VisualStudio solution can be opened with VS 2010. The "CmdRunnerExample" project contains code examples to start playing.

Have fun!


The Global Game Jam 2012

 

Its that time of year again!

It seems like a lifetime ago that I was attending my very first Global Game Jam back in early 2009.

I doubt I could ever have imagined that in the subsequent years I would be working for the company who’s tools I was using for the 48 hour caffeine sustained chaos.

So its with great joy that I’m happy to announce how we are supporting the Jam this year.

First and foremost we are issuing Unity Pro trials to ALL participants attending the jam. Which include iOS, Android and Asset Server. For more information please contact your local venue organizers who in turn, should be receiving information on how to get access to the trial from the global organizers.

In addition to that we are also supporting a small number of venues around the globe directly. These sponsorships will help keep you guys ticking over with food, drink, electricity, rental of space and all of the other costs included in setting up such a tremendous event.

Before I go I’d just like to wish everyone attending (or those still considering attending) the very best of luck. I’m a huge fan of Game Jams myself so I can’t wait to see what you guys come up with! (and I’m totally jealous that I won’t be able to participate this year)

 

Unity 3.5 Developer Preview: Expanding Horizons!

Flashy Bots!

The recently released Unity Developer Preview is jam-packed with new features. Among the most exciting of these features are previews of two new export options for publishing to the web: Google Native Client and Flash.

In addition to leveraging users’ already-installed software to get them into your games even faster, these platforms will allow Unity developers to perform for a previously unreachable audience: Linux users!

Wait, what?

Thanks to the cross-platform nature of Google’s Native Client toolkit, Unity web players built using the Enable NaCl Support option will just work for Chrome users, regardless of whether they’re using Chrome on Linux, Windows, or Mac OSX. This makes the Chrome Web Store one of the first distribution channels to provide high-quality 3D games to all three major desktop platforms.

In addition, players making use of Unity’s new Flash export feature will also run in any Stage 3D-enabled browser, regardless of operating system. Linux users will take a moderate performance hit here, however, as Adobe has delayed Linux support for GPU-accelerated rasterization in Stage 3D. Nevertheless, an out-of-the-box Flash build of the Angry Bots demo looked great and ran smoothly on my Ubuntu workstation, at the cost of somewhat higher CPU usage.

We’re excited about these publishing options because they represent Unity’s first official support for Linux, an oft-requested feature.

How many people are we talking about?

Linux usage is notoriously difficult to track, since there’s no single point where cash gets exchanged for code, and is generally underreported. However, we do have a few relevant data points.

w3schools, a comprehensive online web development reference, keeps comprehensive statistics about their visitors’ operating system usage, as reported by browsers. In 2011, reported Linux usage has held steady between 5 and 6% (for comparison, reported MacOS usage is between 7 and 9%). Additionally, w3schools has been gathering these statistics for years, so it’s possible to see a general growth trend for Linux since it started with around 2% reported usage in 2003. Some have suggested that w3schools’s content biases its userbase toward more technical users who could be more likely than a random sampling of the general public to have adopted Linux, but there are clearly non-technical roads that lead directly to w3schools.

What does this mean for my game?

The Humble Indie Bundle, a series of pay-what-you-choose, independent game bundles that supports Linux, OSX, and Windows, reports that 20 to 35% (based on highly scientific pie chart estimation ;-) ) of each bundle’s total revenue originates from Linux users. In addition, Linux users choose to pay an average of 100%+ more than Windows users, and about 50% more than OSX users. (Current statistics for HIB4 show an average payment of $10.29 for Linux, $7.42 for OSX, and $4.57 for Windows.) Other data points include 2D Boy, who reported that 17% of the sales in their pay-what-you-choose campaign for World of Goo came from Linux users, compared to 18% on OSX, with Linux users again choosing to pay substantially more than users on other platforms. Frictional Games reported in 2010 that 12% of sales for their Penumbra series were attributable to Linux users.

So, this means that you can realistically gain 12-35% revenue potential just by clicking the Enable NaCl Support checkbox before building your webplayer.

Show me the goods!

The Angry Bots demo has been on the Chrome Web Store for some time now – go check it out! Google also featured several Unity games (4 of the 7 games featured were built with Unity) in its recent Chrome Web Store trailer: Cordy, Pirates of New Horizons, Sleepy Jack, and Running Fred.

The Chrome Web Store is the first link every Chrome user sees when opening a new tab, so get your awesome games up there where 33.4% of all Internet users can’t miss them!

January 19

More on recursive merge strategy

A few days ago I had the chance to read a comment on my previous blog post about merge recursive pointing to the Mercurial mailing list where Matt Mackall (of Mercurial fame) strongly criticized my explanation of the recursive merge strategy.

Well, some were simply about the “rendering style” of plastic’s branch explorer (which is what I used to drive the examples), and others about the explanation itself.

Mercurial’s programmer admits that recursive merge is better although argues that it is only worth in some cases and that its costs to implement is bigger than its benefits. Implementing a recursive merge isn’t cheap, as we known down here at Codice, but you know, the big difference between a great product and an exceptional one normally relies on the upper 2% of features that makes it rock.

Today we'll be covering (I'm writing this with the help of Borja, our merge master) "advantages of recursive merge - Case 1: Only one ancestor is the right option".

Back to the drawing board

Recursive merge is not only good for “criss-cross” merge situations but also for more “regular” ones where merge history simply gets complicated.

I’d like to go back to the original example and explain it now in bigger detail:

We’re going to merge from changeset 5 to changeset 6. In this diagram (another explanation using code will come later) we simply say the “content” of the file is A or B or C, but it applies to lines of code (containing important changes, bug fixes and so on).

DAG format

Just in case anyone has trouble understanding that the green lines are merges and they’re rendered from source to destination, here’s an alternative diagram:

Common ancestors

In order to run a merge, you need to identify the “source”, the “destination” and the nearest common ancestor.

In this case the “src” and “dst” are clear but the problem is the “common ancestor” because there’s more than one candidate.

If you look carefully you’ll see that both changesets “2” and “3” can be taken as common ancestors.

A non-recursive merge algorithm will only use one of them, and depending on the “choice”, the result can be quite different.

Selecting “3” as common ancestor

If the algorithm chooses “3” (and as we explained in our previous post, this is the choice taken by Hg, and also would be the one taken by former plastic’s algorithm previous to “merge recursive” implementation) then the following situation will happen:
It will lead to a manual merge, where the user will be forced to choose.

Selecting “2” as common ancestor – the lucky shot

If the algorithm uses “2” as common ancestor, then the merge will be between content “B”, “B” and “C•”, so, since two contributors are the same, the result will be “C”.
It is the expected result as we will see later, and it is a pretty valid choice, the problem is that there’s no good consistent way to choose “2”.

This time, the result matches the expected result, but sometimes it simply leads to an incorrect automatic choice, which is the real problem and the real reason why “recursive” is implemented by git and plastic.

The recursive option

Again, here’s how the “recursive works”: since there’re two ancestors at the same distance, it will “merge them” creating a new virtual ancestor that will be used as the “base” for the final merge between the merge candidates “5” and “6”:
The following image depicts the first step, the calculation of the “virt” common ancestor (the intermediate one):
And then the second step, where the result is calculated automatically, this time without user intervention:

Where is the huge difference?

Comparing recursive and no-recursive algorithms in this example, you might only see that the recursive is able to avoid a manual conflict because it is able to find out how it was solved before. Is it such a big difference? Just avoiding one manual merge?

Real world has the answer: try a "real" merge involving several hundreds of files and then the answer is clear: usable if you don't have to solve the conflicts vs not usable.

Wrap up

We still have a ton of posts to write to share the particular cases where having recursive merge saves the day, so we’ll try to move forward one by one in the coming weeks.

Fun fact: C# methods whose bodies span over multiple source files

While working on Mono.Cecil (your lovely library to analyze and manipulate .net binaries that is used by legions), one thing that struck me as odd for a while, was the fact that a method could have debug symbols for instructions that are defined in multiple files.

Cecil has this type, Instruction. When you’re analyzing a module with debug information (think .pdb or .mdb files), an Instruction may have its SequencePoint property set. A sequence point is nothing but the location of the code in a file that relates to the instruction.

What got me wondering, is that the APIs to retrieve those sequence points make it so that a method can have sequence points in different documents. So be it, this is how I ended up representing it in Cecil, but it’s only recently that I stumbled upon a case where indeed, a C# method had instructions defined in multiple files:

Foo.Bar.cs:
public partial class Foo {
    private List<Bar> _bars = new List<Bar>();
}

Foo.Baz.cs:

public partial class Foo {
    private Baz _baz;

    public Foo (Baz baz)
    {
        _baz = baz;
    }
}

Do you see what’s going on here?

The constructor of Foo is defined in Foo.Baz.cs, but there’s a field initializer in Foo.Bar.cs that is going to be compiled inside Foo’s constructor. When you debug the constructor, you’ll effectively end up jumping between the two files. Crazy right?

Can you think of another case where a C# (or VB.NET for that matters) method would have instructions defined in different files?

Monologue

Monologue is a window into the world, work, and lives of the community members and developers that make up the Mono Project, which is a free cross-platform development environment used primarily on Linux.

If you would rather follow Monologue using a newsreader, we provide the following feed:

RSS 2.0 Feed

Monologue is powered by Mono and the Monologue software.

Bloggers