You are browsing the archive for non-tech.

Porting some Android SDK samples

July 13, 2012 in Guest Post, Java, Oxygene, Prism

As I mentioned last time, I’ve been porting some of the Java Android SDK demos over to Oxygene for Java. This is for various purposes:

  • to ensure I am on top of various Java code layout approaches. The one that requires the most faffing about is nested classes. In Java the nested class gets access to members of the outer class, thanks to having an implicit this parameter passed through the constructor. That requires a bit of manual rewiring, which is a bit of a bore, but no big deal.
  • to get some exposure to various additional Android programming areas.
  • to run more and more code through Oxygene for Java and report any latent bugs that show up when trying it out.
  • to build up more useful Oxygene for Java examples that can be packaged in with the product and thus be of reference use to Oxygene users
  • to find out what issues and bugs are lying in wait for unsuspecting newcomers to Android programming within the recesses of those SDK demos.

I’ve uploaded a bunch of them to Google Play now (see the end of this post) so anyone interested can check them out and report any problems left in there so I can try and remedy them. Of course they are demo apps and so you shouldn’t expect too much of them. They’re just there to demonstrate certain Android programming techniques and so aren’t professional-level applications.

In the last post I looked at the poor support for the exit-the-app-and-come-back situation with Lunar Lander and JetBoy. Well, poor support isn’t really accurate as the apps just crash out when you try and resume them. Poor implementation, poor planning, something like that perhaps.

Anyway, other common themes that come out of more demos are as follows:

1) Background image resources are not resized to accommodate screen sizes. Perhaps back when these demos were written, the various bitmaps used in AccelerometerPlay, JetBoy were larger than the largest of screens. Not now with tablets and large display phones.

In the case of an image on a game that will get an initial size on startup and not change, for example a game that is fixed to landscape or portrait orientation, then you can size the bitmap once after having loaded it. JetBoy is fixed to landscape orientation thanks to this attribute in its activity declaration in the Android manifest file:

android:screenOrientation=”landscape”

Similarly the AccelerometerPlay demo is forced to portrait with this attribute in the activity declaration in the Android manifest:

android:screenOrientation=”portrait”

If you draw in a View descendant, then override the onSizeChanged() method and you can resize the bitmap by passing it to the static Bitmap method Bitmap.createScaledBitmap() along with the target width and height, typically as passed in parameters to onSizeChanged(). For example, in the accelerometer demo I now have this:

method SimulationView.onSizeChanged(w, h, oldw, oldh: Integer);
begin
  // other stuff is here
  …
  // Resize the background bitmap
  // NOTE: original code did not resize the background bitmap
  // so it did not cover the background on larger displays
  mWood := Bitmap.createScaledBitmap(mWood, w, h, true)
end;

If you’re working with a SurfaceView and have implemented the SurfaceHolder.Callback interface then you can do much the same thing in the surfaceChanged() method.

You can also choose to size the bitmap on-demand when it’s needed from its original size to the required size for the target canvas. This will be a little less performant than a one-off resize but can be useful. For example, the JetBoy app has a ready screen before play starts. The background to that screen was not resized appropriately. If you didn’t want to resize the background bitmap once ahead of time you could identify the current size and target size as Rect objects and call an appropriate override of the Canvas object’s drawBitmap() method:

method JetBoyThread.doDrawReady(aCanvas: Canvas);
begin
  var src := new Rect(0, 0, mTitleBG.Width, mTitleBG.Height);
  var dest := new Rect(0, 0, aCanvas.Width, aCanvas.Height);
  aCanvas.drawBitmap(mTitleBG, src, dest, nil);
end;

2) Older games were coded to assume the presence of a directional touchpad (D-Pad). Most modern devices come without one of these, so to make them usable on current devices I’ve had to add in onTouchEvent() overrides in either the View or Activity for simple screen touch responses. In the case of the Snake demo app I implemented GestureDetector.SimpleOnGestureListener to handle directional swipes.

3) Some demos have been updated over the Android releases to take on newer behaviour. For example, there is a simple Bluetooth Chat demo. You can install it and run it on two devices and the users can connect and do a simple Instant Message type chat. In the most recent SDKs for Android 4.0.x (Ice Cream Sandwich) this demo has been tweaked compared to what you see in the samples for the older Android versions. This newer version uses the so-called Holographic theme introduced in Android 3, which adds an ActionBar to the app as a side-effect. What are menu options in the earlier version are now ActionBar actions when installed on a more recent OS.

Also the newer version of the app offers both secure and insecure Bluetooth connections, something the original version didn’t as insecure Bluetooth connections were introduced in Android 2.3.3 (Gingerbread MR1).

The initial question was which version of the demo to bring over to Oxygene. In the end I got the translated app to operate on any Android version from 2.0 (Eclair) onwards.

To get the Holographic theme to be applied for Android 3 (Honeycomb) and later (and thus get the ActionBar) I took advantage of Android’s resource system (as mentioned here). I defined an app theme to be based on Android’s default old-school Theme in a resource file in res\values as per usual.

<resources
    xmlns:android=”
http://schemas.android.com/apk/res/android”>
  <style name=”AppTheme” parent=”@android:style/Theme”>
  </style>
</resources>

But then I defined the same app theme to be based on Theme.Holo in a resource file in res\values-v11.

<resources
    xmlns:android=
http://schemas.android.com/apk/res/android>
  <style name=”AppTheme” parent=”@android:style/Theme.Holo”>
  </style>
</resources>

If running on API 11 (Android 3.0 aka Honeycomb) or later the theme definition will be pulled from this latter directory. All that’s left to finish the job is to apply the app theme to the application in the Android manifest file:

<application android:label=”@string/app_name”
             android:icon=”@drawable/app_icon”
             android:theme=”@style/AppTheme”
             android:debuggable=”true” >

  …
</application>

That’s the appearance. But it was also important to ensure the option for establishing an insecure Bluetooth connection was removed from the menu if running on Android earlier than 2.3.3. Since the menu is defined in a menu resource file this simply involved having two menu definitions, one in the usual res\menu directory and one in res\menu-v10. The menu definition in res\menu has the problem option removed; the menu definition in menu-v10 will be used on Android API 11 (2.3.3) or later and has all menu options defined.

The final aspect of keeping the app version-agnostic is to check the code and what relies on the newer aspects of the source. Anything that needs to be skipped on Android versions earlier than 2.3.3 can be conditionalised using Build.VERSION.SDK_INT, something like this:

if Build.VERSION.SDK_INT >=
     Build.VERSION_CODES.GINGERBREAD_MR1 then
begin
  …
end;

Uploaded demos

Ok, so I’m done pulling Java code over to Oxygene and making it work properly for the time being. I’ve tidied up the demos that I’ve ported and uploaded them to Google Play, giving as useful a description as I can for each of them. The following are online – if you encounter any problems or have any simple improvement suggestions (bear in mind they are meant to just be ports of existing demos) I would appreciate hearing from you.

  • AccelerometerPlay: demonstrates the accelerometer sensor by representing a slab of wood with three shiny balls on it. Tilt the device and the balls roll in a quite realistic manner.
  • Bluetooth Chat: install on 2 Android phones and you can establish a connection (secure or, if on Android 2.3.3 or later, insecure) and have an IM-style chat
  • Cube Live Wallpaper: two live wallpapers. One is a rotating wire cube. One has a settings page to allow to to choose between a rotating wire cube and a rotating wire dodecahedron. On Android home screens that support it (not HTC Sense 3.0 or later, or Android 4.0 or later) the wallpaper responds to offset messages, meaning that the shape will rotate as you move from home screen to home screen.
  • JetBoy: a scroller game that demonstrates Android’s JET audio engine. Destroy a certain number of asteroids in a certain amount of time by firing in time to the music.
  • Lunar Lander: use direction and thrusters to safely land on the landing pad. I’ve mapped touches on areas of the screen (as per the app description on Google Play) to the D-Pad controls, but apparently it’s still a but tricky. This could just be a function of the game implementation, or maybe the D-Pad to screen mappings. Any thoughts, let me know!
  • Snake: The classic snake game. Swipe the screen to change the snake’s direction and reach the apples. Mind yourself and mind the walls!
  • Wiktionary ‘Word of the Day’ Widget: install on your home screen and you get Wiktionary’s word of the day displayed, along with the word’s definition. Touch the widget to open up a Wiktionary browser where you can follow links to other words, search for words or go to a random word.

The full set of Oxygene-ported Android SDK apps can be found at this link.

Alternatively all my Oxygene-powered Android apps can be found at this link.

Android game loops

July 10, 2012 in Guest Post, Java, Oxygene, Prism

I’ve been porting some of the Android SDK samples from their original Java over to Oxygene for Java, with the hope they’ll be included in a forthcoming update to the product.

I’d already contributed a port of the AccelerometerPlay demo, which is a neat little demo of using the accelerometer to control several balls on a surface (the screen).

Among other examples I’ve been looking at are the Lunar Lander and JetBoy demo games. Now, if you wanted to start writing a graphics frame-based game that used a SurfaceView as its output you’d think these would be a great starting point, right?

LunarLander

Wrong!

Well, kind of wrong anyway.

JetBoy

The games work ok and you can play them, although they both have the shortcoming that they were written back in the days when most devices had a D-Pad (directional pad) and/or physical keyboard. Consequently the original examples are unplayable on many current devices. That’s no problem – it’s not much trouble to add in support for touches on bits of the screen or swipes across or up and down the screen. Actually I had to add in swipe support for the Snake sample game, which also relied on a D-Pad, but since that one’s not based on a thread (being a simpler game it uses a Handler and its sendMessageDelayed() method).

The problem with Lunar Lander and JetBoy is with how their thread-based operation has been laid out. The JetBoy architecture was based on the simpler Lunar Lander and so both games suffer from the same problem. The symptom is that if you switch away, maybe by pressing Home or by a phone call coming through, and then switch back the game crashes out. If you look at a logcat from either app running and crashing you’ll find that the problem is an IllegalThreadStateException being thrown with the message:

java.lang.IllegalThreadStateException: Thread already started.

This doesn’t look like a very good basis for a couple of evidently appealing sample apps, being designed with a thread crash in… Clearly people will base their own games on these apps and be rather frustrated by this poor design.

Anyway, enough of the criticism. What’s the issue here? Well, a cursory search on the web shows this has (unsurprisingly) cropped up a lot of times and there have been various ways it has been responded to. So let’s look at the problem and the solution.

The games have an Activity whose UI is made up of a SurfaceView descendant. The game logic is contained in a Thread descendant. When the app starts up and the activity’s onCreate() method runs it creates the custom surface view and asks that view to create the thread.

The surface view has a couple of methods that mark the lifetime of the actual drawable surface: surfaceCreated() and surfaceDestroyed(). In surfaceCreated() the thread is set in motion with a call to its start() method. When the surface is destroyed, for example by switching back to the home screen, two things occur. Firstly a member field flag is set to indicate that the thread’s body (its run() method) should stop whirring round updating state and drawing frames. Then the thread’s join() method is called, which blocks the surface view thread until that run() method has done its job and exited.

Ok, with me so far? No evident problem so far. What happens when we switch back to the app?

Well, when the app’s UI resumes the surface view’s surfaceCreated() method is called, which calls the thread’s start() method to start it off again. And therein lies the nub of the problem. As the documentation states, start() will throw an IllegalThreadStateException if the thread has been started before.

Because of this coding scheme the Lunar Lander and JetBoy apps are set up to fail. So, what’s a good solution?

Well, I’ve tried a couple of options, some of which are frowned upon as not being the right way and settled for the suggestion of StackOverflow user Pompe de velo in this post. The changes required are as follows:

  • in the thread define member variables:
    • var mPauseLock: Object := new Object;
    • var mPaused: Boolean;
  • have the thread’s run() method keep iterating endlessly (while true do… instead of while mRun do…).
  • in this loop, after all the individual iteration’s physics update and frame drawing add:

    locking mPauseLock do
       while mPaused do
         try
           mPauseLock.wait
         except
           on e: InterruptedException do
             { whatever };
         end

  • if your thread already has pause() and unpause()/resume() type methods implemented then great. If not add them.
  • have the pause() method do this:

    locking mPauseLock do
      mPaused := true;

  • have the unpause() method do this:

    locking mPauseLock do
    begin
      mPaused := false;
      mPauseLock.notifyAll
    end;

  • in the activity’s onPause() method call the thread’s pause() method
  • declare a member field in the surface view:

    var mGameIsRunning: Boolean := false;

  • in the surface view’s surfaceDestroyed() method remove all the code relating to managing the thread
  • have the surface view’s surfaceCreated() method change the call to thread.start() to this code:

    if not mGameIsRunning then
    begin
      thread.start;
      mGameIsRunning := true
    end
    else
      thread.unpause;

Yeah, so there’s a few changes there, but once done the app can survive being switched away from and back to.

It would probably be a good move to take the fixed app, strip all the logic out and use it as a skeleton gaming loop app, which I may well do.

For now, I have more bugs to fix in SDK demo apps I’m porting over. Currently I’m getting on top of an issue with the BluetoothChat demo where exiting and restarting the app means connections from another device no longer show up on the UI. It would appear the Android SDK demos didn’t get a particularly good test through….. What’s more of a shame, though, is that despite numerous people reporting issues, the demo apps do not get updated to fix the problems.

<sigh>

Retro effects with Android

July 8, 2012 in Guest Post, Java, Oxygene, Prism

A few weeks back I was browsing Paweł Głowacki’s blog and saw his write-up on implementing both a parallax starfield as well as a 3D starfield using Delphi and FireMonkey. Quite taken with the classic starfield demo idea I though it might be neat to have a go at putting together an Android implementation in Pascal using Oxygene for Java.

As Paweł did, I used the basic Python logic from http://codentronix.com/2011/04/27/a-cool-parallax-starfield-simulation-using-python to build up the parallax version from and then used the logic from http://codentronix.com/2011/05/28/3d-starfield-made-using-python-and-pygame for a basic 3D implementation. Then I bumped into a nice DHTML JavaScript implementation of an interactive starfield at http://www.chiptune.com/starfield/starfield.html, where moving the mouse changes the aspect of travel through the starfield.

So I knocked up some equivalent logic in Oxygene in an Android application and uploaded the result to the Android Market, oh, I mean Google Play. You find the free app through this link if you want to check out the results. The interactive starfield has some settings to customise the number and speed of stars as well as whether touching the screen changes the travel aspect.

StarfieldAppMenu StarfieldAppSettings

StarFieldApp StarFieldApp2

Clearly the logic is reasonably straightforward – in each case it’s really just dots of various sizes drawn on the Canvas of a SurfaceView. This is done again and again after having moved the positions of the stars in ‘space’, but of course care must be taken to be CPU-friendly. To that end an Android Handler is used and each time a frame is drawn, the next one is scheduled in for some small time period later using a call to its postDelayed() method.

Anyway, I was quite pleased with how this little app turned out, and how it gave me an opportunity to go through the Google Play application publication process. And then I started thinking about other old effects from the demos that used to be quite popular in the late 80s and early 90s…

My favourite was the plasma effect: an undulating oozing flow of colours shifting through the screen. A bit of research helped me understand the general principle of how the plasma effect is implemented, with a plasma function at the heart of it. I found a selection of different plasma functions and rolled them into a configurable Android plasma app built with Oxygene for Java, available for free at this link:

Plasma1 Plasma3 Plasma2

Plasma4 Plasma5 Plasma6

These plasma effects are implemented by pre-assigning an interesting palette of colours and then iteratively calculating the value of each pixel of the plasma surface and plotting it on a bitmap. To keep things performant the plasma surface is typically rather less dense than the pixel count of a smart phone screen and so this bitmap is then stretched onto the Canvas of the underlying SurfaceView. However, to minimise the evident pixellation some of the effects actually render virtual pixels and use a random jitter (x & y offset) in conjunction with opacity to smooth out the edges.

Having been bitten by the bug of retro demo effects I then bumped into the Demo Effects Collection Open Source project. This shows, in C++, how a whole raft of old demo effects are implemented, so I picked a few other effects I had a nostalgic affection for and concocted Retro Effects, another free Android app built with Oxygene for Java and available at this link. This one has a fire effect, a particle explosion, shadebobs and copper bars (as well as a starfield and plasma implementation for completeness):

Fire Shadebobs

Copperbars Explosion2

This has all been a terrific trip down memory lane for me, resurging my interest in the old demo effect scene, and using Oxygene for Java has allowed me to build the apps on my favourite mobile platform, Android, using my favourite language syntax, Pascal.

Oh, just in signing off I should mention that I also uploaded a couple of live wallpapers, one with the interactive starfield and one with the configurable plasma functions. Live wallpapers are quite a nice distraction and needn’t be as much of a battery hog as they are sometimes made out to be (especially if implemented carefully). The Android live wallpapers do, however, have a nominal download charge associated with them.

I’ve been porting some of the Android SDK demos from the original Java to Oxygene, including the live wallpaper demo (a rotating cube and a rotating dodecahedron), so I’ll probably blog some technical details on how these things are built at some point in the near future.

Avatar of marc

by marc

It’s Podcast Time!

July 5, 2012 in Cocoa, iOS, Mac, non-tech, Oxygene, Podcast, Relativity, ROFX, Xcode

i know it’s been a while since we have put out an episode of RemObjects Radio, and we apologize for that.

In the meantime however, there have been some other podcast events that might interest you:

  • Yesterday, i had the honor of being invited to join Scotty and John of iDeveloper TV for Episode 58 of their podcast, aptly entitled “More than Two Tiers”.

    We ended up spending pretty much the entire hour of the show talking about Data Abstract, Relativity Server and general technical concepts, challenges and ideas related to multi-tier database access from the perspective of Mac and iOS developers.

    You can find the episode to download and listen to here, although i really recommend subscribing to the entire podcast series, as John and Scotty just do an awesome job of providing information for Mac and iOS developers week after week (and RemObjects Software is proud to have been supporting the show thru sponsorship from day one).

  • Last month, Jim was on the IMI tech Talk Podcast and talked about Augmented Reality, Google Glass and more. Have a listen, Jim’s segment starts around 12 minutes into the episode and goes on thru the end (note that unfortunately the .mp3 link on that page seems to be wrong; the direct link to the right mp3 is here).
  • Finally, the Podcast @ Delphi.org turned the tables in late May, making regular host Jim McKeeth the interviewee in honor of the 50th episode of Delphi developer’s favorite podcast. While the episode touches on many topics, Jim, Jamie and Stuart spend a good deal of the time discussing RemObjects-related topics, including the Oxygene language and compiler, our cross-platform development philosophy, and a lot more. Go check it out here.

Android development session at mobile-focused conference

May 17, 2012 in Guest Post, Java, Oxygene, Prism

On 29th June, 2012 I’ll be travelling to Cambridge, UK to speak at Mobile East 2012, a mobile-focused conference. I’ll be delivering a session on Android development using RemObjects’ Oxygene for Java development tool and catching several of the other sessions during down-time on the day.

I’m looking forward to it – it’s been some months since I’ve spoken at a conference!

Avatar of marc

by marc

Introducing “Train” — JavaScript-based build automation

May 2, 2012 in non-tech, RemObjects, Train


Today i’m excited to talk about a new side project that Carlo and i have been working on in our spare time over the past couple of months: Train.

But let me start with some background.

Here at RemObjects Software, we use a sophisticated (but home grown) continuous integration system spread across several build servers to do automated builds and tests of our products. The build cycle for most of our products is intricate and lengthy, so of course it has to be automated: our “rofx-win” (more on what that one encompasses below) repository alone creates 16 different installers that we deploy, involving dozens of binaries that need to be built and countless additional tasks that need to be performed.

Until recently, we have mostly been using a commercial build automation tool that has served us well for the past almost 10 years, but we started running into its limitations — limitations not by any fault of the tool itself, but limitations imposed by the complexities of our builds.

Some of the problems included:

  • It supported builds for Windows only, meaning for out Mac-based products, we had to use a different solution.*

  • It provided a great IDE for creating build scripts, but that was also Windows only; i’m responsible for a lot of the build script maintenance here myself (because i’m the kind of anal type you need to be to keep these things clean and tidy ;), and i’m glad for any chance to avoid booting my Windows VM.

  • But most importantly, it used a very verbose XML file format where every little adjustment to one part of the script caused thousands of small and inconsequential changes to the XML — changes that made merging a living hell (and we branch like crazy, here). It’s an eye-opening experience when after doing a cumbersome manual merge in Araxis, you get an error telling you that you overlooked a change in line 87,000. Yes, that’s line eight-seven-thousand. Not good.

So, Train

So we set out to create our build script engine to replace this tool, with the following goals in mind:

  • We didn’t want to completely reinvent the wheel.

  • It had to run on Windows and Mac OS X (and potentially elsewhere, such as Linux, though we don’t run it on that, ourselves).

  • Build scripts had to be clean and easy to branch/merge.

  • And, ideally, build scrips should be easily maintainable as plain text.

The result of these goals, lots of extensive spec’ing, and even more coding — mostly by Carlo — is Train, our new open source build script engine.

Train is based on JavaScript, and implemented using Oxygene and our already open-source RemObjects Script JavaScript engine. Simply put, Train is a tool that lets you take a JavaScript source file and run it. But Train is so much more: In addition to letting you use the full flexibility of JavaScript in our build script, Train adds:

  • An extensive base API for common build tasks, from handling files operations over working with .ini or .xml files to building MSBuild, Delphi or Xcode projects. That API is of course expandable, both using .NET modules or directly in JavaScript.

  • Sophisticated handling of variables, including access to environment variables and parameters passed to the build script, and in-string variable resolution.

  • Flexible support for nesting and including sub-scripts.

  • Great and readable logging, both to the console/stdout while a build is running, and to XML and rich HTML log files.

To give you an example, here are some parts of our “rofx-xcode” build script:

include("$(Train)/ci2.train"); // Shared stuff specific to RemObjects' CI2
 
var versionNumber = ci2_GetVersionNumberFromGlobalIni("ROFX");
var sharedRofxWin = ci2_FindClosestSharedFolder("rofx-win"); // find closest/latest "rofx-win" build to copy stuff from
export("CIVersionNumber", versionNumber);
 
log("sharedRofxWin is in "+sharedRofxWin);
 
//...
 
run("Source/RemObjectsSDK.train");
run("Source/DataAbstract.train");
run("Source/TwinPeaks.train");
 
function buildTrial(_project, _targetBase, _sdk)
{
    xcode.rebuild(_project, { configuration: "Trial", target: _targetBase+" for OS X", sdk: "macosx",          destinationFolder: "./Bin" });
    xcode.rebuild(_project, { configuration: "Trial", target: _targetBase+" for iOS",  sdk: "iphoneos",          destinationFolder: "./Bin/iOS" });
    xcode.rebuild(_project, { configuration: "Trial", target: _targetBase+" for iOS",  sdk: "iphonesimulator", destinationFolder: "./Bin/iOS" });
}
 
buildTrial("Source/RemObjectsSDK/RemObjectsSDK.xcodeproj", "RemObjects SDK");
buildTrial("Source/DataAbstract/DataAbstract.xcodeproj", "Data Abstract");
 
// ...
 
xcode.rebuild("Tools/DASchemaModeler/DASchemaModeler.xcodeproj", { configuration: "Release",  destinationFolder: "./Bin" });
xcode.rebuild("Tools/DASchemaModeler/DASchemaModeler.xcodeproj", { configuration: "AppStore", destinationFolder: "./Bin" });
 
// ...
 
file.copy("Release/*", env["CIReleaseFolder"]);

Among other things, you see this script calls run() on “DataAbstract.train”, which is a subscript that we actually ship with the product, so customers can run it standalone if they want to rebuild DA from source. The console output of “DataAbtract.train” while it is running might look something like this:

Dream:Source mh$ train DataAbstract.train 
RemObjects Train - JavaScript-based build automation
Copyright (c) RemObjects Software, 2012. All rights reserved.
script(da.train) {     
  function buildDAProject(Data Abstract for OS X, macosx) {     
    xcode.rebuild(DataAbstract/DataAbstract.xcodeproj, [object Object]) { }   
    xcode.rebuild(DataAbstract/DataAbstract.xcodeproj, [object Object]) { }   
  } function buildDAProject
  function buildDAProject(Data Abstract for iOS, iphoneos) {     
    xcode.rebuild(DataAbstract/DataAbstract.xcodeproj, [object Object]) { }   
    xcode.rebuild(DataAbstract/DataAbstract.xcodeproj, [object Object]) { ...

As you see, it is nice and concise; you can see the flow of actions and JavaScrip functions the script is running thru, without any excess baggage (such as the extensive info Xcode dumps to the console).

Of course both XML and HTML log files can be generated as well, with the HTML being created from the XML using a standard XSL file included in Train. The output of a failed build might look like this:


Train Log file

Of course you can tweak the XSL, or process the XML log file in your own way, if you like.

The Bigger Picture

With Train, we now have the last part of our continuous integration system under our own control, running our own internal software.

The rest (and much bigger and more complex part) of our build infrastructure, affectionately called “CI2″, is very interesting too, and i plan to write more about it in the future (and we are looking into possibly open-sourcing more parts of that, as well — but currently many things in CI2 are designed pretty specifically around our own needs).

Train fits in well with CI2, but is a completely independent piece of technology, and we hope that by making it available as a true open source project (under the BSD license), it will be helpful to many others looking for a clean and easy way to automate builds (or, really, any task).

Train in Action

At RemObjects, we have 5 main repositories that our build system handles: “rofx-win” (Data Abstract, RemObjects SDK and related tools, for all platforms but Xcode), “rofx-xcode” (you guessed it: Data Abstract and RemObjects SDK for Xcode), “oxygene”, “hydra” and “everwood”.

At the time of this writing, all but “rofx-win” have been converted to use Train — and “rofx-win” simply hasn’t because it’s a huge and complex build script that just takes time to convert/rewrite (and in the process get cleaned up and rethought). But between the other four repositories, Train has already been getting some good and thorough real life use, both on Windows and Mac OS X.

Get Train

There’s two ways to get Train, both from github.com/remobjects/train.

  • If you’re feeling adventurous and/or want to get involved in extending and improving Train, clone a copy of our git repository (or fork your on copy — we’re looking forward to your merge requests!) and build it yourself. The clone will include RemObjects Script, so all you need is Oxygene for .NET (the free command line compiler will do).

  • Alternatively, you can just grab the pre-build .zip distro with the latest compiled binaries, ready to run on Windows and Mac OS X (via Mono). We’re currently at revision 0.5, the same version running on our build systems.

Avatar of marc

by marc

What, exactly, is “native” development?

April 19, 2012 in Android, iOS, Mac, Metro, non-tech, Oxygene, Platforms, ROFX, Windows, WP7

Some developers, mostly those tied to unmanaged languages such as C++ or Delphi, define nativeness as compiling directly to the byte code expected by the physical CPU. That’s certainly one way to look at it, but we think it’s imprecise, and doesn’t take into account the full picture and the complexity of today’s software systems. Consider this for example: if you compile an application for x86, and then run it on a x64 CPU – is that really “native”? Arguably not.

CPU-native, unmanaged code, is becoming less and less relevant these days, and we believe true nativeness of code, of applications, and — most of all — of the developer experience defines itself by other criteria.

Here at RemObjects, we pride ourselves on providing truly native software development solutions for a variety of platforms. We consider two different and separate levels to determine what we consider “native” development: a native user experience, and a native developer experience.

A Native User Experience

What makes a native user experience? For a long time, there was only one platform for mainstream development: Windows. This has changed, and users are, by and large, choosing their work environment by preference. Even when avoiding to get into the “OS wars”, it cannot be disregarded that each platform out there today has its own distinct user paradigms, and that customers usually choose their computing platform carefully and want their applications to work and behave well on that particular system, adhering to their platform’s paradigms.

Windows users expect applications to behave “the Windows way”, and Mac users want them to work “the Mac way”. Similarly, iOS users want applications for their iPhones and iPads that fit in with that platform’s design philosophy, and Windows Phone (7) applications once again need to adhere to completely different UI paradigms than what Android users expect from their platform of choice.

Obviously, the degree to which applications need to fit in with their surrounding platform varies — most games, for example, usually sport more esoteric and platform-independent UIs (after all, they aim to take you out of your daily routing and immerse you in an entertainment experience), while business and productivity applications usually should adhere to the platform most strictly.

Nativeness also isn’t purely driven by using stock UI controls and themes exactly as prescribed. For example, many of the most famous and most well-respected iPhone applications add subtle textures or nuances to the OS provided controls. But they continue to feel “native”, because they stick to the basic UI paradigms, and the controls — while looking visually refined — look, feel and, most importantly, behave according to the user’s expectations.

This is generally achieved by using what is often referred to as the “native widget sets” of the platforms. Whether it’s a standard Win32 “Button” control or a native Mac NSButton, each widget set provides its own unique look and feel — from the spacing of text within the confines of the surrounding rectangle, over font sizes, styles and gradient strengths and directions, to the intricate details of how the control reacts and animates when it is clicked or touched. These subtle details are ingrained in the user’s mind; the user has subconscious expectations for how the control will feel when used, often down to the timing of animations. What may seem like unnecessary attention to detail becomes crucial to the user’s experience, and the user will feel an “Uncanny Valley” effect, if their expectations are not met.

But nativeness extends beyond just user controls. Most operating systems provide a lot of general infrastructure that users are used to seeing and working with — from the standardized Open/Close or Print dialogs on desktops to OS-provided Email or Tweet sheets on phones.

We believe that in order to create a truly native user experience with your application, your development tools need to let you work with the native widgets and infrastructure of the platform. No matter how much effort is put into “one size fits all” libraries, no cross-platform button will ever truly feel like a standard Windows button, like a standard Mac button, like a standard iOS button. In order to treat your customers to a truly native application, you need to choose a development tool chain that lets you work against the native platform.

Currently, such tool chains include .NET/WPF, Metro/WinRT, Delphi/VCL (for Windows), Objective-C/Xcode (for Mac and iOS), MonoMac and MonoTouch (for Mac and iOS, respectively), Java (for Android) or MonoDroid (also for Android).

It goes without saying that here at RemObjects we try to support developers with all of these tool chain choices. On the compiler side with Oxygene, we don’t have full coverage, but we can provide support for .NET and WinRT, all the Mono variations, as well as native Java/Android with our new Oxygene for Java. With our Data Abstract product suite, we have you covered on literally each and every one of the combinations listed above.

But: we believe that a native user experience, while key, is only half the story for successful app development.

A Native Developer Experience

Back in the day when Win32 was the gold standard of operating system APIs (and before), developer tools needed to provide strong abstraction layers for developers to work against — because the OS APIs themselves were so basic that working against them directly was akin to working in assembly language (or was, in fact, working in assembly).

When tools like the later Turbo Pascals, Visual Basic, or Delphi first came out, development against the core DOS or Win16/Win32 APIs was a chore, so developers welcomed abstraction layers that made coding easier, from basic class libraries to UI abstraction layers such as TurboVision, OWL, the VCL, or MFC.

But platforms have evolved, and with the likes of Microsoft’s .NET and WinRT, Apple’s Cocoa (and Cocoa Touch) or Android’s Java-based Dalvik, OS APIs have long reached a level that is developer friendly, a level that can and should be coded directly against.

Further abstractions on top of these APIs are a distraction, not a help to the developer, as they add an extra layer of unnecessary overhead to both the application and the development experience. And such abstractions have repeatedly shown to be failures, like when VCL.NET tried to reconstruct Delphi’s well-liked class library on top of the (already much more evolved and sophisticated, but orthogonal and thus incompatible) .NET Framework (then at early version 1.1).

Unnecessary abstractions of already good (or great) APIs serve no purpose to the developers using them. On the contrary, they separate developers from the platform, and from each other. For every article, sample or blog post provided by, say, Apple or the Cocoa community that shows how to use a feature of iOS, there has to be the equivalent “and here is how you do it in MonoTouch”, “and here is how you do it in FireMonkey”, “and here is how you do it in …”. The abstraction keeps developers from being able to (re)use the platform vendor’s documentation or samples. Worse, it fragments the developer community on the same platform, keeping programmers from interacting and sharing code — every Cocoa control written in MonoTouch is a Cocoa control that can’t be easily reused by a developer using the native Xcode/Objective-C toolchain (nor by a developer using FireMonkey, or Titanium, or any other abstraction layer).

Abstractions also keep developers from adopting new platform features quickly and easily. When the latest SDKs from the platform vendor come out, developers using the native tool chains usually can start working with the new technologies from day one (or even earlier). The very moment a new Android SDK hits, native Java developers can consume the new APIs. The very day a new iOS version becomes available, Cocoa developers can start getting their fingers dirty with the new goodness. All the while developers stuck behind a non-native abstraction layer need to wait for their tool vendor to abstract the new APIs for them.

Not to mention that non-native development tools will often lock you in and force you to stick with the abstraction layer.

The main selling point and attractiveness of a non-native tool chain usually is “familiarity”, the notion that the abstraction layer will let you get into a new platform without the steep learning curve of, well, learning a new platform.

But that is misleading and frequently turns out not to be the case. The main learning curve on a new platform is usually not the development language, or even the class framework — it is getting to know the platform itself and how to write great applications for that platform (looping us back to our first criterium: the native user experience).

Working with an abstraction layer turns out to actually have the opposite effect than intended, by making it harder to understand the platform vendor’s documentation (which is all tailored towards the platform-native tools, of course) and making it harder to re-use existing code samples found online.

To go back to the example of iOS: having to look at and understand documentation or samples written for Cocoa’s Objective-C APIs might seem difficult, if one is not yet familiar with the paradigms of Objective-C. But what’s actually more difficult is having to look at that same documentation or sample and then having to figure out how it translates to your — say — C#-based abstraction layer.

And no abstraction layer is ever perfect. Eventually, the underlying platform and its APIs will leak through and will have to be dealt with. Any efforts to avoid getting to know and understand the platform before developing on it is misguided and only delays the inevitable. Eventually the abstraction is missing a feature and the developer has to dig down to the base APIs and implement it themselves. Or a bug arrises that needs more debugging than the abstraction layer supports.

As with the native user experience, here at RemObjects Software we have made it our mission to support (and encourage) developers to use platform-native development tools; you’ll notice we’ll even encourage developers to go for the more native tool chain in cases where recommending a less native solution would mean an additional sale for us.

On the compiler front, Oxygene supports platform native development on classic Windows, Metro (Windows 8) and Android, and it is also a great choice for cross-platform servers based on Mono. The one notable omission is iOS and Mac, for which we recommend the excellent Xcode and Objective-C, even though Oxygene can support it via non-native development tool chains such as Mono and MonoTouch or Java.

With the Data Abstract suite, we support native development for all current major platforms: classic Windows (via .NET and Delphi), Windows Phone, Mac and iOS, as well as Android and other Java-based platforms (Data Abstract for Java is currently in beta).

Other Concerns, Such as Code Reuse

We realize of course that other factors play into the decision for the development tool chain. Considerations such as code reuse might rank higher on the list of priorities than a native development experience, and that is ok.

Our philosophy is that, all other things being equal, developers should aim for a toolchain that is native on both accounts: user experience and developer experience. If necessary, a compromise in developer experience can be made — it is after all a compromise that affects only the developer, if pursued correctly. No compromise, in our experience, should ever be made with regard to providing a truly native user experience.

In terms of code reuse between platforms, we at RemObjects Software aim to help, both on the language front (by providing the common Oxygene language as developer-native language for .NET, WinRT and Java/Android, at least) and on the back-end database front, by keeping Data Abstract wire compatible and letting you share a common server infrastructure for all your native client applications.

Read More

You can find out more about our cross-platform, platform-native products, Oxygene and Data Abstract, at remobjects.com/oxygene and remobjects.com/da, respectively.

And you can find an overview matrix of how our products fit into the various native (as well as semi-native and non-native, if you must go there) development chains, at remobjects.com/products/toolchains.

Thank you for reading, and we are looking forward to your feedback and comments.

Avatar of marc

by marc

This Week on the Wikis

April 18, 2012 in non-tech, ROFX, Wiki

Hi.

About a month ago, we started with a major focus shift towards our documentation wiki (at wiki.remobjects.com. Back when we first started the wiki, years ago, it was an innovative step in developer product documentation and provided a level of information and access that few other component and tool vendors offered. A lot of time has passed since, and we felt that a refresh is needed in order to provide even better and more thorough documentation across our products, from Articles over How Tos, and Samples to core Library Reference docs.

This will be a lengthy process, and you won’t see the wiki radically change over night, but instead, all thru the rest of the year, you should see steady progress and steady improvements both to the kind of information we provide and to how it is provided and accessed.

To accompany that, we want to start a (semi-)weekly series here on the blogs where we will keep you informed about what new content (and infrastructure) has been added in the past week (or so). Because we have a bit of a head start, this first post in the series will be a whopper.

Changed, Cleaner Per-Product Sections

The first thing you’ll see when you visit a product page on the wiki is that we’ve restructured each product’s root page (for example DA/.NET into four big categories — indicated by four big icons across the top.

These same 4 sections will greet you for every product, and they are:

Getting Started: Clicking this section will give you a page with a curated, hand-picked selection of articles, how-tos and (external) videos from RemObjects TV, streamlined to get new users (or existing ones) started with the product. For each product, we start with a detailed look at our project wizard(s) and a walk-thru of the project they generate. And we provide a list of How-Tos and articles about common tasks or goals that users will be likely to want to achieve after starting a fresh project.

If you look at these Getting Started pages now, you will still see a lot of red. That is because we purposely started with a blank slate: we did not want exiting content to drive these pages, so instead, we sat down and approached this from the user’s perspective: “What would you want to do next?”, and added the appropriate links. These will now need to be be filled — some by redirecting or reworking existing content, many of them, with fresh content.

Samples: Almost as important as starting a new project is to find your way around the existing sample projects. Each product now has a thorough overview page that covers all the sample applications we ship (for example RemObjects SDK Samples). The different editions of our respective products aren’t islands, and the samples from the different editions often work together or complement each other; that’s why each product has a shared page that covers the samples across all the platforms, where you can see how it all fits together, and, of course, dive into each of the individual samples.

As with the getting started, we have a lot of coverage still ahead of us, but you will see that quite a few samples are already covered.

Articles: For each product, the articles section (e.g. DA/Xcode will provide direct access to all the articles available for that product. We have always had tools in place that helped us manage the wiki and generate pages, and in the past we mostly used that for library documentation (more on that later). We’ve now extended that so that the Articles (and HowTos) sections are completely driven and auto-generated by meta-data in the individual articles. Each article topic in the wiki now contains meta-information on which product, platform(s), categories, classes and concepts it pertains to, allowing us to generate automatic (but designed to be human-readable) index pages. Articles can automatically reference the classes or concepts they refer to, just as the class documentation can automatically get links to articles that touch on a specific class.

We have started this process with a handful of articles — some new, some pre-existing, but reviewed and approved, so the lists will start out small, but over time we’ll be adding more new articles, as well as reviewing existing content and bringing it into the system if it is still up-to-date.

How-Tos: How-Tos essentially follow the same structure as articles, but are shorter topics that focus on individual tasks (“How do do i display my data in an NSTableView?”).

The Getting Started section is, essentially, a selective view into the larger pools of content that are Articles and How-Tos. These two sections show you all content, while Getting Started shows a hand-picked subset.

Library Docs

We’re also working on a brand new infrastructure for library documentation, which we’ll give more focus in a future blog post. In the past, we automatically generated the basic structure of the class reference pages, and then filled them within the wiki. With our new tool chain, the entire class documentation will be maintained externally, and emitted into the wiki automatically — this gives us more opportunities to use this documentation in other ways, too (for example for generating XmlDoc files), in the long run.

More about that, later.

Better Separation of “work in progress”

In the past, work on new pages (or even creation of empty stub pages) was done on the page’s final URL. This meant that when these pages were linked elsewhere, the links would show blue (instead of the red you see for a missing page), but when you clicked them, you got to an incomplete or empty page. That was frustrating. We are changing this now, so that new pages get written in different locations (with a “WIP” prefix in the URL), until they are ready for consummation. This way, we can start adding links to them, but those links will be immediately obvious as not having content yet. Only when the page is ready will it be relocated, and all the links will turn blue.

In some places (such as the automatically generated Articles lists), you will see that we add a blue “(WIP)” behind the red link, so visitors can find the work-in-progress pages, if interested.

New Content

Let us know what you think! And stay tuned to this space for continued updates.

Windows 8? We got you covered!

April 17, 2012 in .NET, Delphi, JavaScript, Metro, Month of Metro, Oxygene, Visual Studio, Windows

I updated this slide from //Build/Windows 2011 to show where you can use RemObjects Software’s tools with the Windows 8 Platform and Tools.

Naturally, you can continue to use our tools for Delphi and .NET for desktop application development with Oxygene for .NET, Data Abstract and RemObjects SDK. If you are using Hydra, you can even combine Managed .NET and Unmanaged Delphi for the best of both worlds.  Then, with our latest JavaScript client libraries, we also have you covered in the browser.

The part that everyone is interested in is the new Metro style apps. These are the apps designed for touch on tablets and the desktop, and running in the Metro area of Windows 8. Most importantly, Metro style apps are the only ones available through the Windows Store. We got you covered for Metro, too. The latest betas of our .NET editions work with C#, VB and Oxygene for .NET to build XAML based Metro User Interfaces. Thanks to Windows 8′s new support for JavaScript based Metro apps, you can use our JavaScript client libraries for Data Abstract and RemObjects SDK to build Metro apps based on JavaScript and HTML/CSS too.

We are not in the unmanaged Metro space yet. Currently, the only tools that are supported there are Visual C and C++, which we don’t have libraries for. Hopefully in the future we will see that gap filled in one way or another.

One important thing to point out about the JavaScript client libraries is that they ship with all editions, including our Delphi editions. That means if you currently are building solutions with DA/Delphi or RO/Delphi, you can add JavaScript Metro client applications to your solution, all with the RemObjects licenses you have today. We will soon be offering DA/JavaScript as a free separate download too.

Currently, Metro support is only available in our beta builds (which are available to all users with current subscriptions). Rest assured that we will have final versions of our Metro support by the time Windows 8 ships.

Use Oxygene in the 2nd PGD Challenge

March 22, 2012 in .NET, Java, Oxygene, Prism, short

The 2nd Pascal Game Development challenge was officially announced, and Oxygene for .NET (AKA Prism) and Oxygene for Java are both listed as “Key Tools” and “Allowed Languages“. If you are using Oxygene for Java, you might want to take a look at the JMonkey Engine video on RemObjects TV back from when we were still calling it “Cooper”.

As an added bonus, if your game is powered by Oxygene, we will provide you with a complementary Oxygene for Java license.