[disclaimer]


This is a personal blog. The opinions expressed here represent my own and not those of any of my employers or customers.

Except if stated otherwise, all the code shared is reusable under a MIT/X11 licence. If a picture is missing a copyright notice, it's probably because I'm owning it.

Thursday, September 26, 2013

SpriteKit on Xamarin.iOS: fun without compromise

TL;DR: get the source of the game on github.

With the release of iOS7, and same day support in Xamarin.iOS, I'm spending all my free time playing with the new APIs. I particularly love iBeacon and Background Fetch. Next on my list was SpriteKit.

SpriteKit is a 2D game engine, not unlike cocos2d at all. We'll see next that it's going from one platform to another is very simple.

 I'm not a game developer, but I have some experience with cocos2d as I co-wrote (with Miguel) the cocos2d bindings for Xamarin.iOS. At that time, to test the binding, I ported a sample platform jumper game from obj-c cocos2d to c#. And I again ported the same game to SpriteKit. Here are my findings about the experience:

The Pros


  • you can almost to a line by line port between cocos2d and SpriteKit, once you figure out the basics
  • less boilerplate. Or even no boilerplate at all with SpriteKit. a SKView is a UIView, and is ready to serve as soon as you PresentScene() it. Compare that with the directors you have to put in place before writing a line of game logic in cocos2d. It's a win.
  • less leaky abstractions. I haven't compared performances, but SpriteKit doesn't expose stuffs like BatchNodes, so it's one stuff you don't have to bother about.
  • SKAction is a nice addition for objects you don't want to animate yourself in your Update() loop (they're executed just after Update(), and before physics simulation)

The Cons


  • I found myself looking for BitmapFonts. It seems like a standard in game development, but missing from SpriteKit (or I haven't found it). I'm quite confident that's a stuff we'll see in an upcoming new version.

The Rest


  • As the original game, this port doesn't leverage any Physics engine, so I have nothing to say about SKPhysics* stuffs. From the API, it looks very similar to what Chipmunk offer.

So it was a very pleasant port, at the end taking even less lines of code than the original port, and only 2 hours to write. If you want to start developing games, going for SpriteKit on Xamarin.iOS is really a no brainer. No boilerplate, no gotchas, just fun.

The Code

The code is on github, it's MIT/X11 so do whatever you want with it. The graphics are borrowed from the original game, read the LICENSE about their usage.

Tuesday, September 24, 2013

Xamarin.iOS 7 : iBeacons - Part 1: Advertizing

One of my favorite new feature of iOS 7 is the addition of iBeacons. You'll find plenty of articles explaining how it'll change the way you do shopping (if you still shop offline), allows indoor localization, and even more. Glue a beacon on your kids, and you'll know when they go too far away (digital leash). Attach one to your wallet and your phone will tell you you're leaving the house with no cash. Applications are endless.

iBeacons is a protocol on top of Bluetooth LE (Low Energy, also advertised as Bluetooth Smart, and part of the Bluetooth 4.0). It doesn't require any new hardware and is nothing really new by itself. What's new and exciting is its position in iOS: first-class citizen, integrated with CoreLocation, working in the background, ...

The recipe: advertising your position

As of now, the only objects you can use as iBeacons are iOS devices. The protocol should be made available soon, allowing 3rd party components to appear, and at that time they should sell for a few dollars a piece (based on a general purpose BT chip, like the BLE112, a beacon should cost around 40$ to build. Prices will surely drop by using cheaper and specialized chips).

Turning your iOS device into a beacon is really only a few steps:

1. Initialize a CLBeaconRegion

That'll be your beacon. uuid and identifier are mandatory. Major and minor are optional. There's a trick here, uuid doesn't have to be unique. All beacons of a common group will probably have the same uuid, and different major/minor versions.

var beaconId = new NSUuid ("5a2bf809-992f-42c2-8590-6793ecbe2437");  //uuidgen on MacOS, nguid in VS
var beaconRegion = new CLBeaconRegion (beaconId, "yourOrg.yourBeacon");

2. Initialize a CBPeripheralManager

var peripheralManager = new CLPeripheralManager (new PeripheralManagerDelegate(beaconRegion), DispatchQueue.DefaultGlobalQueue, new NSDictionary ());

class PeripheralManagerDelegate : CBPeripheralManagerDelegate
{
    CLBeaconRegion beaconRegion;

    public CBPeripheralManager (CLBeaconRegion beaconRegion)
        this.beaconRegion = beaconRegion;
    }

    public override void StateUpdated (CBPeripheralManager peripheralManager)
    {
        //State will be Unsupported on devices like iPhone4 and prior, PoweredOff if BT is down
        if (peripheralManager.State != CBPeripheralManagerState.PoweredOn)
            return;
        var options = beaconRegion.GetPeripheralData (null);
        peripheralManager.StartAdvertizing (options);
    }
}

And that's it.

Notes and further reading


  • As devices BT ids changes from time to time, your device will be sometimes advertised twice. That won't happen with real iBeacons.
  • If you want to advertize in the Background, enable "Acts as Bluetooth LE accessory" in your info.plist
  • Read Region Monitoring if you need more details.







Wednesday, May 8, 2013

It's all about monkeys

Yesterday evening, May 7, two belgian user groups,  MADN and DotNetHub invited me to give a 2 hour introduction session on creating multi-platforms mobile applications in c# with Xamarin 2.0.

Microsoft Belgium was hosting the session, and the room was packed !

I really enjoyed that evening, and just wanted to thank you all: attendees for their presence and interactions, MADN and DNH for the invite and the bottle of wine, Microsoft Belgium for the place, food and drinks, and Xamarin for the give away licences, monkeys and t-shirts.


Friday, April 26, 2013

Decorating your Xamarin.iOS code with Behaviors

Note: this is the post in which I'm getting out of the closet and make it clear that I had an affair with Silverlight. I'm still thinking about it sometimes, and when I do, this is what happens...

Every time you have to ask your user "What's your favourite colour" or "What is the air-speed velocity of an unladen swallow?" from within your iOS application, you have to ask yourself "Wait, will the field still be visible with the virtual keyboard displayed ?"

I don't know how you do it (experience sharing is welcome), but me, I do it this way:

public override void ViewDidLoad ()
{
 base.ViewDidLoad ();

 //Set Bindings and Commands
 placeField.Bind (ViewModel, "Place");
 sendButton.Command (ViewModel.SendCommand);
 busyIndicator.Bind (ViewModel, "IsBusy");

 //Slide the view on keyboard show/hide
 placeField.EditingDidBegin += (sender, e) => {
  UIView.BeginAnimations ("keyboardslide");
  UIView.SetAnimationCurve (UIViewAnimationCurve.EaseInOut);
  UIView.SetAnimationDuration (.3f);
  var frame = View.Frame;
  frame.Y = -100;
  View.Frame = frame;
  UIView.CommitAnimations();
 };

 placeField.EditingDidEnd += (sender, e) => {
  UIView.BeginAnimations ("keyboardslide");
  UIView.SetAnimationCurve (UIViewAnimationCurve.EaseInOut);
  UIView.SetAnimationDuration (.3f);
  var frame = View.Frame;
  frame.Y = 20;
  View.Frame = frame;
  UIView.CommitAnimations();
 };

}

Friday, April 12, 2013

Thursday, March 28, 2013

Producing Better Bindings: Completeness

Note: like the previous post, this one is a follow-up on a series written by someone else. We're all building on top of giant's shoulders. My giant today is Sébastien Pouliot from Xamarin. Read his series Producing Better Bindings.

Second Note: if you're reading this from a news aggregator, you might miss the embedded gists. Read the original there.

I'm lately enjoying writing bindings for Xamarin.iOS and Xamarin.Mac, a lot for the fun, very little for profit. The biggest project by far was creating a managed bindings for cocos2d (v2). This library is huge (~2500 public methods), and the API is far from being fixed in stone. The library is so big that at some point I just gave up, until Miguel resumed the effort during end-of-year break.

Thursday, March 14, 2013

Await in the Land of iOS - Collisions in Chipmunk

Note: this blog post follows the ones of Frank Krueger about the alpha release of mono 3.x for Xamarin.iOS bringing .NET 4.5 features to the mobile world: Drag-n-drop and Scripting Users. Read that first, it's worth it.

The old way!

If you're using the Chipmunk bindings, the correct way to handle collisions between shapes is to register 4 (FOUR!) handlers for the different steps: begin, preSolve, postSolve and separate. Your collision handling logic is then spread in 4 different functions. All of that for the same collision.

Friday, March 1, 2013

Working around the reverse callback limitation on Xamarin.iOS

There's one annoying technical limitation of Xamarin.iOS if you have to pass a C# delegate instance to unmanaged code. It's not new, and it's well documented.

But still, having to flag the callback with an attribute and no instance method makes an API hard to use if you don't care that much about the internals of the library you're consuming.

I'm currently polishing the Chipmunk binding for Xamarin.iOS, and the cpSpace has some functions taking callbacks, like cpSpaceEachBody or cpSpaceAddPostStepCallback.

Monday, February 11, 2013

Chipmunk bindings for MonoTouch

(c) S. Delcroix 2013
I'm quite pleased to announce the availability of Chipmunk bindings for monotouch. I started that last year, and bound just enough of it to get a sample working, added some constraints lately in order to place labels, and completed it since for the beauty of the task. The image next to this is a screenshot from a system using a motor, a gear joint, pivot joints and some more.

At this point in time, the ~2000 lines of manually crafted lines of code can be found in this pull request, but you probably won't have to wait long before it's merged in the monotouch-bindings repository.

Tuesday, February 5, 2013

Our business app doesn't need your game development skills (using damped springs to place labels on a map)

The problem

Positioning labels on a map, a chart, a plan is a problem every UI developer face at one time or another if he has the chance to work on rich business app. This problem is NP-Hard for non-trivial cases. I faced that issue twice. First while building a silverlight charting library, and then very recently for positioning labels around a pin on a plan. This post isn't about how we solved those two cases. For the charting problem, we went for an algorithmic solution which was working but not optimal. For the second, I don't know how they solved it as I didn't took the job.

Thursday, January 24, 2013

C++ bindings for monotouch using SWIG

cold cold light
(c) S. Delcroix 2013
I love bindings. I've always loved them. Back in the days, I was binding gtk+ and other gobject libs to C# for fun and f-spot usage. Then I bound some obj-C libs to monotouch for a client and some for pleasure.

But last week I faced something new. I wanted to bind (for monotouch) a C++ iPhone lib for which I only received the binaries and the headers files. The component was too large to even think about doing a manual C glue code. I googled about the possible solutions and the only valuable advice was to use SWIG, without any rationale or tutorial. This is then probably a first. An explanation on why SWIG can help you for this, the problem I ran into and the solutions I found.

Wednesday, January 13, 2010

Talk Teaser: Image processing with Mono.Simd

The facts:

Processing time using gdk_pixbuf: 431ms
Same method ported to Mono.Simd: 66ms
That means roughly 6.5 times faster !

Some explanations:
  • The gdk-pixbuf is an unoptimized standard gdk operation (gtk+ 2.18.1), but I don't think a lot of them are optimized either using mmx or SSEx for this platform (x86-64). Feel free to prove me wrong here.
  • Times are averaged.
  • Loading and saving times aren't taken into account here, but both are using gdk_pixbuf operations.
  • The Mono.Simd method acts on vanilla pixbufs, and results are plain old usable pixbufs, not some kind of memory buffer or whatnot.
  • The image attached to this post is not the result of the processing.
This is only a teaser for the short talk I'll be giving at FOSDEM on Sunday Feb 7. Be there if you want to learn more, see the code, or question my sanity for doing this in Mono and not directly as a gdk-pixbuf patch.

Friday, January 8, 2010

DeepzoomIt: a simpleminded DeepZoom composer

Now that Moonlight supports DeepZoom for more than a year, it's about time to fill the blanks and allow one to create deepzoom images, even on linux.

DeepzoomIt does just that.

At least for the simple cases, i.e. no collection support and no selective resolution. But it generate files just right, as shown below (might not work on some planets) .

DeepzoomIt uses gdk_pixbuf for image cropping, scaling, composing. And it shouldn't be sensible to the inability of gdk_pixbuf to scale images bigger than 65536px.

The code is available on gitorious, use it if you like it: http://gitorious.org/deepzoomit.


[3159x2591 sized to viewport via DeepZoom. (shift-)Click to (un-)zoom. Drag to Pan]

[Update 2010.01.11: replaced the pure xaml viewer by a managed one. Pan+Zoom works.]

Thursday, December 3, 2009

Mono devroom @ FOSDEM 2010

Mono got a room at FOSDEM2010 in Brussels, so we won't have to do that in the hallway this year !

Want to speak about something fun you did with mono ? Propose a talk. Using mono on your servers saved your company from bankrupt in 200[89] ? Talk about it too. You are a passionate mono hacker and want to spread the word about what we'll got in the upcoming version ? You know the link.

And for everyone else, eager to learn about it, to discuss it, join on Sunday Feb 7. You're all welcome.

Note: be quick, the deadline for the cfp is around Dec 20.

Monday, November 23, 2009

Unleash your (F-Spot) toolbox

Rumor has it that, during latest UDS, Ubuntu planned to drop Gimp from the default distro and the LiveCD. I won't comment this decision as 1) I have no clue if that's a rumor or more, 2) it was already commented too much, 3) I'm not a whiner, 4) there's a rationale behind that decision and I think I understand it, 5) the full Gimp is only one apt-get away.

But some were concerned about the lack of basic image editing. Enters F-Spot, the loved Photo Manager and his little brother, the --view mode. The --view mode is a standalone application, which, on top of F-spot loaders and widgets, provide a simple (ala eog) image viewer, which only view the images, and let you browse the metadata. This is it. Or was it 1h30 ago. With very few code, I plugged the main F-Spot editors inside the single view mode. And that worked quite well !

Of course, F-Spot editors are nowhere close to Gimp's, and don't even aim too. But they cover 90% of your daily usage and are (probably) simpler to use than Gimp. And even more, you can write (read contribute) some additional ones in very few lines of code. e.g. the BlackAndWhite extension is 120 lines long with the UI, despite behing optimized to run on Simd !



Expect this to be available soon on git, and a bit later in a release !

Friday, November 6, 2009

Multiple branches and translations

Fellow Package Maintainers,

How are you dealing with this ?

I guess f-spot is not the only project maintaining multiple parallel branches, a STABLE one, from which the releases and bugfix releases are created, and a master, open for business, new stuffs, and experimentations.

When we need to correct something on the STABLE branch, we push a new commit over there, then merge the STABLE back to master so it gets the same fixes. That works fine.

But it gets harder with translation commits. Most of the (awesome) translators (well, all except of one) translates the master and commits right there. Then, when it's time to release, I either ignore those translations (and that's seriously annoying for translators who pushed soem work in the .po), or I blindly backport (cherry-pick) the translations back to the STABLE branch and hope that no strings was removed in master's code. Then I merge the STABLE back to master. Both solutions are seriously suboptimal. Really.

I know how this problem is "solved" in most of the GNOME projects by putting deadlines and code freezes, and string freezes, but I guess we're not the only project around with this kind of issue.

The ideal workflow would be to have the translators (hey guys) aware of the STABLE branch, make them translate that branch, have them merge it back to master, and then, optionally, translate the missing/changed strings and commit that to master. I said ideal, cause I'm NOT gonna ask any translator to understand and follow this, be able to maually merge if something goes wrong, etc...

Translators (did I say thanks for your job lately) are already doing an ant job, most of them with no tools but a text editor, and we can't really add any pain to the process.

So, what are you doing in that case. How could we improve the process ?

Comments are open.

Saturday, October 31, 2009

Mono-ifying Gnome3, one dependency at a time

2 quick announcements:

libunique now has a managed binding, Unique#. As the mapping is already feature complete and API stable, the code is tagged 1.0.0. It's simple, it's as easy and obvious to use as the native libunique, it doesn't have funky dependency (except, well, for libunique 1.0.0), it installs itself in the GAC...

The code is hosted on gitorious http://gitorious.org/unique-sharp/unique-sharp and patches are welcome. There's no tarball so far, but if you need one, ask and you might receive.

F-Spot got yet another bugfix release (0.6.1.4) I worked on during the weekend, fixing an X issue on some screens. Unfortunately, the Karmic release of Ubuntu (congrats guys) unleashed a new horde of avid testers, and they were able to find an issue in the --view mode (the same issue, for the same widget, was reported for the facebook exporter too). I'll look at it this weekend, in the meantime the workaround is to run f-spot --view with GDK_NATIVE_WINDOWS=true.

[Update 2009/10/31: bug fixed]

Thursday, October 29, 2009

Every now and then, it's time to...

Regenerate a new keypair

The old keypair served me well during those past 8 years, but I managed to screw it up in the process of upgrading to opensuse 11.2 rc1. Here's the new public part:


-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.12 (GNU/Linux)

mQENBErpajsBCADVpFuXevFtqwT44k5b3fAzWLlLKm0JkawrtFir/lpkZp4SMFrn
ZiQ+4I5OOcptmpQfZ6oLqE1P2pGUsl9H0V9CxI9NOK+z2dQBh36ccPPLXhjtG/wO
rIymJJ0UBVRjGUL+1IhGXI3u/BVY1yzEahCUd2gf3BpJkE8COvB6ewL2KPvCfery
vx5Ot0xAqfKVCAtJ8DEVeeVW+//s++DzdiTMqbRzMApM44rT/nd3ebhx/lEb8Opo
143JZKqyrlJ18f0B6CwVjufvnwqb5fvAA9TWRZ3qfbSvRQcRvhaSnAjR1WiDdmhO
FdJJwFLDfcx9vz8snCoB5aqjLXq+AncuhnTtABEBAAG0KVN0ZXBoYW5lIERlbGNy
b2l4IDxzdGVwaGFuZUBkZWxjcm9peC5vcmc+iQE2BBMBAgAgBQJK6Wo7AhsDBgsJ
CAcDAgQVAggDBBYCAwECHgECF4AACgkQYrBLwhj7hs4PGQgAzX4/Xpbz/g5LP6LU
huNi3mabC/SUfQ/jHfO+0pHpF2jTxaUF+eCdEC86FOZubtTHtvSN9tFBWgazvDaW
HvFBQgKBfjaWUHOXXeMkPsWhOkXIqaEE2kYHuqLrijDNgtTq/So1PcPIpAJsY1rr
No++7xKvC9/usEDlnrcz8D7jyyZN/6FGFMZ2YlxCq2qV7+6yJUK4XpLdrLIYChGW
IlLHL4jrHHwnEDtSg7aTMGK+gy4U2ha/rzcEtOS5ec1Tx3MrkWc2Z3BGHZDDTtJd
xeE85GsxsYWNWgt1XzwuHrvK7yPq3Udvgthqpi//VqXfA5S98edJQNc8BXIBYZ7S
90FB4rkBDQRK6Wo7AQgAr5exsNtPs3EW901frwoVFlZLSwWYJDESUJLK7CLS+B+I
fIwPWTP/v+VkaJqJNdjZkXx9d78XFjG0nb/o4xo2m7moCr/+7HnkE/7CdXmepzgU
oZ9EK1PWyPARYVD6JWAG0NQ/SzcEKqJyo+SCfNgVEdq/ls28zXVM0dzBRjOV5sQg
+fksv91d3cPo3+RKpdHfxAUTaW11nsgXiWofx6wbKvKQl2DSjB+8I+YnfAUaRtJq
2BfYHAl8eXvdMhnwkFNIpMQQ8T5phEHJEcp2k6D03HBIwWEkcIG6OLu3g2XGgC8p
z7o8ktRhUre6dEFDCaX2gYMDKviPikqOOlGvNKRgcQARAQABiQEfBBgBAgAJBQJK
6Wo7AhsMAAoJEGKwS8IY+4bOE7cH+wcnAxDYsnnT8NakDqflpzFgtD2r1SLE1J1s
aKk0XXtSSQWQSpxC7YEm9W37SyCBoajPoganWq8FT28VrRV2OqTi88QFOezvgZIW
VoRJHlrtXj3qvdSkF7zImOzCJpN3bKsp+SSO7Kp9KJ3ypGk7ozkgzArB45C6Ydnx
lxcKuoGpb/lr89c/COq4vsaRw4DaXwYbruFITNvRQyq9rZnnYzLnVvZMvmFWU9JI
NCGa5zJbXeNxBUNYpGA3GjaS5ACeVKyHVIJCG4rlxVW/w4AcrHVv+GqIXcuQWuKN
Io2gaZLUPV38CoeKCWWedvTFtYTqHOcHW9iGofr2kEKbz6kXCQA=
=QzP8
-----END PGP PUBLIC KEY BLOCK-----

Monday, September 28, 2009

Fixes by pack of 12

Important things first, just know that Ruben is no longer AWOL. He's even back to hacking mode, and working, together with Tigger, at adding image metadata support for images to taglib-sharp.

Now to the futile, I just released F-Spot 0.6.1.3 a few minutes ago. The main purpose of it was to fix the slideshow mode on gtk+ 2.18 (which we did) and as I was at releasing, I applied some pending patches from bugzilla, wrote some myself, and backported translations from master.

The change in the importing code is worth noticing. It no longer imports the files first to memory before writing them to disk. It's quite helpful now that most cameras can create video files bigger enough to fill your machine memory in less than a few minutes (at high bitrate, on HD resolution). It's only available if you have libgphoto2 >= 2.4 and doesn't work with the directory driver (used for memory cards e.g.). Marcus is working on a fix in gphoto2, so stay tuned.

If you ask about the screensaver, it still doesn't work with gtk+ 2.18 but works fine with gtk+ master, and will still work just fine with gtk+ 2.18.1 when it goes out.

That's it. Download it, build it, package it, enjoy it!

Wednesday, September 16, 2009

News from the F-Spotters


Some news, in no particular order:

F-Spot 0.6.1.2 was released a couple of minutes ago. It fixes db upgrade for the people who went in holidays in the far future. Now F-Spot can update a db with photos taken (or reported to be) after 2038. It also fixes a crash while running on gtk+ 2.14.

The LiveWebGallery extension is now merged into the main tree, and installable, from the Manage Extension dialog, on any F-spot > 0.6. The extension crashing on gtk+2.14 is part of the past too.

Ruben is MIA. Last time we heard from him, he was "in a park near a pond near a museum".

A new extension, allowing finer control over the BlackAndWhite conversion process is coming soon. It leverages the expensive CPU you paid big bucks for via Mono.Simd. Mandatory screenshot:
That's it for today.