Category Archives: General

For stuff I forget to categorise! Doh!

InterBase XE7 – First Look Events!!

InterBase XE7 First look live and online!

Starting with the InterBase Product Address at CodeRage 9 news about the new edition of InterBase has been slowly spreading.

InterBase project DeltaForce, named due to its new patent pending technology for tracking and querying of deltas, is a highly scalable, low footprint answer to a number of distributed data set questions.

I’m really excited about what we have coming up in the InterBase XE7 preview events.  I will be hitting the road over the coming weeks in person to present and talk to developers, system architects etc about what InterBase DeltaForce (XE7) can help you achieve and how it can dramatically assist you throughout the product life cycle.

InterBase XE7 First Look – LIVE!

I will be in the following cities over the next few weeks for live preview workshops

InterBase XE7 First Look – Webinar

If your unable to attend one of the live events, then a global live webinar, repeated in 3 time zones, will be going out Thursday 4th December.InterBase XE7 First Look

  • 6AM San Francisco / 9AM New York / 2PM London
  • 11AM San Francisco / 2PM New York / 7PM London

5PM San Francisco / 5-Dec 10AM Tokyo / 5-Dec 12PM Sydney
http://embt.co/IBXE7FirstLook

Can’t wait?

If you are a current InterBase customer, then we still have space on the beta for those of you who really can’t wait. Register now and get priority access to explore InterBase DeltaForce now!

To keep up on on the latest, please follow @InterBase on twitter.

InterBase CodeRage 28th-30th November

CodeRage 9Register NOW and join me live at #CodeRage!

CodeRage is a fantastic Object Pascal programming and C++ Programming event – highly recommended for any developer, and best of all – REGISTRATION IS FREE!!

Missed it or got a meeting? – Don’t worry, register and you can still get to see the replays!

My two InterBase CodeRage Sessions!

I will be presenting two InterBase CodeRage sessions on Thursday 30th November 2014

  • the InterBase Keynote (8am Pacific / 4pm UK / 5pm CET) where we will be revealing some of the exciting new developments we are working on with InterBase with project DeltaForce!
  • I will also be talking about InterBase’s free edition that can be used on Windows, Mac OS X, Android and iOS – IBLite in the session Embedding local and remote data access into your applications with IBLite (3pm – C++ & 6pm – Object Pascal)

For times and details of all sessions visit the CodeRage website – See you there!!

 

Expanding FireMonkey TPlatformServices

Over this post, I want to introduce the concept of an Interface and then look at how using Interfaces allows you to expand the FireMonkey TPlatformServices in XE7 – using an example of adding custom support for FullScreen mode on iOS, where it currently isn’t supported out the box.

Interfaces & OOP – Quick Introduction.

For those of you who are aware of what an interface is, you way want to skip the first sections.

Delphi & AppMethod are built on top of the Object Pascal programming language which, as its name suggests is an Object Orientated Programming language – OOP.

Part of OOP is the concept of Interfaces;  Interfaces are in short a contract that classes can then implement and support. Unlike object inheritance (where you can only descend from a single object), an object can introduce and support multiple interfaces at the same time. The great thing about Interfaces is the ability to ask an object if it supports a specific Interface, and if it does, telling it to go do a specific supported method.

Example of an Interface – ISteeringWheel

I am sure we all know what a steering wheel is so lets imagine we have defined in our code an interface ISteeringWheel that can be turned left and turned right with two method TurnLeft and TurnRight

type 
  ISteeringWheel = Interface
  ['{F4F8536B-FCA6-48D1-B3D4-AF4EE9B90964}']
    procedure TurnLeft;
    procedure TurnRight;
  end;

But where are we going to use this SteeringWheel? It could be on a TCar or a TBoat or even a TAirplane.

The job of implementing the code and what happens when you call a method of an Interface is down to the object that supports that interface.

TCar = class(TInterfacedObject, ISteeringWheel)
public
  // Turns wheels
  procedure TurnLeft;
  procedure TurnRight;
end;

TBoat = class(TInterfacedObject, ISteeringWheel)
public
  // Changes the rudder
  procedure TurnLeft;
  procedure TurnRight;
end;

How does this relate to Platform Services?

If we think about phones, tablets, laptops etc, not all devices support the same capabilities; e.g. my iPad doesn’t have a sim card so doesn’t support making calls.  FireMonkey works with this complexity by defining Interfaces that can be queried at run time to determine if a device supports specific capabilities.  By having a contract in code, the platforms are then able to provide to you an object that supports the platform, but also the Interface.

Using our example above, lets imagine, TCar and TBoat are like Android and iOS, and the SteeringWheel is a compass, then you would start to understand that by asking at run time if the compass is supported, we get an iOS or Android object that we know how to talk to as it supports the appropriate interface, but under the hood calls the platform specific API’s.

TPlatformServices and IFMXFullScreenWindowService

So now we understand about Interfaces and how to use them, lets look into a real implementation and how we can use this to update the way the system works by providing a supported Interface.

The IFMXFullScreenWindowService interface supports 3 methods that allow you to find out if the application is running in FullScreen mode (Get), or put it into FullScreen mode (Set) and also define if the Icon is seen.

(I’ve removed the parameters here to make it more readable)

IFMXFullScreenWindowService = interface(IInterface)
  ['{103EB4B7-E899-4684-8174-2EEEE24F1E58}']
  procedure SetFullScreen(....);
  function GetFullScreen(....): Boolean;
  procedure SetShowFullScreenIcon(....);
end;

This Interface has been used by TCommonCustomForm and descendants (of which TForm is the one you will probably be using) and wrapped up into an easy to call property – FullScreen.

To change between full screen and non full screen at run time is as simple as

procedure TForm1.Button1Click(Sender: TObject);
begin
  FullScreen := not FullScreen;
end;

This property was introduced in RAD Studio XE7 / Appmethod September 2014 release and works on Windows, Mac OS X, and Android (Immersive mode). However, there is not an implementation for iOS.

While each platform behaves differently according to its design and platform norms, I want to show you how you can add support for iOS without having to change the common code that works on the other platforms.

Under the hood – FullScreen & TPlatformServices

So first, before we add the service I also want to cover for other examples how you check for a supported PlatformService Interface.

FireMonkey’s TPlatformServices (defined in FMX.Platform)  exposes the instance of TPlatformServices using the Current property.

TPlatformServices.Current

Once you have the Current TPlatformServices instance it can be queried for support of specific interfaces. One of those new interfaces is the IFMXFullScreenWindowService. To find out if it is supported we need to create a variable to point to the service and then ask if its supported. e.g.

var 
  FFullScreenSrvice: IFMXFullScreenWindowService;
begin
  TPlatformServices.Current.SupportsPlatformService(IFMXFullScreenWindowService, FFullScreenSrvice);
  if FFullScreenSrvice <> nil then 
    // its supported - make full screen
    FFullScreenSrvice.SetFullScreen(True);
end;

Once you have an instance of the Interface, you can then just call its methods. There is no need to free an interface as they are reference counted on all platforms.

Adding a new Interface implementation to TPlatformServices

To add a new platform service we again go back to TPlatformServices. There is a method called AddPlatformService. This takes 2 parameters, Firstly the interface you want to add and secondly the instance of an class supporting that Interface.

Using what we learned earlier about creating an object that supports and interface we first need to define a class (TFullScreenServiceiOS) defined  as a TInterfacedObject supporting the desired interface (IFMXFullScreenWindowService).

Full code can be downloaded from code central so you can see how GetFullScreen and SetFullScreen were fully implemented in code.

TFullScreenServiceiOS = class(TInterfacedObject,   IFMXFullScreenWindowService)
public
  function GetFullScreen(....): Boolean;
  procedure SetFullScreen(....);
  procedure SetShowFullScreenIcon(....);
end;

WIth the object defined and implemented, you can then register an instance with the application at run time.  As I only want this to register for iOS, one approach is to use IFDEF’s to call a register procedure during the initialisation of the application.

procedure RegisterFullScreenServiceiOS;
begin
  FullScreeniOS := TFullScreenServiceiOS.Create;
  TPlatformServices.Current.AddPlatformService(
     IFMXFullScreenWindowService, FullScreeniOS);
end;

{$IFDEF IOS}
initialization
  RegisterFullScreenServiceiOS;
{$ENDIF}

With this code in place, it is now possible to run the same application code on iOS and see the FullScreen := not FullScreen move the application in and out of FullScreen mode as it is now supported in iOS.

Summary

Thats it! –  Creating a new class that implements code and supports the interface and registering the class to the TPlatformServices is all you need to do to expand and modify the TPlatformServices.

The full source code for the TPlatformServices and IFMXFullScreenWIndowServices example can be downloaded from code central  http://cc.embarcadero.com/item/30023

Mobile Development Lessons – Delphi & C++

Free series of mobile development lessons for Android and iOS based on C++ and Object Pascal.

Earlier in the year the 2nd edition of the mobile development summer school was run by David I and Jim McKeeth. It was great fun doing the first edition and its amazing to see how some of the tech has moved on further in the year since we first ran summer school. This years was more popular than ever and has been made available on YouTube

YouTube Playlist for video replays

https://www.youtube.com/playlist?list=PLwUPJvR9mZHhLj-gegxc0KpGE0wL2zVBo

Blogs for slides and samples:

To get started is easy!

Download your free trial of RAD Studio https://downloads.embarcadero.com/free/rad_studio

or your FREE edition of Appmethod (C++ Free for Android mobile)
http://www.appmethod.com 

Happy Coding!

Parallel Programming Thread Pool

In my Parallel Programming introduction post I explored how to easily get performance gains when running loop code by using the TParallel.For() loop construct. A key part of the Parallel Programming Library engine is the new ThreadPool that manages some of the complexity behind the scenes when using this syntax, but more on that later.

Following on from this first post I want to explore a common question I have heard. Is it possible to manage the Parallel Programming library thread pool Size? and if so how?

In short Yes, but I want to pose another question: Should you? – Lets explore this below.

Parallel programming thread pool

The Parallel programming thread pool is very smart! It automatically grows and shrinks based on CPU demand when your application runs and requires its use; it also throttles growth as your CPU usage rises ensuring it doesn’t over cook your CPU and ensuring you don’t lock up your machine. This inbuilt intelligence makes it very efficient and courteous out the box. All of this, without ANY management from us developers! 🙂 So why would you want to change this?

Thats not to say you can’t use a custom(ised) pool. If you do want to limit the size of a pool then you can override the defaults of  a TThreadPool.

TThreadPool Defaults

Defined in System.Threading, TThreadPool initiates with a default of 25 threads per CPU.

MaxThreadsPerCPU = 25;

TThreadPool multiplies the MaxThreadsPerCPU with the number of CPU’s on the machine (it gets this form calling TThread.ProcessorCount) and exposes the result via a read only property TThreadPool.MaxWorkerThreads.

To query the default pool size on your machine at runtime you can use TThreadPool’s handy class method that returns the default pool. With this pool you can then query the MaxWorkerThreads. e.g.

var
  i : integer;
begin
  i := TThreadPool.Default.MaxWorkerThreads;
  ShowMessage('Pool size = '+i.ToString());
end;

On my Windows VM running 2 cores I see 50, but on my Mac OS X with 8 cores, this code returns 200.

Customising a TThreadPool

Let me start this section by saying, modifying the default TThreadPool properties is not recommended. 

While possible, it is not recommended to modify the Default TThreadPool options as this is a global instance that is used throughout the application, and you never can be sure where and when its being used. You can however create your own instance of a TThreadPool that you modify and use and this is a better approach.

Creating and modifiying a TThreadPool

Creating a TThreadPool is as simple as declaring the variable and calling the constructor.

With an instance of a TThreadPool, you can then modify the MaxWorkerThreads by overriding the value using the method SetMaxWorkerThreads() which takes in an Integer. This sets it at a flat number regardless of the number of CPU’s you have available.  e.g. the following code reports 10 as the Max size on both my Windows and Mac OSX machines mentioned above.

var
  FPool : TThreadPool;

...

if Pool = nil then begin
  Pool := TThreadPool.Create;
  Pool.SetMaxWorkerThreads(10);
end;

Note, the MaxWorkerThreads number must always be greater than the MinimumWorkerThreads value that (by default) is set from TThread.ProcessorCount.

A word of caution..

Creating a new TThreadPool come with an overhead. From an initial test where I creating a new TThreadPool for running a small TParallel.For() loop, and then disposing it afterwards it actually decrease performance on your application compared to a traditional for loop. For this reason alone, I would always use a global TThreadPool. When the pool was created globally, the speed performance was immediately backup compared to the create and destroy on demand idea.

 Example of using a custom TThreadPool

Below is an example where Pool is a global TThreadPool.  When the button is selected to run a TThreadPool with a maximum of 10 WorkerThreads. The only adjustments from the example in the previous tutorials is that we now pass in Pool as a paramater to the For loop, note however that this is not being created and free’ed each time in this code.

var
  Pool: TThreadPool;

procedure TForm5.Button1Click(Sender: TObject);
var
 Tot: Integer;
 SW: TStopwatch;
begin
 // counts the prime numbers below a given value
 Tot := 0;
 SW := TStopWatch.Create;
 SW.Start;

 if Pool = nil then begin 
   Pool := TThreadPool.Create;
   Pool.SetMaxWorkerThreads(10);
 end;
 TParallel.For(1, Max, procedure (I: Integer)
   begin
     if IsPrime (I) then
       TInterlocked.Increment (Tot);
   end,Pool);
 SW.Stop;
 Memo1.Lines.Add (Format (
 'Parallel (Custom Pool) for loop: %d - %d', [SW.ElapsedMilliseconds, Tot]));
end;

I would say that while this gives me a sense of control, I actually don’t like the fact that I am messing with something that is highly tuned. I would personally conclude that a ThreadPool should be created as the application has initialised and that you use this. Ideally I would say use the default one, as it behaviour is very good already, but if you really want to make more work for yourself, then you can always set the properties of a new pool and use it.

 A thank you to Allen Bauer for his input while writing this post.

Parallel Programming with Delphi XE7; a quick introduction

Everyone knows that typically device / computers today have multiple CPU’s, even my phone has 4! But when it comes to programming to get full benefits of working across those cores its often been a little tricky or time consuming and extra code overhead to manage.  Well… that is until now with Parallel Programming with Delphi!

Starting with Delphi, C++ Builder and RAD Studio XE7, there is a new library that simplifies the effort needed to get tasks running in parallel, aptly named the Parallel Programming Library.

The Parallel Programming Library lives within the System.Threading unit and is made up of a number of new helpful features that can be easily introduced into new and also existing projects. There are also loads of overloaded arguments for fine tuning and supporting C++ working with this as well as Object Pascal.

These features include a new Parallel for loop that is easy to uses, along side a number of more advanced features for running tasks, joining tasks, waiting on groups of tasks etc to process. Under the hood there is a thread pool that self tunes itself automatically (based on the load on the CPU’s).

To give you an idea about how easily this is to plug in, lets take a simple example where you want to work out if a number is a prime number.

function IsPrime (N: Integer): Boolean;
var
 Test: Integer;
begin
 IsPrime := True;
 for Test := 2 to N - 1 do
   if (N mod Test) = 0 then
   begin
     IsPrime := False;
     break; {jump out of the for loop}
   end;
end;

The traditional way to loop  and check for the number of prime numbers between 1 to X value would be to do something like this where each number is checked in sequence and the total stored into a variable (here Tot is an integer)

const
 Max = 50000; // 50K

for I := 1 to Max do
 begin
   if IsPrime (I) then
     Inc (Tot);
 end;

Using the new Parallel library, this can be achieved by replaces the “for” command with a call to the class function TParallel.For passing in the code to be run as an anonymous method.

In addition, to avoid clashes with multiple threads running, you can call TInterlocked.Increment.

TParallel.For(1, Max, procedure (I: Integer)
 begin
   if IsPrime (I) then
     TInterlocked.Increment (Tot);
 end);

So what difference does this make?

Using TStopWatch from System.Diagnostics we are able to test the time to run each version of the loop above. Even on my VM running only 2 cores the time drops from 415ms for the standard for loop down to 192ms using the Parallel programming library version. On my Mac where there are more cores available it goes from 382ms down to 90ms for the same test!

What I love about this, is this is a really easy solution to plug into existing code as its part of the language and framework.

The great thing about writing native code is that we can take advantage of all the cores on a device. 🙂 Including Mobiles! However, as a word of caution, use it only where you need to on mobile as it will use more battery if you are running multiple threads heavily.

Samples

An other example that can help get your head around how to use the Parallel Programming library is a sample of Conways game of life for both Object Pascal and C++ in the samples directory shipped with XE7, located in the RTL samples. e.g.

C:\Users\Public\Documents\Embarcadero\Studio\15.0\Samples\Object Pascal\RTL\Parallel Library
C:\Users\Public\Documents\Embarcadero\Studio\15.0\Samples\CPP\RTL\Parallel Library

Not sure about you, but I’m off to speed up some processing in some old projects I have 🙂 Happy coding!

Debugging to PA Server on Windows

PA Server – What and why?

When developing software for multiple platforms you often need to debug and run applications on machine and devices that are not your development PC. The RAD Studio and Appmethod approach to this is an ingenious little program that acts as a go-between from the IDE to the remote device / machine. Called PAServer (PA = Platform Assistant) allows the IDE to retrieve the full call stack at run time, pause code with break points, inspect values etc, exactly as you would do debugging a local application.

PA Server is often used on a Mac OS X target for running and debugging applications to Mac OS X, iOS Simulator and iOS Devices, however there is also a windows version of PAServer and this can also be used to simplify preparing for deployment.

PA Server runs over TCP/IP and while developers often use it for local network work, in theory there is no reason why you can not use it to remote debug that trouble some customer where you can’t quite recreate what they are doing. (as long as they are happy for you to install the PA Server client on their machine).

PA Server is also great for deploying files directly to a remote machine when used with the Deployment Options for the project. This ensures that all the files specified are pushed remotely. This is great for updating a remote server or internal build machines.

Installation of PAServer

PA Server needs to be installed on the machine you want to run applications on remotely The install files both Windows and Mac OS X are located in the PAServer folder under your Appmethod / RAD Studio / Delphi / C++ Builder installation. e.g. with RAD Studio XE7 they are located at C:\Program Files (x86)\Embarcadero\Studio\15.0\PAServer.

Both installers (Windows / Mac OS X) just require you to push the next button a few times to install the server.

Running PA Server remotely…

PA Server is ultimately a Console application that you launch, enter a session password (that remote developers will need to connect to the session) and leave running without having to go back to it, but this is how to launch it on each platform.

..on MAC OS X

To launch PAServer on a Mac you have two choices.

  1. Go to “Applications” and choose PAServer 15.0 (for XE7)
  2. Use the new GUI in LaunchPad called PAServer Manager PAServer Manager Icon

If you use PAServer Manager you will see the icon appear at the top of your screen in the menu bar. Clicking on this allows you to “Add Server” (I just call it MyMac by default) and then start and stop the services as well as other useful things like viewing the information (such as IP Address etc).  A lot easier than remembering command codes.

PA Server Manager

PA Server Manager is also useful for managing groups of developers who want to run multiple instances of PA Server on the same machine when developing.

..On Windows

To launch PA Server on windows once installed, you need to browse to the PAServer folder (typically C:\Program Files (x86)\Embarcadero\PAServer\15.0) and double click on the PAServer application.

PAServer on Windows Running
PAServer running on Windows

 Connecting to PAServer running on a Windows machine from the IDE

With PA Server installed, opened and a password set for the session, it is possible to make the remote connection (or even a loopback for a more advanced local test). To achieve this we need to configure a profile for connecting to the remote PAServer instance. – this is really quick to do.

Firstly select the desired compilation target of Win32 or Win64  in the Project Manager, and then right click and choose properties.  The platform properties window is then opened allowing you to choose a profile for the target.

Platform Properties

By default you will need to choose “Add New…” under platforms the first time you run this step, subsequently you will already have the profile saved.

 

Following the wizard for Add New, you can enter a name (e.g. MyPC) and then the IP address (port 64211 should be default unless you have changed it during install). Once you have the IPAddress or pc name entered you can “Test Connection” to verify that the path is working correctly.

Platform Properties Wizard 2

If this fails then check you IP Address is correct – if unsure type “i” into the PAServer console and hit enter to get a list of the listening IPAddresses and check your firewall.

Once you have selected the Platform Profile and its tested, all you need to do is hit run just like before.  Rather than deploying to your project directory, deploying to PA Server sends out all the files into a the PAServer scratch directory (under Documents\PAServer) e.g. C:\Users\Steve\Documents\PAServer\15.0\scratch-dir\

Tip for making things simple?

If you have selected any feature files or added your own files under Deployment Options when developing your applications, e.g. enabling InterBase, IBLite or DBExpress etc. These files will be packaged up for you when running out to PAServer giving you a complete folder structure with files ready for packaging. This also makes testing locally a lot lot simpler 🙂

Getting back to normal

Once you are done testing against a remote profile you can easily return to running locally by right clicking on the target and choosing to Revert to Default Connection.

Revert to default connection

Summer School 2014 – Android and iOS development training

Last year I had the pleasure of hosting the majority of the mobile development training series “Developer Direct – Summer School“.  It was great fun covering everything from Application UI design to local storage through to remote data collection.

The last year has seem some major enhancements to RAD Studio and Appmethod with new components making some of this easier and more exciting with new possibilities, so the content has been updated and re-run by David I and Jim McKeeth in both C++ and Object Pascal/Delphi programming lessons.

SummerSchool2014

To watch the 6 iOS and Android native development lessons register for free at http://forms.embarcadero.com/RADSummerSchool2014